Sonic Blaze Testnet

Token

Beanz (BEANZ)
ERC-20

Overview

Max Total Supply

54,454.626783037233470236 BEANZ

Holders

10

Market

Price

$0.00 @ 0.000000 S

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
10,977.333739284124649745 BEANZ
0x8ddb1591ba5abab6035c41c81fcda89bef90bd6b
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
BEANZ

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 13 : Beanz.sol
//SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable2Step.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";

contract BEANZ is ERC20Burnable, Ownable2Step, ReentrancyGuard {
    address payable public FEE_ADDRESS;

    uint256 private constant MIN = 1000;

    uint16 public sell_fee = 975;
    uint16 public buy_fee = 975;
    uint16 public buy_fee_leverage = 10;
    uint16 private constant FEE_BASE_1000 = 1000;

    uint16 private constant FEES_BUY = 125;
    uint16 private constant FEES_SELL = 125;

    bool public start = false;

    uint128 private constant SONICinWEI = 1 * 10 ** 18;

    uint256 private totalBorrowed = 0;
    uint256 private totalCollateral = 0;

    uint128 public constant maxSupply = 10e28;
    uint256 public totalMinted;
    uint256 public lastPrice = 0;

    struct Loan {
        uint256 collateral; // shares of token staked
        uint256 borrowed; // user reward per token paid
        uint256 endDate;
        uint256 numberOfDays;
    }

    mapping(address => Loan) public Loans;

    mapping(uint256 => uint256) public BorrowedByDate;
    mapping(uint256 => uint256) public CollateralByDate;
    uint256 public lastLiquidationDate;
    event Price(uint256 time, uint256 price, uint256 volumeInSonic);
    event MaxUpdated(uint256 max);
    event SellFeeUpdated(uint256 sellFee);
    event FeeAddressUpdated(address _address);
    event BuyFeeUpdated(uint256 buyFee);
    event LeverageFeeUpdated(uint256 leverageFee);
    event Started(bool started);
    event Liquidate(uint256 time, uint256 amount);
    event LoanDataUpdate(
        uint256 collateralByDate,
        uint256 borrowedByDate,
        uint256 totalBorrowed,
        uint256 totalCollateral
    );
    event SendSonic(address to, uint256 amount);

    constructor() ERC20("Beanz", "BEANZ") Ownable(msg.sender) {
        lastLiquidationDate = getMidnightTimestamp(block.timestamp);
    }
    function setStart() public payable onlyOwner {
        require(FEE_ADDRESS != address(0x0), "Must set fee address");
        uint256 teamMint = msg.value * MIN;
        require(teamMint >= 1 ether);
        mint(msg.sender, teamMint);

        _transfer(
            msg.sender,
            0x000000000000000000000000000000000000dEaD,
            1 ether
        );
        start = true;
        emit Started(true);
    }

    function mint(address to, uint256 value) private {
        require(to != address(0x0), "Can't mint to to 0x0 address");
        totalMinted = totalMinted + value;
        require(totalMinted <= maxSupply, "NO MORE BEANZ");

        _mint(to, value);
    }

    function setFeeAddress(address _address) external onlyOwner {
        require(
            _address != address(0x0),
            "Can't set fee address to 0x0 address"
        );
        FEE_ADDRESS = payable(_address);
        emit FeeAddressUpdated(_address);
    }

    function setBuyFee(uint16 amount) external onlyOwner {
        require(amount <= 992, "buy fee must be greater than FEES_BUY");
        require(amount >= 975, "buy fee must be less than 2.5%");
        buy_fee = amount;
        emit BuyFeeUpdated(amount);
    }
    function setBuyFeeLeverage(uint16 amount) external onlyOwner {
        require(amount <= 25, "leverage buy fee must be less 2.5%");
        require(amount >= 0, "leverage buy fee must be greater than 0%");
        buy_fee_leverage = amount;
        emit LeverageFeeUpdated(amount);
    }
    function setSellFee(uint16 amount) external onlyOwner {
        require(amount <= 992, "sell fee must be greater than FEES_SELL");
        require(amount >= 975, "sell fee must be less than 2.5%");
        sell_fee = amount;
        emit SellFeeUpdated(amount);
    }
    function buy(address receiver) external payable nonReentrant {
        liquidate();
        require(start, "Trading must be initialized");

        require(receiver != address(0x0), "Reciever cannot be 0x0 address");

        // Mint Beanz to sender
        // AUDIT: to user round down
        uint256 beanz = SONICtoBEANS(msg.value);

        mint(receiver, (beanz * getBuyFee()) / FEE_BASE_1000);

        // Team fee
        uint256 feeAddressAmount = msg.value / FEES_BUY;
        require(feeAddressAmount > MIN, "must trade over min");
        sendSonic(FEE_ADDRESS, feeAddressAmount);

        safetyCheck(msg.value);
    }
    function sell(uint256 beanz) external nonReentrant {
        liquidate();

        // Total Eth to be sent
        // AUDIT: to user round down
        uint256 sonic = BEANStoSONIC(beanz);

        // Burn of JAY
        uint256 feeAddressAmount = sonic / FEES_SELL;
        _burn(msg.sender, beanz);

        // Payment to sender
        sendSonic(msg.sender, (sonic * sell_fee) / FEE_BASE_1000);

        // Team fee

        require(feeAddressAmount > MIN, "must trade over min");
        sendSonic(FEE_ADDRESS, feeAddressAmount);

        safetyCheck(sonic);
    }

    // Calculation may be off if liqudation is due to occur
    function getBuyAmount(uint256 amount) public view returns (uint256) {
        uint256 beanz = SONICtoBEANSNoTrade(amount);
        return ((beanz * getBuyFee()) / FEE_BASE_1000);
    }
    function leverageFee(
        uint256 sonic,
        uint256 numberOfDays
    ) public view returns (uint256) {
        uint256 mintFee = (sonic * buy_fee_leverage) / FEE_BASE_1000;

        uint256 interest = getInterestFee(sonic, numberOfDays);

        return (mintFee + interest);
    }

    function leverage(
        uint256 sonic,
        uint256 numberOfDays
    ) public payable nonReentrant {
        require(start, "Trading must be initialized");
        require(
            numberOfDays < 366,
            "Max borrow/extension must be 365 days or less"
        );

        Loan memory userLoan = Loans[msg.sender];
        if (userLoan.borrowed != 0) {
            if (isLoanExpired(msg.sender)) {
                delete Loans[msg.sender];
            }
            require(
                Loans[msg.sender].borrowed == 0,
                "Use account with no loans"
            );
        }
        liquidate();
        uint256 endDate = getMidnightTimestamp(
            (numberOfDays * 1 days) + block.timestamp
        );

        uint256 sonicFee = leverageFee(sonic, numberOfDays);

        uint256 userSonic = sonic - sonicFee;

        uint256 feeAddressAmount = (sonicFee * 3) / 10;
        uint256 userBorrow = (userSonic * 99) / 100;
        uint256 overCollateralizationAmount = (userSonic) / 100;
        uint256 subValue = feeAddressAmount + overCollateralizationAmount;
        uint256 totalFee = (sonicFee + overCollateralizationAmount);
        uint256 feeOverage;
        if (msg.value > totalFee) {
            feeOverage = msg.value - totalFee;
            sendSonic(msg.sender, feeOverage);
        }
        require(
            msg.value - feeOverage == totalFee,
            "Insufficient sonic fee sent"
        );

        // AUDIT: to user round down
        uint256 userBeanz = SONICtoBEANSLev(userSonic, subValue);
        mint(address(this), userBeanz);

        require(feeAddressAmount > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressAmount);

        addLoansByDate(userBorrow, userBeanz, endDate);
        Loans[msg.sender] = Loan({
            collateral: userBeanz,
            borrowed: userBorrow,
            endDate: endDate,
            numberOfDays: numberOfDays
        });

        safetyCheck(sonic);
    }

    function getInterestFee(
        uint256 amount,
        uint256 numberOfDays
    ) public pure returns (uint256) {
        uint256 interest = Math.mulDiv(0.039e18, numberOfDays, 365) + 0.001e18;
        return Math.mulDiv(amount, interest, 1e18);
    }

    function borrow(uint256 sonic, uint256 numberOfDays) public nonReentrant {
        require(
            numberOfDays < 366,
            "Max borrow/extension must be 365 days or less"
        );
        require(sonic != 0, "Must borrow more than 0");
        if (isLoanExpired(msg.sender)) {
            delete Loans[msg.sender];
        }
        require(
            Loans[msg.sender].borrowed == 0,
            "Use borrowMore to borrow more"
        );
        liquidate();
        uint256 endDate = getMidnightTimestamp(
            (numberOfDays * 1 days) + block.timestamp
        );

        uint256 sonicFee = getInterestFee(sonic, numberOfDays);

        uint256 feeAddressFee = (sonicFee * 3) / 10;

        //AUDIT: beanz required from user round up?
        uint256 userBeanz = SONICtoBEANSNoTradeCeil(sonic);

        uint256 newUserBorrow = (sonic * 99) / 100;

        Loans[msg.sender] = Loan({
            collateral: userBeanz,
            borrowed: newUserBorrow,
            endDate: endDate,
            numberOfDays: numberOfDays
        });

        _transfer(msg.sender, address(this), userBeanz);
        require(feeAddressFee > MIN, "Fees must be higher than min.");

        sendSonic(msg.sender, newUserBorrow - sonicFee);
        sendSonic(FEE_ADDRESS, feeAddressFee);

        addLoansByDate(newUserBorrow, userBeanz, endDate);

        safetyCheck(sonicFee);
    }
    function borrowMore(uint256 sonic) public nonReentrant {
        require(!isLoanExpired(msg.sender), "Loan expired use borrow");
        require(sonic != 0, "Must borrow more than 0");
        liquidate();
        uint256 userBorrowed = Loans[msg.sender].borrowed;
        uint256 userCollateral = Loans[msg.sender].collateral;
        uint256 userEndDate = Loans[msg.sender].endDate;

        uint256 todayMidnight = getMidnightTimestamp(block.timestamp);
        uint256 newBorrowLength = (userEndDate - todayMidnight) / 1 days;

        uint256 sonicFee = getInterestFee(sonic, newBorrowLength);

        //AUDIT: beanz required from user round up?
        uint256 userBeanz = SONICtoBEANSNoTradeCeil(sonic);
        uint256 userBorrowedInBeanz = SONICtoBEANSNoTrade(userBorrowed);
        uint256 userExcessInBeanz = ((userCollateral) * 99) /
            100 -
            userBorrowedInBeanz;

        uint256 requireCollateralFromUser = userBeanz;
        if (userExcessInBeanz >= userBeanz) {
            requireCollateralFromUser = 0;
        } else {
            requireCollateralFromUser =
                requireCollateralFromUser -
                userExcessInBeanz;
        }

        uint256 feeAddressFee = (sonicFee * 3) / 10;

        uint256 newUserBorrow = (sonic * 99) / 100;

        uint256 newUserBorrowTotal = userBorrowed + newUserBorrow;
        uint256 newUserCollateralTotal = userCollateral +
            requireCollateralFromUser;

        Loans[msg.sender] = Loan({
            collateral: newUserCollateralTotal,
            borrowed: newUserBorrowTotal,
            endDate: userEndDate,
            numberOfDays: newBorrowLength
        });

        if (requireCollateralFromUser != 0) {
            _transfer(msg.sender, address(this), requireCollateralFromUser);
        }

        require(feeAddressFee > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressFee);
        sendSonic(msg.sender, newUserBorrow - sonicFee);

        addLoansByDate(newUserBorrow, requireCollateralFromUser, userEndDate);

        safetyCheck(sonicFee);
    }

    function removeCollateral(uint256 amount) public nonReentrant {
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        liquidate();
        uint256 collateral = Loans[msg.sender].collateral;
        // AUDIT: to user round down
        require(
            Loans[msg.sender].borrowed <=
                (BEANStoSONIC(collateral - amount) * 99) / 100,
            "Require 99% collateralization rate"
        );
        Loans[msg.sender].collateral = Loans[msg.sender].collateral - amount;
        _transfer(address(this), msg.sender, amount);
        subLoansByDate(0, amount, Loans[msg.sender].endDate);

        safetyCheck(0);
    }
    function repay() public payable nonReentrant {
        uint256 borrowed = Loans[msg.sender].borrowed;
        require(borrowed > msg.value, "Must repay less than borrowed amount");
        require(msg.value != 0, "Must repay something");

        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, cannot repay"
        );
        uint256 newBorrow = borrowed - msg.value;
        Loans[msg.sender].borrowed = newBorrow;
        subLoansByDate(msg.value, 0, Loans[msg.sender].endDate);

        safetyCheck(0);
    }
    function closePosition() public payable nonReentrant {
        uint256 borrowed = Loans[msg.sender].borrowed;
        uint256 collateral = Loans[msg.sender].collateral;
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        require(borrowed == msg.value, "Must return entire borrowed amount");
        _transfer(address(this), msg.sender, collateral);
        subLoansByDate(borrowed, collateral, Loans[msg.sender].endDate);

        delete Loans[msg.sender];
        safetyCheck(0);
    }
    function flashClosePosition() public nonReentrant {
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        liquidate();
        uint256 borrowed = Loans[msg.sender].borrowed;

        uint256 collateral = Loans[msg.sender].collateral;

        // AUDIT: from user round up
        uint256 collateralInSonic = BEANStoSONIC(collateral);
        _burn(address(this), collateral);

        uint256 collateralInSonicAfterFee = (collateralInSonic * 99) / 100;

        uint256 fee = collateralInSonic / 100;
        require(
            collateralInSonicAfterFee >= borrowed,
            "You do not have enough collateral to close position"
        );

        uint256 toUser = collateralInSonicAfterFee - borrowed;
        uint256 feeAddressFee = (fee * 3) / 10;

        sendSonic(msg.sender, toUser);

        require(feeAddressFee > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressFee);
        subLoansByDate(borrowed, collateral, Loans[msg.sender].endDate);

        delete Loans[msg.sender];
        safetyCheck(borrowed);
    }

    function extendLoan(
        uint256 numberOfDays
    ) public payable nonReentrant returns (uint256) {
        uint256 oldEndDate = Loans[msg.sender].endDate;
        uint256 borrowed = Loans[msg.sender].borrowed;
        uint256 collateral = Loans[msg.sender].collateral;
        uint256 _numberOfDays = Loans[msg.sender].numberOfDays;

        uint256 newEndDate = oldEndDate + (numberOfDays * 1 days);

        uint256 loanFee = getInterestFee(borrowed, numberOfDays);
        require(
            !isLoanExpired(msg.sender),
            "Your loan has been liquidated, no collateral to remove"
        );
        require(loanFee == msg.value, "Loan extension fee incorrect");
        uint256 feeAddressFee = (loanFee * 3) / 10;
        require(feeAddressFee > MIN, "Fees must be higher than min.");
        sendSonic(FEE_ADDRESS, feeAddressFee);
        subLoansByDate(borrowed, collateral, oldEndDate);
        addLoansByDate(borrowed, collateral, newEndDate);
        Loans[msg.sender].endDate = newEndDate;
        Loans[msg.sender].numberOfDays = numberOfDays + _numberOfDays;
        require(
            (newEndDate - block.timestamp) / 1 days < 366,
            "Loan must be under 365 days"
        );

        safetyCheck(msg.value);
        return loanFee;
    }

    function liquidate() public {
        uint256 borrowed;
        uint256 collateral;

        while (lastLiquidationDate < block.timestamp) {
            collateral = collateral + CollateralByDate[lastLiquidationDate];
            borrowed = borrowed + BorrowedByDate[lastLiquidationDate];
            lastLiquidationDate = lastLiquidationDate + 1 days;
        }
        if (collateral != 0) {
            totalCollateral = totalCollateral - collateral;
            _burn(address(this), collateral);
        }
        if (borrowed != 0) {
            totalBorrowed = totalBorrowed - borrowed;
            emit Liquidate(lastLiquidationDate - 1 days, borrowed);
        }
    }

    function addLoansByDate(
        uint256 borrowed,
        uint256 collateral,
        uint256 date
    ) private {
        CollateralByDate[date] = CollateralByDate[date] + collateral;
        BorrowedByDate[date] = BorrowedByDate[date] + borrowed;
        totalBorrowed = totalBorrowed + borrowed;
        totalCollateral = totalCollateral + collateral;
        emit LoanDataUpdate(
            CollateralByDate[date],
            BorrowedByDate[date],
            totalBorrowed,
            totalCollateral
        );
    }
    function subLoansByDate(
        uint256 borrowed,
        uint256 collateral,
        uint256 date
    ) private {
        CollateralByDate[date] = CollateralByDate[date] - collateral;
        BorrowedByDate[date] = BorrowedByDate[date] - borrowed;
        totalBorrowed = totalBorrowed - borrowed;
        totalCollateral = totalCollateral - collateral;
        emit LoanDataUpdate(
            CollateralByDate[date],
            BorrowedByDate[date],
            totalBorrowed,
            totalCollateral
        );
    }

    // utility fxns
    function getMidnightTimestamp(uint256 date) public pure returns (uint256) {
        uint256 midnightTimestamp = date - (date % 86400); // Subtracting the remainder when divided by the number of seconds in a day (86400)
        return midnightTimestamp + 1 days;
    }

    function getLoansExpiringByDate(
        uint256 date
    ) public view returns (uint256, uint256) {
        return (
            BorrowedByDate[getMidnightTimestamp(date)],
            CollateralByDate[getMidnightTimestamp(date)]
        );
    }

    function getLoanByAddress(
        address _address
    ) public view returns (uint256, uint256, uint256) {
        if (Loans[_address].endDate >= block.timestamp) {
            return (
                Loans[_address].collateral,
                Loans[_address].borrowed,
                Loans[_address].endDate
            );
        } else {
            return (0, 0, 0);
        }
    }

    function isLoanExpired(address _address) public view returns (bool) {
        return Loans[_address].endDate < block.timestamp;
    }

    function getBuyFee() public view returns (uint256) {
        return buy_fee;
    }

    // Buy Beanz

    function getTotalBorrowed() public view returns (uint256) {
        return totalBorrowed;
    }

    function getTotalCollateral() public view returns (uint256) {
        return totalCollateral;
    }

    function getBacking() public view returns (uint256) {
        return address(this).balance + getTotalBorrowed();
    }

    function safetyCheck(uint256 sonic) private {
        uint256 newPrice = (getBacking() * 1 ether) / totalSupply();
        uint256 _totalColateral = balanceOf(address(this));
        require(
            _totalColateral >= totalCollateral,
            "The beanz balance of the contract must be greater than or equal to the collateral"
        );
        require(lastPrice <= newPrice, "The price of beanz cannot decrease");
        lastPrice = newPrice;
        emit Price(block.timestamp, newPrice, sonic);
    }

    function BEANStoSONIC(uint256 value) public view returns (uint256) {
        return Math.mulDiv(value, getBacking(), totalSupply());
    }

    function SONICtoBEANS(uint256 value) public view returns (uint256) {
        return Math.mulDiv(value, totalSupply(), getBacking() - value);
    }

    function SONICtoBEANSLev(
        uint256 value,
        uint256 fee
    ) public view returns (uint256) {
        uint256 backing = getBacking() - fee;
        return (value * totalSupply() + (backing - 1)) / backing;
    }

    function SONICtoBEANSNoTradeCeil(
        uint256 value
    ) public view returns (uint256) {
        uint256 backing = getBacking();
        return (value * totalSupply() + (backing - 1)) / backing;
    }
    function SONICtoBEANSNoTrade(uint256 value) public view returns (uint256) {
        uint256 backing = getBacking();
        return Math.mulDiv(value, totalSupply(), backing);
    }

    function sendSonic(address _address, uint256 _value) internal {
        (bool success, ) = _address.call{value: _value}("");
        require(success, "SONIC Transfer failed.");
        emit SendSonic(_address, _value);
    }

    //utils
    function getBuyBeanz(uint256 amount) external view returns (uint256) {
        return
            (amount * (totalSupply()) * (buy_fee)) /
            (getBacking()) /
            (FEE_BASE_1000);
    }

    receive() external payable {}

    fallback() external payable {}
}

File 2 of 13 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

import {Panic} from "../Panic.sol";
import {SafeCast} from "./SafeCast.sol";

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an success flag (no overflow).
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an success flag (no overflow).
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an success flag (no overflow).
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.
     *
     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.
     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute
     * one branch when needed, making this function more expensive.
     */
    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {
        unchecked {
            // branchless ternary works because:
            // b ^ (a ^ b) == a
            // b ^ 0 == b
            return b ^ ((a ^ b) * SafeCast.toUint(condition));
        }
    }

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

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

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

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }

        // The following calculation ensures accurate ceiling division without overflow.
        // Since a is non-zero, (a - 1) / b will not overflow.
        // The largest possible result occurs when (a - 1) / b is type(uint256).max,
        // but the largest value we can obtain is type(uint256).max - 1, which happens
        // when a = type(uint256).max and b = 1.
        unchecked {
            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);
        }
    }

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.
            if (denominator <= prod1) {
                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));
            }

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

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

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

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

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

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

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

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

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

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2⁸
            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶
            inverse *= 2 - denominator * inverse; // inverse mod 2³²
            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴
            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸
            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶

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

    /**
     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);
    }

    /**
     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.
     *
     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.
     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.
     *
     * If the input value is not inversible, 0 is returned.
     *
     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the
     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.
     */
    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {
        unchecked {
            if (n == 0) return 0;

            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)
            // Used to compute integers x and y such that: ax + ny = gcd(a, n).
            // When the gcd is 1, then the inverse of a modulo n exists and it's x.
            // ax + ny = 1
            // ax = 1 + (-y)n
            // ax ≡ 1 (mod n) # x is the inverse of a modulo n

            // If the remainder is 0 the gcd is n right away.
            uint256 remainder = a % n;
            uint256 gcd = n;

            // Therefore the initial coefficients are:
            // ax + ny = gcd(a, n) = n
            // 0a + 1n = n
            int256 x = 0;
            int256 y = 1;

            while (remainder != 0) {
                uint256 quotient = gcd / remainder;

                (gcd, remainder) = (
                    // The old remainder is the next gcd to try.
                    remainder,
                    // Compute the next remainder.
                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd
                    // where gcd is at most n (capped to type(uint256).max)
                    gcd - remainder * quotient
                );

                (x, y) = (
                    // Increment the coefficient of a.
                    y,
                    // Decrement the coefficient of n.
                    // Can overflow, but the result is casted to uint256 so that the
                    // next value of y is "wrapped around" to a value between 0 and n - 1.
                    x - y * int256(quotient)
                );
            }

            if (gcd != 1) return 0; // No inverse exists.
            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.
        }
    }

    /**
     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.
     *
     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is
     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that
     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.
     *
     * NOTE: this function does NOT check that `p` is a prime greater than `2`.
     */
    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {
        unchecked {
            return Math.modExp(a, p - 2, p);
        }
    }

    /**
     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)
     *
     * Requirements:
     * - modulus can't be zero
     * - underlying staticcall to precompile must succeed
     *
     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make
     * sure the chain you're using it on supports the precompiled contract for modular exponentiation
     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,
     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly
     * interpreted as 0.
     */
    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {
        (bool success, uint256 result) = tryModExp(b, e, m);
        if (!success) {
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }
        return result;
    }

    /**
     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).
     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying
     * to operate modulo 0 or if the underlying precompile reverted.
     *
     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain
     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in
     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack
     * of a revert, but the result may be incorrectly interpreted as 0.
     */
    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {
        if (m == 0) return (false, 0);
        assembly ("memory-safe") {
            let ptr := mload(0x40)
            // | Offset    | Content    | Content (Hex)                                                      |
            // |-----------|------------|--------------------------------------------------------------------|
            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |
            // | 0x60:0x7f | value of b | 0x<.............................................................b> |
            // | 0x80:0x9f | value of e | 0x<.............................................................e> |
            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |
            mstore(ptr, 0x20)
            mstore(add(ptr, 0x20), 0x20)
            mstore(add(ptr, 0x40), 0x20)
            mstore(add(ptr, 0x60), b)
            mstore(add(ptr, 0x80), e)
            mstore(add(ptr, 0xa0), m)

            // Given the result < m, it's guaranteed to fit in 32 bytes,
            // so we can use the memory scratch space located at offset 0.
            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)
            result := mload(0x00)
        }
    }

    /**
     * @dev Variant of {modExp} that supports inputs of arbitrary length.
     */
    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {
        (bool success, bytes memory result) = tryModExp(b, e, m);
        if (!success) {
            Panic.panic(Panic.DIVISION_BY_ZERO);
        }
        return result;
    }

    /**
     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.
     */
    function tryModExp(
        bytes memory b,
        bytes memory e,
        bytes memory m
    ) internal view returns (bool success, bytes memory result) {
        if (_zeroBytes(m)) return (false, new bytes(0));

        uint256 mLen = m.length;

        // Encode call args in result and move the free memory pointer
        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);

        assembly ("memory-safe") {
            let dataPtr := add(result, 0x20)
            // Write result on top of args to avoid allocating extra memory.
            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)
            // Overwrite the length.
            // result.length > returndatasize() is guaranteed because returndatasize() == m.length
            mstore(result, mLen)
            // Set the memory pointer after the returned data.
            mstore(0x40, add(dataPtr, mLen))
        }
    }

    /**
     * @dev Returns whether the provided byte array is zero.
     */
    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {
        for (uint256 i = 0; i < byteArray.length; ++i) {
            if (byteArray[i] != 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only
     * using integer operations.
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        unchecked {
            // Take care of easy edge cases when a == 0 or a == 1
            if (a <= 1) {
                return a;
            }

            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a
            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between
            // the current value as `ε_n = | x_n - sqrt(a) |`.
            //
            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root
            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is
            // bigger than any uint256.
            //
            // By noticing that
            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`
            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar
            // to the msb function.
            uint256 aa = a;
            uint256 xn = 1;

            if (aa >= (1 << 128)) {
                aa >>= 128;
                xn <<= 64;
            }
            if (aa >= (1 << 64)) {
                aa >>= 64;
                xn <<= 32;
            }
            if (aa >= (1 << 32)) {
                aa >>= 32;
                xn <<= 16;
            }
            if (aa >= (1 << 16)) {
                aa >>= 16;
                xn <<= 8;
            }
            if (aa >= (1 << 8)) {
                aa >>= 8;
                xn <<= 4;
            }
            if (aa >= (1 << 4)) {
                aa >>= 4;
                xn <<= 2;
            }
            if (aa >= (1 << 2)) {
                xn <<= 1;
            }

            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).
            //
            // We can refine our estimation by noticing that the middle of that interval minimizes the error.
            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).
            // This is going to be our x_0 (and ε_0)
            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)

            // From here, Newton's method give us:
            // x_{n+1} = (x_n + a / x_n) / 2
            //
            // One should note that:
            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a
            //              = ((x_n² + a) / (2 * x_n))² - a
            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a
            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)
            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)
            //              = (x_n² - a)² / (2 * x_n)²
            //              = ((x_n² - a) / (2 * x_n))²
            //              ≥ 0
            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n
            //
            // This gives us the proof of quadratic convergence of the sequence:
            // ε_{n+1} = | x_{n+1} - sqrt(a) |
            //         = | (x_n + a / x_n) / 2 - sqrt(a) |
            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |
            //         = | (x_n - sqrt(a))² / (2 * x_n) |
            //         = | ε_n² / (2 * x_n) |
            //         = ε_n² / | (2 * x_n) |
            //
            // For the first iteration, we have a special case where x_0 is known:
            // ε_1 = ε_0² / | (2 * x_0) |
            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))
            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))
            //     ≤ 2**(e-3) / 3
            //     ≤ 2**(e-3-log2(3))
            //     ≤ 2**(e-4.5)
            //
            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:
            // ε_{n+1} = ε_n² / | (2 * x_n) |
            //         ≤ (2**(e-k))² / (2 * 2**(e-1))
            //         ≤ 2**(2*e-2*k) / 2**e
            //         ≤ 2**(e-2*k)
            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above
            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5
            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9
            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18
            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36
            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72

            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision
            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either
            // sqrt(a) or sqrt(a) + 1.
            return xn - SafeCast.toUint(xn > a / xn);
        }
    }

    /**
     * @dev Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        uint256 exp;
        unchecked {
            exp = 128 * SafeCast.toUint(value > (1 << 128) - 1);
            value >>= exp;
            result += exp;

            exp = 64 * SafeCast.toUint(value > (1 << 64) - 1);
            value >>= exp;
            result += exp;

            exp = 32 * SafeCast.toUint(value > (1 << 32) - 1);
            value >>= exp;
            result += exp;

            exp = 16 * SafeCast.toUint(value > (1 << 16) - 1);
            value >>= exp;
            result += exp;

            exp = 8 * SafeCast.toUint(value > (1 << 8) - 1);
            value >>= exp;
            result += exp;

            exp = 4 * SafeCast.toUint(value > (1 << 4) - 1);
            value >>= exp;
            result += exp;

            exp = 2 * SafeCast.toUint(value > (1 << 2) - 1);
            value >>= exp;
            result += exp;

            result += SafeCast.toUint(value > 1);
        }
        return result;
    }

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

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

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

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        uint256 isGt;
        unchecked {
            isGt = SafeCast.toUint(value > (1 << 128) - 1);
            value >>= isGt * 128;
            result += isGt * 16;

            isGt = SafeCast.toUint(value > (1 << 64) - 1);
            value >>= isGt * 64;
            result += isGt * 8;

            isGt = SafeCast.toUint(value > (1 << 32) - 1);
            value >>= isGt * 32;
            result += isGt * 4;

            isGt = SafeCast.toUint(value > (1 << 16) - 1);
            value >>= isGt * 16;
            result += isGt * 2;

            result += SafeCast.toUint(value > (1 << 8) - 1);
        }
        return result;
    }

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

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

File 3 of 13 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @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 EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * 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;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

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

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

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

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

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

File 4 of 13 : Ownable2Step.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.20;

import {Ownable} from "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This extension of the {Ownable} contract includes a two-step mechanism to transfer
 * ownership, where the new owner must call {acceptOwnership} in order to replace the
 * old one. This can help prevent common mistakes, such as transfers of ownership to
 * incorrect accounts, or to contracts that are unable to interact with the
 * permission system.
 *
 * The initial owner is specified at deployment time in the constructor for `Ownable`. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

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

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     *
     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        if (pendingOwner() != sender) {
            revert OwnableUnauthorizedAccount(sender);
        }
        _transferOwnership(sender);
    }
}

File 5 of 13 : ERC20Burnable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Burnable.sol)

pragma solidity ^0.8.20;

import {ERC20} from "../ERC20.sol";
import {Context} from "../../../utils/Context.sol";

/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys a `value` amount of tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 value) public virtual {
        _burn(_msgSender(), value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, deducting from
     * the caller's allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `value`.
     */
    function burnFrom(address account, uint256 value) public virtual {
        _spendAllowance(account, _msgSender(), value);
        _burn(account, value);
    }
}

File 6 of 13 : SafeCast.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.20;

/**
 * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeCast {
    /**
     * @dev Value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);

    /**
     * @dev An int value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedIntToUint(int256 value);

    /**
     * @dev Value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);

    /**
     * @dev An uint value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedUintToInt(uint256 value);

    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        if (value > type(uint248).max) {
            revert SafeCastOverflowedUintDowncast(248, value);
        }
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        if (value > type(uint240).max) {
            revert SafeCastOverflowedUintDowncast(240, value);
        }
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        if (value > type(uint232).max) {
            revert SafeCastOverflowedUintDowncast(232, value);
        }
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        if (value > type(uint224).max) {
            revert SafeCastOverflowedUintDowncast(224, value);
        }
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        if (value > type(uint216).max) {
            revert SafeCastOverflowedUintDowncast(216, value);
        }
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        if (value > type(uint208).max) {
            revert SafeCastOverflowedUintDowncast(208, value);
        }
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        if (value > type(uint200).max) {
            revert SafeCastOverflowedUintDowncast(200, value);
        }
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        if (value > type(uint192).max) {
            revert SafeCastOverflowedUintDowncast(192, value);
        }
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        if (value > type(uint184).max) {
            revert SafeCastOverflowedUintDowncast(184, value);
        }
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        if (value > type(uint176).max) {
            revert SafeCastOverflowedUintDowncast(176, value);
        }
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        if (value > type(uint168).max) {
            revert SafeCastOverflowedUintDowncast(168, value);
        }
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        if (value > type(uint160).max) {
            revert SafeCastOverflowedUintDowncast(160, value);
        }
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        if (value > type(uint152).max) {
            revert SafeCastOverflowedUintDowncast(152, value);
        }
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        if (value > type(uint144).max) {
            revert SafeCastOverflowedUintDowncast(144, value);
        }
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        if (value > type(uint136).max) {
            revert SafeCastOverflowedUintDowncast(136, value);
        }
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        if (value > type(uint128).max) {
            revert SafeCastOverflowedUintDowncast(128, value);
        }
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        if (value > type(uint120).max) {
            revert SafeCastOverflowedUintDowncast(120, value);
        }
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        if (value > type(uint112).max) {
            revert SafeCastOverflowedUintDowncast(112, value);
        }
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        if (value > type(uint104).max) {
            revert SafeCastOverflowedUintDowncast(104, value);
        }
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        if (value > type(uint96).max) {
            revert SafeCastOverflowedUintDowncast(96, value);
        }
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        if (value > type(uint88).max) {
            revert SafeCastOverflowedUintDowncast(88, value);
        }
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        if (value > type(uint80).max) {
            revert SafeCastOverflowedUintDowncast(80, value);
        }
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        if (value > type(uint72).max) {
            revert SafeCastOverflowedUintDowncast(72, value);
        }
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        if (value > type(uint64).max) {
            revert SafeCastOverflowedUintDowncast(64, value);
        }
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        if (value > type(uint56).max) {
            revert SafeCastOverflowedUintDowncast(56, value);
        }
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        if (value > type(uint48).max) {
            revert SafeCastOverflowedUintDowncast(48, value);
        }
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        if (value > type(uint40).max) {
            revert SafeCastOverflowedUintDowncast(40, value);
        }
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        if (value > type(uint32).max) {
            revert SafeCastOverflowedUintDowncast(32, value);
        }
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        if (value > type(uint24).max) {
            revert SafeCastOverflowedUintDowncast(24, value);
        }
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        if (value > type(uint16).max) {
            revert SafeCastOverflowedUintDowncast(16, value);
        }
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        if (value > type(uint8).max) {
            revert SafeCastOverflowedUintDowncast(8, value);
        }
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        if (value < 0) {
            revert SafeCastOverflowedIntToUint(value);
        }
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(248, value);
        }
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(240, value);
        }
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(232, value);
        }
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(224, value);
        }
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(216, value);
        }
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(208, value);
        }
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(200, value);
        }
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(192, value);
        }
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(184, value);
        }
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(176, value);
        }
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(168, value);
        }
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(160, value);
        }
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
     * Counterpart to Solidity's `int152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     */
    function toInt152(int256 value) internal pure returns (int152 downcasted) {
        downcasted = int152(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(152, value);
        }
    }

    /**
     * @dev Returns the downcasted int144 from int256, reverting on
     * overflow (when the input is less than smallest int144 or
     * greater than largest int144).
     *
     * Counterpart to Solidity's `int144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     */
    function toInt144(int256 value) internal pure returns (int144 downcasted) {
        downcasted = int144(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(144, value);
        }
    }

    /**
     * @dev Returns the downcasted int136 from int256, reverting on
     * overflow (when the input is less than smallest int136 or
     * greater than largest int136).
     *
     * Counterpart to Solidity's `int136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     */
    function toInt136(int256 value) internal pure returns (int136 downcasted) {
        downcasted = int136(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(136, value);
        }
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toInt128(int256 value) internal pure returns (int128 downcasted) {
        downcasted = int128(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(128, value);
        }
    }

    /**
     * @dev Returns the downcasted int120 from int256, reverting on
     * overflow (when the input is less than smallest int120 or
     * greater than largest int120).
     *
     * Counterpart to Solidity's `int120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     */
    function toInt120(int256 value) internal pure returns (int120 downcasted) {
        downcasted = int120(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(120, value);
        }
    }

    /**
     * @dev Returns the downcasted int112 from int256, reverting on
     * overflow (when the input is less than smallest int112 or
     * greater than largest int112).
     *
     * Counterpart to Solidity's `int112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     */
    function toInt112(int256 value) internal pure returns (int112 downcasted) {
        downcasted = int112(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(112, value);
        }
    }

    /**
     * @dev Returns the downcasted int104 from int256, reverting on
     * overflow (when the input is less than smallest int104 or
     * greater than largest int104).
     *
     * Counterpart to Solidity's `int104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     */
    function toInt104(int256 value) internal pure returns (int104 downcasted) {
        downcasted = int104(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(104, value);
        }
    }

    /**
     * @dev Returns the downcasted int96 from int256, reverting on
     * overflow (when the input is less than smallest int96 or
     * greater than largest int96).
     *
     * Counterpart to Solidity's `int96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toInt96(int256 value) internal pure returns (int96 downcasted) {
        downcasted = int96(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(96, value);
        }
    }

    /**
     * @dev Returns the downcasted int88 from int256, reverting on
     * overflow (when the input is less than smallest int88 or
     * greater than largest int88).
     *
     * Counterpart to Solidity's `int88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     */
    function toInt88(int256 value) internal pure returns (int88 downcasted) {
        downcasted = int88(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(88, value);
        }
    }

    /**
     * @dev Returns the downcasted int80 from int256, reverting on
     * overflow (when the input is less than smallest int80 or
     * greater than largest int80).
     *
     * Counterpart to Solidity's `int80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     */
    function toInt80(int256 value) internal pure returns (int80 downcasted) {
        downcasted = int80(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(80, value);
        }
    }

    /**
     * @dev Returns the downcasted int72 from int256, reverting on
     * overflow (when the input is less than smallest int72 or
     * greater than largest int72).
     *
     * Counterpart to Solidity's `int72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     */
    function toInt72(int256 value) internal pure returns (int72 downcasted) {
        downcasted = int72(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(72, value);
        }
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toInt64(int256 value) internal pure returns (int64 downcasted) {
        downcasted = int64(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(64, value);
        }
    }

    /**
     * @dev Returns the downcasted int56 from int256, reverting on
     * overflow (when the input is less than smallest int56 or
     * greater than largest int56).
     *
     * Counterpart to Solidity's `int56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     */
    function toInt56(int256 value) internal pure returns (int56 downcasted) {
        downcasted = int56(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(56, value);
        }
    }

    /**
     * @dev Returns the downcasted int48 from int256, reverting on
     * overflow (when the input is less than smallest int48 or
     * greater than largest int48).
     *
     * Counterpart to Solidity's `int48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     */
    function toInt48(int256 value) internal pure returns (int48 downcasted) {
        downcasted = int48(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(48, value);
        }
    }

    /**
     * @dev Returns the downcasted int40 from int256, reverting on
     * overflow (when the input is less than smallest int40 or
     * greater than largest int40).
     *
     * Counterpart to Solidity's `int40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     */
    function toInt40(int256 value) internal pure returns (int40 downcasted) {
        downcasted = int40(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(40, value);
        }
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toInt32(int256 value) internal pure returns (int32 downcasted) {
        downcasted = int32(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(32, value);
        }
    }

    /**
     * @dev Returns the downcasted int24 from int256, reverting on
     * overflow (when the input is less than smallest int24 or
     * greater than largest int24).
     *
     * Counterpart to Solidity's `int24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     */
    function toInt24(int256 value) internal pure returns (int24 downcasted) {
        downcasted = int24(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(24, value);
        }
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toInt16(int256 value) internal pure returns (int16 downcasted) {
        downcasted = int16(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(16, value);
        }
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     */
    function toInt8(int256 value) internal pure returns (int8 downcasted) {
        downcasted = int8(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(8, value);
        }
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        if (value > uint256(type(int256).max)) {
            revert SafeCastOverflowedUintToInt(value);
        }
        return int256(value);
    }

    /**
     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.
     */
    function toUint(bool b) internal pure returns (uint256 u) {
        assembly ("memory-safe") {
            u := iszero(iszero(b))
        }
    }
}

File 7 of 13 : Panic.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)

pragma solidity ^0.8.20;

/**
 * @dev Helper library for emitting standardized panic codes.
 *
 * ```solidity
 * contract Example {
 *      using Panic for uint256;
 *
 *      // Use any of the declared internal constants
 *      function foo() { Panic.GENERIC.panic(); }
 *
 *      // Alternatively
 *      function foo() { Panic.panic(Panic.GENERIC); }
 * }
 * ```
 *
 * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].
 *
 * _Available since v5.1._
 */
// slither-disable-next-line unused-state
library Panic {
    /// @dev generic / unspecified error
    uint256 internal constant GENERIC = 0x00;
    /// @dev used by the assert() builtin
    uint256 internal constant ASSERT = 0x01;
    /// @dev arithmetic underflow or overflow
    uint256 internal constant UNDER_OVERFLOW = 0x11;
    /// @dev division or modulo by zero
    uint256 internal constant DIVISION_BY_ZERO = 0x12;
    /// @dev enum conversion error
    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;
    /// @dev invalid encoding in storage
    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;
    /// @dev empty array pop
    uint256 internal constant EMPTY_ARRAY_POP = 0x31;
    /// @dev array out of bounds access
    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;
    /// @dev resource error (too large allocation or too large array)
    uint256 internal constant RESOURCE_ERROR = 0x41;
    /// @dev calling invalid internal function
    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;

    /// @dev Reverts with a panic code. Recommended to use with
    /// the internal constants with predefined codes.
    function panic(uint256 code) internal pure {
        assembly ("memory-safe") {
            mstore(0x00, 0x4e487b71)
            mstore(0x20, code)
            revert(0x1c, 0x24)
        }
    }
}

File 8 of 13 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 9 of 13 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

    mapping(address account => mapping(address spender => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

File 10 of 13 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/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.
 *
 * The initial owner is set to the address provided by the deployer. 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;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _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 11 of 13 : draft-IERC6093.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC-20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC-721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC-1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

File 12 of 13 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC-20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 13 of 13 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

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

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

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

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

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

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

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

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

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"buyFee","type":"uint256"}],"name":"BuyFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_address","type":"address"}],"name":"FeeAddressUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"leverageFee","type":"uint256"}],"name":"LeverageFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Liquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"collateralByDate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowedByDate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalBorrowed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalCollateral","type":"uint256"}],"name":"LoanDataUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"}],"name":"MaxUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"volumeInSonic","type":"uint256"}],"name":"Price","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sellFee","type":"uint256"}],"name":"SellFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SendSonic","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"started","type":"bool"}],"name":"Started","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"BEANStoSONIC","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"BorrowedByDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"CollateralByDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_ADDRESS","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"Loans","outputs":[{"internalType":"uint256","name":"collateral","type":"uint256"},{"internalType":"uint256","name":"borrowed","type":"uint256"},{"internalType":"uint256","name":"endDate","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SONICtoBEANS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SONICtoBEANSLev","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SONICtoBEANSNoTrade","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SONICtoBEANSNoTradeCeil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"}],"name":"borrowMore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"buy","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"buy_fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buy_fee_leverage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closePosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"extendLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"flashClosePosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBacking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBuyBeanz","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBuyFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"getInterestFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getLoanByAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"date","type":"uint256"}],"name":"getLoansExpiringByDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"date","type":"uint256"}],"name":"getMidnightTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getTotalBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isLoanExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastLiquidationDate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"leverage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sonic","type":"uint256"},{"internalType":"uint256","name":"numberOfDays","type":"uint256"}],"name":"leverageFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","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":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"removeCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"repay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"beanz","type":"uint256"}],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sell_fee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"setBuyFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"setBuyFeeLeverage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"amount","type":"uint16"}],"name":"setSellFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStart","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526008805466ffffffffffffff60a01b1916640a03cf03cf60a01b1790555f6009819055600a819055600c5534801561003a575f5ffd5b5033604051806040016040528060058152602001642132b0b73d60d91b815250604051806040016040528060058152602001642122a0a72d60d91b81525081600390816100879190610218565b5060046100948282610218565b5050506001600160a01b0381166100c457604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b6100cd816100e4565b5060016007556100dc42610100565b601055610331565b600680546001600160a01b03191690556100fd8161012f565b50565b5f8061010f62015180846102d2565b6101199084610305565b9050610128816201518061031e565b9392505050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806101a857607f821691505b6020821081036101c657634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561021357805f5260205f20601f840160051c810160208510156101f15750805b601f840160051c820191505b81811015610210575f81556001016101fd565b50505b505050565b81516001600160401b0381111561023157610231610180565b6102458161023f8454610194565b846101cc565b6020601f821160018114610277575f83156102605750848201515b5f19600385901b1c1916600184901b178455610210565b5f84815260208120601f198516915b828110156102a65787850151825560209485019460019092019101610286565b50848210156102c357868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f826102ec57634e487b7160e01b5f52601260045260245ffd5b500690565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610318576103186102f1565b92915050565b80820180821115610318576103186102f1565b61331c8061033e5f395ff3fe608060405260043610610374575f3560e01c806379ba5097116101ce578063abd545bf11610100578063e064648a11610099578063eb1edd611161006b578063eb1edd6114610aab578063f088d54714610aca578063f2fde38b14610add578063ff7bf6f514610afc57005b8063e064648a14610a31578063e30c397814610a50578063e3eb5ed314610a6d578063e4849b3214610a8c57005b8063c962a4b5116100d2578063c962a4b51461096d578063d5abeb0114610998578063d6eb5910146109d9578063dd62ed3e146109ed57005b8063abd545bf14610910578063be9a655514610931578063c393d0e314610951578063c94220ab1461095957005b806390594cce116101725780639d41ac3a116101445780639d41ac3a14610868578063a2309ff81461087c578063a9059cbb14610891578063a925e4a4146108b057005b806390594cce146107dc57806395ced06f146107fb57806395d89b41146108355780639d0bf2e91461084957005b80638705fcd4116101ab5780638705fcd41461074e5780638ca385a71461076d5780638da5cb5b1461078c5780638f818b90146107bd57005b806379ba50971461070857806379cc67901461071c5780637ace2ac91461073b57005b8063313ce567116102a757806342966c681161024b57806370a082311161021d57806370a082311461068257806370c47671146106b657806370f84ba9146106d5578063715018a6146106f457005b806342966c68146106065780634fbf3ab0146106255780635e96263c146106505780635fdd4be21461066357005b806335975a371161028457806335975a37146105b657806336189d43146105be5780633be4e598146105df578063402d8883146105fe57005b8063313ce567146105675780633237c158146105825780633421f750146105a157005b80630c767d881161031957806318160ddd116102eb57806318160ddd146105015780631fb87f391461051557806323b872dd1461053457806328a070251461055357005b80630c767d88146104705780630ecbcdab1461048f578063162b51fc146104ae57806317a5a97e146104e257005b806303fac5a21161035257806303fac5a2146103ec578063053f14da1461040b57806306fdde0314610420578063095ea7b31461044157005b8063024cad3b146103765780630307c4a1146103af578063035b7c4b146103cd575b005b348015610381575f5ffd5b50610395610390366004612ffa565b610b1b565b604080519283526020830191909152015b60405180910390f35b3480156103ba575f5ffd5b506009545b6040519081526020016103a6565b3480156103d8575f5ffd5b506103bf6103e7366004613011565b610b5a565b3480156103f7575f5ffd5b506103bf610406366004613011565b610ba0565b348015610416575f5ffd5b506103bf600c5481565b34801561042b575f5ffd5b50610434610be4565b6040516103a69190613031565b34801561044c575f5ffd5b5061046061045b36600461307c565b610c74565b60405190151581526020016103a6565b34801561047b575f5ffd5b506103bf61048a366004612ffa565b610c8b565b34801561049a575f5ffd5b506103746104a9366004613011565b610cb1565b3480156104b9575f5ffd5b506008546104cf90600160b01b900461ffff1681565b60405161ffff90911681526020016103a6565b3480156104ed575f5ffd5b506103746104fc3660046130a4565b610ef5565b34801561050c575f5ffd5b506002546103bf565b348015610520575f5ffd5b506103bf61052f366004612ffa565b610fb4565b34801561053f575f5ffd5b5061046061054e3660046130c5565b610fed565b34801561055e575f5ffd5b50610374611010565b348015610572575f5ffd5b50604051601281526020016103a6565b34801561058d575f5ffd5b5061037461059c366004612ffa565b6110f7565b3480156105ac575f5ffd5b506103bf60105481565b610374611238565b3480156105c9575f5ffd5b506008546104cf90600160c01b900461ffff1681565b3480156105ea575f5ffd5b506103bf6105f9366004613011565b611315565b610374611361565b348015610611575f5ffd5b50610374610620366004612ffa565b6114d0565b348015610630575f5ffd5b506103bf61063f366004612ffa565b600e6020525f908152604090205481565b61037461065e366004613011565b6114da565b34801561066e575f5ffd5b506103bf61067d366004612ffa565b61181d565b34801561068d575f5ffd5b506103bf61069c3660046130ff565b6001600160a01b03165f9081526020819052604090205490565b3480156106c1575f5ffd5b506103746106d03660046130a4565b611837565b3480156106e0575f5ffd5b506104606106ef3660046130ff565b611949565b3480156106ff575f5ffd5b50610374611968565b348015610713575f5ffd5b50610374611979565b348015610727575f5ffd5b5061037461073636600461307c565b6119ba565b6103bf610749366004612ffa565b6119cf565b348015610759575f5ffd5b506103746107683660046130ff565b611bb8565b348015610778575f5ffd5b506103bf610787366004612ffa565b611c70565b348015610797575f5ffd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016103a6565b3480156107c8575f5ffd5b50600854600160b01b900461ffff166103bf565b3480156107e7575f5ffd5b506103bf6107f6366004612ffa565b611c91565b348015610806575f5ffd5b5061081a6108153660046130ff565b611cdd565b604080519384526020840192909252908201526060016103a6565b348015610840575f5ffd5b50610434611d41565b348015610854575f5ffd5b50610374610863366004612ffa565b611d50565b348015610873575f5ffd5b50610374611fe6565b348015610887575f5ffd5b506103bf600b5481565b34801561089c575f5ffd5b506104606108ab36600461307c565b6121a0565b3480156108bb575f5ffd5b506108f06108ca3660046130ff565b600d6020525f908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103a6565b34801561091b575f5ffd5b506008546104cf90600160a01b900461ffff1681565b34801561093c575f5ffd5b5060085461046090600160d01b900460ff1681565b6103746121ad565b348015610964575f5ffd5b506103bf6122a4565b348015610978575f5ffd5b506103bf610987366004612ffa565b600f6020525f908152604090205481565b3480156109a3575f5ffd5b506109b86c01431e0fae6d7217caa000000081565b6040516fffffffffffffffffffffffffffffffff90911681526020016103a6565b3480156109e4575f5ffd5b50600a546103bf565b3480156109f8575f5ffd5b506103bf610a07366004613118565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610a3c575f5ffd5b50610374610a4b3660046130a4565b6122bd565b348015610a5b575f5ffd5b506006546001600160a01b03166107a5565b348015610a78575f5ffd5b506103bf610a87366004612ffa565b6123d1565b348015610a97575f5ffd5b50610374610aa6366004612ffa565b6123f9565b348015610ab6575f5ffd5b506008546107a5906001600160a01b031681565b610374610ad83660046130ff565b6124cb565b348015610ae8575f5ffd5b50610374610af73660046130ff565b61263f565b348015610b07575f5ffd5b506103bf610b16366004612ffa565b6126b0565b5f5f600e5f610b29856123d1565b81526020019081526020015f2054600f5f610b43866123d1565b81526020019081526020015f205491509150915091565b5f5f610b70668a8e4b1a3d80008461016d6126df565b610b819066038d7ea4c6800061315d565b9050610b968482670de0b6b3a76400006126df565b9150505b92915050565b5f5f82610bab6122a4565b610bb59190613170565b905080610bc3600182613170565b600254610bd09087613183565b610bda919061315d565b610b9691906131ae565b606060038054610bf3906131c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1f906131c1565b8015610c6a5780601f10610c4157610100808354040283529160200191610c6a565b820191905f5260205f20905b815481529060010190602001808311610c4d57829003601f168201915b5050505050905090565b5f33610c81818585612795565b5060019392505050565b5f5f610c956122a4565b9050610caa83610ca460025490565b836126df565b9392505050565b610cb96127a7565b61016e8110610ce35760405162461bcd60e51b8152600401610cda906131f9565b60405180910390fd5b815f03610d2c5760405162461bcd60e51b815260206004820152601760248201527604d75737420626f72726f77206d6f7265207468616e203604c1b6044820152606401610cda565b610d3533611949565b15610d5e57335f908152600d602052604081208181556001810182905560028101829055600301555b335f908152600d602052604090206001015415610dbd5760405162461bcd60e51b815260206004820152601d60248201527f55736520626f72726f774d6f726520746f20626f72726f77206d6f72650000006044820152606401610cda565b610dc5611010565b5f610de142610dd78462015180613183565b610a87919061315d565b90505f610dee8484610b5a565b90505f600a610dfe836003613183565b610e0891906131ae565b90505f610e14866126b0565b90505f6064610e24886063613183565b610e2e91906131ae565b6040805160808101825284815260208082018481528284018a8152606084018c8152335f818152600d90955295909320935184559051600184015551600283015551600390910155909150610e849030846127d1565b6103e88311610ea55760405162461bcd60e51b8152600401610cda90613246565b610eb833610eb38684613170565b61282e565b600854610ece906001600160a01b03168461282e565b610ed981838761290e565b610ee2846129d9565b5050505050610ef16001600755565b5050565b610efd612b4c565b60198161ffff161115610f5d5760405162461bcd60e51b815260206004820152602260248201527f6c657665726167652062757920666565206d757374206265206c65737320322e604482015261352560f01b6064820152608401610cda565b6008805461ffff60c01b1916600160c01b61ffff8416908102919091179091556040519081527fd4e469371f09a592c9c4fde36ed11fd123a8cc55d93bd2920ea6ad544dff4395906020015b60405180910390a150565b5f5f610fbf83610c8b565b90506103e8610fd960085461ffff600160b01b9091041690565b610fe39083613183565b610caa91906131ae565b5f33610ffa858285612b79565b6110058585856127d1565b506001949350505050565b5f5f5b426010541015611071576010545f908152600f6020526040902054611038908261315d565b6010545f908152600e6020526040902054909150611056908361315d565b915060105462015180611069919061315d565b601055611013565b80156110925780600a546110859190613170565b600a556110923082612bf5565b8115610ef157816009546110a69190613170565b6009556010547f253e5385159062a101837d58c10ad4694c58979ebc3ba6b5cb2cbba2fe461692906110dc906201518090613170565b60408051918252602082018590520160405180910390a15050565b6110ff6127a7565b61110833611949565b156111255760405162461bcd60e51b8152600401610cda9061327d565b61112d611010565b335f908152600d6020526040902054606461114b61067d8484613170565b611156906063613183565b61116091906131ae565b335f908152600d602052604090206001015411156111cb5760405162461bcd60e51b815260206004820152602260248201527f526571756972652039392520636f6c6c61746572616c697a6174696f6e207261604482015261746560f01b6064820152608401610cda565b335f908152600d60205260409020546111e5908390613170565b335f818152600d6020526040902091909155611203903090846127d1565b335f908152600d602052604081206002015461122191908490612c29565b61122a5f6129d9565b506112356001600755565b50565b611240612b4c565b6008546001600160a01b031661128f5760405162461bcd60e51b81526020600482015260146024820152734d7573742073657420666565206164647265737360601b6044820152606401610cda565b5f61129c6103e834613183565b9050670de0b6b3a76400008110156112b2575f5ffd5b6112bc3382612c94565b6112d13361dead670de0b6b3a76400006127d1565b6008805460ff60d01b1916600160d01b179055604051600181527f4f366f0dc5cd876e456f089309e0c62fc2bc0e116c6f6ae308c392b4ad45b5b990602001610fa9565b6008545f9081906103e89061133590600160c01b900461ffff1686613183565b61133f91906131ae565b90505f61134c8585610b5a565b9050611358818361315d565b95945050505050565b6113696127a7565b335f908152600d60205260409020600101543481116113d65760405162461bcd60e51b8152602060048201526024808201527f4d757374207265706179206c657373207468616e20626f72726f77656420616d6044820152631bdd5b9d60e21b6064820152608401610cda565b345f0361141c5760405162461bcd60e51b81526020600482015260146024820152734d75737420726570617920736f6d657468696e6760601b6044820152606401610cda565b61142533611949565b156114865760405162461bcd60e51b815260206004820152602b60248201527f596f7572206c6f616e20686173206265656e206c6971756964617465642c206360448201526a616e6e6f7420726570617960a81b6064820152608401610cda565b5f6114913483613170565b335f908152600d6020526040812060018101839055600201549192506114b991349190612c29565b6114c25f6129d9565b50506114ce6001600755565b565b6112353382612bf5565b6114e26127a7565b600854600160d01b900460ff1661153b5760405162461bcd60e51b815260206004820152601b60248201527f54726164696e67206d75737420626520696e697469616c697a656400000000006044820152606401610cda565b61016e811061155c5760405162461bcd60e51b8152600401610cda906131f9565b335f908152600d6020908152604091829020825160808101845281548152600182015492810183905260028201549381019390935260030154606083015215611630576115a833611949565b156115d157335f908152600d602052604081208181556001810182905560028101829055600301555b335f908152600d6020526040902060010154156116305760405162461bcd60e51b815260206004820152601960248201527f557365206163636f756e742077697468206e6f206c6f616e73000000000000006044820152606401610cda565b611638611010565b5f61164a42610dd78562015180613183565b90505f6116578585611315565b90505f6116648287613170565b90505f600a611674846003613183565b61167e91906131ae565b90505f606461168e846063613183565b61169891906131ae565b90505f6116a66064856131ae565b90505f6116b3828561315d565b90505f6116c0838861315d565b90505f813411156116e1576116d58234613170565b90506116e1338261282e565b816116ec8234613170565b146117395760405162461bcd60e51b815260206004820152601b60248201527f496e73756666696369656e7420736f6e6963206665652073656e7400000000006044820152606401610cda565b5f6117448885610ba0565b90506117503082612c94565b6103e887116117715760405162461bcd60e51b8152600401610cda90613246565b600854611787906001600160a01b03168861282e565b61179286828c61290e565b60405180608001604052808281526020018781526020018b81526020018d815250600d5f336001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f01556020820151816001015560408201518160020155606082015181600301559050506118088d6129d9565b5050505050505050505050610ef16001600755565b5f610b9a8261182a6122a4565b6002546126df565b6126df565b61183f612b4c565b6103e08161ffff1611156118a35760405162461bcd60e51b815260206004820152602560248201527f62757920666565206d7573742062652067726561746572207468616e20464545604482015264535f42555960d81b6064820152608401610cda565b6103cf8161ffff1610156118f95760405162461bcd60e51b815260206004820152601e60248201527f62757920666565206d757374206265206c657373207468616e20322e352500006044820152606401610cda565b6008805461ffff60b01b1916600160b01b61ffff8416908102919091179091556040519081527f7c1445c98b278c9970d007fca6048704bcb25af7cc4a04eb56565d9a9f149ca390602001610fa9565b6001600160a01b03165f908152600d6020526040902060020154421190565b611970612b4c565b6114ce5f612d53565b60065433906001600160a01b031681146119b15760405163118cdaa760e01b81526001600160a01b0382166004820152602401610cda565b61123581612d53565b6119c5823383612b79565b610ef18282612bf5565b5f6119d86127a7565b335f908152600d60205260408120600281015460018201548254600390930154919390929190611a0b8762015180613183565b611a15908661315d565b90505f611a228589610b5a565b9050611a2d33611949565b15611a4a5760405162461bcd60e51b8152600401610cda9061327d565b348114611a995760405162461bcd60e51b815260206004820152601c60248201527f4c6f616e20657874656e73696f6e2066656520696e636f7272656374000000006044820152606401610cda565b5f600a611aa7836003613183565b611ab191906131ae565b90506103e88111611ad45760405162461bcd60e51b8152600401610cda90613246565b600854611aea906001600160a01b03168261282e565b611af5868689612c29565b611b0086868561290e565b335f908152600d60205260409020600201839055611b1e848a61315d565b335f908152600d602052604090206003015561016e62015180611b414286613170565b611b4b91906131ae565b10611b985760405162461bcd60e51b815260206004820152601b60248201527f4c6f616e206d75737420626520756e64657220333635206461797300000000006044820152606401610cda565b611ba1346129d9565b5095505050505050611bb36001600755565b919050565b611bc0612b4c565b6001600160a01b038116611c225760405162461bcd60e51b8152602060048201526024808201527f43616e27742073657420666565206164647265737320746f20307830206164646044820152637265737360e01b6064820152608401610cda565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f446e39bcf1b47cfadfaa23442cb4b34682cfe6bd9220da084894e3b1f834e4f390602001610fa9565b5f610b9a82611c7e60025490565b84611c876122a4565b6118329190613170565b5f6103e8611c9d6122a4565b60085461ffff600160b01b90910416611cb560025490565b611cbf9086613183565b611cc99190613183565b611cd391906131ae565b610b9a91906131ae565b6001600160a01b0381165f908152600d6020526040812060020154819081904211611d31575050506001600160a01b0381165f908152600d6020526040902080546001820154600290920154909190611d3a565b505f9150819050805b9193909250565b606060048054610bf3906131c1565b611d586127a7565b611d6133611949565b15611dae5760405162461bcd60e51b815260206004820152601760248201527f4c6f616e20657870697265642075736520626f72726f770000000000000000006044820152606401610cda565b805f03611df75760405162461bcd60e51b815260206004820152601760248201527604d75737420626f72726f77206d6f7265207468616e203604c1b6044820152606401610cda565b611dff611010565b335f908152600d60205260408120600181015481546002909201549092611e25426123d1565b90505f62015180611e368385613170565b611e4091906131ae565b90505f611e4d8783610b5a565b90505f611e59886126b0565b90505f611e6588610c8b565b90505f816064611e768a6063613183565b611e8091906131ae565b611e8a9190613170565b905082808210611e9b57505f611ea8565b611ea58282613170565b90505b5f600a611eb6876003613183565b611ec091906131ae565b90505f6064611ed08e6063613183565b611eda91906131ae565b90505f611ee7828e61315d565b90505f611ef4858e61315d565b905060405180608001604052808281526020018381526020018d81526020018b815250600d5f336001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f0155602082015181600101556040820151816002015560608201518160030155905050845f14611f7557611f753330876127d1565b6103e88411611f965760405162461bcd60e51b8152600401610cda90613246565b600854611fac906001600160a01b03168561282e565b611fba33610eb38b86613170565b611fc583868e61290e565b611fce896129d9565b50505050505050505050505050506112356001600755565b611fee6127a7565b611ff733611949565b156120145760405162461bcd60e51b8152600401610cda9061327d565b61201c611010565b335f908152600d6020526040812060018101549054909161203c8261181d565b90506120483083612bf5565b5f6064612056836063613183565b61206091906131ae565b90505f61206e6064846131ae565b9050848210156120dc5760405162461bcd60e51b815260206004820152603360248201527f596f7520646f206e6f74206861766520656e6f75676820636f6c6c617465726160448201527236103a379031b637b9b2903837b9b4ba34b7b760691b6064820152608401610cda565b5f6120e78684613170565b90505f600a6120f7846003613183565b61210191906131ae565b905061210d338361282e565b6103e8811161212e5760405162461bcd60e51b8152600401610cda90613246565b600854612144906001600160a01b03168261282e565b335f908152600d60205260409020600201546121639088908890612c29565b335f908152600d6020526040812081815560018101829055600281018290556003015561218f876129d9565b505050505050506114ce6001600755565b5f33610c818185856127d1565b6121b56127a7565b335f818152600d602052604090206001810154905490916121d590611949565b156121f25760405162461bcd60e51b8152600401610cda9061327d565b34821461224c5760405162461bcd60e51b815260206004820152602260248201527f4d7573742072657475726e20656e7469726520626f72726f77656420616d6f756044820152611b9d60f21b6064820152608401610cda565b6122573033836127d1565b335f908152600d60205260409020600201546122769083908390612c29565b335f908152600d6020526040812081815560018101829055600281018290556003018190556114c2906129d9565b5f6122ae60095490565b6122b8904761315d565b905090565b6122c5612b4c565b6103e08161ffff16111561232b5760405162461bcd60e51b815260206004820152602760248201527f73656c6c20666565206d7573742062652067726561746572207468616e2046456044820152661154d7d4d1531360ca1b6064820152608401610cda565b6103cf8161ffff1610156123815760405162461bcd60e51b815260206004820152601f60248201527f73656c6c20666565206d757374206265206c657373207468616e20322e3525006044820152606401610cda565b6008805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f495ee53ee22006979ebc689a00ed737d7c13b6419142f82dcaea4ed95ac1e78090602001610fa9565b5f806123e062015180846132d3565b6123ea9084613170565b9050610caa816201518061315d565b6124016127a7565b612409611010565b5f6124138261181d565b90505f612421607d836131ae565b905061242d3384612bf5565b6008546124599033906103e89061244f90600160a01b900461ffff1686613183565b610eb391906131ae565b6103e881116124a05760405162461bcd60e51b815260206004820152601360248201527236bab9ba103a3930b2329037bb32b91036b4b760691b6044820152606401610cda565b6008546124b6906001600160a01b03168261282e565b6124bf826129d9565b50506112356001600755565b6124d36127a7565b6124db611010565b600854600160d01b900460ff166125345760405162461bcd60e51b815260206004820152601b60248201527f54726164696e67206d75737420626520696e697469616c697a656400000000006044820152606401610cda565b6001600160a01b03811661258a5760405162461bcd60e51b815260206004820152601e60248201527f52656369657665722063616e6e6f7420626520307830206164647265737300006044820152606401610cda565b5f61259434611c70565b90506125cb826103e86125b260085461ffff600160b01b9091041690565b6125bc9085613183565b6125c691906131ae565b612c94565b5f6125d7607d346131ae565b90506103e881116126205760405162461bcd60e51b815260206004820152601360248201527236bab9ba103a3930b2329037bb32b91036b4b760691b6044820152606401610cda565b600854612636906001600160a01b03168261282e565b6124bf346129d9565b612647612b4c565b600680546001600160a01b0383166001600160a01b031990911681179091556126786005546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f5f6126ba6122a4565b9050806126c8600182613170565b6002546126d59086613183565b610fe3919061315d565b5f838302815f1985870982811083820303915050805f03612713578382816127095761270961319a565b0492505050610caa565b80841161272a5761272a6003851502601118612d6c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6127a28383836001612d7d565b505050565b6002600754036127ca57604051633ee5aeb560e01b815260040160405180910390fd5b6002600755565b6001600160a01b0383166127fa57604051634b637e8f60e11b81525f6004820152602401610cda565b6001600160a01b0382166128235760405163ec442f0560e01b81525f6004820152602401610cda565b6127a2838383612e4f565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114612877576040519150601f19603f3d011682016040523d82523d5f602084013e61287c565b606091505b50509050806128c65760405162461bcd60e51b815260206004820152601660248201527529a7a724a1902a3930b739b332b9103330b4b632b21760511b6044820152606401610cda565b604080516001600160a01b0385168152602081018490527f03bbe564cb1b78e43195eeadbde99e5b89b19345862807fcfb59f884e4165e2591015b60405180910390a1505050565b5f818152600f602052604090205461292790839061315d565b5f828152600f6020908152604080832093909355600e9052205461294c90849061315d565b5f828152600e602052604090205560095461296890849061315d565b600955600a5461297990839061315d565b600a8190555f828152600f6020908152604080832054600e8352928190205460095482519485529284015282015260608101919091527faec00f5213a37254bc68a26b0685d1a5b2bf513e1e587c94c7df7f4a62b56c9c90608001612901565b5f6129e360025490565b6129eb6122a4565b6129fd90670de0b6b3a7640000613183565b612a0791906131ae565b305f9081526020819052604081205491925050600a54811015612aac5760405162461bcd60e51b815260206004820152605160248201527f546865206265616e7a2062616c616e6365206f662074686520636f6e7472616360448201527f74206d7573742062652067726561746572207468616e206f7220657175616c206064820152701d1bc81d1a194818dbdb1b185d195c985b607a1b608482015260a401610cda565b81600c541115612b095760405162461bcd60e51b815260206004820152602260248201527f546865207072696365206f66206265616e7a2063616e6e6f7420646563726561604482015261736560f01b6064820152608401610cda565b600c82905560408051428152602081018490529081018490527f4afcb4a87cdbd9974efdb92ee48bc8d7cd0ae4bf217004db3d080cbaee652ca790606001612901565b6005546001600160a01b031633146114ce5760405163118cdaa760e01b8152336004820152602401610cda565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811015612bef5781811015612be157604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610cda565b612bef84848484035f612d7d565b50505050565b6001600160a01b038216612c1e57604051634b637e8f60e11b81525f6004820152602401610cda565b610ef1825f83612e4f565b5f818152600f6020526040902054612c42908390613170565b5f828152600f6020908152604080832093909355600e90522054612c67908490613170565b5f828152600e6020526040902055600954612c83908490613170565b600955600a54612979908390613170565b6001600160a01b038216612cea5760405162461bcd60e51b815260206004820152601c60248201527f43616e2774206d696e7420746f20746f203078302061646472657373000000006044820152606401610cda565b80600b54612cf8919061315d565b600b8190556c01431e0fae6d7217caa00000001015612d495760405162461bcd60e51b815260206004820152600d60248201526c27279026a7a922902122a0a72d60991b6044820152606401610cda565b610ef18282612f75565b600680546001600160a01b031916905561123581612fa9565b634e487b715f52806020526024601cfd5b6001600160a01b038416612da65760405163e602df0560e01b81525f6004820152602401610cda565b6001600160a01b038316612dcf57604051634a1406b160e11b81525f6004820152602401610cda565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015612bef57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612e4191815260200190565b60405180910390a350505050565b6001600160a01b038316612e79578060025f828254612e6e919061315d565b90915550612ee99050565b6001600160a01b0383165f9081526020819052604090205481811015612ecb5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610cda565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612f0557600280548290039055612f23565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612f6891815260200190565b60405180910390a3505050565b6001600160a01b038216612f9e5760405163ec442f0560e01b81525f6004820152602401610cda565b610ef15f8383612e4f565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f6020828403121561300a575f5ffd5b5035919050565b5f5f60408385031215613022575f5ffd5b50508035926020909101359150565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b0381168114611bb3575f5ffd5b5f5f6040838503121561308d575f5ffd5b61309683613066565b946020939093013593505050565b5f602082840312156130b4575f5ffd5b813561ffff81168114610caa575f5ffd5b5f5f5f606084860312156130d7575f5ffd5b6130e084613066565b92506130ee60208501613066565b929592945050506040919091013590565b5f6020828403121561310f575f5ffd5b610caa82613066565b5f5f60408385031215613129575f5ffd5b61313283613066565b915061314060208401613066565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610b9a57610b9a613149565b81810381811115610b9a57610b9a613149565b8082028115828204841417610b9a57610b9a613149565b634e487b7160e01b5f52601260045260245ffd5b5f826131bc576131bc61319a565b500490565b600181811c908216806131d557607f821691505b6020821081036131f357634e487b7160e01b5f52602260045260245ffd5b50919050565b6020808252602d908201527f4d617820626f72726f772f657874656e73696f6e206d7573742062652033363560408201526c2064617973206f72206c65737360981b606082015260800190565b6020808252601d908201527f46656573206d75737420626520686967686572207468616e206d696e2e000000604082015260600190565b60208082526036908201527f596f7572206c6f616e20686173206265656e206c6971756964617465642c206e6040820152756f20636f6c6c61746572616c20746f2072656d6f766560501b606082015260800190565b5f826132e1576132e161319a565b50069056fea2646970667358221220333de36a80351bbf75f129741d3ae9dbe96718ae2a42ff6873d3063e35d9272f64736f6c634300081c0033

Deployed Bytecode

0x608060405260043610610374575f3560e01c806379ba5097116101ce578063abd545bf11610100578063e064648a11610099578063eb1edd611161006b578063eb1edd6114610aab578063f088d54714610aca578063f2fde38b14610add578063ff7bf6f514610afc57005b8063e064648a14610a31578063e30c397814610a50578063e3eb5ed314610a6d578063e4849b3214610a8c57005b8063c962a4b5116100d2578063c962a4b51461096d578063d5abeb0114610998578063d6eb5910146109d9578063dd62ed3e146109ed57005b8063abd545bf14610910578063be9a655514610931578063c393d0e314610951578063c94220ab1461095957005b806390594cce116101725780639d41ac3a116101445780639d41ac3a14610868578063a2309ff81461087c578063a9059cbb14610891578063a925e4a4146108b057005b806390594cce146107dc57806395ced06f146107fb57806395d89b41146108355780639d0bf2e91461084957005b80638705fcd4116101ab5780638705fcd41461074e5780638ca385a71461076d5780638da5cb5b1461078c5780638f818b90146107bd57005b806379ba50971461070857806379cc67901461071c5780637ace2ac91461073b57005b8063313ce567116102a757806342966c681161024b57806370a082311161021d57806370a082311461068257806370c47671146106b657806370f84ba9146106d5578063715018a6146106f457005b806342966c68146106065780634fbf3ab0146106255780635e96263c146106505780635fdd4be21461066357005b806335975a371161028457806335975a37146105b657806336189d43146105be5780633be4e598146105df578063402d8883146105fe57005b8063313ce567146105675780633237c158146105825780633421f750146105a157005b80630c767d881161031957806318160ddd116102eb57806318160ddd146105015780631fb87f391461051557806323b872dd1461053457806328a070251461055357005b80630c767d88146104705780630ecbcdab1461048f578063162b51fc146104ae57806317a5a97e146104e257005b806303fac5a21161035257806303fac5a2146103ec578063053f14da1461040b57806306fdde0314610420578063095ea7b31461044157005b8063024cad3b146103765780630307c4a1146103af578063035b7c4b146103cd575b005b348015610381575f5ffd5b50610395610390366004612ffa565b610b1b565b604080519283526020830191909152015b60405180910390f35b3480156103ba575f5ffd5b506009545b6040519081526020016103a6565b3480156103d8575f5ffd5b506103bf6103e7366004613011565b610b5a565b3480156103f7575f5ffd5b506103bf610406366004613011565b610ba0565b348015610416575f5ffd5b506103bf600c5481565b34801561042b575f5ffd5b50610434610be4565b6040516103a69190613031565b34801561044c575f5ffd5b5061046061045b36600461307c565b610c74565b60405190151581526020016103a6565b34801561047b575f5ffd5b506103bf61048a366004612ffa565b610c8b565b34801561049a575f5ffd5b506103746104a9366004613011565b610cb1565b3480156104b9575f5ffd5b506008546104cf90600160b01b900461ffff1681565b60405161ffff90911681526020016103a6565b3480156104ed575f5ffd5b506103746104fc3660046130a4565b610ef5565b34801561050c575f5ffd5b506002546103bf565b348015610520575f5ffd5b506103bf61052f366004612ffa565b610fb4565b34801561053f575f5ffd5b5061046061054e3660046130c5565b610fed565b34801561055e575f5ffd5b50610374611010565b348015610572575f5ffd5b50604051601281526020016103a6565b34801561058d575f5ffd5b5061037461059c366004612ffa565b6110f7565b3480156105ac575f5ffd5b506103bf60105481565b610374611238565b3480156105c9575f5ffd5b506008546104cf90600160c01b900461ffff1681565b3480156105ea575f5ffd5b506103bf6105f9366004613011565b611315565b610374611361565b348015610611575f5ffd5b50610374610620366004612ffa565b6114d0565b348015610630575f5ffd5b506103bf61063f366004612ffa565b600e6020525f908152604090205481565b61037461065e366004613011565b6114da565b34801561066e575f5ffd5b506103bf61067d366004612ffa565b61181d565b34801561068d575f5ffd5b506103bf61069c3660046130ff565b6001600160a01b03165f9081526020819052604090205490565b3480156106c1575f5ffd5b506103746106d03660046130a4565b611837565b3480156106e0575f5ffd5b506104606106ef3660046130ff565b611949565b3480156106ff575f5ffd5b50610374611968565b348015610713575f5ffd5b50610374611979565b348015610727575f5ffd5b5061037461073636600461307c565b6119ba565b6103bf610749366004612ffa565b6119cf565b348015610759575f5ffd5b506103746107683660046130ff565b611bb8565b348015610778575f5ffd5b506103bf610787366004612ffa565b611c70565b348015610797575f5ffd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016103a6565b3480156107c8575f5ffd5b50600854600160b01b900461ffff166103bf565b3480156107e7575f5ffd5b506103bf6107f6366004612ffa565b611c91565b348015610806575f5ffd5b5061081a6108153660046130ff565b611cdd565b604080519384526020840192909252908201526060016103a6565b348015610840575f5ffd5b50610434611d41565b348015610854575f5ffd5b50610374610863366004612ffa565b611d50565b348015610873575f5ffd5b50610374611fe6565b348015610887575f5ffd5b506103bf600b5481565b34801561089c575f5ffd5b506104606108ab36600461307c565b6121a0565b3480156108bb575f5ffd5b506108f06108ca3660046130ff565b600d6020525f908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016103a6565b34801561091b575f5ffd5b506008546104cf90600160a01b900461ffff1681565b34801561093c575f5ffd5b5060085461046090600160d01b900460ff1681565b6103746121ad565b348015610964575f5ffd5b506103bf6122a4565b348015610978575f5ffd5b506103bf610987366004612ffa565b600f6020525f908152604090205481565b3480156109a3575f5ffd5b506109b86c01431e0fae6d7217caa000000081565b6040516fffffffffffffffffffffffffffffffff90911681526020016103a6565b3480156109e4575f5ffd5b50600a546103bf565b3480156109f8575f5ffd5b506103bf610a07366004613118565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610a3c575f5ffd5b50610374610a4b3660046130a4565b6122bd565b348015610a5b575f5ffd5b506006546001600160a01b03166107a5565b348015610a78575f5ffd5b506103bf610a87366004612ffa565b6123d1565b348015610a97575f5ffd5b50610374610aa6366004612ffa565b6123f9565b348015610ab6575f5ffd5b506008546107a5906001600160a01b031681565b610374610ad83660046130ff565b6124cb565b348015610ae8575f5ffd5b50610374610af73660046130ff565b61263f565b348015610b07575f5ffd5b506103bf610b16366004612ffa565b6126b0565b5f5f600e5f610b29856123d1565b81526020019081526020015f2054600f5f610b43866123d1565b81526020019081526020015f205491509150915091565b5f5f610b70668a8e4b1a3d80008461016d6126df565b610b819066038d7ea4c6800061315d565b9050610b968482670de0b6b3a76400006126df565b9150505b92915050565b5f5f82610bab6122a4565b610bb59190613170565b905080610bc3600182613170565b600254610bd09087613183565b610bda919061315d565b610b9691906131ae565b606060038054610bf3906131c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1f906131c1565b8015610c6a5780601f10610c4157610100808354040283529160200191610c6a565b820191905f5260205f20905b815481529060010190602001808311610c4d57829003601f168201915b5050505050905090565b5f33610c81818585612795565b5060019392505050565b5f5f610c956122a4565b9050610caa83610ca460025490565b836126df565b9392505050565b610cb96127a7565b61016e8110610ce35760405162461bcd60e51b8152600401610cda906131f9565b60405180910390fd5b815f03610d2c5760405162461bcd60e51b815260206004820152601760248201527604d75737420626f72726f77206d6f7265207468616e203604c1b6044820152606401610cda565b610d3533611949565b15610d5e57335f908152600d602052604081208181556001810182905560028101829055600301555b335f908152600d602052604090206001015415610dbd5760405162461bcd60e51b815260206004820152601d60248201527f55736520626f72726f774d6f726520746f20626f72726f77206d6f72650000006044820152606401610cda565b610dc5611010565b5f610de142610dd78462015180613183565b610a87919061315d565b90505f610dee8484610b5a565b90505f600a610dfe836003613183565b610e0891906131ae565b90505f610e14866126b0565b90505f6064610e24886063613183565b610e2e91906131ae565b6040805160808101825284815260208082018481528284018a8152606084018c8152335f818152600d90955295909320935184559051600184015551600283015551600390910155909150610e849030846127d1565b6103e88311610ea55760405162461bcd60e51b8152600401610cda90613246565b610eb833610eb38684613170565b61282e565b600854610ece906001600160a01b03168461282e565b610ed981838761290e565b610ee2846129d9565b5050505050610ef16001600755565b5050565b610efd612b4c565b60198161ffff161115610f5d5760405162461bcd60e51b815260206004820152602260248201527f6c657665726167652062757920666565206d757374206265206c65737320322e604482015261352560f01b6064820152608401610cda565b6008805461ffff60c01b1916600160c01b61ffff8416908102919091179091556040519081527fd4e469371f09a592c9c4fde36ed11fd123a8cc55d93bd2920ea6ad544dff4395906020015b60405180910390a150565b5f5f610fbf83610c8b565b90506103e8610fd960085461ffff600160b01b9091041690565b610fe39083613183565b610caa91906131ae565b5f33610ffa858285612b79565b6110058585856127d1565b506001949350505050565b5f5f5b426010541015611071576010545f908152600f6020526040902054611038908261315d565b6010545f908152600e6020526040902054909150611056908361315d565b915060105462015180611069919061315d565b601055611013565b80156110925780600a546110859190613170565b600a556110923082612bf5565b8115610ef157816009546110a69190613170565b6009556010547f253e5385159062a101837d58c10ad4694c58979ebc3ba6b5cb2cbba2fe461692906110dc906201518090613170565b60408051918252602082018590520160405180910390a15050565b6110ff6127a7565b61110833611949565b156111255760405162461bcd60e51b8152600401610cda9061327d565b61112d611010565b335f908152600d6020526040902054606461114b61067d8484613170565b611156906063613183565b61116091906131ae565b335f908152600d602052604090206001015411156111cb5760405162461bcd60e51b815260206004820152602260248201527f526571756972652039392520636f6c6c61746572616c697a6174696f6e207261604482015261746560f01b6064820152608401610cda565b335f908152600d60205260409020546111e5908390613170565b335f818152600d6020526040902091909155611203903090846127d1565b335f908152600d602052604081206002015461122191908490612c29565b61122a5f6129d9565b506112356001600755565b50565b611240612b4c565b6008546001600160a01b031661128f5760405162461bcd60e51b81526020600482015260146024820152734d7573742073657420666565206164647265737360601b6044820152606401610cda565b5f61129c6103e834613183565b9050670de0b6b3a76400008110156112b2575f5ffd5b6112bc3382612c94565b6112d13361dead670de0b6b3a76400006127d1565b6008805460ff60d01b1916600160d01b179055604051600181527f4f366f0dc5cd876e456f089309e0c62fc2bc0e116c6f6ae308c392b4ad45b5b990602001610fa9565b6008545f9081906103e89061133590600160c01b900461ffff1686613183565b61133f91906131ae565b90505f61134c8585610b5a565b9050611358818361315d565b95945050505050565b6113696127a7565b335f908152600d60205260409020600101543481116113d65760405162461bcd60e51b8152602060048201526024808201527f4d757374207265706179206c657373207468616e20626f72726f77656420616d6044820152631bdd5b9d60e21b6064820152608401610cda565b345f0361141c5760405162461bcd60e51b81526020600482015260146024820152734d75737420726570617920736f6d657468696e6760601b6044820152606401610cda565b61142533611949565b156114865760405162461bcd60e51b815260206004820152602b60248201527f596f7572206c6f616e20686173206265656e206c6971756964617465642c206360448201526a616e6e6f7420726570617960a81b6064820152608401610cda565b5f6114913483613170565b335f908152600d6020526040812060018101839055600201549192506114b991349190612c29565b6114c25f6129d9565b50506114ce6001600755565b565b6112353382612bf5565b6114e26127a7565b600854600160d01b900460ff1661153b5760405162461bcd60e51b815260206004820152601b60248201527f54726164696e67206d75737420626520696e697469616c697a656400000000006044820152606401610cda565b61016e811061155c5760405162461bcd60e51b8152600401610cda906131f9565b335f908152600d6020908152604091829020825160808101845281548152600182015492810183905260028201549381019390935260030154606083015215611630576115a833611949565b156115d157335f908152600d602052604081208181556001810182905560028101829055600301555b335f908152600d6020526040902060010154156116305760405162461bcd60e51b815260206004820152601960248201527f557365206163636f756e742077697468206e6f206c6f616e73000000000000006044820152606401610cda565b611638611010565b5f61164a42610dd78562015180613183565b90505f6116578585611315565b90505f6116648287613170565b90505f600a611674846003613183565b61167e91906131ae565b90505f606461168e846063613183565b61169891906131ae565b90505f6116a66064856131ae565b90505f6116b3828561315d565b90505f6116c0838861315d565b90505f813411156116e1576116d58234613170565b90506116e1338261282e565b816116ec8234613170565b146117395760405162461bcd60e51b815260206004820152601b60248201527f496e73756666696369656e7420736f6e6963206665652073656e7400000000006044820152606401610cda565b5f6117448885610ba0565b90506117503082612c94565b6103e887116117715760405162461bcd60e51b8152600401610cda90613246565b600854611787906001600160a01b03168861282e565b61179286828c61290e565b60405180608001604052808281526020018781526020018b81526020018d815250600d5f336001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f01556020820151816001015560408201518160020155606082015181600301559050506118088d6129d9565b5050505050505050505050610ef16001600755565b5f610b9a8261182a6122a4565b6002546126df565b6126df565b61183f612b4c565b6103e08161ffff1611156118a35760405162461bcd60e51b815260206004820152602560248201527f62757920666565206d7573742062652067726561746572207468616e20464545604482015264535f42555960d81b6064820152608401610cda565b6103cf8161ffff1610156118f95760405162461bcd60e51b815260206004820152601e60248201527f62757920666565206d757374206265206c657373207468616e20322e352500006044820152606401610cda565b6008805461ffff60b01b1916600160b01b61ffff8416908102919091179091556040519081527f7c1445c98b278c9970d007fca6048704bcb25af7cc4a04eb56565d9a9f149ca390602001610fa9565b6001600160a01b03165f908152600d6020526040902060020154421190565b611970612b4c565b6114ce5f612d53565b60065433906001600160a01b031681146119b15760405163118cdaa760e01b81526001600160a01b0382166004820152602401610cda565b61123581612d53565b6119c5823383612b79565b610ef18282612bf5565b5f6119d86127a7565b335f908152600d60205260408120600281015460018201548254600390930154919390929190611a0b8762015180613183565b611a15908661315d565b90505f611a228589610b5a565b9050611a2d33611949565b15611a4a5760405162461bcd60e51b8152600401610cda9061327d565b348114611a995760405162461bcd60e51b815260206004820152601c60248201527f4c6f616e20657874656e73696f6e2066656520696e636f7272656374000000006044820152606401610cda565b5f600a611aa7836003613183565b611ab191906131ae565b90506103e88111611ad45760405162461bcd60e51b8152600401610cda90613246565b600854611aea906001600160a01b03168261282e565b611af5868689612c29565b611b0086868561290e565b335f908152600d60205260409020600201839055611b1e848a61315d565b335f908152600d602052604090206003015561016e62015180611b414286613170565b611b4b91906131ae565b10611b985760405162461bcd60e51b815260206004820152601b60248201527f4c6f616e206d75737420626520756e64657220333635206461797300000000006044820152606401610cda565b611ba1346129d9565b5095505050505050611bb36001600755565b919050565b611bc0612b4c565b6001600160a01b038116611c225760405162461bcd60e51b8152602060048201526024808201527f43616e27742073657420666565206164647265737320746f20307830206164646044820152637265737360e01b6064820152608401610cda565b600880546001600160a01b0319166001600160a01b0383169081179091556040519081527f446e39bcf1b47cfadfaa23442cb4b34682cfe6bd9220da084894e3b1f834e4f390602001610fa9565b5f610b9a82611c7e60025490565b84611c876122a4565b6118329190613170565b5f6103e8611c9d6122a4565b60085461ffff600160b01b90910416611cb560025490565b611cbf9086613183565b611cc99190613183565b611cd391906131ae565b610b9a91906131ae565b6001600160a01b0381165f908152600d6020526040812060020154819081904211611d31575050506001600160a01b0381165f908152600d6020526040902080546001820154600290920154909190611d3a565b505f9150819050805b9193909250565b606060048054610bf3906131c1565b611d586127a7565b611d6133611949565b15611dae5760405162461bcd60e51b815260206004820152601760248201527f4c6f616e20657870697265642075736520626f72726f770000000000000000006044820152606401610cda565b805f03611df75760405162461bcd60e51b815260206004820152601760248201527604d75737420626f72726f77206d6f7265207468616e203604c1b6044820152606401610cda565b611dff611010565b335f908152600d60205260408120600181015481546002909201549092611e25426123d1565b90505f62015180611e368385613170565b611e4091906131ae565b90505f611e4d8783610b5a565b90505f611e59886126b0565b90505f611e6588610c8b565b90505f816064611e768a6063613183565b611e8091906131ae565b611e8a9190613170565b905082808210611e9b57505f611ea8565b611ea58282613170565b90505b5f600a611eb6876003613183565b611ec091906131ae565b90505f6064611ed08e6063613183565b611eda91906131ae565b90505f611ee7828e61315d565b90505f611ef4858e61315d565b905060405180608001604052808281526020018381526020018d81526020018b815250600d5f336001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f0155602082015181600101556040820151816002015560608201518160030155905050845f14611f7557611f753330876127d1565b6103e88411611f965760405162461bcd60e51b8152600401610cda90613246565b600854611fac906001600160a01b03168561282e565b611fba33610eb38b86613170565b611fc583868e61290e565b611fce896129d9565b50505050505050505050505050506112356001600755565b611fee6127a7565b611ff733611949565b156120145760405162461bcd60e51b8152600401610cda9061327d565b61201c611010565b335f908152600d6020526040812060018101549054909161203c8261181d565b90506120483083612bf5565b5f6064612056836063613183565b61206091906131ae565b90505f61206e6064846131ae565b9050848210156120dc5760405162461bcd60e51b815260206004820152603360248201527f596f7520646f206e6f74206861766520656e6f75676820636f6c6c617465726160448201527236103a379031b637b9b2903837b9b4ba34b7b760691b6064820152608401610cda565b5f6120e78684613170565b90505f600a6120f7846003613183565b61210191906131ae565b905061210d338361282e565b6103e8811161212e5760405162461bcd60e51b8152600401610cda90613246565b600854612144906001600160a01b03168261282e565b335f908152600d60205260409020600201546121639088908890612c29565b335f908152600d6020526040812081815560018101829055600281018290556003015561218f876129d9565b505050505050506114ce6001600755565b5f33610c818185856127d1565b6121b56127a7565b335f818152600d602052604090206001810154905490916121d590611949565b156121f25760405162461bcd60e51b8152600401610cda9061327d565b34821461224c5760405162461bcd60e51b815260206004820152602260248201527f4d7573742072657475726e20656e7469726520626f72726f77656420616d6f756044820152611b9d60f21b6064820152608401610cda565b6122573033836127d1565b335f908152600d60205260409020600201546122769083908390612c29565b335f908152600d6020526040812081815560018101829055600281018290556003018190556114c2906129d9565b5f6122ae60095490565b6122b8904761315d565b905090565b6122c5612b4c565b6103e08161ffff16111561232b5760405162461bcd60e51b815260206004820152602760248201527f73656c6c20666565206d7573742062652067726561746572207468616e2046456044820152661154d7d4d1531360ca1b6064820152608401610cda565b6103cf8161ffff1610156123815760405162461bcd60e51b815260206004820152601f60248201527f73656c6c20666565206d757374206265206c657373207468616e20322e3525006044820152606401610cda565b6008805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f495ee53ee22006979ebc689a00ed737d7c13b6419142f82dcaea4ed95ac1e78090602001610fa9565b5f806123e062015180846132d3565b6123ea9084613170565b9050610caa816201518061315d565b6124016127a7565b612409611010565b5f6124138261181d565b90505f612421607d836131ae565b905061242d3384612bf5565b6008546124599033906103e89061244f90600160a01b900461ffff1686613183565b610eb391906131ae565b6103e881116124a05760405162461bcd60e51b815260206004820152601360248201527236bab9ba103a3930b2329037bb32b91036b4b760691b6044820152606401610cda565b6008546124b6906001600160a01b03168261282e565b6124bf826129d9565b50506112356001600755565b6124d36127a7565b6124db611010565b600854600160d01b900460ff166125345760405162461bcd60e51b815260206004820152601b60248201527f54726164696e67206d75737420626520696e697469616c697a656400000000006044820152606401610cda565b6001600160a01b03811661258a5760405162461bcd60e51b815260206004820152601e60248201527f52656369657665722063616e6e6f7420626520307830206164647265737300006044820152606401610cda565b5f61259434611c70565b90506125cb826103e86125b260085461ffff600160b01b9091041690565b6125bc9085613183565b6125c691906131ae565b612c94565b5f6125d7607d346131ae565b90506103e881116126205760405162461bcd60e51b815260206004820152601360248201527236bab9ba103a3930b2329037bb32b91036b4b760691b6044820152606401610cda565b600854612636906001600160a01b03168261282e565b6124bf346129d9565b612647612b4c565b600680546001600160a01b0383166001600160a01b031990911681179091556126786005546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b5f5f6126ba6122a4565b9050806126c8600182613170565b6002546126d59086613183565b610fe3919061315d565b5f838302815f1985870982811083820303915050805f03612713578382816127095761270961319a565b0492505050610caa565b80841161272a5761272a6003851502601118612d6c565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6127a28383836001612d7d565b505050565b6002600754036127ca57604051633ee5aeb560e01b815260040160405180910390fd5b6002600755565b6001600160a01b0383166127fa57604051634b637e8f60e11b81525f6004820152602401610cda565b6001600160a01b0382166128235760405163ec442f0560e01b81525f6004820152602401610cda565b6127a2838383612e4f565b5f826001600160a01b0316826040515f6040518083038185875af1925050503d805f8114612877576040519150601f19603f3d011682016040523d82523d5f602084013e61287c565b606091505b50509050806128c65760405162461bcd60e51b815260206004820152601660248201527529a7a724a1902a3930b739b332b9103330b4b632b21760511b6044820152606401610cda565b604080516001600160a01b0385168152602081018490527f03bbe564cb1b78e43195eeadbde99e5b89b19345862807fcfb59f884e4165e2591015b60405180910390a1505050565b5f818152600f602052604090205461292790839061315d565b5f828152600f6020908152604080832093909355600e9052205461294c90849061315d565b5f828152600e602052604090205560095461296890849061315d565b600955600a5461297990839061315d565b600a8190555f828152600f6020908152604080832054600e8352928190205460095482519485529284015282015260608101919091527faec00f5213a37254bc68a26b0685d1a5b2bf513e1e587c94c7df7f4a62b56c9c90608001612901565b5f6129e360025490565b6129eb6122a4565b6129fd90670de0b6b3a7640000613183565b612a0791906131ae565b305f9081526020819052604081205491925050600a54811015612aac5760405162461bcd60e51b815260206004820152605160248201527f546865206265616e7a2062616c616e6365206f662074686520636f6e7472616360448201527f74206d7573742062652067726561746572207468616e206f7220657175616c206064820152701d1bc81d1a194818dbdb1b185d195c985b607a1b608482015260a401610cda565b81600c541115612b095760405162461bcd60e51b815260206004820152602260248201527f546865207072696365206f66206265616e7a2063616e6e6f7420646563726561604482015261736560f01b6064820152608401610cda565b600c82905560408051428152602081018490529081018490527f4afcb4a87cdbd9974efdb92ee48bc8d7cd0ae4bf217004db3d080cbaee652ca790606001612901565b6005546001600160a01b031633146114ce5760405163118cdaa760e01b8152336004820152602401610cda565b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f19811015612bef5781811015612be157604051637dc7a0d960e11b81526001600160a01b03841660048201526024810182905260448101839052606401610cda565b612bef84848484035f612d7d565b50505050565b6001600160a01b038216612c1e57604051634b637e8f60e11b81525f6004820152602401610cda565b610ef1825f83612e4f565b5f818152600f6020526040902054612c42908390613170565b5f828152600f6020908152604080832093909355600e90522054612c67908490613170565b5f828152600e6020526040902055600954612c83908490613170565b600955600a54612979908390613170565b6001600160a01b038216612cea5760405162461bcd60e51b815260206004820152601c60248201527f43616e2774206d696e7420746f20746f203078302061646472657373000000006044820152606401610cda565b80600b54612cf8919061315d565b600b8190556c01431e0fae6d7217caa00000001015612d495760405162461bcd60e51b815260206004820152600d60248201526c27279026a7a922902122a0a72d60991b6044820152606401610cda565b610ef18282612f75565b600680546001600160a01b031916905561123581612fa9565b634e487b715f52806020526024601cfd5b6001600160a01b038416612da65760405163e602df0560e01b81525f6004820152602401610cda565b6001600160a01b038316612dcf57604051634a1406b160e11b81525f6004820152602401610cda565b6001600160a01b038085165f9081526001602090815260408083209387168352929052208290558015612bef57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051612e4191815260200190565b60405180910390a350505050565b6001600160a01b038316612e79578060025f828254612e6e919061315d565b90915550612ee99050565b6001600160a01b0383165f9081526020819052604090205481811015612ecb5760405163391434e360e21b81526001600160a01b03851660048201526024810182905260448101839052606401610cda565b6001600160a01b0384165f9081526020819052604090209082900390555b6001600160a01b038216612f0557600280548290039055612f23565b6001600160a01b0382165f9081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051612f6891815260200190565b60405180910390a3505050565b6001600160a01b038216612f9e5760405163ec442f0560e01b81525f6004820152602401610cda565b610ef15f8383612e4f565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f6020828403121561300a575f5ffd5b5035919050565b5f5f60408385031215613022575f5ffd5b50508035926020909101359150565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b0381168114611bb3575f5ffd5b5f5f6040838503121561308d575f5ffd5b61309683613066565b946020939093013593505050565b5f602082840312156130b4575f5ffd5b813561ffff81168114610caa575f5ffd5b5f5f5f606084860312156130d7575f5ffd5b6130e084613066565b92506130ee60208501613066565b929592945050506040919091013590565b5f6020828403121561310f575f5ffd5b610caa82613066565b5f5f60408385031215613129575f5ffd5b61313283613066565b915061314060208401613066565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610b9a57610b9a613149565b81810381811115610b9a57610b9a613149565b8082028115828204841417610b9a57610b9a613149565b634e487b7160e01b5f52601260045260245ffd5b5f826131bc576131bc61319a565b500490565b600181811c908216806131d557607f821691505b6020821081036131f357634e487b7160e01b5f52602260045260245ffd5b50919050565b6020808252602d908201527f4d617820626f72726f772f657874656e73696f6e206d7573742062652033363560408201526c2064617973206f72206c65737360981b606082015260800190565b6020808252601d908201527f46656573206d75737420626520686967686572207468616e206d696e2e000000604082015260600190565b60208082526036908201527f596f7572206c6f616e20686173206265656e206c6971756964617465642c206e6040820152756f20636f6c6c61746572616c20746f2072656d6f766560501b606082015260800190565b5f826132e1576132e161319a565b50069056fea2646970667358221220333de36a80351bbf75f129741d3ae9dbe96718ae2a42ff6873d3063e35d9272f64736f6c634300081c0033

Deployed Bytecode Sourcemap

309:20654:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17780:247;;;;;;;;;;-1:-1:-1;17780:247:12;;;;;:::i;:::-;;:::i;:::-;;;;419:25:13;;;475:2;460:18;;453:34;;;;392:18;17780:247:12;;;;;;;;18674:95;;;;;;;;;;-1:-1:-1;18749:13:12;;18674:95;;;644:25:13;;;632:2;617:18;18674:95:12;498:177:13;7656:253:12;;;;;;;;;;-1:-1:-1;7656:253:12;;;;;:::i;:::-;;:::i;19820:224::-;;;;;;;;;;-1:-1:-1;19820:224:12;;;;;:::i;:::-;;:::i;959:28::-;;;;;;;;;;;;;;;;1779:89:3;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3998:186::-;;;;;;;;;;-1:-1:-1;3998:186:3;;;;;:::i;:::-;;:::i;:::-;;;2102:14:13;;2095:22;2077:41;;2065:2;2050:18;3998:186:3;1937:187:13;20260:180:12;;;;;;;;;;-1:-1:-1;20260:180:12;;;;;:::i;:::-;;:::i;7915:1396::-;;;;;;;;;;-1:-1:-1;7915:1396:12;;;;;:::i;:::-;;:::i;495:27::-;;;;;;;;;;-1:-1:-1;495:27:12;;;;-1:-1:-1;;;495:27:12;;;;;;;;;2303:6:13;2291:19;;;2273:38;;2261:2;2246:18;495:27:12;2129:188:13;3328:287:12;;;;;;;;;;-1:-1:-1;3328:287:12;;;;;:::i;:::-;;:::i;2849:97:3:-;;;;;;;;;;-1:-1:-1;2927:12:3;;2849:97;;5161:184:12;;;;;;;;;;-1:-1:-1;5161:184:12;;;;;:::i;:::-;;:::i;4776:244:3:-;;;;;;;;;;-1:-1:-1;4776:244:3;;;;;:::i;:::-;;:::i;15742:676:12:-;;;;;;;;;;;;;:::i;2707:82:3:-;;;;;;;;;;-1:-1:-1;2707:82:3;;2780:2;3120:36:13;;3108:2;3093:18;2707:82:3;2978:184:13;11424:725:12;;;;;;;;;;-1:-1:-1;11424:725:12;;;;;:::i;:::-;;:::i;1340:34::-;;;;;;;;;;;;;;;;2101:421;;;:::i;528:35::-;;;;;;;;;;-1:-1:-1;528:35:12;;;;-1:-1:-1;;;528:35:12;;;;;;5350:290;;;;;;;;;;-1:-1:-1;5350:290:12;;;;;:::i;:::-;;:::i;12154:558::-;;;:::i;618:87:5:-;;;;;;;;;;-1:-1:-1;618:87:5;;;;;:::i;:::-;;:::i;1228:49:12:-;;;;;;;;;;-1:-1:-1;1228:49:12;;;;;:::i;:::-;;;;;;;;;;;;;;5646:2004;;;;;;:::i;:::-;;:::i;19524:138::-;;;;;;;;;;-1:-1:-1;19524:138:12;;;;;:::i;:::-;;:::i;3004:116:3:-;;;;;;;;;;-1:-1:-1;3004:116:3;;;;;:::i;:::-;-1:-1:-1;;;;;3095:18:3;3069:7;3095:18;;;;;;;;;;;;3004:116;3062:261:12;;;;;;;;;;-1:-1:-1;3062:261:12;;;;;:::i;:::-;;:::i;18429:133::-;;;;;;;;;;-1:-1:-1;18429:133:12;;;;;:::i;:::-;;:::i;2293:101:0:-;;;;;;;;;;;;;:::i;2244:229:1:-;;;;;;;;;;;;;:::i;1021:158:5:-;;;;;;;;;;-1:-1:-1;1021:158:5;;;;;:::i;:::-;;:::i;14459:1277:12:-;;;;;;:::i;:::-;;:::i;2789:267::-;;;;;;;;;;-1:-1:-1;2789:267:12;;;;;:::i;:::-;;:::i;19668:146::-;;;;;;;;;;-1:-1:-1;19668:146:12;;;;;:::i;:::-;;:::i;1638:85:0:-;;;;;;;;;;-1:-1:-1;1710:6:0;;-1:-1:-1;;;;;1710:6:0;1638:85;;;-1:-1:-1;;;;;3522:32:13;;;3504:51;;3492:2;3477:18;1638:85:0;3358:203:13;18568:82:12;;;;;;;;;;-1:-1:-1;18636:7:12;;-1:-1:-1;;;18636:7:12;;;;18568:82;;20688:202;;;;;;;;;;-1:-1:-1;20688:202:12;;;;;:::i;:::-;;:::i;18033:390::-;;;;;;;;;;-1:-1:-1;18033:390:12;;;;;:::i;:::-;;:::i;:::-;;;;3768:25:13;;;3824:2;3809:18;;3802:34;;;;3852:18;;;3845:34;3756:2;3741:18;18033:390:12;3566:319:13;1981:93:3;;;;;;;;;;;;;:::i;9316:2102:12:-;;;;;;;;;;-1:-1:-1;9316:2102:12;;;;;:::i;:::-;;:::i;13301:1152::-;;;;;;;;;;;;;:::i;927:26::-;;;;;;;;;;;;;;;;3315:178:3;;;;;;;;;;-1:-1:-1;3315:178:3;;;;;:::i;:::-;;:::i;1184:37:12:-;;;;;;;;;;-1:-1:-1;1184:37:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4121:25:13;;;4177:2;4162:18;;4155:34;;;;4205:18;;;4198:34;4263:2;4248:18;;4241:34;4108:3;4093:19;1184:37:12;3890:391:13;461:28:12;;;;;;;;;;-1:-1:-1;461:28:12;;;;-1:-1:-1;;;461:28:12;;;;;;710:25;;;;;;;;;;-1:-1:-1;710:25:12;;;;-1:-1:-1;;;710:25:12;;;;;;12717:579;;;:::i;18880:118::-;;;;;;;;;;;;;:::i;1283:51::-;;;;;;;;;;-1:-1:-1;1283:51:12;;;;;:::i;:::-;;;;;;;;;;;;;;880:41;;;;;;;;;;;;916:5;880:41;;;;;4462:34:13;4450:47;;;4432:66;;4420:2;4405:18;880:41:12;4286:218:13;18775:99:12;;;;;;;;;;-1:-1:-1;18852:15:12;;18775:99;;3551:140:3;;;;;;;;;;-1:-1:-1;3551:140:3;;;;;:::i;:::-;-1:-1:-1;;;;;3657:18:3;;;3631:7;3657:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;3551:140;3620:267:12;;;;;;;;;;-1:-1:-1;3620:267:12;;;;;:::i;:::-;;:::i;1232:99:1:-;;;;;;;;;;-1:-1:-1;1311:13:1;;-1:-1:-1;;;;;1311:13:1;1232:99;;17507:267:12;;;;;;;;;;-1:-1:-1;17507:267:12;;;;;:::i;:::-;;:::i;4527:568::-;;;;;;;;;;-1:-1:-1;4527:568:12;;;;;:::i;:::-;;:::i;378:34::-;;;;;;;;;;-1:-1:-1;378:34:12;;;;-1:-1:-1;;;;;378:34:12;;;3892:630;;;;;;:::i;:::-;;:::i;1649:178:1:-;;;;;;;;;;-1:-1:-1;1649:178:1;;;;;:::i;:::-;;:::i;20050:205:12:-;;;;;;;;;;-1:-1:-1;20050:205:12;;;;;:::i;:::-;;:::i;17780:247::-;17861:7;17870;17910:14;:42;17925:26;17946:4;17925:20;:26::i;:::-;17910:42;;;;;;;;;;;;17966:16;:44;17983:26;18004:4;17983:20;:26::i;:::-;17966:44;;;;;;;;;;;;17889:131;;;;17780:247;;;:::o;7656:253::-;7761:7;7780:16;7799:40;7811:8;7821:12;7835:3;7799:11;:40::i;:::-;:51;;7842:8;7799:51;:::i;:::-;7780:70;;7867:35;7879:6;7887:8;7897:4;7867:11;:35::i;:::-;7860:42;;;7656:253;;;;;:::o;19820:224::-;19916:7;19935:15;19968:3;19953:12;:10;:12::i;:::-;:18;;;;:::i;:::-;19935:36;-1:-1:-1;19935:36:12;20014:11;20024:1;19935:36;20014:11;:::i;:::-;2927:12:3;;19989:21:12;;:5;:21;:::i;:::-;:37;;;;:::i;:::-;19988:49;;;;:::i;1779:89:3:-;1824:13;1856:5;1849:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1779:89;:::o;3998:186::-;4071:4;735:10:7;4125:31:3;735:10:7;4141:7:3;4150:5;4125:8;:31::i;:::-;-1:-1:-1;4173:4:3;;3998:186;-1:-1:-1;;;3998:186:3:o;20260:180:12:-;20325:7;20344:15;20362:12;:10;:12::i;:::-;20344:30;;20391:42;20403:5;20410:13;2927:12:3;;;2849:97;20410:13:12;20425:7;20391:11;:42::i;:::-;20384:49;20260:180;-1:-1:-1;;;20260:180:12:o;7915:1396::-;2500:21:9;:19;:21::i;:::-;8034:3:12::1;8019:12;:18;7998:110;;;;-1:-1:-1::0;;;7998:110:12::1;;;;;;;:::i;:::-;;;;;;;;;8126:5;8135:1;8126:10:::0;8118:46:::1;;;::::0;-1:-1:-1;;;8118:46:12;;6824:2:13;8118:46:12::1;::::0;::::1;6806:21:13::0;6863:2;6843:18;;;6836:30;-1:-1:-1;;;6882:18:13;;;6875:53;6945:18;;8118:46:12::1;6622:347:13::0;8118:46:12::1;8178:25;8192:10;8178:13;:25::i;:::-;8174:80;;;8232:10;8226:17;::::0;;;:5:::1;:17;::::0;;;;8219:24;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;8174:80:::1;8290:10;8284:17;::::0;;;:5:::1;:17;::::0;;;;:26:::1;;::::0;:31;8263:107:::1;;;::::0;-1:-1:-1;;;8263:107:12;;7176:2:13;8263:107:12::1;::::0;::::1;7158:21:13::0;7215:2;7195:18;;;7188:30;7254:31;7234:18;;;7227:59;7303:18;;8263:107:12::1;6974:353:13::0;8263:107:12::1;8380:11;:9;:11::i;:::-;8401:15;8419:85;8479:15;8454:21;:12:::0;8469:6:::1;8454:21;:::i;:::-;8453:41;;;;:::i;8419:85::-;8401:103;;8515:16;8534:35;8549:5;8556:12;8534:14;:35::i;:::-;8515:54:::0;-1:-1:-1;8580:21:12::1;8621:2;8605:12;8515:54:::0;8616:1:::1;8605:12;:::i;:::-;8604:19;;;;:::i;:::-;8580:43;;8686:17;8706:30;8730:5;8706:23;:30::i;:::-;8686:50:::0;-1:-1:-1;8747:21:12::1;8786:3;8772:10;:5:::0;8780:2:::1;8772:10;:::i;:::-;8771:18;;;;:::i;:::-;8820:158;::::0;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;;;8806:10:::1;-1:-1:-1::0;8800:17:12;;;:5:::1;:17:::0;;;;;;;:178;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;8747:42;;-1:-1:-1;8989:47:12::1;::::0;9019:4:::1;8851:9:::0;8989::::1;:47::i;:::-;450:4;9054:13;:19;9046:61;;;;-1:-1:-1::0;;;9046:61:12::1;;;;;;;:::i;:::-;9118:47;9128:10;9140:24;9156:8:::0;9140:13;:24:::1;:::i;:::-;9118:9;:47::i;:::-;9185:11;::::0;9175:37:::1;::::0;-1:-1:-1;;;;;9185:11:12::1;9198:13:::0;9175:9:::1;:37::i;:::-;9223:49;9238:13;9253:9;9264:7;9223:14;:49::i;:::-;9283:21;9295:8;9283:11;:21::i;:::-;7988:1323;;;;;2542:20:9::0;1857:1;3068:7;:21;2888:208;2542:20;7915:1396:12;;:::o;3328:287::-;1531:13:0;:11;:13::i;:::-;3417:2:12::1;3407:6;:12;;;;3399:59;;;::::0;-1:-1:-1;;;3399:59:12;;7892:2:13;3399:59:12::1;::::0;::::1;7874:21:13::0;7931:2;7911:18;;;7904:30;7970:34;7950:18;;;7943:62;-1:-1:-1;;;8021:18:13;;;8014:32;8063:19;;3399:59:12::1;7690:398:13::0;3399:59:12::1;3542:16;:25:::0;;-1:-1:-1;;;;3542:25:12::1;-1:-1:-1::0;;;3542:25:12::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;3582:26:::1;::::0;2273:38:13;;;3582:26:12::1;::::0;2261:2:13;2246:18;3582:26:12::1;;;;;;;;3328:287:::0;:::o;5161:184::-;5220:7;5239:13;5255:27;5275:6;5255:19;:27::i;:::-;5239:43;-1:-1:-1;609:4:12;5309:11;18636:7;;;-1:-1:-1;;;18636:7:12;;;;;18568:82;5309:11;5301:19;;:5;:19;:::i;:::-;5300:37;;;;:::i;4776:244:3:-;4863:4;735:10:7;4919:37:3;4935:4;735:10:7;4950:5:3;4919:15;:37::i;:::-;4966:26;4976:4;4982:2;4986:5;4966:9;:26::i;:::-;-1:-1:-1;5009:4:3;;4776:244;-1:-1:-1;;;;4776:244:3:o;15742:676:12:-;15780:16;15806:18;15835:269;15864:15;15842:19;;:37;15835:269;;;15938:19;;15921:37;;;;:16;:37;;;;;;15908:50;;:10;:50;:::i;:::-;16009:19;;15994:35;;;;:14;:35;;;;;;15895:63;;-1:-1:-1;15983:46:12;;:8;:46;:::i;:::-;15972:57;;16065:19;;16087:6;16065:28;;;;:::i;:::-;16043:19;:50;15835:269;;;16117:15;;16113:138;;16184:10;16166:15;;:28;;;;:::i;:::-;16148:15;:46;16208:32;16222:4;16229:10;16208:5;:32::i;:::-;16264:13;;16260:152;;16325:8;16309:13;;:24;;;;:::i;:::-;16293:13;:40;16362:19;;16352:49;;16362:28;;16384:6;;16362:28;:::i;:::-;16352:49;;;419:25:13;;;475:2;460:18;;453:34;;;392:18;16352:49:12;;;;;;;15770:648;;15742:676::o;11424:725::-;2500:21:9;:19;:21::i;:::-;11518:25:12::1;11532:10;11518:13;:25::i;:::-;11517:26;11496:127;;;;-1:-1:-1::0;;;11496:127:12::1;;;;;;;:::i;:::-;11633:11;:9;:11::i;:::-;11681:10;11654:18;11675:17:::0;;;:5:::1;:17;::::0;;;;:28;11860:3:::1;11818:33;11831:19;11844:6:::0;11675:28;11831:19:::1;:::i;11818:33::-;:38;::::0;11854:2:::1;11818:38;:::i;:::-;11817:46;;;;:::i;:::-;11777:10;11771:17;::::0;;;:5:::1;:17;::::0;;;;:26:::1;;::::0;:92:::1;;11750:173;;;::::0;-1:-1:-1;;;11750:173:12;;9321:2:13;11750:173:12::1;::::0;::::1;9303:21:13::0;9360:2;9340:18;;;9333:30;9399:34;9379:18;;;9372:62;-1:-1:-1;;;9450:18:13;;;9443:32;9492:19;;11750:173:12::1;9119:398:13::0;11750:173:12::1;11970:10;11964:17;::::0;;;:5:::1;:17;::::0;;;;:28;:37:::1;::::0;11995:6;;11964:37:::1;:::i;:::-;11939:10;11933:17;::::0;;;:5:::1;:17;::::0;;;;:68;;;;12011:44:::1;::::0;12029:4:::1;::::0;12048:6;12011:9:::1;:44::i;:::-;12097:10;12080:1;12091:17:::0;;;:5:::1;:17;::::0;;;;:25:::1;;::::0;12065:52:::1;::::0;12080:1;12083:6;;12065:14:::1;:52::i;:::-;12128:14;12140:1;12128:11;:14::i;:::-;11486:663;2542:20:9::0;1857:1;3068:7;:21;2888:208;2542:20;11424:725:12;:::o;2101:421::-;1531:13:0;:11;:13::i;:::-;2164:11:12::1;::::0;-1:-1:-1;;;;;2164:11:12::1;2156:60;;;::::0;-1:-1:-1;;;2156:60:12;;9724:2:13;2156:60:12::1;::::0;::::1;9706:21:13::0;9763:2;9743:18;;;9736:30;-1:-1:-1;;;9782:18:13;;;9775:50;9842:18;;2156:60:12::1;9522:344:13::0;2156:60:12::1;2226:16;2245:15;450:4;2245:9;:15;:::i;:::-;2226:34;;2290:7;2278:8;:19;;2270:28;;;;;;2308:26;2313:10;2325:8;2308:4;:26::i;:::-;2345:120;2368:10;2392:42;2448:7;2345:9;:120::i;:::-;2475:5;:12:::0;;-1:-1:-1;;;;2475:12:12::1;-1:-1:-1::0;;;2475:12:12::1;::::0;;2502:13:::1;::::0;-1:-1:-1;2077:41:13;;2502:13:12::1;::::0;2065:2:13;2050:18;2502:13:12::1;1937:187:13::0;5350:290:12;5497:16;;5451:7;;;;609:4;;5489:24;;-1:-1:-1;;;5497:16:12;;5488:42;5497:16;5489:5;:24;:::i;:::-;5488:42;;;;:::i;:::-;5470:60;;5541:16;5560:35;5575:5;5582:12;5560:14;:35::i;:::-;5541:54;-1:-1:-1;5614:18:12;5541:54;5614:7;:18;:::i;:::-;5606:27;5350:290;-1:-1:-1;;;;;5350:290:12:o;12154:558::-;2500:21:9;:19;:21::i;:::-;12234:10:12::1;12209:16;12228:17:::0;;;:5:::1;:17;::::0;;;;:26:::1;;::::0;12283:9:::1;12272:20:::0;::::1;12264:69;;;::::0;-1:-1:-1;;;12264:69:12;;10073:2:13;12264:69:12::1;::::0;::::1;10055:21:13::0;10112:2;10092:18;;;10085:30;10151:34;10131:18;;;10124:62;-1:-1:-1;;;10202:18:13;;;10195:34;10246:19;;12264:69:12::1;9871:400:13::0;12264:69:12::1;12351:9;12364:1;12351:14:::0;12343:47:::1;;;::::0;-1:-1:-1;;;12343:47:12;;10478:2:13;12343:47:12::1;::::0;::::1;10460:21:13::0;10517:2;10497:18;;;10490:30;-1:-1:-1;;;10536:18:13;;;10529:50;10596:18;;12343:47:12::1;10276:344:13::0;12343:47:12::1;12423:25;12437:10;12423:13;:25::i;:::-;12422:26;12401:116;;;::::0;-1:-1:-1;;;12401:116:12;;10827:2:13;12401:116:12::1;::::0;::::1;10809:21:13::0;10866:2;10846:18;;;10839:30;10905:34;10885:18;;;10878:62;-1:-1:-1;;;10956:18:13;;;10949:41;11007:19;;12401:116:12::1;10625:407:13::0;12401:116:12::1;12527:17;12547:20;12558:9;12547:8:::0;:20:::1;:::i;:::-;12583:10;12577:17;::::0;;;:5:::1;:17;::::0;;;;:26:::1;::::0;::::1;:38:::0;;;12654:25:::1;;::::0;12527:40;;-1:-1:-1;12625:55:12::1;::::0;12640:9:::1;::::0;12577:17;12625:14:::1;:55::i;:::-;12691:14;12703:1;12691:11;:14::i;:::-;12199:513;;2542:20:9::0;1857:1;3068:7;:21;2888:208;2542:20;12154:558:12:o;618:87:5:-;672:26;735:10:7;692:5:5;672;:26::i;5646:2004:12:-;2500:21:9;:19;:21::i;:::-;5769:5:12::1;::::0;-1:-1:-1;;;5769:5:12;::::1;;;5761:45;;;::::0;-1:-1:-1;;;5761:45:12;;11239:2:13;5761:45:12::1;::::0;::::1;11221:21:13::0;11278:2;11258:18;;;11251:30;11317:29;11297:18;;;11290:57;11364:18;;5761:45:12::1;11037:351:13::0;5761:45:12::1;5852:3;5837:12;:18;5816:110;;;;-1:-1:-1::0;;;5816:110:12::1;;;;;;;:::i;:::-;5966:10;5937:20;5960:17:::0;;;:5:::1;:17;::::0;;;;;;;;5937:40;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;;::::0;;;;;5991:22;5987:269:::1;;6033:25;6047:10;6033:13;:25::i;:::-;6029:88;;;6091:10;6085:17;::::0;;;:5:::1;:17;::::0;;;;6078:24;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;6029:88:::1;6161:10;6155:17;::::0;;;:5:::1;:17;::::0;;;;:26:::1;;::::0;:31;6130:115:::1;;;::::0;-1:-1:-1;;;6130:115:12;;11595:2:13;6130:115:12::1;::::0;::::1;11577:21:13::0;11634:2;11614:18;;;11607:30;11673:27;11653:18;;;11646:55;11718:18;;6130:115:12::1;11393:349:13::0;6130:115:12::1;6265:11;:9;:11::i;:::-;6286:15;6304:85;6364:15;6339:21;:12:::0;6354:6:::1;6339:21;:::i;6304:85::-;6286:103;;6400:16;6419:32;6431:5;6438:12;6419:11;:32::i;:::-;6400:51:::0;-1:-1:-1;6462:17:12::1;6482:16;6400:51:::0;6482:5;:16:::1;:::i;:::-;6462:36:::0;-1:-1:-1;6509:24:12::1;6553:2;6537:12;:8:::0;6548:1:::1;6537:12;:::i;:::-;6536:19;;;;:::i;:::-;6509:46:::0;-1:-1:-1;6565:18:12::1;6605:3;6587:14;:9:::0;6599:2:::1;6587:14;:::i;:::-;6586:22;;;;:::i;:::-;6565:43:::0;-1:-1:-1;6618:35:12::1;6656:17;6670:3;6657:9:::0;6656:17:::1;:::i;:::-;6618:55:::0;-1:-1:-1;6683:16:12::1;6702:46;6618:55:::0;6702:16;:46:::1;:::i;:::-;6683:65:::0;-1:-1:-1;6758:16:12::1;6778:38;6789:27:::0;6778:8;:38:::1;:::i;:::-;6758:59;;6827:18;6871:8;6859:9;:20;6855:131;;;6908:20;6920:8:::0;6908:9:::1;:20;:::i;:::-;6895:33;;6942;6952:10;6964;6942:9;:33::i;:::-;7042:8:::0;7016:22:::1;7028:10:::0;7016:9:::1;:22;:::i;:::-;:34;6995:108;;;::::0;-1:-1:-1;;;6995:108:12;;11949:2:13;6995:108:12::1;::::0;::::1;11931:21:13::0;11988:2;11968:18;;;11961:30;12027:29;12007:18;;;12000:57;12074:18;;6995:108:12::1;11747:351:13::0;6995:108:12::1;7151:17;7171:36;7187:9;7198:8;7171:15;:36::i;:::-;7151:56;;7217:30;7230:4;7237:9;7217:4;:30::i;:::-;450:4;7266:16;:22;7258:64;;;;-1:-1:-1::0;;;7258:64:12::1;;;;;;;:::i;:::-;7342:11;::::0;7332:40:::1;::::0;-1:-1:-1;;;;;7342:11:12::1;7355:16:::0;7332:9:::1;:40::i;:::-;7383:46;7398:10;7410:9;7421:7;7383:14;:46::i;:::-;7459:155;;;;;;;;7490:9;7459:155;;;;7523:10;7459:155;;;;7556:7;7459:155;;;;7591:12;7459:155;;::::0;7439:5:::1;:17;7445:10;-1:-1:-1::0;;;;;7439:17:12::1;-1:-1:-1::0;;;;;7439:17:12::1;;;;;;;;;;;;:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7625:18;7637:5;7625:11;:18::i;:::-;5751:1899;;;;;;;;;;;2542:20:9::0;1857:1;3068:7;:21;2888:208;19524:138:12;19582:7;19608:47;19620:5;19627:12;:10;:12::i;:::-;2927::3;;19608:11:12;:47::i;19641:13::-;19608:11;:47::i;3062:261::-;1531:13:0;:11;:13::i;:::-;3143:3:12::1;3133:6;:13;;;;3125:63;;;::::0;-1:-1:-1;;;3125:63:12;;12305:2:13;3125:63:12::1;::::0;::::1;12287:21:13::0;12344:2;12324:18;;;12317:30;12383:34;12363:18;;;12356:62;-1:-1:-1;;;12434:18:13;;;12427:35;12479:19;;3125:63:12::1;12103:401:13::0;3125:63:12::1;3216:3;3206:6;:13;;;;3198:56;;;::::0;-1:-1:-1;;;3198:56:12;;12711:2:13;3198:56:12::1;::::0;::::1;12693:21:13::0;12750:2;12730:18;;;12723:30;12789:32;12769:18;;;12762:60;12839:18;;3198:56:12::1;12509:354:13::0;3198:56:12::1;3264:7;:16:::0;;-1:-1:-1;;;;3264:16:12::1;-1:-1:-1::0;;;3264:16:12::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;3295:21:::1;::::0;2273:38:13;;;3295:21:12::1;::::0;2261:2:13;2246:18;3295:21:12::1;2129:188:13::0;18429:133:12;-1:-1:-1;;;;;18514:15:12;18491:4;18514:15;;;:5;:15;;;;;:23;;;18540:15;-1:-1:-1;18514:41:12;18429:133::o;2293:101:0:-;1531:13;:11;:13::i;:::-;2357:30:::1;2384:1;2357:18;:30::i;2244:229:1:-:0;1311:13;;735:10:7;;-1:-1:-1;;;;;1311:13:1;2339:24;;2335:96;;2386:34;;-1:-1:-1;;;2386:34:1;;-1:-1:-1;;;;;3522:32:13;;2386:34:1;;;3504:51:13;3477:18;;2386:34:1;3358:203:13;2335:96:1;2440:26;2459:6;2440:18;:26::i;1021:158:5:-;1096:45;1112:7;735:10:7;1135:5:5;1096:15;:45::i;:::-;1151:21;1157:7;1166:5;1151;:21::i;14459:1277:12:-;14552:7;2500:21:9;:19;:21::i;:::-;14598:10:12::1;14571:18;14592:17:::0;;;:5:::1;:17;::::0;;;;:25:::1;::::0;::::1;::::0;14646:26:::1;::::0;::::1;::::0;14703:28;;14765:30:::1;::::0;;::::1;::::0;14592:25;;14646:26;;14703:28;14765:30;14841:21:::1;:12:::0;14856:6:::1;14841:21;:::i;:::-;14827:36;::::0;:10;:36:::1;:::i;:::-;14806:57;;14874:15;14892:38;14907:8;14917:12;14892:14;:38::i;:::-;14874:56;;14962:25;14976:10;14962:13;:25::i;:::-;14961:26;14940:127;;;;-1:-1:-1::0;;;14940:127:12::1;;;;;;;:::i;:::-;15096:9;15085:7;:20;15077:61;;;::::0;-1:-1:-1;;;15077:61:12;;13070:2:13;15077:61:12::1;::::0;::::1;13052:21:13::0;13109:2;13089:18;;;13082:30;13148;13128:18;;;13121:58;13196:18;;15077:61:12::1;12868:352:13::0;15077:61:12::1;15148:21;15188:2;15173:11;:7:::0;15183:1:::1;15173:11;:::i;:::-;15172:18;;;;:::i;:::-;15148:42;;450:4;15208:13;:19;15200:61;;;;-1:-1:-1::0;;;15200:61:12::1;;;;;;;:::i;:::-;15281:11;::::0;15271:37:::1;::::0;-1:-1:-1;;;;;15281:11:12::1;15294:13:::0;15271:9:::1;:37::i;:::-;15318:48;15333:8;15343:10;15355;15318:14;:48::i;:::-;15376;15391:8;15401:10;15413;15376:14;:48::i;:::-;15440:10;15434:17;::::0;;;:5:::1;:17;::::0;;;;:25:::1;;:38:::0;;;15515:28:::1;15530:13:::0;15515:12;:28:::1;:::i;:::-;15488:10;15482:17;::::0;;;:5:::1;:17;::::0;;;;:30:::1;;:61:::0;15616:3:::1;15607:6;15575:28;15588:15;15575:10:::0;:28:::1;:::i;:::-;15574:39;;;;:::i;:::-;:45;15553:119;;;::::0;-1:-1:-1;;;15553:119:12;;13427:2:13;15553:119:12::1;::::0;::::1;13409:21:13::0;13466:2;13446:18;;;13439:30;13505:29;13485:18;;;13478:57;13552:18;;15553:119:12::1;13225:351:13::0;15553:119:12::1;15683:22;15695:9;15683:11;:22::i;:::-;-1:-1:-1::0;15722:7:12;-1:-1:-1;;;;;;2542:20:9;1857:1;3068:7;:21;2888:208;2542:20;14459:1277:12;;;:::o;2789:267::-;1531:13:0;:11;:13::i;:::-;-1:-1:-1;;;;;2880:24:12;::::1;2859:107;;;::::0;-1:-1:-1;;;2859:107:12;;13783:2:13;2859:107:12::1;::::0;::::1;13765:21:13::0;13822:2;13802:18;;;13795:30;13861:34;13841:18;;;13834:62;-1:-1:-1;;;13912:18:13;;;13905:34;13956:19;;2859:107:12::1;13581:400:13::0;2859:107:12::1;2976:11;:31:::0;;-1:-1:-1;;;;;;2976:31:12::1;-1:-1:-1::0;;;;;2976:31:12;::::1;::::0;;::::1;::::0;;;3022:27:::1;::::0;3504:51:13;;;3022:27:12::1;::::0;3492:2:13;3477:18;3022:27:12::1;3358:203:13::0;19668:146:12;19726:7;19752:55;19764:5;19771:13;2927:12:3;;;2849:97;19771:13:12;19801:5;19786:12;:10;:12::i;:::-;:20;;;;:::i;20688:202::-;20748:7;609:4;20840:12;:10;:12::i;:::-;20815:7;;;-1:-1:-1;;;20815:7:12;;;;20797:13;2927:12:3;;;2849:97;20797:13:12;20787:24;;:6;:24;:::i;:::-;:36;;;;:::i;:::-;20786:67;;;;:::i;:::-;:97;;;;:::i;18033:390::-;-1:-1:-1;;;;;18153:15:12;;18112:7;18153:15;;;:5;:15;;;;;:23;;;18112:7;;;;18180:15;-1:-1:-1;18149:268:12;;-1:-1:-1;;;;;;;;18236:15:12;;;;;;:5;:15;;;;;:26;;18280:24;;;;18322:23;;;;;18236:26;;18280:24;18211:148;;18149:268;-1:-1:-1;18398:1:12;;-1:-1:-1;18398:1:12;;-1:-1:-1;18398:1:12;18149:268;18033:390;;;;;:::o;1981:93:3:-;2028:13;2060:7;2053:14;;;;;:::i;9316:2102:12:-;2500:21:9;:19;:21::i;:::-;9390:25:12::1;9404:10;9390:13;:25::i;:::-;9389:26;9381:62;;;::::0;-1:-1:-1;;;9381:62:12;;14188:2:13;9381:62:12::1;::::0;::::1;14170:21:13::0;14227:2;14207:18;;;14200:30;14266:25;14246:18;;;14239:53;14309:18;;9381:62:12::1;13986:347:13::0;9381:62:12::1;9461:5;9470:1;9461:10:::0;9453:46:::1;;;::::0;-1:-1:-1;;;9453:46:12;;6824:2:13;9453:46:12::1;::::0;::::1;6806:21:13::0;6863:2;6843:18;;;6836:30;-1:-1:-1;;;6882:18:13;;;6875:53;6945:18;;9453:46:12::1;6622:347:13::0;9453:46:12::1;9509:11;:9;:11::i;:::-;9559:10;9530:20;9553:17:::0;;;:5:::1;:17;::::0;;;;:26:::1;::::0;::::1;::::0;9614:28;;9674:25:::1;::::0;;::::1;::::0;9553:26;;9734:37:::1;9755:15;9734:20;:37::i;:::-;9710:61:::0;-1:-1:-1;9781:23:12::1;9839:6;9808:27;9710:61:::0;9808:11;:27:::1;:::i;:::-;9807:38;;;;:::i;:::-;9781:64;;9856:16;9875:38;9890:5;9897:15;9875:14;:38::i;:::-;9856:57;;9976:17;9996:30;10020:5;9996:23;:30::i;:::-;9976:50;;10036:27;10066:33;10086:12;10066:19;:33::i;:::-;10036:63:::0;-1:-1:-1;10109:25:12::1;10036:63:::0;10175:3:::1;10138:21;10139:14:::0;10157:2:::1;10138:21;:::i;:::-;10137:41;;;;:::i;:::-;:75;;;;:::i;:::-;10109:103:::0;-1:-1:-1;10259:9:12;10282:30;;::::1;10278:226;;-1:-1:-1::0;10356:1:12::1;10278:226;;;10432:61;10476:17:::0;10432:25;:61:::1;:::i;:::-;10388:105;;10278:226;10514:21;10555:2;10539:12;:8:::0;10550:1:::1;10539:12;:::i;:::-;10538:19;;;;:::i;:::-;10514:43:::0;-1:-1:-1;10568:21:12::1;10607:3;10593:10;:5:::0;10601:2:::1;10593:10;:::i;:::-;10592:18;;;;:::i;:::-;10568:42:::0;-1:-1:-1;10621:26:12::1;10650:28;10568:42:::0;10650:12;:28:::1;:::i;:::-;10621:57:::0;-1:-1:-1;10688:30:12::1;10721:54;10750:25:::0;10721:14;:54:::1;:::i;:::-;10688:87;;10806:183;;;;;;;;10837:22;10806:183;;;;10883:18;10806:183;;;;10924:11;10806:183;;;;10963:15;10806:183;;::::0;10786:5:::1;:17;10792:10;-1:-1:-1::0;;;;;10786:17:12::1;-1:-1:-1::0;;;;;10786:17:12::1;;;;;;;;;;;;:203;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11004:25;11033:1;11004:30;11000:124;;11050:63;11060:10;11080:4;11087:25;11050:9;:63::i;:::-;450:4;11142:13;:19;11134:61;;;;-1:-1:-1::0;;;11134:61:12::1;;;;;;;:::i;:::-;11215:11;::::0;11205:37:::1;::::0;-1:-1:-1;;;;;11215:11:12::1;11228:13:::0;11205:9:::1;:37::i;:::-;11252:47;11262:10;11274:24;11290:8:::0;11274:13;:24:::1;:::i;11252:47::-;11310:69;11325:13;11340:25;11367:11;11310:14;:69::i;:::-;11390:21;11402:8;11390:11;:21::i;:::-;9371:2047;;;;;;;;;;;;;;2542:20:9::0;1857:1;3068:7;:21;2888:208;13301:1152:12;2500:21:9;:19;:21::i;:::-;13383:25:12::1;13397:10;13383:13;:25::i;:::-;13382:26;13361:127;;;;-1:-1:-1::0;;;13361:127:12::1;;;;;;;:::i;:::-;13498:11;:9;:11::i;:::-;13544:10;13519:16;13538:17:::0;;;:5:::1;:17;::::0;;;;:26:::1;::::0;::::1;::::0;13596:28;;13538:26;;13700:24:::1;13596:28:::0;13700:12:::1;:24::i;:::-;13672:52;;13734:32;13748:4;13755:10;13734:5;:32::i;:::-;13777:33;13840:3;13814:22;:17:::0;13834:2:::1;13814:22;:::i;:::-;13813:30;;;;:::i;:::-;13777:66:::0;-1:-1:-1;13854:11:12::1;13868:23;13888:3;13868:17:::0;:23:::1;:::i;:::-;13854:37;;13951:8;13922:25;:37;;13901:135;;;::::0;-1:-1:-1;;;13901:135:12;;14540:2:13;13901:135:12::1;::::0;::::1;14522:21:13::0;14579:2;14559:18;;;14552:30;14618:34;14598:18;;;14591:62;-1:-1:-1;;;14669:18:13;;;14662:49;14728:19;;13901:135:12::1;14338:415:13::0;13901:135:12::1;14047:14;14064:36;14092:8:::0;14064:25;:36:::1;:::i;:::-;14047:53:::0;-1:-1:-1;14110:21:12::1;14146:2;14135:7;:3:::0;14141:1:::1;14135:7;:::i;:::-;14134:14;;;;:::i;:::-;14110:38;;14159:29;14169:10;14181:6;14159:9;:29::i;:::-;450:4;14207:13;:19;14199:61;;;;-1:-1:-1::0;;;14199:61:12::1;;;;;;;:::i;:::-;14280:11;::::0;14270:37:::1;::::0;-1:-1:-1;;;;;14280:11:12::1;14293:13:::0;14270:9:::1;:37::i;:::-;14360:10;14354:17;::::0;;;:5:::1;:17;::::0;;;;:25:::1;;::::0;14317:63:::1;::::0;14332:8;;14342:10;;14317:14:::1;:63::i;:::-;14404:10;14398:17;::::0;;;:5:::1;:17;::::0;;;;14391:24;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;14425:21:::1;14437:8:::0;14425:11:::1;:21::i;:::-;13351:1102;;;;;;;2542:20:9::0;1857:1;3068:7;:21;2888:208;3315:178:3;3384:4;735:10:7;3438:27:3;735:10:7;3455:2:3;3459:5;3438:9;:27::i;12717:579:12:-;2500:21:9;:19;:21::i;:::-;12805:10:12::1;12780:16;12799:17:::0;;;:5:::1;:17;::::0;;;;:26:::1;::::0;::::1;::::0;12856:28;;12799:26;;12916:25:::1;::::0;:13:::1;:25::i;:::-;12915:26;12894:127;;;;-1:-1:-1::0;;;12894:127:12::1;;;;;;;:::i;:::-;13051:9;13039:8;:21;13031:68;;;::::0;-1:-1:-1;;;13031:68:12;;14960:2:13;13031:68:12::1;::::0;::::1;14942:21:13::0;14999:2;14979:18;;;14972:30;15038:34;15018:18;;;15011:62;-1:-1:-1;;;15089:18:13;;;15082:32;15131:19;;13031:68:12::1;14758:398:13::0;13031:68:12::1;13109:48;13127:4;13134:10;13146;13109:9;:48::i;:::-;13210:10;13204:17;::::0;;;:5:::1;:17;::::0;;;;:25:::1;;::::0;13167:63:::1;::::0;13182:8;;13192:10;;13167:14:::1;:63::i;:::-;13254:10;13248:17;::::0;;;:5:::1;:17;::::0;;;;13241:24;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;;::::0;;;13275:14:::1;::::0;:11:::1;:14::i;18880:118::-:0;18923:7;18973:18;18749:13;;;18674:95;18973:18;18949:42;;:21;:42;:::i;:::-;18942:49;;18880:118;:::o;3620:267::-;1531:13:0;:11;:13::i;:::-;3702:3:12::1;3692:6;:13;;;;3684:65;;;::::0;-1:-1:-1;;;3684:65:12;;15363:2:13;3684:65:12::1;::::0;::::1;15345:21:13::0;15402:2;15382:18;;;15375:30;15441:34;15421:18;;;15414:62;-1:-1:-1;;;15492:18:13;;;15485:37;15539:19;;3684:65:12::1;15161:403:13::0;3684:65:12::1;3777:3;3767:6;:13;;;;3759:57;;;::::0;-1:-1:-1;;;3759:57:12;;15771:2:13;3759:57:12::1;::::0;::::1;15753:21:13::0;15810:2;15790:18;;;15783:30;15849:33;15829:18;;;15822:61;15900:18;;3759:57:12::1;15569:355:13::0;3759:57:12::1;3826:8;:17:::0;;-1:-1:-1;;;;3826:17:12::1;-1:-1:-1::0;;;3826:17:12::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;3858:22:::1;::::0;2273:38:13;;;3858:22:12::1;::::0;2261:2:13;2246:18;3858:22:12::1;2129:188:13::0;17507:267:12;17572:7;;17627:12;17634:5;17627:4;:12;:::i;:::-;17619:21;;:4;:21;:::i;:::-;17591:49;-1:-1:-1;17741:26:12;17591:49;17761:6;17741:26;:::i;4527:568::-;2500:21:9;:19;:21::i;:::-;4588:11:12::1;:9;:11::i;:::-;4679:13;4695:19;4708:5;4695:12;:19::i;:::-;4679:35:::0;-1:-1:-1;4748:24:12::1;4775:17;700:3;4679:35:::0;4775:17:::1;:::i;:::-;4748:44;;4802:24;4808:10;4820:5;4802;:24::i;:::-;4897:8;::::0;4866:57:::1;::::0;4876:10:::1;::::0;609:4:::1;::::0;4889:16:::1;::::0;-1:-1:-1;;;4897:8:12;::::1;4888:34;4897:8;4889:5:::0;:16:::1;:::i;:::-;4888:34;;;;:::i;4866:57::-;450:4;4963:16;:22;4955:54;;;::::0;-1:-1:-1;;;4955:54:12;;16248:2:13;4955:54:12::1;::::0;::::1;16230:21:13::0;16287:2;16267:18;;;16260:30;-1:-1:-1;;;16306:18:13;;;16299:49;16365:18;;4955:54:12::1;16046:343:13::0;4955:54:12::1;5029:11;::::0;5019:40:::1;::::0;-1:-1:-1;;;;;5029:11:12::1;5042:16:::0;5019:9:::1;:40::i;:::-;5070:18;5082:5;5070:11;:18::i;:::-;4578:517;;2542:20:9::0;1857:1;3068:7;:21;2888:208;3892:630:12;2500:21:9;:19;:21::i;:::-;3963:11:12::1;:9;:11::i;:::-;3992:5;::::0;-1:-1:-1;;;3992:5:12;::::1;;;3984:45;;;::::0;-1:-1:-1;;;3984:45:12;;11239:2:13;3984:45:12::1;::::0;::::1;11221:21:13::0;11278:2;11258:18;;;11251:30;11317:29;11297:18;;;11290:57;11364:18;;3984:45:12::1;11037:351:13::0;3984:45:12::1;-1:-1:-1::0;;;;;4048:24:12;::::1;4040:67;;;::::0;-1:-1:-1;;;4040:67:12;;16596:2:13;4040:67:12::1;::::0;::::1;16578:21:13::0;16635:2;16615:18;;;16608:30;16674:32;16654:18;;;16647:60;16724:18;;4040:67:12::1;16394:354:13::0;4040:67:12::1;4187:13;4203:23;4216:9;4203:12;:23::i;:::-;4187:39:::0;-1:-1:-1;4237:53:12::1;4242:8:::0;609:4:::1;4261:11;18636:7:::0;;;-1:-1:-1;;;18636:7:12;;;;;18568:82;4261:11:::1;4253:19;::::0;:5;:19:::1;:::i;:::-;4252:37;;;;:::i;:::-;4237:4;:53::i;:::-;4321:24;4348:20;655:3;4348:9;:20;:::i;:::-;4321:47;;450:4;4386:16;:22;4378:54;;;::::0;-1:-1:-1;;;4378:54:12;;16248:2:13;4378:54:12::1;::::0;::::1;16230:21:13::0;16287:2;16267:18;;;16260:30;-1:-1:-1;;;16306:18:13;;;16299:49;16365:18;;4378:54:12::1;16046:343:13::0;4378:54:12::1;4452:11;::::0;4442:40:::1;::::0;-1:-1:-1;;;;;4452:11:12::1;4465:16:::0;4442:9:::1;:40::i;:::-;4493:22;4505:9;4493:11;:22::i;1649:178:1:-:0;1531:13:0;:11;:13::i;:::-;1738::1::1;:24:::0;;-1:-1:-1;;;;;1738:24:1;::::1;-1:-1:-1::0;;;;;;1738:24:1;;::::1;::::0;::::1;::::0;;;1802:7:::1;1710:6:0::0;;-1:-1:-1;;;;;1710:6:0;;1638:85;1802:7:1::1;-1:-1:-1::0;;;;;1777:43:1::1;;;;;;;;;;;1649:178:::0;:::o;20050:205:12:-;20133:7;20152:15;20170:12;:10;:12::i;:::-;20152:30;-1:-1:-1;20152:30:12;20225:11;20235:1;20152:30;20225:11;:::i;:::-;2927:12:3;;20200:21:12;;:5;:21;:::i;:::-;:37;;;;:::i;4996:4226:10:-;5078:14;5449:5;;;5078:14;-1:-1:-1;;5453:1:10;5449;5621:20;5694:5;5690:2;5687:13;5679:5;5675:2;5671:14;5667:34;5658:43;;;5796:5;5805:1;5796:10;5792:368;;6134:11;6126:5;:19;;;;;:::i;:::-;;6119:26;;;;;;5792:368;6285:5;6270:11;:20;6266:143;;6310:84;3066:5;6330:16;;3065:36;940:4:8;3060:42:10;6310:11;:84::i;:::-;6664:17;6799:11;6796:1;6793;6786:25;7199:12;7229:15;;;7214:31;;7348:22;;;;;8094:1;8075;:15;;8074:21;;8327;;;8323:25;;8312:36;8397:21;;;8393:25;;8382:36;8469:21;;;8465:25;;8454:36;8540:21;;;8536:25;;8525:36;8613:21;;;8609:25;;8598:36;8687:21;;;8683:25;;;8672:36;7597:12;;;;7593:23;;;7618:1;7589:31;6913:20;;;6902:32;;;7709:12;;;;6960:21;;;;7446:16;;;;7700:21;;;;9163:15;;;;;-1:-1:-1;;4996:4226:10;;;;;:::o;8726:128:3:-;8810:37;8819:5;8826:7;8835:5;8842:4;8810:8;:37::i;:::-;8726:128;;;:::o;2575:307:9:-;1899:1;2702:7;;:18;2698:86;;2743:30;;-1:-1:-1;;;2743:30:9;;;;;;;;;;;2698:86;1899:1;2858:7;:17;2575:307::o;5393:300:3:-;-1:-1:-1;;;;;5476:18:3;;5472:86;;5517:30;;-1:-1:-1;;;5517:30:3;;5544:1;5517:30;;;3504:51:13;3477:18;;5517:30:3;3358:203:13;5472:86:3;-1:-1:-1;;;;;5571:16:3;;5567:86;;5610:32;;-1:-1:-1;;;5610:32:3;;5639:1;5610:32;;;3504:51:13;3477:18;;5610:32:3;3358:203:13;5567:86:3;5662:24;5670:4;5676:2;5680:5;5662:7;:24::i;20446:224:12:-;20519:12;20537:8;-1:-1:-1;;;;;20537:13:12;20558:6;20537:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20518:51;;;20587:7;20579:42;;;;-1:-1:-1;;;20579:42:12;;17165:2:13;20579:42:12;;;17147:21:13;17204:2;17184:18;;;17177:30;-1:-1:-1;;;17223:18:13;;;17216:52;17285:18;;20579:42:12;16963:346:13;20579:42:12;20636:27;;;-1:-1:-1;;;;;17506:32:13;;17488:51;;17570:2;17555:18;;17548:34;;;20636:27:12;;17461:18:13;20636:27:12;;;;;;;;20508:162;20446:224;;:::o;16424:526::-;16573:22;;;;:16;:22;;;;;;:35;;16598:10;;16573:35;:::i;:::-;16548:22;;;;:16;:22;;;;;;;;:60;;;;16641:14;:20;;;;:31;;16664:8;;16641:31;:::i;:::-;16618:20;;;;:14;:20;;;;;:54;16698:13;;:24;;16714:8;;16698:24;:::i;:::-;16682:13;:40;16750:15;;:28;;16768:10;;16750:28;:::i;:::-;16732:15;:46;;;16821:22;;;;:16;:22;;;;;;;;;16857:14;:20;;;;;;;16891:13;;16793:150;;4121:25:13;;;4162:18;;;4155:34;4205:18;;4198:34;4263:2;4248:18;;4241:34;;;;16793:150:12;;4108:3:13;4093:19;16793:150:12;3890:391:13;19004:514:12;19058:16;19104:13;2927:12:3;;;2849:97;19104:13:12;19078:12;:10;:12::i;:::-;:22;;19093:7;19078:22;:::i;:::-;19077:40;;;;:::i;:::-;19171:4;19127:23;3095:18:3;;;;;;;;;;;19058:59:12;;-1:-1:-1;19127:50:12;19227:15;;19208;:34;;19187:162;;;;-1:-1:-1;;;19187:162:12;;17795:2:13;19187:162:12;;;17777:21:13;17834:2;17814:18;;;17807:30;17873:34;17853:18;;;17846:62;17944:34;17924:18;;;17917:62;-1:-1:-1;;;17995:19:13;;;17988:48;18053:19;;19187:162:12;17593:485:13;19187:162:12;19380:8;19367:9;;:21;;19359:68;;;;-1:-1:-1;;;19359:68:12;;18285:2:13;19359:68:12;;;18267:21:13;18324:2;18304:18;;;18297:30;18363:34;18343:18;;;18336:62;-1:-1:-1;;;18414:18:13;;;18407:32;18456:19;;19359:68:12;18083:398:13;19359:68:12;19437:9;:20;;;19472:39;;;19478:15;3768:25:13;;3824:2;3809:18;;3802:34;;;3852:18;;;3845:34;;;19472:39:12;;3756:2:13;3741:18;19472:39:12;3566:319:13;1796:162:0;1710:6;;-1:-1:-1;;;;;1710:6:0;735:10:7;1855:23:0;1851:101;;1901:40;;-1:-1:-1;;;1901:40:0;;735:10:7;1901:40:0;;;3504:51:13;3477:18;;1901:40:0;3358:203:13;10415:476:3;-1:-1:-1;;;;;3657:18:3;;;10514:24;3657:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;10580:36:3;;10576:309;;;10655:5;10636:16;:24;10632:130;;;10687:60;;-1:-1:-1;;;10687:60:3;;-1:-1:-1;;;;;18706:32:13;;10687:60:3;;;18688:51:13;18755:18;;;18748:34;;;18798:18;;;18791:34;;;18661:18;;10687:60:3;18486:345:13;10632:130:3;10803:57;10812:5;10819:7;10847:5;10828:16;:24;10854:5;10803:8;:57::i;:::-;10504:387;10415:476;;;:::o;7984:206::-;-1:-1:-1;;;;;8054:21:3;;8050:89;;8098:30;;-1:-1:-1;;;8098:30:3;;8125:1;8098:30;;;3504:51:13;3477:18;;8098:30:3;3358:203:13;8050:89:3;8148:35;8156:7;8173:1;8177:5;8148:7;:35::i;16955:526:12:-;17104:22;;;;:16;:22;;;;;;:35;;17129:10;;17104:35;:::i;:::-;17079:22;;;;:16;:22;;;;;;;;:60;;;;17172:14;:20;;;;:31;;17195:8;;17172:31;:::i;:::-;17149:20;;;;:14;:20;;;;;:54;17229:13;;:24;;17245:8;;17229:24;:::i;:::-;17213:13;:40;17281:15;;:28;;17299:10;;17281:28;:::i;2528:255::-;-1:-1:-1;;;;;2595:18:12;;2587:59;;;;-1:-1:-1;;;2587:59:12;;19038:2:13;2587:59:12;;;19020:21:13;19077:2;19057:18;;;19050:30;19116;19096:18;;;19089:58;19164:18;;2587:59:12;18836:352:13;2587:59:12;2684:5;2670:11;;:19;;;;:::i;:::-;2656:11;:33;;;916:5;-1:-1:-1;2707:24:12;2699:50;;;;-1:-1:-1;;;2699:50:12;;19395:2:13;2699:50:12;;;19377:21:13;19434:2;19414:18;;;19407:30;-1:-1:-1;;;19453:18:13;;;19446:43;19506:18;;2699:50:12;19193:337:13;2699:50:12;2760:16;2766:2;2770:5;2760;:16::i;2011:153:1:-;2100:13;2093:20;;-1:-1:-1;;;;;;2093:20:1;;;2123:34;2148:8;2123:24;:34::i;1776:194:8:-;1881:10;1875:4;1868:24;1918:4;1912;1905:18;1949:4;1943;1936:18;9701:432:3;-1:-1:-1;;;;;9813:19:3;;9809:89;;9855:32;;-1:-1:-1;;;9855:32:3;;9884:1;9855:32;;;3504:51:13;3477:18;;9855:32:3;3358:203:13;9809:89:3;-1:-1:-1;;;;;9911:21:3;;9907:90;;9955:31;;-1:-1:-1;;;9955:31:3;;9983:1;9955:31;;;3504:51:13;3477:18;;9955:31:3;3358:203:13;9907:90:3;-1:-1:-1;;;;;10006:18:3;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;:35;;;10051:76;;;;10101:7;-1:-1:-1;;;;;10085:31:3;10094:5;-1:-1:-1;;;;;10085:31:3;;10110:5;10085:31;;;;644:25:13;;632:2;617:18;;498:177;10085:31:3;;;;;;;;9701:432;;;;:::o;6008:1107::-;-1:-1:-1;;;;;6097:18:3;;6093:540;;6249:5;6233:12;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;6093:540:3;;-1:-1:-1;6093:540:3;;-1:-1:-1;;;;;6307:15:3;;6285:19;6307:15;;;;;;;;;;;6340:19;;;6336:115;;;6386:50;;-1:-1:-1;;;6386:50:3;;-1:-1:-1;;;;;18706:32:13;;6386:50:3;;;18688:51:13;18755:18;;;18748:34;;;18798:18;;;18791:34;;;18661:18;;6386:50:3;18486:345:13;6336:115:3;-1:-1:-1;;;;;6571:15:3;;:9;:15;;;;;;;;;;6589:19;;;;6571:37;;6093:540;-1:-1:-1;;;;;6647:16:3;;6643:425;;6810:12;:21;;;;;;;6643:425;;;-1:-1:-1;;;;;7021:13:3;;:9;:13;;;;;;;;;;:22;;;;;;6643:425;7098:2;-1:-1:-1;;;;;7083:25:3;7092:4;-1:-1:-1;;;;;7083:25:3;;7102:5;7083:25;;;;644::13;;632:2;617:18;;498:177;7083:25:3;;;;;;;;6008:1107;;;:::o;7458:208::-;-1:-1:-1;;;;;7528:21:3;;7524:91;;7572:32;;-1:-1:-1;;;7572:32:3;;7601:1;7572:32;;;3504:51:13;3477:18;;7572:32:3;3358:203:13;7524:91:3;7624:35;7640:1;7644:7;7653:5;7624:7;:35::i;2912:187:0:-;3004:6;;;-1:-1:-1;;;;;3020:17:0;;;-1:-1:-1;;;;;;3020:17:0;;;;;;;3052:40;;3004:6;;;3020:17;3004:6;;3052:40;;2985:16;;3052:40;2975:124;2912:187;:::o;14:226:13:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;187:23:13;;14:226;-1:-1:-1;14:226:13:o;680:346::-;748:6;756;809:2;797:9;788:7;784:23;780:32;777:52;;;825:1;822;815:12;777:52;-1:-1:-1;;870:23:13;;;990:2;975:18;;;962:32;;-1:-1:-1;680:346:13:o;1031:418::-;1180:2;1169:9;1162:21;1143:4;1212:6;1206:13;1255:6;1250:2;1239:9;1235:18;1228:34;1314:6;1309:2;1301:6;1297:15;1292:2;1281:9;1277:18;1271:50;1370:1;1365:2;1356:6;1345:9;1341:22;1337:31;1330:42;1440:2;1433;1429:7;1424:2;1416:6;1412:15;1408:29;1397:9;1393:45;1389:54;1381:62;;;1031:418;;;;:::o;1454:173::-;1522:20;;-1:-1:-1;;;;;1571:31:13;;1561:42;;1551:70;;1617:1;1614;1607:12;1632:300;1700:6;1708;1761:2;1749:9;1740:7;1736:23;1732:32;1729:52;;;1777:1;1774;1767:12;1729:52;1800:29;1819:9;1800:29;:::i;:::-;1790:39;1898:2;1883:18;;;;1870:32;;-1:-1:-1;;;1632:300:13:o;2322:272::-;2380:6;2433:2;2421:9;2412:7;2408:23;2404:32;2401:52;;;2449:1;2446;2439:12;2401:52;2488:9;2475:23;2538:6;2531:5;2527:18;2520:5;2517:29;2507:57;;2560:1;2557;2550:12;2599:374;2676:6;2684;2692;2745:2;2733:9;2724:7;2720:23;2716:32;2713:52;;;2761:1;2758;2751:12;2713:52;2784:29;2803:9;2784:29;:::i;:::-;2774:39;;2832:38;2866:2;2855:9;2851:18;2832:38;:::i;:::-;2599:374;;2822:48;;-1:-1:-1;;;2939:2:13;2924:18;;;;2911:32;;2599:374::o;3167:186::-;3226:6;3279:2;3267:9;3258:7;3254:23;3250:32;3247:52;;;3295:1;3292;3285:12;3247:52;3318:29;3337:9;3318:29;:::i;4509:260::-;4577:6;4585;4638:2;4626:9;4617:7;4613:23;4609:32;4606:52;;;4654:1;4651;4644:12;4606:52;4677:29;4696:9;4677:29;:::i;:::-;4667:39;;4725:38;4759:2;4748:9;4744:18;4725:38;:::i;:::-;4715:48;;4509:260;;;;;:::o;4998:127::-;5059:10;5054:3;5050:20;5047:1;5040:31;5090:4;5087:1;5080:15;5114:4;5111:1;5104:15;5130:125;5195:9;;;5216:10;;;5213:36;;;5229:18;;:::i;5260:128::-;5327:9;;;5348:11;;;5345:37;;;5362:18;;:::i;5393:168::-;5466:9;;;5497;;5514:15;;;5508:22;;5494:37;5484:71;;5535:18;;:::i;5566:127::-;5627:10;5622:3;5618:20;5615:1;5608:31;5658:4;5655:1;5648:15;5682:4;5679:1;5672:15;5698:120;5738:1;5764;5754:35;;5769:18;;:::i;:::-;-1:-1:-1;5803:9:13;;5698:120::o;5823:380::-;5902:1;5898:12;;;;5945;;;5966:61;;6020:4;6012:6;6008:17;5998:27;;5966:61;6073:2;6065:6;6062:14;6042:18;6039:38;6036:161;;6119:10;6114:3;6110:20;6107:1;6100:31;6154:4;6151:1;6144:15;6182:4;6179:1;6172:15;6036:161;;5823:380;;;:::o;6208:409::-;6410:2;6392:21;;;6449:2;6429:18;;;6422:30;6488:34;6483:2;6468:18;;6461:62;-1:-1:-1;;;6554:2:13;6539:18;;6532:43;6607:3;6592:19;;6208:409::o;7332:353::-;7534:2;7516:21;;;7573:2;7553:18;;;7546:30;7612:31;7607:2;7592:18;;7585:59;7676:2;7661:18;;7332:353::o;8696:418::-;8898:2;8880:21;;;8937:2;8917:18;;;8910:30;8976:34;8971:2;8956:18;;8949:62;-1:-1:-1;;;9042:2:13;9027:18;;9020:52;9104:3;9089:19;;8696:418::o;15929:112::-;15961:1;15987;15977:35;;15992:18;;:::i;:::-;-1:-1:-1;16026:9:13;;15929:112::o

Swarm Source

ipfs://333de36a80351bbf75f129741d3ae9dbe96718ae2a42ff6873d3063e35d9272f
[ 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.