ETH Price: $3,236.06 (-5.22%)

Contract

0xc1aD1eB79ccADD578a190E6E602d63e44C3681dB
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
Add Stake143033932022-03-01 20:52:271353 days ago1646167947IN
0xc1aD1eB7...44C3681dB
0 ETH0.009873762.04414097
Withdraw143017602022-03-01 14:46:581353 days ago1646146018IN
0xc1aD1eB7...44C3681dB
0 ETH0.0033758744.54959643
Withdraw143016902022-03-01 14:31:451353 days ago1646145105IN
0xc1aD1eB7...44C3681dB
0 ETH0.0045932449.45459516
Withdraw142967562022-02-28 20:15:471354 days ago1646079347IN
0xc1aD1eB7...44C3681dB
0 ETH0.0061235380.68754381
Withdraw142799882022-02-26 6:07:531356 days ago1645855673IN
0xc1aD1eB7...44C3681dB
0 ETH0.003814450.80657261
Add Stake142428162022-02-20 12:06:121362 days ago1645358772IN
0xc1aD1eB7...44C3681dB
0 ETH0.0073952346.46648504
Add Stake142039052022-02-14 11:03:361368 days ago1644836616IN
0xc1aD1eB7...44C3681dB
0 ETH0.0061701138.76870155
Add Stake141867272022-02-11 19:44:551371 days ago1644608695IN
0xc1aD1eB7...44C3681dB
0 ETH0.0121642197.31219134
Add Stake141866822022-02-11 19:34:061371 days ago1644608046IN
0xc1aD1eB7...44C3681dB
0 ETH0.01861954117.00984498
Withdraw141732522022-02-09 17:36:441373 days ago1644428204IN
0xc1aD1eB7...44C3681dB
0 ETH0.00751395104.86583686
Withdraw141670402022-02-08 18:29:031374 days ago1644344943IN
0xc1aD1eB7...44C3681dB
0 ETH0.0090398565.94343756
Withdraw141510092022-02-06 7:02:021376 days ago1644130922IN
0xc1aD1eB7...44C3681dB
0 ETH0.0057435841.8979852
Add Stake141467992022-02-05 15:29:491377 days ago1644074989IN
0xc1aD1eB7...44C3681dB
0 ETH0.0083402652.40836771
Add Stake141449512022-02-05 8:36:381377 days ago1644050198IN
0xc1aD1eB7...44C3681dB
0 ETH0.0079991964.0048461
Add Stake141343332022-02-03 17:21:151379 days ago1643908875IN
0xc1aD1eB7...44C3681dB
0 ETH0.02880359181.00894863
Withdraw141339222022-02-03 15:55:051379 days ago1643903705IN
0xc1aD1eB7...44C3681dB
0 ETH0.01585423103.12906304
Add Stake141316192022-02-03 7:14:091379 days ago1643872449IN
0xc1aD1eB7...44C3681dB
0 ETH0.010285685.5778701
Withdraw141315542022-02-03 7:01:351379 days ago1643871695IN
0xc1aD1eB7...44C3681dB
0 ETH0.0128646693.84445113
Withdraw141160472022-01-31 21:20:391382 days ago1643664039IN
0xc1aD1eB7...44C3681dB
0 ETH0.01601894116.617598
Add Stake141009682022-01-29 13:38:301384 days ago1643463510IN
0xc1aD1eB7...44C3681dB
0 ETH0.004085393.78775963
Add Stake141009672022-01-29 13:38:101384 days ago1643463490IN
0xc1aD1eB7...44C3681dB
0 ETH0.012893383.54480777
Add Stake141008212022-01-29 13:06:531384 days ago1643461613IN
0xc1aD1eB7...44C3681dB
0 ETH0.0124839780.88618577
Add Stake140959282022-01-28 18:59:371385 days ago1643396377IN
0xc1aD1eB7...44C3681dB
0 ETH0.02444513158.39729291
Withdraw140702022022-01-24 19:28:101389 days ago1643052490IN
0xc1aD1eB7...44C3681dB
0 ETH0.02085474151.46048729
Add Stake139337892022-01-03 17:18:501410 days ago1641230330IN
0xc1aD1eB7...44C3681dB
0 ETH0.01952838122.71198521
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
evaiStableCoinFund

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
/**
 *Submitted for verification at Etherscan.io on 2021-12-09
*/

// File contracts/timelib.sol

//SPDX-License-Identifier:  MIT AND BSD-4-Clause

pragma solidity ^0.8.0;

// ----------------------------------------------------------------------------
// BokkyPooBah's DateTime Library v1.01
//
// A gas-efficient Solidity date and time library
//
// https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
//
// Tested date range 1970/01/01 to 2345/12/31
//
// Conventions:
// Unit      | Range         | Notes
// :-------- |:-------------:|:-----
// timestamp | >= 0          | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
// year      | 1970 ... 2345 |
// month     | 1 ... 12      |
// day       | 1 ... 31      |
// hour      | 0 ... 23      |
// minute    | 0 ... 59      |
// second    | 0 ... 59      |
// dayOfWeek | 1 ... 7       | 1 = Monday, ..., 7 = Sunday
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
// ----------------------------------------------------------------------------

library BokkyPooBahsDateTimeLibrary {
    uint256 constant SECONDS_PER_DAY = 24 * 60 * 60;
    uint256 constant SECONDS_PER_HOUR = 60 * 60;
    uint256 constant SECONDS_PER_MINUTE = 60;
    int256 constant OFFSET19700101 = 2440588;

    uint256 constant DOW_MON = 1;
    uint256 constant DOW_TUE = 2;
    uint256 constant DOW_WED = 3;
    uint256 constant DOW_THU = 4;
    uint256 constant DOW_FRI = 5;
    uint256 constant DOW_SAT = 6;
    uint256 constant DOW_SUN = 7;

    // ------------------------------------------------------------------------
    // Calculate the number of days from 1970/01/01 to year/month/day using
    // the date conversion algorithm from
    //   http://aa.usno.navy.mil/faq/docs/JD_Formula.php
    // and subtracting the offset 2440588 so that 1970/01/01 is day 0
    //
    // days = day
    //      - 32075
    //      + 1461 * (year + 4800 + (month - 14) / 12) / 4
    //      + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
    //      - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
    //      - offset
    // ------------------------------------------------------------------------
    function _daysFromDate(
        uint256 year,
        uint256 month,
        uint256 day
    ) internal pure returns (uint256 _days) {
        require(year >= 1970);
        int256 _year = int256(year);
        int256 _month = int256(month);
        int256 _day = int256(day);

        int256 __days = _day -
            32075 +
            (1461 * (_year + 4800 + (_month - 14) / 12)) /
            4 +
            (367 * (_month - 2 - ((_month - 14) / 12) * 12)) /
            12 -
            (3 * ((_year + 4900 + (_month - 14) / 12) / 100)) /
            4 -
            OFFSET19700101;

        _days = uint256(__days);
    }

    // ------------------------------------------------------------------------
    // Calculate year/month/day from the number of days since 1970/01/01 using
    // the date conversion algorithm from
    //   http://aa.usno.navy.mil/faq/docs/JD_Formula.php
    // and adding the offset 2440588 so that 1970/01/01 is day 0
    //
    // int L = days + 68569 + offset
    // int N = 4 * L / 146097
    // L = L - (146097 * N + 3) / 4
    // year = 4000 * (L + 1) / 1461001
    // L = L - 1461 * year / 4 + 31
    // month = 80 * L / 2447
    // dd = L - 2447 * month / 80
    // L = month / 11
    // month = month + 2 - 12 * L
    // year = 100 * (N - 49) + year + L
    // ------------------------------------------------------------------------
    function _daysToDate(uint256 _days)
        internal
        pure
        returns (
            uint256 year,
            uint256 month,
            uint256 day
        )
    {
        int256 __days = int256(_days);

        int256 L = __days + 68569 + OFFSET19700101;
        int256 N = (4 * L) / 146097;
        L = L - (146097 * N + 3) / 4;
        int256 _year = (4000 * (L + 1)) / 1461001;
        L = L - (1461 * _year) / 4 + 31;
        int256 _month = (80 * L) / 2447;
        int256 _day = L - (2447 * _month) / 80;
        L = _month / 11;
        _month = _month + 2 - 12 * L;
        _year = 100 * (N - 49) + _year + L;

        year = uint256(_year);
        month = uint256(_month);
        day = uint256(_day);
    }

    function timestampFromDate(
        uint256 year,
        uint256 month,
        uint256 day
    ) internal pure returns (uint256 timestamp) {
        timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
    }

    function timestampFromDateTime(
        uint256 year,
        uint256 month,
        uint256 day,
        uint256 hour,
        uint256 minute,
        uint256 second
    ) internal pure returns (uint256 timestamp) {
        timestamp =
            _daysFromDate(year, month, day) *
            SECONDS_PER_DAY +
            hour *
            SECONDS_PER_HOUR +
            minute *
            SECONDS_PER_MINUTE +
            second;
    }

    function timestampToDate(uint256 timestamp)
        internal
        pure
        returns (
            uint256 year,
            uint256 month,
            uint256 day
        )
    {
        (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }

    function timestampToDateTime(uint256 timestamp)
        internal
        pure
        returns (
            uint256 year,
            uint256 month,
            uint256 day,
            uint256 hour,
            uint256 minute,
            uint256 second
        )
    {
        (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
        uint256 secs = timestamp % SECONDS_PER_DAY;
        hour = secs / SECONDS_PER_HOUR;
        secs = secs % SECONDS_PER_HOUR;
        minute = secs / SECONDS_PER_MINUTE;
        second = secs % SECONDS_PER_MINUTE;
    }

    function isValidDate(
        uint256 year,
        uint256 month,
        uint256 day
    ) internal pure returns (bool valid) {
        if (year >= 1970 && month > 0 && month <= 12) {
            uint256 daysInMonth = _getDaysInMonth(year, month);
            if (day > 0 && day <= daysInMonth) {
                valid = true;
            }
        }
    }

    function isValidDateTime(
        uint256 year,
        uint256 month,
        uint256 day,
        uint256 hour,
        uint256 minute,
        uint256 second
    ) internal pure returns (bool valid) {
        if (isValidDate(year, month, day)) {
            if (hour < 24 && minute < 60 && second < 60) {
                valid = true;
            }
        }
    }

    function isLeapYear(uint256 timestamp)
        internal
        pure
        returns (bool leapYear)
    {
        (uint256 year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY);
        leapYear = _isLeapYear(year);
    }

    function _isLeapYear(uint256 year) internal pure returns (bool leapYear) {
        leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
    }

    function isWeekDay(uint256 timestamp) internal pure returns (bool weekDay) {
        weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
    }

    function isWeekEnd(uint256 timestamp) internal pure returns (bool weekEnd) {
        weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
    }

    function getDaysInMonth(uint256 timestamp)
        internal
        pure
        returns (uint256 daysInMonth)
    {
        (uint256 year, uint256 month, ) = _daysToDate(
            timestamp / SECONDS_PER_DAY
        );
        daysInMonth = _getDaysInMonth(year, month);
    }

    function _getDaysInMonth(uint256 year, uint256 month)
        internal
        pure
        returns (uint256 daysInMonth)
    {
        if (
            month == 1 ||
            month == 3 ||
            month == 5 ||
            month == 7 ||
            month == 8 ||
            month == 10 ||
            month == 12
        ) {
            daysInMonth = 31;
        } else if (month != 2) {
            daysInMonth = 30;
        } else {
            daysInMonth = _isLeapYear(year) ? 29 : 28;
        }
    }

    // 1 = Monday, 7 = Sunday
    function getDayOfWeek(uint256 timestamp)
        internal
        pure
        returns (uint256 dayOfWeek)
    {
        uint256 _days = timestamp / SECONDS_PER_DAY;
        dayOfWeek = ((_days + 3) % 7) + 1;
    }

    function getYear(uint256 timestamp) internal pure returns (uint256 year) {
        (year, , ) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }

    function getMonth(uint256 timestamp) internal pure returns (uint256 month) {
        (, month, ) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }

    function getDay(uint256 timestamp) internal pure returns (uint256 day) {
        (, , day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    }

    function getHour(uint256 timestamp) internal pure returns (uint256 hour) {
        uint256 secs = timestamp % SECONDS_PER_DAY;
        hour = secs / SECONDS_PER_HOUR;
    }

    function getMinute(uint256 timestamp)
        internal
        pure
        returns (uint256 minute)
    {
        uint256 secs = timestamp % SECONDS_PER_HOUR;
        minute = secs / SECONDS_PER_MINUTE;
    }

    function getSecond(uint256 timestamp)
        internal
        pure
        returns (uint256 second)
    {
        second = timestamp % SECONDS_PER_MINUTE;
    }

    function addYears(uint256 timestamp, uint256 _years)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        (uint256 year, uint256 month, uint256 day) = _daysToDate(
            timestamp / SECONDS_PER_DAY
        );
        year += _years;
        uint256 daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp =
            _daysFromDate(year, month, day) *
            SECONDS_PER_DAY +
            (timestamp % SECONDS_PER_DAY);
        require(newTimestamp >= timestamp);
    }

    function addMonths(uint256 timestamp, uint256 _months)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        (uint256 year, uint256 month, uint256 day) = _daysToDate(
            timestamp / SECONDS_PER_DAY
        );
        month += _months;
        year += (month - 1) / 12;
        month = ((month - 1) % 12) + 1;
        uint256 daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp =
            _daysFromDate(year, month, day) *
            SECONDS_PER_DAY +
            (timestamp % SECONDS_PER_DAY);
        require(newTimestamp >= timestamp);
    }

    function addDays(uint256 timestamp, uint256 _days)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp + _days * SECONDS_PER_DAY;
        require(newTimestamp >= timestamp);
    }

    function addHours(uint256 timestamp, uint256 _hours)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
        require(newTimestamp >= timestamp);
    }

    function addMinutes(uint256 timestamp, uint256 _minutes)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
        require(newTimestamp >= timestamp);
    }

    function addSeconds(uint256 timestamp, uint256 _seconds)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp + _seconds;
        require(newTimestamp >= timestamp);
    }

    function subYears(uint256 timestamp, uint256 _years)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        (uint256 year, uint256 month, uint256 day) = _daysToDate(
            timestamp / SECONDS_PER_DAY
        );
        year -= _years;
        uint256 daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp =
            _daysFromDate(year, month, day) *
            SECONDS_PER_DAY +
            (timestamp % SECONDS_PER_DAY);
        require(newTimestamp <= timestamp);
    }

    function subMonths(uint256 timestamp, uint256 _months)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        (uint256 year, uint256 month, uint256 day) = _daysToDate(
            timestamp / SECONDS_PER_DAY
        );
        uint256 yearMonth = year * 12 + (month - 1) - _months;
        year = yearMonth / 12;
        month = (yearMonth % 12) + 1;
        uint256 daysInMonth = _getDaysInMonth(year, month);
        if (day > daysInMonth) {
            day = daysInMonth;
        }
        newTimestamp =
            _daysFromDate(year, month, day) *
            SECONDS_PER_DAY +
            (timestamp % SECONDS_PER_DAY);
        require(newTimestamp <= timestamp);
    }

    function subDays(uint256 timestamp, uint256 _days)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp - _days * SECONDS_PER_DAY;
        require(newTimestamp <= timestamp);
    }

    function subHours(uint256 timestamp, uint256 _hours)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
        require(newTimestamp <= timestamp);
    }

    function subMinutes(uint256 timestamp, uint256 _minutes)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
        require(newTimestamp <= timestamp);
    }

    function subSeconds(uint256 timestamp, uint256 _seconds)
        internal
        pure
        returns (uint256 newTimestamp)
    {
        newTimestamp = timestamp - _seconds;
        require(newTimestamp <= timestamp);
    }

    function diffYears(uint256 fromTimestamp, uint256 toTimestamp)
        internal
        pure
        returns (uint256 _years)
    {
        require(fromTimestamp <= toTimestamp);
        (uint256 fromYear, , ) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
        (uint256 toYear, , ) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
        _years = toYear - fromYear;
    }

    function diffMonths(uint256 fromTimestamp, uint256 toTimestamp)
        internal
        pure
        returns (uint256 _months)
    {
        require(fromTimestamp <= toTimestamp);
        (uint256 fromYear, uint256 fromMonth, ) = _daysToDate(
            fromTimestamp / SECONDS_PER_DAY
        );
        (uint256 toYear, uint256 toMonth, ) = _daysToDate(
            toTimestamp / SECONDS_PER_DAY
        );
        _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
    }

    function diffDays(uint256 fromTimestamp, uint256 toTimestamp)
        internal
        pure
        returns (uint256 _days)
    {
        require(fromTimestamp <= toTimestamp);
        _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
    }

    function diffHours(uint256 fromTimestamp, uint256 toTimestamp)
        internal
        pure
        returns (uint256 _hours)
    {
        require(fromTimestamp <= toTimestamp);
        _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
    }

    function diffMinutes(uint256 fromTimestamp, uint256 toTimestamp)
        internal
        pure
        returns (uint256 _minutes)
    {
        require(fromTimestamp <= toTimestamp);
        _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
    }

    function diffSeconds(uint256 fromTimestamp, uint256 toTimestamp)
        internal
        pure
        returns (uint256 _seconds)
    {
        require(fromTimestamp <= toTimestamp);
        _seconds = toTimestamp - fromTimestamp;
    }
}


// File contracts/math.sol

/*
 * ABDK Math 64.64 Smart Contract Library.  Copyright © 2019 by ABDK Consulting.
 * Author: Mikhail Vladimirov <[email protected]>
 */
pragma solidity ^0.8.0;

/**
 * Smart contract library of mathematical functions operating with signed
 * 64.64-bit fixed point numbers.  Signed 64.64-bit fixed point number is
 * basically a simple fraction whose numerator is signed 128-bit integer and
 * denominator is 2^64.  As long as denominator is always the same, there is no
 * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are
 * represented by int128 type holding only the numerator.
 */
library ABDKMath64x64 {
    /*
     * Minimum value signed 64.64-bit fixed point number may have.
     */
    int128 private constant MIN_64x64 = -0x80000000000000000000000000000000;

    /*
     * Maximum value signed 64.64-bit fixed point number may have.
     */
    int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

    /**
     * Convert signed 256-bit integer number into signed 64.64-bit fixed point
     * number.  Revert on overflow.
     *
     * @param x signed 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function fromInt(int256 x) internal pure returns (int128) {
        unchecked {
            require(x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF);
            return int128(x << 64);
        }
    }

    /**
     * Convert signed 64.64 fixed point number into signed 64-bit integer number
     * rounding down.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64-bit integer number
     */
    function toInt(int128 x) internal pure returns (int64) {
        unchecked {
            return int64(x >> 64);
        }
    }

    /**
     * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point
     * number.  Revert on overflow.
     *
     * @param x unsigned 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function fromUInt(uint256 x) internal pure returns (int128) {
        unchecked {
            require(x <= 0x7FFFFFFFFFFFFFFF);
            return int128(int256(x << 64));
        }
    }

    /**
     * Convert signed 64.64 fixed point number into unsigned 64-bit integer
     * number rounding down.  Revert on underflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return unsigned 64-bit integer number
     */
    function toUInt(int128 x) internal pure returns (uint64) {
        unchecked {
            require(x >= 0);
            return uint64(uint128(x >> 64));
        }
    }

    /**
     * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point
     * number rounding down.  Revert on overflow.
     *
     * @param x signed 128.128-bin fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function from128x128(int256 x) internal pure returns (int128) {
        unchecked {
            int256 result = x >> 64;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Convert signed 64.64 fixed point number into signed 128.128 fixed point
     * number.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 128.128 fixed point number
     */
    function to128x128(int128 x) internal pure returns (int256) {
        unchecked {
            return int256(x) << 64;
        }
    }

    /**
     * Calculate x + y.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function add(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 result = int256(x) + y;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x - y.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function sub(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 result = int256(x) - y;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x * y rounding down.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function mul(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 result = (int256(x) * y) >> 64;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point
     * number and y is signed 256-bit integer number.  Revert on overflow.
     *
     * @param x signed 64.64 fixed point number
     * @param y signed 256-bit integer number
     * @return signed 256-bit integer number
     */
    function muli(int128 x, int256 y) internal pure returns (int256) {
        unchecked {
            if (x == MIN_64x64) {
                require(
                    y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF &&
                        y <= 0x1000000000000000000000000000000000000000000000000
                );
                return -y << 63;
            } else {
                bool negativeResult = false;
                if (x < 0) {
                    x = -x;
                    negativeResult = true;
                }
                if (y < 0) {
                    y = -y; // We rely on overflow behavior here
                    negativeResult = !negativeResult;
                }
                uint256 absoluteResult = mulu(x, uint256(y));
                if (negativeResult) {
                    require(
                        absoluteResult <=
                            0x8000000000000000000000000000000000000000000000000000000000000000
                    );
                    return -int256(absoluteResult); // We rely on overflow behavior here
                } else {
                    require(
                        absoluteResult <=
                            0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
                    );
                    return int256(absoluteResult);
                }
            }
        }
    }

    /**
     * Calculate x * y rounding down, where x is signed 64.64 fixed point number
     * and y is unsigned 256-bit integer number.  Revert on overflow.
     *
     * @param x signed 64.64 fixed point number
     * @param y unsigned 256-bit integer number
     * @return unsigned 256-bit integer number
     */
    function mulu(int128 x, uint256 y) internal pure returns (uint256) {
        unchecked {
            if (y == 0) return 0;

            require(x >= 0);

            uint256 lo = (uint256(int256(x)) *
                (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64;
            uint256 hi = uint256(int256(x)) * (y >> 128);

            require(hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
            hi <<= 64;

            require(
                hi <=
                    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -
                        lo
            );
            return hi + lo;
        }
    }

    /**
     * Calculate x / y rounding towards zero.  Revert on overflow or when y is
     * zero.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function div(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            require(y != 0);
            int256 result = (int256(x) << 64) / y;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate x / y rounding towards zero, where x and y are signed 256-bit
     * integer numbers.  Revert on overflow or when y is zero.
     *
     * @param x signed 256-bit integer number
     * @param y signed 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function divi(int256 x, int256 y) internal pure returns (int128) {
        unchecked {
            require(y != 0);

            bool negativeResult = false;
            if (x < 0) {
                x = -x; // We rely on overflow behavior here
                negativeResult = true;
            }
            if (y < 0) {
                y = -y; // We rely on overflow behavior here
                negativeResult = !negativeResult;
            }
            uint128 absoluteResult = divuu(uint256(x), uint256(y));
            if (negativeResult) {
                require(absoluteResult <= 0x80000000000000000000000000000000);
                return -int128(absoluteResult); // We rely on overflow behavior here
            } else {
                require(absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
                return int128(absoluteResult); // We rely on overflow behavior here
            }
        }
    }

    /**
     * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
     * integer numbers.  Revert on overflow or when y is zero.
     *
     * @param x unsigned 256-bit integer number
     * @param y unsigned 256-bit integer number
     * @return signed 64.64-bit fixed point number
     */
    function divu(uint256 x, uint256 y) internal pure returns (int128) {
        unchecked {
            require(y != 0);
            uint128 result = divuu(x, y);
            require(result <= uint128(MAX_64x64));
            return int128(result);
        }
    }

    /**
     * Calculate -x.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function neg(int128 x) internal pure returns (int128) {
        unchecked {
            require(x != MIN_64x64);
            return -x;
        }
    }

    /**
     * Calculate |x|.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function abs(int128 x) internal pure returns (int128) {
        unchecked {
            require(x != MIN_64x64);
            return x < 0 ? -x : x;
        }
    }

    /**
     * Calculate 1 / x rounding towards zero.  Revert on overflow or when x is
     * zero.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function inv(int128 x) internal pure returns (int128) {
        unchecked {
            require(x != 0);
            int256 result = int256(0x100000000000000000000000000000000) / x;
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function avg(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            return int128((int256(x) + int256(y)) >> 1);
        }
    }

    /**
     * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down.
     * Revert on overflow or in case x * y is negative.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function gavg(int128 x, int128 y) internal pure returns (int128) {
        unchecked {
            int256 m = int256(x) * int256(y);
            require(m >= 0);
            require(
                m <
                    0x4000000000000000000000000000000000000000000000000000000000000000
            );
            return int128(sqrtu(uint256(m)));
        }
    }

    /**
     * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number
     * and y is unsigned 256-bit integer number.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @param y uint256 value
     * @return signed 64.64-bit fixed point number
     */
    function pow(int128 x, uint256 y) internal pure returns (int128) {
        unchecked {
            bool negative = x < 0 && y & 1 == 1;

            uint256 absX = uint128(x < 0 ? -x : x);
            uint256 absResult;
            absResult = 0x100000000000000000000000000000000;

            if (absX <= 0x10000000000000000) {
                absX <<= 63;
                while (y != 0) {
                    if (y & 0x1 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    if (y & 0x2 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    if (y & 0x4 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    if (y & 0x8 != 0) {
                        absResult = (absResult * absX) >> 127;
                    }
                    absX = (absX * absX) >> 127;

                    y >>= 4;
                }

                absResult >>= 64;
            } else {
                uint256 absXShift = 63;
                if (absX < 0x1000000000000000000000000) {
                    absX <<= 32;
                    absXShift -= 32;
                }
                if (absX < 0x10000000000000000000000000000) {
                    absX <<= 16;
                    absXShift -= 16;
                }
                if (absX < 0x1000000000000000000000000000000) {
                    absX <<= 8;
                    absXShift -= 8;
                }
                if (absX < 0x10000000000000000000000000000000) {
                    absX <<= 4;
                    absXShift -= 4;
                }
                if (absX < 0x40000000000000000000000000000000) {
                    absX <<= 2;
                    absXShift -= 2;
                }
                if (absX < 0x80000000000000000000000000000000) {
                    absX <<= 1;
                    absXShift -= 1;
                }

                uint256 resultShift = 0;
                while (y != 0) {
                    require(absXShift < 64);

                    if (y & 0x1 != 0) {
                        absResult = (absResult * absX) >> 127;
                        resultShift += absXShift;
                        if (absResult > 0x100000000000000000000000000000000) {
                            absResult >>= 1;
                            resultShift += 1;
                        }
                    }
                    absX = (absX * absX) >> 127;
                    absXShift <<= 1;
                    if (absX >= 0x100000000000000000000000000000000) {
                        absX >>= 1;
                        absXShift += 1;
                    }

                    y >>= 1;
                }

                require(resultShift < 64);
                absResult >>= 64 - resultShift;
            }
            int256 result = negative ? -int256(absResult) : int256(absResult);
            require(result >= MIN_64x64 && result <= MAX_64x64);
            return int128(result);
        }
    }

    /**
     * Calculate sqrt (x) rounding down.  Revert if x < 0.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function sqrt(int128 x) internal pure returns (int128) {
        unchecked {
            require(x >= 0);
            return int128(sqrtu(uint256(int256(x)) << 64));
        }
    }

    /**
     * Calculate binary logarithm of x.  Revert if x <= 0.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function log_2(int128 x) internal pure returns (int128) {
        unchecked {
            require(x > 0);

            int256 msb = 0;
            int256 xc = x;
            if (xc >= 0x10000000000000000) {
                xc >>= 64;
                msb += 64;
            }
            if (xc >= 0x100000000) {
                xc >>= 32;
                msb += 32;
            }
            if (xc >= 0x10000) {
                xc >>= 16;
                msb += 16;
            }
            if (xc >= 0x100) {
                xc >>= 8;
                msb += 8;
            }
            if (xc >= 0x10) {
                xc >>= 4;
                msb += 4;
            }
            if (xc >= 0x4) {
                xc >>= 2;
                msb += 2;
            }
            if (xc >= 0x2) msb += 1; // No need to shift xc anymore

            int256 result = (msb - 64) << 64;
            uint256 ux = uint256(int256(x)) << uint256(127 - msb);
            for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) {
                ux *= ux;
                uint256 b = ux >> 255;
                ux >>= 127 + b;
                result += bit * int256(b);
            }

            return int128(result);
        }
    }

    /**
     * Calculate natural logarithm of x.  Revert if x <= 0.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function ln(int128 x) internal pure returns (int128) {
        unchecked {
            require(x > 0);

            return
                int128(
                    int256(
                        (uint256(int256(log_2(x))) *
                            0xB17217F7D1CF79ABC9E3B39803F2F6AF) >> 128
                    )
                );
        }
    }

    /**
     * Calculate binary exponent of x.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function exp_2(int128 x) internal pure returns (int128) {
        unchecked {
            require(x < 0x400000000000000000); // Overflow

            if (x < -0x400000000000000000) return 0; // Underflow

            uint256 result = 0x80000000000000000000000000000000;

            if (x & 0x8000000000000000 > 0)
                result = (result * 0x16A09E667F3BCC908B2FB1366EA957D3E) >> 128;
            if (x & 0x4000000000000000 > 0)
                result = (result * 0x1306FE0A31B7152DE8D5A46305C85EDEC) >> 128;
            if (x & 0x2000000000000000 > 0)
                result = (result * 0x1172B83C7D517ADCDF7C8C50EB14A791F) >> 128;
            if (x & 0x1000000000000000 > 0)
                result = (result * 0x10B5586CF9890F6298B92B71842A98363) >> 128;
            if (x & 0x800000000000000 > 0)
                result = (result * 0x1059B0D31585743AE7C548EB68CA417FD) >> 128;
            if (x & 0x400000000000000 > 0)
                result = (result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8) >> 128;
            if (x & 0x200000000000000 > 0)
                result = (result * 0x10163DA9FB33356D84A66AE336DCDFA3F) >> 128;
            if (x & 0x100000000000000 > 0)
                result = (result * 0x100B1AFA5ABCBED6129AB13EC11DC9543) >> 128;
            if (x & 0x80000000000000 > 0)
                result = (result * 0x10058C86DA1C09EA1FF19D294CF2F679B) >> 128;
            if (x & 0x40000000000000 > 0)
                result = (result * 0x1002C605E2E8CEC506D21BFC89A23A00F) >> 128;
            if (x & 0x20000000000000 > 0)
                result = (result * 0x100162F3904051FA128BCA9C55C31E5DF) >> 128;
            if (x & 0x10000000000000 > 0)
                result = (result * 0x1000B175EFFDC76BA38E31671CA939725) >> 128;
            if (x & 0x8000000000000 > 0)
                result = (result * 0x100058BA01FB9F96D6CACD4B180917C3D) >> 128;
            if (x & 0x4000000000000 > 0)
                result = (result * 0x10002C5CC37DA9491D0985C348C68E7B3) >> 128;
            if (x & 0x2000000000000 > 0)
                result = (result * 0x1000162E525EE054754457D5995292026) >> 128;
            if (x & 0x1000000000000 > 0)
                result = (result * 0x10000B17255775C040618BF4A4ADE83FC) >> 128;
            if (x & 0x800000000000 > 0)
                result = (result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB) >> 128;
            if (x & 0x400000000000 > 0)
                result = (result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9) >> 128;
            if (x & 0x200000000000 > 0)
                result = (result * 0x10000162E43F4F831060E02D839A9D16D) >> 128;
            if (x & 0x100000000000 > 0)
                result = (result * 0x100000B1721BCFC99D9F890EA06911763) >> 128;
            if (x & 0x80000000000 > 0)
                result = (result * 0x10000058B90CF1E6D97F9CA14DBCC1628) >> 128;
            if (x & 0x40000000000 > 0)
                result = (result * 0x1000002C5C863B73F016468F6BAC5CA2B) >> 128;
            if (x & 0x20000000000 > 0)
                result = (result * 0x100000162E430E5A18F6119E3C02282A5) >> 128;
            if (x & 0x10000000000 > 0)
                result = (result * 0x1000000B1721835514B86E6D96EFD1BFE) >> 128;
            if (x & 0x8000000000 > 0)
                result = (result * 0x100000058B90C0B48C6BE5DF846C5B2EF) >> 128;
            if (x & 0x4000000000 > 0)
                result = (result * 0x10000002C5C8601CC6B9E94213C72737A) >> 128;
            if (x & 0x2000000000 > 0)
                result = (result * 0x1000000162E42FFF037DF38AA2B219F06) >> 128;
            if (x & 0x1000000000 > 0)
                result = (result * 0x10000000B17217FBA9C739AA5819F44F9) >> 128;
            if (x & 0x800000000 > 0)
                result = (result * 0x1000000058B90BFCDEE5ACD3C1CEDC823) >> 128;
            if (x & 0x400000000 > 0)
                result = (result * 0x100000002C5C85FE31F35A6A30DA1BE50) >> 128;
            if (x & 0x200000000 > 0)
                result = (result * 0x10000000162E42FF0999CE3541B9FFFCF) >> 128;
            if (x & 0x100000000 > 0)
                result = (result * 0x100000000B17217F80F4EF5AADDA45554) >> 128;
            if (x & 0x80000000 > 0)
                result = (result * 0x10000000058B90BFBF8479BD5A81B51AD) >> 128;
            if (x & 0x40000000 > 0)
                result = (result * 0x1000000002C5C85FDF84BD62AE30A74CC) >> 128;
            if (x & 0x20000000 > 0)
                result = (result * 0x100000000162E42FEFB2FED257559BDAA) >> 128;
            if (x & 0x10000000 > 0)
                result = (result * 0x1000000000B17217F7D5A7716BBA4A9AE) >> 128;
            if (x & 0x8000000 > 0)
                result = (result * 0x100000000058B90BFBE9DDBAC5E109CCE) >> 128;
            if (x & 0x4000000 > 0)
                result = (result * 0x10000000002C5C85FDF4B15DE6F17EB0D) >> 128;
            if (x & 0x2000000 > 0)
                result = (result * 0x1000000000162E42FEFA494F1478FDE05) >> 128;
            if (x & 0x1000000 > 0)
                result = (result * 0x10000000000B17217F7D20CF927C8E94C) >> 128;
            if (x & 0x800000 > 0)
                result = (result * 0x1000000000058B90BFBE8F71CB4E4B33D) >> 128;
            if (x & 0x400000 > 0)
                result = (result * 0x100000000002C5C85FDF477B662B26945) >> 128;
            if (x & 0x200000 > 0)
                result = (result * 0x10000000000162E42FEFA3AE53369388C) >> 128;
            if (x & 0x100000 > 0)
                result = (result * 0x100000000000B17217F7D1D351A389D40) >> 128;
            if (x & 0x80000 > 0)
                result = (result * 0x10000000000058B90BFBE8E8B2D3D4EDE) >> 128;
            if (x & 0x40000 > 0)
                result = (result * 0x1000000000002C5C85FDF4741BEA6E77E) >> 128;
            if (x & 0x20000 > 0)
                result = (result * 0x100000000000162E42FEFA39FE95583C2) >> 128;
            if (x & 0x10000 > 0)
                result = (result * 0x1000000000000B17217F7D1CFB72B45E1) >> 128;
            if (x & 0x8000 > 0)
                result = (result * 0x100000000000058B90BFBE8E7CC35C3F0) >> 128;
            if (x & 0x4000 > 0)
                result = (result * 0x10000000000002C5C85FDF473E242EA38) >> 128;
            if (x & 0x2000 > 0)
                result = (result * 0x1000000000000162E42FEFA39F02B772C) >> 128;
            if (x & 0x1000 > 0)
                result = (result * 0x10000000000000B17217F7D1CF7D83C1A) >> 128;
            if (x & 0x800 > 0)
                result = (result * 0x1000000000000058B90BFBE8E7BDCBE2E) >> 128;
            if (x & 0x400 > 0)
                result = (result * 0x100000000000002C5C85FDF473DEA871F) >> 128;
            if (x & 0x200 > 0)
                result = (result * 0x10000000000000162E42FEFA39EF44D91) >> 128;
            if (x & 0x100 > 0)
                result = (result * 0x100000000000000B17217F7D1CF79E949) >> 128;
            if (x & 0x80 > 0)
                result = (result * 0x10000000000000058B90BFBE8E7BCE544) >> 128;
            if (x & 0x40 > 0)
                result = (result * 0x1000000000000002C5C85FDF473DE6ECA) >> 128;
            if (x & 0x20 > 0)
                result = (result * 0x100000000000000162E42FEFA39EF366F) >> 128;
            if (x & 0x10 > 0)
                result = (result * 0x1000000000000000B17217F7D1CF79AFA) >> 128;
            if (x & 0x8 > 0)
                result = (result * 0x100000000000000058B90BFBE8E7BCD6D) >> 128;
            if (x & 0x4 > 0)
                result = (result * 0x10000000000000002C5C85FDF473DE6B2) >> 128;
            if (x & 0x2 > 0)
                result = (result * 0x1000000000000000162E42FEFA39EF358) >> 128;
            if (x & 0x1 > 0)
                result = (result * 0x10000000000000000B17217F7D1CF79AB) >> 128;

            result >>= uint256(int256(63 - (x >> 64)));
            require(result <= uint256(int256(MAX_64x64)));

            return int128(int256(result));
        }
    }

    /**
     * Calculate natural exponent of x.  Revert on overflow.
     *
     * @param x signed 64.64-bit fixed point number
     * @return signed 64.64-bit fixed point number
     */
    function exp(int128 x) internal pure returns (int128) {
        unchecked {
            require(x < 0x400000000000000000); // Overflow

            if (x < -0x400000000000000000) return 0; // Underflow

            return
                exp_2(
                    int128(
                        (int256(x) * 0x171547652B82FE1777D0FFDA0D23A7D12) >> 128
                    )
                );
        }
    }

    /**
     * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit
     * integer numbers.  Revert on overflow or when y is zero.
     *
     * @param x unsigned 256-bit integer number
     * @param y unsigned 256-bit integer number
     * @return unsigned 64.64-bit fixed point number
     */
    function divuu(uint256 x, uint256 y) private pure returns (uint128) {
        unchecked {
            require(y != 0);

            uint256 result;

            if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
                result = (x << 64) / y;
            else {
                uint256 msb = 192;
                uint256 xc = x >> 192;
                if (xc >= 0x100000000) {
                    xc >>= 32;
                    msb += 32;
                }
                if (xc >= 0x10000) {
                    xc >>= 16;
                    msb += 16;
                }
                if (xc >= 0x100) {
                    xc >>= 8;
                    msb += 8;
                }
                if (xc >= 0x10) {
                    xc >>= 4;
                    msb += 4;
                }
                if (xc >= 0x4) {
                    xc >>= 2;
                    msb += 2;
                }
                if (xc >= 0x2) msb += 1; // No need to shift xc anymore

                result = (x << (255 - msb)) / (((y - 1) >> (msb - 191)) + 1);
                require(result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

                uint256 hi = result * (y >> 128);
                uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);

                uint256 xh = x >> 192;
                uint256 xl = x << 64;

                if (xl < lo) xh -= 1;
                xl -= lo; // We rely on overflow behavior here
                lo = hi << 128;
                if (xl < lo) xh -= 1;
                xl -= lo; // We rely on overflow behavior here

                assert(xh == hi >> 128);

                result += xl / y;
            }

            require(result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
            return uint128(result);
        }
    }

    /**
     * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer
     * number.
     *
     * @param x unsigned 256-bit integer number
     * @return unsigned 128-bit integer number
     */
    function sqrtu(uint256 x) private pure returns (uint128) {
        unchecked {
            if (x == 0) return 0;
            else {
                uint256 xx = x;
                uint256 r = 1;
                if (xx >= 0x100000000000000000000000000000000) {
                    xx >>= 128;
                    r <<= 64;
                }
                if (xx >= 0x10000000000000000) {
                    xx >>= 64;
                    r <<= 32;
                }
                if (xx >= 0x100000000) {
                    xx >>= 32;
                    r <<= 16;
                }
                if (xx >= 0x10000) {
                    xx >>= 16;
                    r <<= 8;
                }
                if (xx >= 0x100) {
                    xx >>= 8;
                    r <<= 4;
                }
                if (xx >= 0x10) {
                    xx >>= 4;
                    r <<= 2;
                }
                if (xx >= 0x8) {
                    r <<= 1;
                }
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1;
                r = (r + x / r) >> 1; // Seven iterations should be enough
                uint256 r1 = x / r;
                return uint128(r < r1 ? r : r1);
            }
        }
    }
}


// File @openzeppelin/contracts/token/ERC20/[email protected]


pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/math/[email protected]


pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        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 division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}


// File @openzeppelin/contracts/security/[email protected]



pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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


// File contracts/stakingStableCoin.sol

pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;





contract evaiStableCoinFund is ReentrancyGuard {
    
    using SafeMath for uint256;
    
    struct stakeType {
        bool active;
        uint8 Type;
        uint80 percentageReturn;
        uint80 bonusTerm;
        uint80 bonusMultiplier;
        uint128 minAmount;
        uint128 maxAmount;
    }

    struct stake {
        bool active;
        bool partialWithdrawn;
        bool settled;
        uint8 Type;
        address ownerAddress;
        uint32 startOfTerm;
        uint32 endOfTerm;
        uint32 id;
        uint32 linkedStakeID;
        uint64 evaiAmount;
        uint64 settlementAmount;
        uint64 stakeReturns;
    }

    IERC20 evaiToken;
    uint8 currentStakeType;
    address owner;
    uint32 currentStakeID;
    uint64 currentStakedEvaiAmount;
    uint64 totalProfitsDistrubuted;
    uint64 totalStakedEvaiAmount;
    bool acceptingStakes;
    uint32 acceptingStakesEndTime;

    event AddStake(
        uint8 _Type,
        address _stakeOwner,
        uint32 _startofTerm,
        uint32 _stakeID,
        uint64 _evaiAmount
    );

    event ReStake(
        uint8 _Type,
        address _stakeOwner,
        uint32 _startOfTerm,
        uint32 _stakeID,
        uint64 _evaiAmount,
        uint32 _linkedStakeID
    );

    event WithdrawStake(
        bool _active,
        bool _partialWithdrawn,
        bool _settled,
        uint32 _stakeID,
        uint32 _endOfTerm,
        uint64 _settlementAmount
    );

    mapping(uint32 => stake) stakeByID;
    mapping(address => uint32[]) stakeByOwnerAddress;
    mapping(uint32 => stakeType) stakeTypes;
    mapping(uint32 => bool) stakeTypeAlreadyExists;

    constructor(address _token) {
        evaiToken = IERC20(_token);
        owner = msg.sender;
        acceptingStakes = false;
        acceptingStakesEndTime = uint32(block.timestamp);
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address _newOwner) external onlyOwner {
        owner = _newOwner;
    }

    function evaiTransfer(uint32 _stakeID) private {
        // Transfer the evai tokens to the stake owner.
        evaiToken.transfer(msg.sender, stakeByID[_stakeID].settlementAmount);
    }

    function setInitialState(
        uint32 _currentStakeID,
        uint64 _currentStakedEvaiAmount,
        uint64 _totalProfitsDistrubuted,
        uint64 _totalStakedEvaiAmount)
        external
        onlyOwner
    {
        currentStakeID = _currentStakeID;
        currentStakedEvaiAmount = _currentStakedEvaiAmount;
        totalProfitsDistrubuted = _totalProfitsDistrubuted;
        totalStakedEvaiAmount = _totalStakedEvaiAmount;
    }

    function addManualStake(
        stake calldata _stake
    )
        external
        onlyOwner
    {
        stakeByID[_stake.id] = _stake;
        stakeByOwnerAddress[_stake.ownerAddress].push(_stake.id);
    }

    function removeManualStake(uint32 _stakeID)
        external
        onlyOwner
    {

        require(stakeByID[_stakeID].active, "Stake does not exist");

        // Remove the stake from the stakeByOwnerAddress mapping.
        uint32[] memory userStakes = stakeByOwnerAddress[stakeByID[_stakeID].ownerAddress];
        uint32[] memory newStakes = new uint32[](userStakes.length - 1);
        uint newStakeId = 0;
        for (uint i = 0; i < userStakes.length; ++i) {
            if (userStakes[i] != _stakeID) {
                newStakes[newStakeId++] = _stakeID;
            }
        }
        stakeByOwnerAddress[stakeByID[_stakeID].ownerAddress] = newStakes;

        // Remove the stake from the stakeByID mapping.
        delete stakeByID[_stakeID];

    }

    function getCurrentCountOfStakeTypes()
        external
        view
        onlyOwner
        returns (uint32 currentStakeTypes)
    {
        return currentStakeType;
    }

    function getCurrentStakeID()
        external
        view
        onlyOwner
        returns (uint32 currentStakeId)
    {
        return currentStakeID;
    }

    function getStakeType(uint32 _stakeType)
        external
        view
        onlyOwner
        returns (stakeType memory)
    {
        return stakeTypes[_stakeType];
    }

    function getBalance() external view onlyOwner returns (uint256) {
        return evaiToken.balanceOf(address(this));
    }

    function getStakesByAddress(address _user)
        external
        view
        onlyOwner
        returns (uint32[] memory)
    {
        require(
            _user != address(0),
            "EVAIFUND:Address can't be a zero address"
        );
        return stakeByOwnerAddress[_user];
    }

    function getTotalStaked()
        external
        view
        returns (uint64 totalEvaiAmountStaked)
    {
        return totalStakedEvaiAmount;
    }

    function getTotalProfitsDistributed()
        external
        view
        returns (uint64 totalProfits)
    {
        return totalProfitsDistrubuted;
    }

    function getCurrentStakedAmount()
        external
        view
        returns (uint64 currentStakedEvai)
    {
        return currentStakedEvaiAmount;
    }

    function getMyStakes() external view returns (uint32[] memory) {
        return stakeByOwnerAddress[msg.sender];
    }

    function getStakeDetailsByStakeID(uint32 _stakeID)
        external
        view
        returns (stake memory)
    {
        require(
            msg.sender == owner ||
                msg.sender == stakeByID[_stakeID].ownerAddress,
            "Unauthorized User."
        );
        return stakeByID[_stakeID];
    }

    function addStakeType(
        bool _active,
        uint80 _percentageReturn,
        uint80 _bonusTerm,
        uint80 _bonusMultiplier,
        uint128 _minAmount,
        uint128 _maxAmount
    ) external onlyOwner {
        currentStakeType += 1;
        stakeTypes[currentStakeType].Type = currentStakeType;
        stakeTypes[currentStakeType].active = _active;
        stakeTypes[currentStakeType].percentageReturn = _percentageReturn;
        stakeTypes[currentStakeType].bonusTerm = _bonusTerm;
        stakeTypes[currentStakeType].bonusMultiplier = _bonusMultiplier;
        stakeTypes[currentStakeType].minAmount = _minAmount;
        stakeTypes[currentStakeType].maxAmount = _maxAmount;
        stakeTypeAlreadyExists[currentStakeType] = true;
    }

    function updateStakeType(
        uint8 _stakeType,
        bool _active,
        uint80 _percentageReturn,
        uint80 _bonusTerm,
        uint80 _bonusMultiplier,
        uint128 _minAmount,
        uint128 _maxAmount
    ) external onlyOwner {
        require(
            stakeTypeAlreadyExists[_stakeType] == true,
            "This stakeType doesn't exists"
        );
        stakeTypes[currentStakeType].active = _active;
        stakeTypes[_stakeType].percentageReturn = _percentageReturn;
        stakeTypes[_stakeType].bonusTerm = _bonusTerm;
        stakeTypes[currentStakeType].bonusMultiplier = _bonusMultiplier;
        stakeTypes[_stakeType].minAmount = _minAmount;
        stakeTypes[_stakeType].maxAmount = _maxAmount;
    }

    function updateAcceptingStakes(bool _acceptingStakes) external onlyOwner {
        acceptingStakes = _acceptingStakes;
        if (_acceptingStakes == false) {
            acceptingStakesEndTime = uint32(block.timestamp);
        } else {
            acceptingStakesEndTime = 0;
        }
    }

    function claimToInvest() external onlyOwner {
        evaiToken.approve(address(this), evaiToken.balanceOf(address(this)));
        evaiToken.transfer(owner, evaiToken.balanceOf(address(this)));
    }

    function evaisetStakeAttributesAndUpdateGlobalVariables(
        uint64 _amount,
        uint8 _type,
        uint32 _ID
    ) private {
        // set stake attributes
        stakeByID[_ID].active = true;
        stakeByID[_ID].Type = _type;
        stakeByID[_ID].ownerAddress = msg.sender;
        stakeByID[_ID].startOfTerm = uint32(block.timestamp);
        stakeByID[_ID].id = currentStakeID;
        stakeByID[_ID].evaiAmount = _amount;
        stakeByOwnerAddress[msg.sender].push(_ID);
        totalStakedEvaiAmount += _amount;
        currentStakedEvaiAmount += _amount;
    }

    function emitWithdrawStake(uint32 _stakeID) private {
        stakeByID[_stakeID].endOfTerm = uint32(block.timestamp);
        // emit WithdrawStake event
        emit WithdrawStake(
            stakeByID[_stakeID].active,
            stakeByID[_stakeID].partialWithdrawn,
            stakeByID[_stakeID].settled,
            _stakeID,
            stakeByID[_stakeID].endOfTerm,
            stakeByID[_stakeID].settlementAmount
        );
    }

    function addStake(uint64 _amount, uint8 _type) external nonReentrant {
        require(acceptingStakes, "Can't add a stake at this time, contract disabled for maintenance");
        require(
            stakeTypes[_type].active,
            "Can't add a stake with the provided stakeType"
        );
        require(stakeTypeAlreadyExists[_type], "The Stake type doesn't exist");

        require(
            _amount >= stakeTypes[_type].minAmount &&
                _amount <= stakeTypes[_type].maxAmount,
            "Staked amount is more than maximum amount specified for the stake"
        );

        require(
            evaiToken.balanceOf(msg.sender) >= _amount,
            "Insufficient Evai Balance. Please buy more EVAI Tokens."
        );
        // stakeID counter update
        currentStakeID += 1;
        //Transfer evai tokens from the msg.sender(stake owner) to the contract
        evaisetStakeAttributesAndUpdateGlobalVariables(
            _amount,
            _type,
            currentStakeID
        );
        evaiToken.transferFrom(msg.sender, address(this), _amount);

        emit AddStake(
            _type,
            stakeByID[currentStakeID].ownerAddress,
            stakeByID[currentStakeID].startOfTerm,
            stakeByID[currentStakeID].id,
            stakeByID[currentStakeID].evaiAmount
        );
    }

    function reStake(
        uint64 _amount,
        uint8 _type,
        uint32 _linkedStakeID
    ) internal {
        require(stakeTypeAlreadyExists[_type], "The Stake type doesn't exist");
        // stakeID counter update
        currentStakeID += 1;
        evaisetStakeAttributesAndUpdateGlobalVariables(
            _amount,
            _type,
            currentStakeID
        );
        stakeByID[currentStakeID].linkedStakeID = _linkedStakeID;

        emit ReStake(
            _type,
            stakeByID[currentStakeID].ownerAddress,
            stakeByID[currentStakeID].startOfTerm,
            stakeByID[currentStakeID].id,
            stakeByID[currentStakeID].evaiAmount,
            stakeByID[currentStakeID].linkedStakeID
        );
    }

    function withdraw(
        uint32 _stakeID,
        bool _full,
        uint64 _withdrawAmount
    ) external nonReentrant {
        require(
            stakeByID[_stakeID].ownerAddress == msg.sender,
            "Unauthorized Stake owner"
        );
        require(stakeByID[_stakeID].active == true, "Stake was settled");
        uint256 elapsedTime = BokkyPooBahsDateTimeLibrary.diffDays(
            uint256(stakeByID[_stakeID].startOfTerm),
            uint256(block.timestamp)
        );
        uint256 totalReturns;
        uint256 stakeReturns;
        uint256 rewardEndTime;
        if (elapsedTime < stakeTypes[stakeByID[_stakeID].Type].bonusTerm) {
            totalReturns = compound(
                (stakeByID[_stakeID].evaiAmount),
                (stakeTypes[stakeByID[_stakeID].Type].percentageReturn),
                elapsedTime
            );
            stakeReturns = totalReturns - stakeByID[_stakeID].evaiAmount;
        } else if (
            elapsedTime == stakeTypes[stakeByID[_stakeID].Type].bonusTerm
        ) {
            totalReturns = (stakeByID[_stakeID].evaiAmount *
                (stakeTypes[stakeByID[_stakeID].Type].bonusMultiplier));
            stakeReturns = totalReturns - (stakeByID[_stakeID].evaiAmount);
        } else if (
            elapsedTime > stakeTypes[stakeByID[_stakeID].Type].bonusTerm
        ) {
            uint256 daysForYearInProgress = elapsedTime.mod(
                uint256(stakeTypes[stakeByID[_stakeID].Type].bonusTerm)
            );
            uint256 completedYears = (elapsedTime.sub(daysForYearInProgress))
                .div(uint256(stakeTypes[stakeByID[_stakeID].Type].bonusTerm));

            rewardEndTime = BokkyPooBahsDateTimeLibrary.addDays(
                uint256(stakeByID[_stakeID].startOfTerm),
                uint256(
                    (completedYears + 1) *
                        uint256(stakeTypes[stakeByID[_stakeID].Type].bonusTerm)
                )
            );

            if (rewardEndTime < uint256(block.timestamp)) {
                // Calculated elapsed time again
                elapsedTime = BokkyPooBahsDateTimeLibrary.diffDays(
                    uint256(stakeByID[_stakeID].startOfTerm),
                    rewardEndTime
                );

                daysForYearInProgress = elapsedTime.mod(
                    uint256(stakeTypes[stakeByID[_stakeID].Type].bonusTerm)
                );
                completedYears = (elapsedTime.sub(daysForYearInProgress)).div(
                    uint256(stakeTypes[stakeByID[_stakeID].Type].bonusTerm)
                );
            }

            uint256 bMul = uint256(
                stakeTypes[stakeByID[_stakeID].Type].bonusMultiplier
            );

            uint256 postBonusBalance = calculatePostBonusBalance(
                uint256(stakeByID[_stakeID].evaiAmount),
                completedYears,
                bMul
            );

            uint256 pReturns = stakeTypes[stakeByID[_stakeID].Type]
                .percentageReturn;

            totalReturns = compound(
                postBonusBalance,
                pReturns,
                daysForYearInProgress
            );
            stakeReturns = totalReturns - (stakeByID[_stakeID].evaiAmount);
        }

        if (_full == true) {
            stakeByID[_stakeID].partialWithdrawn = false;
            stakeByID[_stakeID].settlementAmount = uint64(totalReturns);
            stakeByID[_stakeID].stakeReturns = uint64(stakeReturns);
        } else {
            require(
                _withdrawAmount <= uint64(totalReturns),
                "Amount to claim is higher than returns"
            );
            stakeByID[_stakeID].settlementAmount = _withdrawAmount;
        }

        if (
            _full == true &&
            stakeByID[_stakeID].settlementAmount <=
            evaiToken.balanceOf(address(this))
        ) {
            //Update the global variables
            currentStakedEvaiAmount -= stakeByID[_stakeID].evaiAmount;
            totalProfitsDistrubuted += stakeByID[_stakeID].stakeReturns;
            // set the stake attributes
            stakeByID[_stakeID].active = false;
            stakeByID[_stakeID].settled = true;
            evaiTransfer(_stakeID);
            emitWithdrawStake(_stakeID);
        } else if (
            _full == true &&
            stakeByID[_stakeID].settlementAmount >=
            evaiToken.balanceOf(address(this))
        ) {
            // set the stake attributes
            stakeByID[_stakeID].active = false;
            emitWithdrawStake(_stakeID);
        } else if (
            _full == false &&
            stakeByID[_stakeID].settlementAmount <=
            evaiToken.balanceOf(address(this))
        ) {
            // Update the global variables
            currentStakedEvaiAmount -= stakeByID[_stakeID].evaiAmount;
            // set the stake attributes
            stakeByID[_stakeID].active = false;
            stakeByID[_stakeID].partialWithdrawn = true;
            stakeByID[_stakeID].settled = true;
            evaiTransfer(_stakeID);
            emitWithdrawStake(_stakeID);
            // restake with the remaining amount
            uint8 Type = stakeByID[_stakeID].Type;
            uint256 reStakeAmount = totalReturns -
                (stakeByID[_stakeID].settlementAmount);
            reStake(uint64(reStakeAmount), Type, _stakeID);
        } else if (
            _full == false &&
            stakeByID[_stakeID].settlementAmount >=
            evaiToken.balanceOf(address(this))
        ) {
            // set the stake attributes
            stakeByID[_stakeID].active = false;
            stakeByID[_stakeID].partialWithdrawn = true;
            emitWithdrawStake(_stakeID);
        }
    }

    function compound(
        uint256 principal,
        uint256 ratio,
        uint256 n
    ) public pure returns (uint256) {
        return
            ABDKMath64x64.mulu(
                ABDKMath64x64.pow(
                    ABDKMath64x64.add(
                        ABDKMath64x64.fromUInt(1),
                        ABDKMath64x64.divu(ratio, 100 * 10**6)
                    ),
                    n
                ),
                principal
            );
    }

    function calculatePostBonusBalance(
        uint256 amount,
        uint256 completedYears,
        uint256 bonusMultiplier
    ) public pure returns (uint256) {
        return
            compound(amount, ((bonusMultiplier - 10**6) * 100), completedYears);
    }

    function settleStakes(uint32[] memory _stakeIDs) external onlyOwner {
        for (uint256 i = 0; i < _stakeIDs.length; i++) {
            if (
                stakeByID[_stakeIDs[i]].active == true &&
                stakeByID[_stakeIDs[i]].partialWithdrawn == false
            ) {
                currentStakedEvaiAmount -= stakeByID[_stakeIDs[i]]
                    .settlementAmount;
                stakeByID[_stakeIDs[i]].active = false;
                stakeByID[_stakeIDs[i]].settled = true;

                evaiToken.approve(
                    stakeByID[_stakeIDs[i]].ownerAddress,
                    stakeByID[_stakeIDs[i]].settlementAmount
                );

                evaiToken.transfer(
                    stakeByID[_stakeIDs[i]].ownerAddress,
                    stakeByID[_stakeIDs[i]].settlementAmount
                );
            }
        }
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"_Type","type":"uint8"},{"indexed":false,"internalType":"address","name":"_stakeOwner","type":"address"},{"indexed":false,"internalType":"uint32","name":"_startofTerm","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_stakeID","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"_evaiAmount","type":"uint64"}],"name":"AddStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"_Type","type":"uint8"},{"indexed":false,"internalType":"address","name":"_stakeOwner","type":"address"},{"indexed":false,"internalType":"uint32","name":"_startOfTerm","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_stakeID","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"_evaiAmount","type":"uint64"},{"indexed":false,"internalType":"uint32","name":"_linkedStakeID","type":"uint32"}],"name":"ReStake","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"_active","type":"bool"},{"indexed":false,"internalType":"bool","name":"_partialWithdrawn","type":"bool"},{"indexed":false,"internalType":"bool","name":"_settled","type":"bool"},{"indexed":false,"internalType":"uint32","name":"_stakeID","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"_endOfTerm","type":"uint32"},{"indexed":false,"internalType":"uint64","name":"_settlementAmount","type":"uint64"}],"name":"WithdrawStake","type":"event"},{"inputs":[{"components":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"partialWithdrawn","type":"bool"},{"internalType":"bool","name":"settled","type":"bool"},{"internalType":"uint8","name":"Type","type":"uint8"},{"internalType":"address","name":"ownerAddress","type":"address"},{"internalType":"uint32","name":"startOfTerm","type":"uint32"},{"internalType":"uint32","name":"endOfTerm","type":"uint32"},{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"linkedStakeID","type":"uint32"},{"internalType":"uint64","name":"evaiAmount","type":"uint64"},{"internalType":"uint64","name":"settlementAmount","type":"uint64"},{"internalType":"uint64","name":"stakeReturns","type":"uint64"}],"internalType":"struct evaiStableCoinFund.stake","name":"_stake","type":"tuple"}],"name":"addManualStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_amount","type":"uint64"},{"internalType":"uint8","name":"_type","type":"uint8"}],"name":"addStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"uint80","name":"_percentageReturn","type":"uint80"},{"internalType":"uint80","name":"_bonusTerm","type":"uint80"},{"internalType":"uint80","name":"_bonusMultiplier","type":"uint80"},{"internalType":"uint128","name":"_minAmount","type":"uint128"},{"internalType":"uint128","name":"_maxAmount","type":"uint128"}],"name":"addStakeType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"completedYears","type":"uint256"},{"internalType":"uint256","name":"bonusMultiplier","type":"uint256"}],"name":"calculatePostBonusBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"claimToInvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"principal","type":"uint256"},{"internalType":"uint256","name":"ratio","type":"uint256"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"compound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentCountOfStakeTypes","outputs":[{"internalType":"uint32","name":"currentStakeTypes","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentStakeID","outputs":[{"internalType":"uint32","name":"currentStakeId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentStakedAmount","outputs":[{"internalType":"uint64","name":"currentStakedEvai","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyStakes","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_stakeID","type":"uint32"}],"name":"getStakeDetailsByStakeID","outputs":[{"components":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"partialWithdrawn","type":"bool"},{"internalType":"bool","name":"settled","type":"bool"},{"internalType":"uint8","name":"Type","type":"uint8"},{"internalType":"address","name":"ownerAddress","type":"address"},{"internalType":"uint32","name":"startOfTerm","type":"uint32"},{"internalType":"uint32","name":"endOfTerm","type":"uint32"},{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"linkedStakeID","type":"uint32"},{"internalType":"uint64","name":"evaiAmount","type":"uint64"},{"internalType":"uint64","name":"settlementAmount","type":"uint64"},{"internalType":"uint64","name":"stakeReturns","type":"uint64"}],"internalType":"struct evaiStableCoinFund.stake","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_stakeType","type":"uint32"}],"name":"getStakeType","outputs":[{"components":[{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint8","name":"Type","type":"uint8"},{"internalType":"uint80","name":"percentageReturn","type":"uint80"},{"internalType":"uint80","name":"bonusTerm","type":"uint80"},{"internalType":"uint80","name":"bonusMultiplier","type":"uint80"},{"internalType":"uint128","name":"minAmount","type":"uint128"},{"internalType":"uint128","name":"maxAmount","type":"uint128"}],"internalType":"struct evaiStableCoinFund.stakeType","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getStakesByAddress","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalProfitsDistributed","outputs":[{"internalType":"uint64","name":"totalProfits","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalStaked","outputs":[{"internalType":"uint64","name":"totalEvaiAmountStaked","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_stakeID","type":"uint32"}],"name":"removeManualStake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_currentStakeID","type":"uint32"},{"internalType":"uint64","name":"_currentStakedEvaiAmount","type":"uint64"},{"internalType":"uint64","name":"_totalProfitsDistrubuted","type":"uint64"},{"internalType":"uint64","name":"_totalStakedEvaiAmount","type":"uint64"}],"name":"setInitialState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_stakeIDs","type":"uint32[]"}],"name":"settleStakes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_acceptingStakes","type":"bool"}],"name":"updateAcceptingStakes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_stakeType","type":"uint8"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"uint80","name":"_percentageReturn","type":"uint80"},{"internalType":"uint80","name":"_bonusTerm","type":"uint80"},{"internalType":"uint80","name":"_bonusMultiplier","type":"uint80"},{"internalType":"uint128","name":"_minAmount","type":"uint128"},{"internalType":"uint128","name":"_maxAmount","type":"uint128"}],"name":"updateStakeType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_stakeID","type":"uint32"},{"internalType":"bool","name":"_full","type":"bool"},{"internalType":"uint64","name":"_withdrawAmount","type":"uint64"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162003cb338038062003cb3833981016040819052620000349162000089565b6001600081905580546001600160a01b039092166001600160a01b031992831617905560028054909116331790556003805463ffffffff4216600160881b0264ffffffffff60801b19909116179055620000bb565b6000602082840312156200009c57600080fd5b81516001600160a01b0381168114620000b457600080fd5b9392505050565b613be880620000cb6000396000f3fe608060405234801561001057600080fd5b506004361061014d5760003560e01c806375567598116100c3578063be50e9ac1161007c578063be50e9ac1461032c578063c0c0d2c81461034c578063f2fde38b1461035f578063f3c85eba14610372578063f4453ecf14610385578063fb15b6e71461039857600080fd5b806375567598146102c557806392df8d97146102d857806397a4861a146102e057806399acb0fc146102f5578063a6bf8b1514610308578063b88f53cd1461031957600080fd5b806339c019451161011557806339c01945146101de5780633a4af6db146101f15780633b2e182f1461027f57806340ac1502146102875780634967f1a11461029f5780634f3c9417146102b257600080fd5b80630917e7761461015257806312065fe01461018357806319a39b48146101995780633664a63a146101ae57806336744fd7146101cb575b600080fd5b600354600160401b90046001600160401b03165b6040516001600160401b0390911681526020015b60405180910390f35b61018b6103ab565b60405190815260200161017a565b6101ac6101a7366004613258565b610436565b005b6101b66105cc565b60405163ffffffff909116815260200161017a565b6101ac6101d93660046132ce565b6105fa565b6101ac6101ec366004613319565b6106c7565b6102046101ff366004613375565b610746565b60405161017a9190600060e08201905082511515825260ff602084015116602083015260408301516001600160501b038082166040850152806060860151166060850152806080860151166080850152505060a08301516001600160801b0380821660a08501528060c08601511660c0850152505092915050565b6101b661082f565b600254600160c01b90046001600160401b0316610166565b6101ac6102ad3660046133a8565b61085a565b6101ac6102c036600461346c565b610ca6565b6101ac6102d33660046134b7565b6118f6565b6101ac611963565b6102e8611b48565b60405161017a91906134d4565b61018b61030336600461351e565b611bd5565b6003546001600160401b0316610166565b6102e861032736600461355f565b611c01565b61033f61033a366004613375565b611d18565b60405161017a919061357c565b6101ac61035a366004613680565b611eda565b6101ac61036d36600461355f565b6123ed565b61018b61038036600461351e565b612426565b6101ac6103933660046136b9565b61245a565b6101ac6103a6366004613375565b61259f565b6002546000906001600160a01b031633146103c557600080fd5b6001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561040d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104319190613743565b905090565b6002546001600160a01b0316331461044d57600080fd5b60018054819060149061046b908390600160a01b900460ff16613772565b825460ff91821661010093840a908102908302199091161790925560018054600160a01b908190048416600081815260066020908152604080832080549490970261ff00199094169390931790955583548390048616815281812080549d151560ff199e8f1617905583548390048616815281812080546001600160501b039d8e1662010000026bffffffffffffffffffff00001990911617905583548390048616815281812080549b8d16600160601b0269ffffffffffffffffffff60601b19909c169b909b17909a55825482900485168a52808a20805499909b16600160b01b026001600160b01b0390991698909817909955805489900483168852868820810180546001600160801b039788166001600160801b031990911617905580548990048316885286882081018054958716600160801b02959096169490941790945582549690960490951684526007909152912080549093161790915550565b6002546000906001600160a01b031633146105e657600080fd5b50600254600160a01b900463ffffffff1690565b6002546001600160a01b0316331461061157600080fd5b8060046000610627610100840160e08501613375565b63ffffffff168152602081019190915260400160002061064782826137d0565b5060059050600061065e60a084016080850161355f565b6001600160a01b031681526020810191909152604001600020610688610100830160e08401613375565b8154600181018355600092835260209092206008830401805460079093166004026101000a63ffffffff81810219909416929093169290920217905550565b6002546001600160a01b031633146106de57600080fd5b600280546001600160401b03948516600160c01b026001600160c01b0363ffffffff909716600160a01b02969096166001600160a01b03909116179490941790935560038054938316600160401b026001600160801b03199094169190921617919091179055565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526002546001600160a01b0316331461079657600080fd5b5063ffffffff8116600090815260066020908152604091829020825160e081018452815460ff80821615158352610100820416938201939093526001600160501b03620100008404811694820194909452600160601b830484166060820152600160b01b90920490921660808201526001909101546001600160801b0380821660a0840152600160801b9091041660c08201525b919050565b6002546000906001600160a01b0316331461084957600080fd5b50600154600160a01b900460ff1690565b6002546001600160a01b0316331461087157600080fd5b60005b8151811015610ca2576004600083838151811061089357610893613a21565b60209081029190910181015163ffffffff1682528101919091526040016000205460ff16151560011480156109045750600460008383815181106108d9576108d9613a21565b60209081029190910181015163ffffffff16825281019190915260400160002054610100900460ff16155b15610c90576004600083838151811061091f5761091f613a21565b60209081029190910181015163ffffffff16825281019190915260400160002060010154600280546001600160401b03600160801b909304831692601891610970918591600160c01b900416613a37565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506000600460008484815181106109ac576109ac613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160006101000a81548160ff021916908315150217905550600160046000848481518110610a0057610a00613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160026101000a81548160ff021916908315150217905550600160009054906101000a90046001600160a01b03166001600160a01b031663095ea7b360046000858581518110610a7657610a76613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046001600160a01b031660046000868681518110610ac557610ac5613a21565b60209081029190910181015163ffffffff16825281019190915260409081016000206001015490516001600160e01b031960e085901b1681526001600160a01b0390921660048301526001600160401b03600160801b9091041660248201526044016020604051808303816000875af1158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190613a5f565b5060015482516001600160a01b039091169063a9059cbb90600490600090869086908110610b9a57610b9a613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046001600160a01b031660046000868681518110610be957610be9613a21565b60209081029190910181015163ffffffff16825281019190915260409081016000206001015490516001600160e01b031960e085901b1681526001600160a01b0390921660048301526001600160401b03600160801b9091041660248201526044016020604051808303816000875af1158015610c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8e9190613a5f565b505b80610c9a81613a7c565b915050610874565b5050565b60026000541415610cfe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600090815563ffffffff8416815260046020526040902054600160201b90046001600160a01b03163314610d765760405162461bcd60e51b815260206004820152601860248201527f556e617574686f72697a6564205374616b65206f776e657200000000000000006044820152606401610cf5565b63ffffffff831660009081526004602052604090205460ff161515600114610dd45760405162461bcd60e51b815260206004820152601160248201527014dd185ad9481dd85cc81cd95d1d1b1959607a1b6044820152606401610cf5565b63ffffffff8084166000908152600460205260408120549091610dff91600160c01b900416426127f3565b63ffffffff85166000908152600460209081526040808320546301000000900460ff16835260069091528120549192509081908190600160601b90046001600160501b0316841015610ee65763ffffffff87166000908152600460209081526040808320600181015490546301000000900460ff168452600690925290912054610ea991600160401b90046001600160401b0316906201000090046001600160501b031686612426565b63ffffffff8816600090815260046020526040902060010154909350610edf90600160401b90046001600160401b031684613a97565b91506112ed565b63ffffffff87166000908152600460209081526040808320546301000000900460ff1683526006909152902054600160601b90046001600160501b0316841415610fcc5763ffffffff8716600081815260046020818152604080842080546301000000900460ff1685526006835290842054949093525260010154610f8b91600160b01b90046001600160501b031690600160401b90046001600160401b0316613aae565b63ffffffff88166000908152600460205260409020600101546001600160501b03919091169350610edf90600160401b90046001600160401b031684613a97565b63ffffffff87166000908152600460209081526040808320546301000000900460ff1683526006909152902054600160601b90046001600160501b03168411156112ed5763ffffffff8781166000908152600460209081526040808320546301000000900460ff1683526006909152812054909161105e918791600160601b9091046001600160501b03169061282116565b63ffffffff8981166000908152600460209081526040808320546301000000900460ff1683526006909152812054929350916110ba91600160601b9091046001600160501b0316906110b4908990869061283316565b9061283f565b63ffffffff8a81166000908152600460209081526040808320546301000000810460ff16845260069092529091205492935061112692600160c01b90910490911690600160601b90046001600160501b0316611117846001613add565b6111219190613af5565b61284b565b9250428310156112005763ffffffff808a1660009081526004602052604090205461115a91600160c01b90910416846127f3565b63ffffffff8a81166000908152600460209081526040808320546301000000900460ff16835260069091529020549197506111a9918891600160601b9091046001600160501b03169061282116565b63ffffffff8a81166000908152600460209081526040808320546301000000900460ff16835260069091529020549193506111fd91600160601b90046001600160501b0316906110b4908990869061283316565b90505b63ffffffff8916600081815260046020818152604080842080546301000000900460ff168552600683529084205494845291905260010154600160b01b9092046001600160501b03169161126590600160401b90046001600160401b03168484611bd5565b63ffffffff8c166000908152600460209081526040808320546301000000900460ff16835260069091529020549091506201000090046001600160501b03166112af828287612426565b63ffffffff8d166000908152600460205260409020600101549098506112e590600160401b90046001600160401b031689613a97565b965050505050505b600186151514156113585763ffffffff87166000908152600460205260409020805461ff001916815560010180546001600160401b03848116600160c01b026001600160c01b03918716600160801b02919091166001600160801b0390921691909117179055611405565b826001600160401b0316856001600160401b031611156113c95760405162461bcd60e51b815260206004820152602660248201527f416d6f756e7420746f20636c61696d20697320686967686572207468616e2072604482015265657475726e7360d01b6064820152608401610cf5565b63ffffffff87166000908152600460205260409020600101805467ffffffffffffffff60801b1916600160801b6001600160401b038816021790555b60018615151480156114aa57506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147e9190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031611155b156115a95763ffffffff8716600090815260046020526040902060010154600280546001600160401b03600160401b9093048316926018916114f5918591600160c01b900416613a37565b82546101009290920a6001600160401b0381810219909316918316021790915563ffffffff891660009081526004602052604081206001015460038054600160c01b909204841694509261154b91859116613b14565b82546001600160401b039182166101009390930a92830291909202199091161790555063ffffffff87166000908152600460205260409020805462ff00ff19166201000017905561159b87612873565b6115a487612913565b6118e8565b600186151514801561164e57506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116229190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031610155b156116795763ffffffff87166000908152600460205260409020805460ff191690556115a487612913565b8515801561171a57506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156116ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ee9190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031611155b156118175763ffffffff8716600090815260046020526040902060010154600280546001600160401b03600160401b909304831692601891611765918591600160c01b900416613a37565b82546101009290920a6001600160401b038181021990931691909216919091021790555063ffffffff87166000908152600460205260409020805462ffffff1916620101001790556117b687612873565b6117bf87612913565b63ffffffff871660009081526004602052604081208054600190910154630100000090910460ff16919061180390600160801b90046001600160401b031686613a97565b905061181081838b6129d8565b50506118e8565b851580156118b857506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188c9190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031610155b156118e85763ffffffff87166000908152600460205260409020805461ffff19166101001790556118e887612913565b505060016000555050505050565b6002546001600160a01b0316331461190d57600080fd5b6003805460ff60801b1916600160801b8315159081029190911790915561194f57506003805463ffffffff60881b1916600160881b4263ffffffff1602179055565b6003805463ffffffff60881b191690555b50565b6002546001600160a01b0316331461197a57600080fd5b6001546040516370a0823160e01b815230600482018190526001600160a01b039092169163095ea7b39183906370a0823190602401602060405180830381865afa1580156119cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f09190613743565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5f9190613a5f565b506001546002546040516370a0823160e01b81523060048201526001600160a01b039283169263a9059cbb92169083906370a0823190602401602060405180830381865afa158015611ab5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad99190613743565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611b24573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119609190613a5f565b33600090815260056020908152604091829020805483518184028101840190945280845260609392830182828015611bcb57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611b8e5790505b5050505050905090565b6000611bf984611be8620f424085613a97565b611bf3906064613af5565b85612426565b949350505050565b6002546060906001600160a01b03163314611c1b57600080fd5b6001600160a01b038216611c825760405162461bcd60e51b815260206004820152602860248201527f4556414946554e443a416464726573732063616e27742062652061207a65726f604482015267206164647265737360c01b6064820152608401610cf5565b6001600160a01b03821660009081526005602090815260409182902080548351818402810184019094528084529091830182828015611d0c57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611ccf5790505b50505050509050919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101919091526002546001600160a01b0316331480611db6575063ffffffff8216600090815260046020526040902054600160201b90046001600160a01b031633145b611df75760405162461bcd60e51b81526020600482015260126024820152712ab730baba3437b934bd32b2102ab9b2b91760711b6044820152606401610cf5565b5063ffffffff908116600090815260046020908152604091829020825161018081018452815460ff8082161515835261010080830482161515958401959095526201000082048116151595830195909552630100000081049094166060820152600160201b8085046001600160a01b03166080830152600160c01b808604871660a0840152600160e01b909504861660c083015260019092015480861660e083015291820490941691840191909152600160401b81046001600160401b03908116610120850152600160801b820481166101408501529190041661016082015290565b60026000541415611f2d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cf5565b6002600055600354600160801b900460ff16611fbb5760405162461bcd60e51b815260206004820152604160248201527f43616e2774206164642061207374616b6520617420746869732074696d652c2060448201527f636f6e74726163742064697361626c656420666f72206d61696e74656e616e636064820152606560f81b608482015260a401610cf5565b60ff808216600090815260066020526040902054166120325760405162461bcd60e51b815260206004820152602d60248201527f43616e2774206164642061207374616b652077697468207468652070726f766960448201526c646564207374616b655479706560981b6064820152608401610cf5565b60ff808216600090815260076020526040902054166120935760405162461bcd60e51b815260206004820152601c60248201527f546865205374616b65207479706520646f65736e2774206578697374000000006044820152606401610cf5565b60ff81166000908152600660205260409020600101546001600160801b03166001600160401b038316108015906120f8575060ff8116600090815260066020526040902060010154600160801b90046001600160801b03166001600160401b03831611155b6121745760405162461bcd60e51b815260206004820152604160248201527f5374616b656420616d6f756e74206973206d6f7265207468616e206d6178696d60448201527f756d20616d6f756e742073706563696669656420666f7220746865207374616b6064820152606560f81b608482015260a401610cf5565b6001546040516370a0823160e01b81523360048201526001600160401b038416916001600160a01b0316906370a0823190602401602060405180830381865afa1580156121c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e99190613743565b101561225d5760405162461bcd60e51b815260206004820152603760248201527f496e73756666696369656e7420457661692042616c616e63652e20506c65617360448201527f6520627579206d6f7265204556414920546f6b656e732e0000000000000000006064820152608401610cf5565b6001600260148282829054906101000a900463ffffffff1661227f9190613b3f565b92506101000a81548163ffffffff021916908363ffffffff1602179055506122ba8282600260149054906101000a900463ffffffff16612b73565b6001546040516323b872dd60e01b81523360048201523060248201526001600160401b03841660448201526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613a5f565b50600254600160a01b900463ffffffff9081166000908152600460209081526040918290208054600190910154835160ff87168152600160201b83046001600160a01b031693810193909352600160c01b9091048416928201929092529181166060830152600160401b90046001600160401b031660808201527f4cd436d796a8aeaa1ea89b9c7a6677b8e1d623bab83dc61231387eebbee54da89060a00160405180910390a150506001600055565b6002546001600160a01b0316331461240457600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611bf961245461244e61243b6001612ce3565b612449876305f5e100612d01565b612d38565b84612d6c565b85612f8f565b6002546001600160a01b0316331461247157600080fd5b60ff8088166000908152600760205260409020541615156001146124d75760405162461bcd60e51b815260206004820152601d60248201527f54686973207374616b655479706520646f65736e2774206578697374730000006044820152606401610cf5565b6001805460ff600160a01b91829004811660009081526006602052604080822080549b151560ff19909c169b909b17909a55998116808b52898b2080546001600160501b03998a16600160601b0269ffffffffffffffffffff60601b199b8b1662010000029b909b1662010000600160b01b031990911617999099178955835492909204168952968820805494909516600160b01b026001600160b01b0390941693909317909355939094526001600160801b03908116600160801b02921691909117910155565b6002546001600160a01b031633146125b657600080fd5b63ffffffff811660009081526004602052604090205460ff166126125760405162461bcd60e51b815260206004820152601460248201527314dd185ad948191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610cf5565b63ffffffff8116600090815260046020908152604080832054600160201b90046001600160a01b0316835260058252808320805482518185028101850190935280835291929091908301828280156126b557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116126785790505b505050505090506000600182516126cc9190613a97565b6001600160401b038111156126e3576126e3613392565b60405190808252806020026020018201604052801561270c578160200160208202803683370190505b5090506000805b8351811015612791578463ffffffff1684828151811061273557612735613a21565b602002602001015163ffffffff16146127815784838361275481613a7c565b94508151811061276657612766613a21565b602002602001019063ffffffff16908163ffffffff16815250505b61278a81613a7c565b9050612713565b5063ffffffff8416600090815260046020908152604080832054600160201b90046001600160a01b031683526005825290912083516127d292850190613158565b5050505063ffffffff16600090815260046020526040812081815560010155565b60008183111561280257600080fd5b620151806128108484613a97565b61281a9190613b74565b9392505050565b600061281a8284613b88565b92915050565b600061281a8284613a97565b600061281a8284613b74565b600061285a6201518083613af5565b6128649084613add565b90508281101561282d57600080fd5b6001805463ffffffff831660009081526004602081905260409182902090930154905163a9059cbb60e01b81523393810193909352600160801b90046001600160401b031660248301526001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156128ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca29190613a5f565b63ffffffff81811660008181526004602090815260409182902080546001600160e01b038116600160e01b4288168102918217808555600190940154865160ff948516938516939093171515835261010085048416151595830195909552620100008404909216151581860152606081019590955290049093166080830152600160801b9092046001600160401b031660a082015290517f12af337d6b95104df7fab937b814091438d10f8cf303f0baaf3d9c1418b221579160c0908290030190a150565b60ff80831660009081526007602052604090205416612a395760405162461bcd60e51b815260206004820152601c60248201527f546865205374616b65207479706520646f65736e2774206578697374000000006044820152606401610cf5565b6001600260148282829054906101000a900463ffffffff16612a5b9190613b3f565b92506101000a81548163ffffffff021916908363ffffffff160217905550612a968383600260149054906101000a900463ffffffff16612b73565b60028054600160a01b9081900463ffffffff90811660009081526004602090815260408083206001908101805467ffffffff000000001916600160201b8a881681029190911790915596549590950484168352918290208054940154825160ff891681528686046001600160a01b031692810192909252600160c01b9094048316818301528383166060820152600160401b84046001600160401b03166080820152939092041660a0830152517f1ac1f6840b3b8b799354f38f608bbd84cea6363be3bff4fabba86306b5c32fa29160c0908290030190a1505050565b63ffffffff81811660008181526004602081815260408084208054600163ff0000ff19909116630100000060ff8c1602178117640100000000600160e01b03191633600160201b810263ffffffff60c01b191691909117600160c01b428b16021783556002549282018054600160a01b9094048a166fffffffffffffffff00000000ffffffff1990941693909317600160401b6001600160401b038e811682029290921790945590875260058552928620805491820181558652929094206008808404909101805460079094169094026101000a968702199092169590940294909417905560038054879491939192612c729286929190910416613b14565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555082600260188282829054906101000a90046001600160401b0316612cba9190613b14565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550505050565b6000677fffffffffffffff821115612cfa57600080fd5b5060401b90565b600081612d0d57600080fd5b6000612d198484612ff7565b905060016001607f1b036001600160801b038216111561281a57600080fd5b6000600f83810b9083900b0160016001607f1b03198112801590612d63575060016001607f1b038113155b61281a57600080fd5b600080600084600f0b128015612d855750826001166001145b905060008085600f0b12612d995784612d9e565b846000035b6001600160801b03169050600160801b600160401b8211612e3357603f82901b91505b8415612e2b576001851615612dd6578102607f1c5b908002607f1c906002851615612dec578102607f1c5b908002607f1c906004851615612e02578102607f1c5b908002607f1c906008851615612e18578102607f1c5b60049490941c93908002607f1c90612dc1565b60401c612f49565b603f600160601b831015612e4d5760209290921b91601f19015b600160701b831015612e655760109290921b91600f19015b600160781b831015612e7d5760089290921b91600719015b6001607c1b831015612e955760049290921b91600319015b6001607e1b831015612ead5760029290921b91600119015b6001607f1b831015612ec55760019290921b91600019015b60005b8615612f325760408210612edb57600080fd5b6001871615612f0157918302607f1c918101600160801b831115612f0157600192831c92015b928002607f1c9260019190911b90600160801b8410612f2657600193841c9391909101905b600187901c9650612ec8565b60408110612f3f57600080fd5b6040039190911c90505b600083612f565781612f5b565b816000035b905060016001607f1b03198112801590612f7c575060016001607f1b038113155b612f8557600080fd5b9695505050505050565b600081612f9e5750600061282d565b600083600f0b1215612faf57600080fd5b600f83900b6001600160801b038316810260401c90608084901c026001600160c01b03811115612fde57600080fd5b60401b8119811115612fef57600080fd5b019392505050565b60008161300357600080fd5b60006001600160c01b03841161302e5782604085901b8161302657613026613b5e565b049050613144565b60c084811c600160201b8110613046576020918201911c5b620100008110613058576010918201911c5b6101008110613069576008918201911c5b60108110613079576004918201911c5b60048110613089576002918201911c5b60028110613098576001820191505b60bf820360018603901c6001018260ff0387901b816130b9576130b9613b5e565b0492506001600160801b038311156130d057600080fd5b608085901c83026001600160801b038616840260c088901c604089901b828110156130fc576001820391505b608084901b92900382811015613113576001820391505b829003608084901c821461312957613129613b9c565b88818161313857613138613b5e565b04870196505050505050505b6001600160801b0381111561281a57600080fd5b828054828255906000526020600020906007016008900481019282156131f75791602002820160005b838211156131c557835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302613181565b80156131f55782816101000a81549063ffffffff02191690556004016020816003010492830192600103026131c5565b505b50613203929150613207565b5090565b5b808211156132035760008155600101613208565b801515811461196057600080fd5b80356001600160501b038116811461082a57600080fd5b80356001600160801b038116811461082a57600080fd5b60008060008060008060c0878903121561327157600080fd5b863561327c8161321c565b955061328a6020880161322a565b94506132986040880161322a565b93506132a66060880161322a565b92506132b460808801613241565b91506132c260a08801613241565b90509295509295509295565b600061018082840312156132e157600080fd5b50919050565b63ffffffff8116811461196057600080fd5b803561082a816132e7565b6001600160401b038116811461196057600080fd5b6000806000806080858703121561332f57600080fd5b843561333a816132e7565b9350602085013561334a81613304565b9250604085013561335a81613304565b9150606085013561336a81613304565b939692955090935050565b60006020828403121561338757600080fd5b813561281a816132e7565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156133bb57600080fd5b82356001600160401b03808211156133d257600080fd5b818501915085601f8301126133e657600080fd5b8135818111156133f8576133f8613392565b8060051b604051601f19603f8301168101818110858211171561341d5761341d613392565b60405291825284820192508381018501918883111561343b57600080fd5b938501935b8285101561346057613451856132f9565b84529385019392850192613440565b98975050505050505050565b60008060006060848603121561348157600080fd5b833561348c816132e7565b9250602084013561349c8161321c565b915060408401356134ac81613304565b809150509250925092565b6000602082840312156134c957600080fd5b813561281a8161321c565b6020808252825182820181905260009190848201906040850190845b8181101561351257835163ffffffff16835292840192918401916001016134f0565b50909695505050505050565b60008060006060848603121561353357600080fd5b505081359360208301359350604090920135919050565b6001600160a01b038116811461196057600080fd5b60006020828403121561357157600080fd5b813561281a8161354a565b8151151581526101808101602083015161359a602084018215159052565b5060408301516135ae604084018215159052565b5060608301516135c3606084018260ff169052565b5060808301516135de60808401826001600160a01b03169052565b5060a08301516135f660a084018263ffffffff169052565b5060c083015161360e60c084018263ffffffff169052565b5060e083015161362660e084018263ffffffff169052565b506101008381015163ffffffff1690830152610120808401516001600160401b0390811691840191909152610140808501518216908401526101609384015116929091019190915290565b60ff8116811461196057600080fd5b6000806040838503121561369357600080fd5b823561369e81613304565b915060208301356136ae81613671565b809150509250929050565b600080600080600080600060e0888a0312156136d457600080fd5b87356136df81613671565b965060208801356136ef8161321c565b95506136fd6040890161322a565b945061370b6060890161322a565b93506137196080890161322a565b925061372760a08901613241565b915061373560c08901613241565b905092959891949750929550565b60006020828403121561375557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168060ff03821115612fef57612fef61375c565b6000813561282d8161321c565b6000813561282d81613671565b6000813561282d8161354a565b6000813561282d816132e7565b6000813561282d81613304565b6137f06137dc8361378f565b825490151560ff1660ff1991909116178255565b6138196137ff6020840161378f565b82805461ff00191691151560081b61ff0016919091179055565b6138446138286040840161378f565b82805462ff0000191691151560101b62ff000016919091179055565b61386d6138536060840161379c565b825463ff000000191660189190911b63ff00000016178255565b6138a861387c608084016137a9565b828054640100000000600160c01b03191660209290921b640100000000600160c01b0316919091179055565b6138db6138b760a084016137b6565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b61390e6138ea60c084016137b6565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b6001810161393861392160e085016137b6565b825463ffffffff191663ffffffff91909116178255565b61396a61394861010085016137b6565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b6139ac61397a61012085016137c3565b82546fffffffffffffffff0000000000000000191660409190911b6fffffffffffffffff000000000000000016178255565b6139e86139bc61014085016137c3565b82805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b613a1c6139f861016085016137c3565b8280546001600160c01b031660c09290921b6001600160c01b031916919091179055565b505050565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b0383811690831681811015613a5757613a5761375c565b039392505050565b600060208284031215613a7157600080fd5b815161281a8161321c565b6000600019821415613a9057613a9061375c565b5060010190565b600082821015613aa957613aa961375c565b500390565b60006001600160501b0380831681851681830481118215151615613ad457613ad461375c565b02949350505050565b60008219821115613af057613af061375c565b500190565b6000816000190483118215151615613b0f57613b0f61375c565b500290565b60006001600160401b03808316818516808303821115613b3657613b3661375c565b01949350505050565b600063ffffffff808316818516808303821115613b3657613b3661375c565b634e487b7160e01b600052601260045260246000fd5b600082613b8357613b83613b5e565b500490565b600082613b9757613b97613b5e565b500690565b634e487b7160e01b600052600160045260246000fdfea26469706673582212206db16fbbde263090fdb449aeaf28fa7992f5ef78106a31234bd72f825d69ab4464736f6c634300080a003300000000000000000000000050f09629d0afdf40398a3f317cc676ca9132055c

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061014d5760003560e01c806375567598116100c3578063be50e9ac1161007c578063be50e9ac1461032c578063c0c0d2c81461034c578063f2fde38b1461035f578063f3c85eba14610372578063f4453ecf14610385578063fb15b6e71461039857600080fd5b806375567598146102c557806392df8d97146102d857806397a4861a146102e057806399acb0fc146102f5578063a6bf8b1514610308578063b88f53cd1461031957600080fd5b806339c019451161011557806339c01945146101de5780633a4af6db146101f15780633b2e182f1461027f57806340ac1502146102875780634967f1a11461029f5780634f3c9417146102b257600080fd5b80630917e7761461015257806312065fe01461018357806319a39b48146101995780633664a63a146101ae57806336744fd7146101cb575b600080fd5b600354600160401b90046001600160401b03165b6040516001600160401b0390911681526020015b60405180910390f35b61018b6103ab565b60405190815260200161017a565b6101ac6101a7366004613258565b610436565b005b6101b66105cc565b60405163ffffffff909116815260200161017a565b6101ac6101d93660046132ce565b6105fa565b6101ac6101ec366004613319565b6106c7565b6102046101ff366004613375565b610746565b60405161017a9190600060e08201905082511515825260ff602084015116602083015260408301516001600160501b038082166040850152806060860151166060850152806080860151166080850152505060a08301516001600160801b0380821660a08501528060c08601511660c0850152505092915050565b6101b661082f565b600254600160c01b90046001600160401b0316610166565b6101ac6102ad3660046133a8565b61085a565b6101ac6102c036600461346c565b610ca6565b6101ac6102d33660046134b7565b6118f6565b6101ac611963565b6102e8611b48565b60405161017a91906134d4565b61018b61030336600461351e565b611bd5565b6003546001600160401b0316610166565b6102e861032736600461355f565b611c01565b61033f61033a366004613375565b611d18565b60405161017a919061357c565b6101ac61035a366004613680565b611eda565b6101ac61036d36600461355f565b6123ed565b61018b61038036600461351e565b612426565b6101ac6103933660046136b9565b61245a565b6101ac6103a6366004613375565b61259f565b6002546000906001600160a01b031633146103c557600080fd5b6001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561040d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104319190613743565b905090565b6002546001600160a01b0316331461044d57600080fd5b60018054819060149061046b908390600160a01b900460ff16613772565b825460ff91821661010093840a908102908302199091161790925560018054600160a01b908190048416600081815260066020908152604080832080549490970261ff00199094169390931790955583548390048616815281812080549d151560ff199e8f1617905583548390048616815281812080546001600160501b039d8e1662010000026bffffffffffffffffffff00001990911617905583548390048616815281812080549b8d16600160601b0269ffffffffffffffffffff60601b19909c169b909b17909a55825482900485168a52808a20805499909b16600160b01b026001600160b01b0390991698909817909955805489900483168852868820810180546001600160801b039788166001600160801b031990911617905580548990048316885286882081018054958716600160801b02959096169490941790945582549690960490951684526007909152912080549093161790915550565b6002546000906001600160a01b031633146105e657600080fd5b50600254600160a01b900463ffffffff1690565b6002546001600160a01b0316331461061157600080fd5b8060046000610627610100840160e08501613375565b63ffffffff168152602081019190915260400160002061064782826137d0565b5060059050600061065e60a084016080850161355f565b6001600160a01b031681526020810191909152604001600020610688610100830160e08401613375565b8154600181018355600092835260209092206008830401805460079093166004026101000a63ffffffff81810219909416929093169290920217905550565b6002546001600160a01b031633146106de57600080fd5b600280546001600160401b03948516600160c01b026001600160c01b0363ffffffff909716600160a01b02969096166001600160a01b03909116179490941790935560038054938316600160401b026001600160801b03199094169190921617919091179055565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526002546001600160a01b0316331461079657600080fd5b5063ffffffff8116600090815260066020908152604091829020825160e081018452815460ff80821615158352610100820416938201939093526001600160501b03620100008404811694820194909452600160601b830484166060820152600160b01b90920490921660808201526001909101546001600160801b0380821660a0840152600160801b9091041660c08201525b919050565b6002546000906001600160a01b0316331461084957600080fd5b50600154600160a01b900460ff1690565b6002546001600160a01b0316331461087157600080fd5b60005b8151811015610ca2576004600083838151811061089357610893613a21565b60209081029190910181015163ffffffff1682528101919091526040016000205460ff16151560011480156109045750600460008383815181106108d9576108d9613a21565b60209081029190910181015163ffffffff16825281019190915260400160002054610100900460ff16155b15610c90576004600083838151811061091f5761091f613a21565b60209081029190910181015163ffffffff16825281019190915260400160002060010154600280546001600160401b03600160801b909304831692601891610970918591600160c01b900416613a37565b92506101000a8154816001600160401b0302191690836001600160401b031602179055506000600460008484815181106109ac576109ac613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160006101000a81548160ff021916908315150217905550600160046000848481518110610a0057610a00613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160026101000a81548160ff021916908315150217905550600160009054906101000a90046001600160a01b03166001600160a01b031663095ea7b360046000858581518110610a7657610a76613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046001600160a01b031660046000868681518110610ac557610ac5613a21565b60209081029190910181015163ffffffff16825281019190915260409081016000206001015490516001600160e01b031960e085901b1681526001600160a01b0390921660048301526001600160401b03600160801b9091041660248201526044016020604051808303816000875af1158015610b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6a9190613a5f565b5060015482516001600160a01b039091169063a9059cbb90600490600090869086908110610b9a57610b9a613a21565b602002602001015163ffffffff1663ffffffff16815260200190815260200160002060000160049054906101000a90046001600160a01b031660046000868681518110610be957610be9613a21565b60209081029190910181015163ffffffff16825281019190915260409081016000206001015490516001600160e01b031960e085901b1681526001600160a01b0390921660048301526001600160401b03600160801b9091041660248201526044016020604051808303816000875af1158015610c6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8e9190613a5f565b505b80610c9a81613a7c565b915050610874565b5050565b60026000541415610cfe5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b6002600090815563ffffffff8416815260046020526040902054600160201b90046001600160a01b03163314610d765760405162461bcd60e51b815260206004820152601860248201527f556e617574686f72697a6564205374616b65206f776e657200000000000000006044820152606401610cf5565b63ffffffff831660009081526004602052604090205460ff161515600114610dd45760405162461bcd60e51b815260206004820152601160248201527014dd185ad9481dd85cc81cd95d1d1b1959607a1b6044820152606401610cf5565b63ffffffff8084166000908152600460205260408120549091610dff91600160c01b900416426127f3565b63ffffffff85166000908152600460209081526040808320546301000000900460ff16835260069091528120549192509081908190600160601b90046001600160501b0316841015610ee65763ffffffff87166000908152600460209081526040808320600181015490546301000000900460ff168452600690925290912054610ea991600160401b90046001600160401b0316906201000090046001600160501b031686612426565b63ffffffff8816600090815260046020526040902060010154909350610edf90600160401b90046001600160401b031684613a97565b91506112ed565b63ffffffff87166000908152600460209081526040808320546301000000900460ff1683526006909152902054600160601b90046001600160501b0316841415610fcc5763ffffffff8716600081815260046020818152604080842080546301000000900460ff1685526006835290842054949093525260010154610f8b91600160b01b90046001600160501b031690600160401b90046001600160401b0316613aae565b63ffffffff88166000908152600460205260409020600101546001600160501b03919091169350610edf90600160401b90046001600160401b031684613a97565b63ffffffff87166000908152600460209081526040808320546301000000900460ff1683526006909152902054600160601b90046001600160501b03168411156112ed5763ffffffff8781166000908152600460209081526040808320546301000000900460ff1683526006909152812054909161105e918791600160601b9091046001600160501b03169061282116565b63ffffffff8981166000908152600460209081526040808320546301000000900460ff1683526006909152812054929350916110ba91600160601b9091046001600160501b0316906110b4908990869061283316565b9061283f565b63ffffffff8a81166000908152600460209081526040808320546301000000810460ff16845260069092529091205492935061112692600160c01b90910490911690600160601b90046001600160501b0316611117846001613add565b6111219190613af5565b61284b565b9250428310156112005763ffffffff808a1660009081526004602052604090205461115a91600160c01b90910416846127f3565b63ffffffff8a81166000908152600460209081526040808320546301000000900460ff16835260069091529020549197506111a9918891600160601b9091046001600160501b03169061282116565b63ffffffff8a81166000908152600460209081526040808320546301000000900460ff16835260069091529020549193506111fd91600160601b90046001600160501b0316906110b4908990869061283316565b90505b63ffffffff8916600081815260046020818152604080842080546301000000900460ff168552600683529084205494845291905260010154600160b01b9092046001600160501b03169161126590600160401b90046001600160401b03168484611bd5565b63ffffffff8c166000908152600460209081526040808320546301000000900460ff16835260069091529020549091506201000090046001600160501b03166112af828287612426565b63ffffffff8d166000908152600460205260409020600101549098506112e590600160401b90046001600160401b031689613a97565b965050505050505b600186151514156113585763ffffffff87166000908152600460205260409020805461ff001916815560010180546001600160401b03848116600160c01b026001600160c01b03918716600160801b02919091166001600160801b0390921691909117179055611405565b826001600160401b0316856001600160401b031611156113c95760405162461bcd60e51b815260206004820152602660248201527f416d6f756e7420746f20636c61696d20697320686967686572207468616e2072604482015265657475726e7360d01b6064820152608401610cf5565b63ffffffff87166000908152600460205260409020600101805467ffffffffffffffff60801b1916600160801b6001600160401b038816021790555b60018615151480156114aa57506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561145a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147e9190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031611155b156115a95763ffffffff8716600090815260046020526040902060010154600280546001600160401b03600160401b9093048316926018916114f5918591600160c01b900416613a37565b82546101009290920a6001600160401b0381810219909316918316021790915563ffffffff891660009081526004602052604081206001015460038054600160c01b909204841694509261154b91859116613b14565b82546001600160401b039182166101009390930a92830291909202199091161790555063ffffffff87166000908152600460205260409020805462ff00ff19166201000017905561159b87612873565b6115a487612913565b6118e8565b600186151514801561164e57506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156115fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116229190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031610155b156116795763ffffffff87166000908152600460205260409020805460ff191690556115a487612913565b8515801561171a57506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156116ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ee9190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031611155b156118175763ffffffff8716600090815260046020526040902060010154600280546001600160401b03600160401b909304831692601891611765918591600160c01b900416613a37565b82546101009290920a6001600160401b038181021990931691909216919091021790555063ffffffff87166000908152600460205260409020805462ffffff1916620101001790556117b687612873565b6117bf87612913565b63ffffffff871660009081526004602052604081208054600190910154630100000090910460ff16919061180390600160801b90046001600160401b031686613a97565b905061181081838b6129d8565b50506118e8565b851580156118b857506001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188c9190613743565b63ffffffff8816600090815260046020526040902060010154600160801b90046001600160401b031610155b156118e85763ffffffff87166000908152600460205260409020805461ffff19166101001790556118e887612913565b505060016000555050505050565b6002546001600160a01b0316331461190d57600080fd5b6003805460ff60801b1916600160801b8315159081029190911790915561194f57506003805463ffffffff60881b1916600160881b4263ffffffff1602179055565b6003805463ffffffff60881b191690555b50565b6002546001600160a01b0316331461197a57600080fd5b6001546040516370a0823160e01b815230600482018190526001600160a01b039092169163095ea7b39183906370a0823190602401602060405180830381865afa1580156119cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f09190613743565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611a3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a5f9190613a5f565b506001546002546040516370a0823160e01b81523060048201526001600160a01b039283169263a9059cbb92169083906370a0823190602401602060405180830381865afa158015611ab5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ad99190613743565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015611b24573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119609190613a5f565b33600090815260056020908152604091829020805483518184028101840190945280845260609392830182828015611bcb57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611b8e5790505b5050505050905090565b6000611bf984611be8620f424085613a97565b611bf3906064613af5565b85612426565b949350505050565b6002546060906001600160a01b03163314611c1b57600080fd5b6001600160a01b038216611c825760405162461bcd60e51b815260206004820152602860248201527f4556414946554e443a416464726573732063616e27742062652061207a65726f604482015267206164647265737360c01b6064820152608401610cf5565b6001600160a01b03821660009081526005602090815260409182902080548351818402810184019094528084529091830182828015611d0c57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411611ccf5790505b50505050509050919050565b6040805161018081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081018290526101608101919091526002546001600160a01b0316331480611db6575063ffffffff8216600090815260046020526040902054600160201b90046001600160a01b031633145b611df75760405162461bcd60e51b81526020600482015260126024820152712ab730baba3437b934bd32b2102ab9b2b91760711b6044820152606401610cf5565b5063ffffffff908116600090815260046020908152604091829020825161018081018452815460ff8082161515835261010080830482161515958401959095526201000082048116151595830195909552630100000081049094166060820152600160201b8085046001600160a01b03166080830152600160c01b808604871660a0840152600160e01b909504861660c083015260019092015480861660e083015291820490941691840191909152600160401b81046001600160401b03908116610120850152600160801b820481166101408501529190041661016082015290565b60026000541415611f2d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cf5565b6002600055600354600160801b900460ff16611fbb5760405162461bcd60e51b815260206004820152604160248201527f43616e2774206164642061207374616b6520617420746869732074696d652c2060448201527f636f6e74726163742064697361626c656420666f72206d61696e74656e616e636064820152606560f81b608482015260a401610cf5565b60ff808216600090815260066020526040902054166120325760405162461bcd60e51b815260206004820152602d60248201527f43616e2774206164642061207374616b652077697468207468652070726f766960448201526c646564207374616b655479706560981b6064820152608401610cf5565b60ff808216600090815260076020526040902054166120935760405162461bcd60e51b815260206004820152601c60248201527f546865205374616b65207479706520646f65736e2774206578697374000000006044820152606401610cf5565b60ff81166000908152600660205260409020600101546001600160801b03166001600160401b038316108015906120f8575060ff8116600090815260066020526040902060010154600160801b90046001600160801b03166001600160401b03831611155b6121745760405162461bcd60e51b815260206004820152604160248201527f5374616b656420616d6f756e74206973206d6f7265207468616e206d6178696d60448201527f756d20616d6f756e742073706563696669656420666f7220746865207374616b6064820152606560f81b608482015260a401610cf5565b6001546040516370a0823160e01b81523360048201526001600160401b038416916001600160a01b0316906370a0823190602401602060405180830381865afa1580156121c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121e99190613743565b101561225d5760405162461bcd60e51b815260206004820152603760248201527f496e73756666696369656e7420457661692042616c616e63652e20506c65617360448201527f6520627579206d6f7265204556414920546f6b656e732e0000000000000000006064820152608401610cf5565b6001600260148282829054906101000a900463ffffffff1661227f9190613b3f565b92506101000a81548163ffffffff021916908363ffffffff1602179055506122ba8282600260149054906101000a900463ffffffff16612b73565b6001546040516323b872dd60e01b81523360048201523060248201526001600160401b03841660448201526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015612319573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233d9190613a5f565b50600254600160a01b900463ffffffff9081166000908152600460209081526040918290208054600190910154835160ff87168152600160201b83046001600160a01b031693810193909352600160c01b9091048416928201929092529181166060830152600160401b90046001600160401b031660808201527f4cd436d796a8aeaa1ea89b9c7a6677b8e1d623bab83dc61231387eebbee54da89060a00160405180910390a150506001600055565b6002546001600160a01b0316331461240457600080fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611bf961245461244e61243b6001612ce3565b612449876305f5e100612d01565b612d38565b84612d6c565b85612f8f565b6002546001600160a01b0316331461247157600080fd5b60ff8088166000908152600760205260409020541615156001146124d75760405162461bcd60e51b815260206004820152601d60248201527f54686973207374616b655479706520646f65736e2774206578697374730000006044820152606401610cf5565b6001805460ff600160a01b91829004811660009081526006602052604080822080549b151560ff19909c169b909b17909a55998116808b52898b2080546001600160501b03998a16600160601b0269ffffffffffffffffffff60601b199b8b1662010000029b909b1662010000600160b01b031990911617999099178955835492909204168952968820805494909516600160b01b026001600160b01b0390941693909317909355939094526001600160801b03908116600160801b02921691909117910155565b6002546001600160a01b031633146125b657600080fd5b63ffffffff811660009081526004602052604090205460ff166126125760405162461bcd60e51b815260206004820152601460248201527314dd185ad948191bd95cc81b9bdd08195e1a5cdd60621b6044820152606401610cf5565b63ffffffff8116600090815260046020908152604080832054600160201b90046001600160a01b0316835260058252808320805482518185028101850190935280835291929091908301828280156126b557602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116126785790505b505050505090506000600182516126cc9190613a97565b6001600160401b038111156126e3576126e3613392565b60405190808252806020026020018201604052801561270c578160200160208202803683370190505b5090506000805b8351811015612791578463ffffffff1684828151811061273557612735613a21565b602002602001015163ffffffff16146127815784838361275481613a7c565b94508151811061276657612766613a21565b602002602001019063ffffffff16908163ffffffff16815250505b61278a81613a7c565b9050612713565b5063ffffffff8416600090815260046020908152604080832054600160201b90046001600160a01b031683526005825290912083516127d292850190613158565b5050505063ffffffff16600090815260046020526040812081815560010155565b60008183111561280257600080fd5b620151806128108484613a97565b61281a9190613b74565b9392505050565b600061281a8284613b88565b92915050565b600061281a8284613a97565b600061281a8284613b74565b600061285a6201518083613af5565b6128649084613add565b90508281101561282d57600080fd5b6001805463ffffffff831660009081526004602081905260409182902090930154905163a9059cbb60e01b81523393810193909352600160801b90046001600160401b031660248301526001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156128ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca29190613a5f565b63ffffffff81811660008181526004602090815260409182902080546001600160e01b038116600160e01b4288168102918217808555600190940154865160ff948516938516939093171515835261010085048416151595830195909552620100008404909216151581860152606081019590955290049093166080830152600160801b9092046001600160401b031660a082015290517f12af337d6b95104df7fab937b814091438d10f8cf303f0baaf3d9c1418b221579160c0908290030190a150565b60ff80831660009081526007602052604090205416612a395760405162461bcd60e51b815260206004820152601c60248201527f546865205374616b65207479706520646f65736e2774206578697374000000006044820152606401610cf5565b6001600260148282829054906101000a900463ffffffff16612a5b9190613b3f565b92506101000a81548163ffffffff021916908363ffffffff160217905550612a968383600260149054906101000a900463ffffffff16612b73565b60028054600160a01b9081900463ffffffff90811660009081526004602090815260408083206001908101805467ffffffff000000001916600160201b8a881681029190911790915596549590950484168352918290208054940154825160ff891681528686046001600160a01b031692810192909252600160c01b9094048316818301528383166060820152600160401b84046001600160401b03166080820152939092041660a0830152517f1ac1f6840b3b8b799354f38f608bbd84cea6363be3bff4fabba86306b5c32fa29160c0908290030190a1505050565b63ffffffff81811660008181526004602081815260408084208054600163ff0000ff19909116630100000060ff8c1602178117640100000000600160e01b03191633600160201b810263ffffffff60c01b191691909117600160c01b428b16021783556002549282018054600160a01b9094048a166fffffffffffffffff00000000ffffffff1990941693909317600160401b6001600160401b038e811682029290921790945590875260058552928620805491820181558652929094206008808404909101805460079094169094026101000a968702199092169590940294909417905560038054879491939192612c729286929190910416613b14565b92506101000a8154816001600160401b0302191690836001600160401b0316021790555082600260188282829054906101000a90046001600160401b0316612cba9190613b14565b92506101000a8154816001600160401b0302191690836001600160401b03160217905550505050565b6000677fffffffffffffff821115612cfa57600080fd5b5060401b90565b600081612d0d57600080fd5b6000612d198484612ff7565b905060016001607f1b036001600160801b038216111561281a57600080fd5b6000600f83810b9083900b0160016001607f1b03198112801590612d63575060016001607f1b038113155b61281a57600080fd5b600080600084600f0b128015612d855750826001166001145b905060008085600f0b12612d995784612d9e565b846000035b6001600160801b03169050600160801b600160401b8211612e3357603f82901b91505b8415612e2b576001851615612dd6578102607f1c5b908002607f1c906002851615612dec578102607f1c5b908002607f1c906004851615612e02578102607f1c5b908002607f1c906008851615612e18578102607f1c5b60049490941c93908002607f1c90612dc1565b60401c612f49565b603f600160601b831015612e4d5760209290921b91601f19015b600160701b831015612e655760109290921b91600f19015b600160781b831015612e7d5760089290921b91600719015b6001607c1b831015612e955760049290921b91600319015b6001607e1b831015612ead5760029290921b91600119015b6001607f1b831015612ec55760019290921b91600019015b60005b8615612f325760408210612edb57600080fd5b6001871615612f0157918302607f1c918101600160801b831115612f0157600192831c92015b928002607f1c9260019190911b90600160801b8410612f2657600193841c9391909101905b600187901c9650612ec8565b60408110612f3f57600080fd5b6040039190911c90505b600083612f565781612f5b565b816000035b905060016001607f1b03198112801590612f7c575060016001607f1b038113155b612f8557600080fd5b9695505050505050565b600081612f9e5750600061282d565b600083600f0b1215612faf57600080fd5b600f83900b6001600160801b038316810260401c90608084901c026001600160c01b03811115612fde57600080fd5b60401b8119811115612fef57600080fd5b019392505050565b60008161300357600080fd5b60006001600160c01b03841161302e5782604085901b8161302657613026613b5e565b049050613144565b60c084811c600160201b8110613046576020918201911c5b620100008110613058576010918201911c5b6101008110613069576008918201911c5b60108110613079576004918201911c5b60048110613089576002918201911c5b60028110613098576001820191505b60bf820360018603901c6001018260ff0387901b816130b9576130b9613b5e565b0492506001600160801b038311156130d057600080fd5b608085901c83026001600160801b038616840260c088901c604089901b828110156130fc576001820391505b608084901b92900382811015613113576001820391505b829003608084901c821461312957613129613b9c565b88818161313857613138613b5e565b04870196505050505050505b6001600160801b0381111561281a57600080fd5b828054828255906000526020600020906007016008900481019282156131f75791602002820160005b838211156131c557835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302613181565b80156131f55782816101000a81549063ffffffff02191690556004016020816003010492830192600103026131c5565b505b50613203929150613207565b5090565b5b808211156132035760008155600101613208565b801515811461196057600080fd5b80356001600160501b038116811461082a57600080fd5b80356001600160801b038116811461082a57600080fd5b60008060008060008060c0878903121561327157600080fd5b863561327c8161321c565b955061328a6020880161322a565b94506132986040880161322a565b93506132a66060880161322a565b92506132b460808801613241565b91506132c260a08801613241565b90509295509295509295565b600061018082840312156132e157600080fd5b50919050565b63ffffffff8116811461196057600080fd5b803561082a816132e7565b6001600160401b038116811461196057600080fd5b6000806000806080858703121561332f57600080fd5b843561333a816132e7565b9350602085013561334a81613304565b9250604085013561335a81613304565b9150606085013561336a81613304565b939692955090935050565b60006020828403121561338757600080fd5b813561281a816132e7565b634e487b7160e01b600052604160045260246000fd5b600060208083850312156133bb57600080fd5b82356001600160401b03808211156133d257600080fd5b818501915085601f8301126133e657600080fd5b8135818111156133f8576133f8613392565b8060051b604051601f19603f8301168101818110858211171561341d5761341d613392565b60405291825284820192508381018501918883111561343b57600080fd5b938501935b8285101561346057613451856132f9565b84529385019392850192613440565b98975050505050505050565b60008060006060848603121561348157600080fd5b833561348c816132e7565b9250602084013561349c8161321c565b915060408401356134ac81613304565b809150509250925092565b6000602082840312156134c957600080fd5b813561281a8161321c565b6020808252825182820181905260009190848201906040850190845b8181101561351257835163ffffffff16835292840192918401916001016134f0565b50909695505050505050565b60008060006060848603121561353357600080fd5b505081359360208301359350604090920135919050565b6001600160a01b038116811461196057600080fd5b60006020828403121561357157600080fd5b813561281a8161354a565b8151151581526101808101602083015161359a602084018215159052565b5060408301516135ae604084018215159052565b5060608301516135c3606084018260ff169052565b5060808301516135de60808401826001600160a01b03169052565b5060a08301516135f660a084018263ffffffff169052565b5060c083015161360e60c084018263ffffffff169052565b5060e083015161362660e084018263ffffffff169052565b506101008381015163ffffffff1690830152610120808401516001600160401b0390811691840191909152610140808501518216908401526101609384015116929091019190915290565b60ff8116811461196057600080fd5b6000806040838503121561369357600080fd5b823561369e81613304565b915060208301356136ae81613671565b809150509250929050565b600080600080600080600060e0888a0312156136d457600080fd5b87356136df81613671565b965060208801356136ef8161321c565b95506136fd6040890161322a565b945061370b6060890161322a565b93506137196080890161322a565b925061372760a08901613241565b915061373560c08901613241565b905092959891949750929550565b60006020828403121561375557600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168060ff03821115612fef57612fef61375c565b6000813561282d8161321c565b6000813561282d81613671565b6000813561282d8161354a565b6000813561282d816132e7565b6000813561282d81613304565b6137f06137dc8361378f565b825490151560ff1660ff1991909116178255565b6138196137ff6020840161378f565b82805461ff00191691151560081b61ff0016919091179055565b6138446138286040840161378f565b82805462ff0000191691151560101b62ff000016919091179055565b61386d6138536060840161379c565b825463ff000000191660189190911b63ff00000016178255565b6138a861387c608084016137a9565b828054640100000000600160c01b03191660209290921b640100000000600160c01b0316919091179055565b6138db6138b760a084016137b6565b82805463ffffffff60c01b191660c09290921b63ffffffff60c01b16919091179055565b61390e6138ea60c084016137b6565b8280546001600160e01b031660e09290921b6001600160e01b031916919091179055565b6001810161393861392160e085016137b6565b825463ffffffff191663ffffffff91909116178255565b61396a61394861010085016137b6565b825467ffffffff00000000191660209190911b67ffffffff0000000016178255565b6139ac61397a61012085016137c3565b82546fffffffffffffffff0000000000000000191660409190911b6fffffffffffffffff000000000000000016178255565b6139e86139bc61014085016137c3565b82805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b613a1c6139f861016085016137c3565b8280546001600160c01b031660c09290921b6001600160c01b031916919091179055565b505050565b634e487b7160e01b600052603260045260246000fd5b60006001600160401b0383811690831681811015613a5757613a5761375c565b039392505050565b600060208284031215613a7157600080fd5b815161281a8161321c565b6000600019821415613a9057613a9061375c565b5060010190565b600082821015613aa957613aa961375c565b500390565b60006001600160501b0380831681851681830481118215151615613ad457613ad461375c565b02949350505050565b60008219821115613af057613af061375c565b500190565b6000816000190483118215151615613b0f57613b0f61375c565b500290565b60006001600160401b03808316818516808303821115613b3657613b3661375c565b01949350505050565b600063ffffffff808316818516808303821115613b3657613b3661375c565b634e487b7160e01b600052601260045260246000fd5b600082613b8357613b83613b5e565b500490565b600082613b9757613b97613b5e565b500690565b634e487b7160e01b600052600160045260246000fdfea26469706673582212206db16fbbde263090fdb449aeaf28fa7992f5ef78106a31234bd72f825d69ab4464736f6c634300080a0033

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

00000000000000000000000050f09629d0afdf40398a3f317cc676ca9132055c

-----Decoded View---------------
Arg [0] : _token (address): 0x50f09629d0afDF40398a3F317cc676cA9132055c

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000050f09629d0afdf40398a3f317cc676ca9132055c


Deployed Bytecode Sourcemap

60309:18695:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65114:158;65243:21;;-1:-1:-1;;;65243:21:0;;-1:-1:-1;;;;;65243:21:0;65114:158;;;-1:-1:-1;;;;;283:31:1;;;265:50;;253:2;238:18;65114:158:0;;;;;;;;64668:124;;;:::i;:::-;;;472:25:1;;;460:2;445:18;64668:124:0;326:177:1;66089:779:0;;;;;;:::i;:::-;;:::i;:::-;;64305:166;;;:::i;:::-;;;1890:10:1;1878:23;;;1860:42;;1848:2;1833:18;64305:166:0;1716:192:1;63093:220:0;;;;;;:::i;:::-;;:::i;62630:455::-;;;;;;:::i;:::-;;:::i;64479:181::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;3747:4:1;3789:3;3778:9;3774:19;3766:27;;3840:6;3834:13;3827:21;3820:29;3809:9;3802:48;3918:4;3910;3902:6;3898:17;3892:24;3888:35;3881:4;3870:9;3866:20;3859:65;3971:4;3963:6;3959:17;3953:24;-1:-1:-1;;;;;4074:2:1;4060:12;4056:21;4049:4;4038:9;4034:20;4027:51;4146:2;4138:4;4130:6;4126:17;4120:24;4116:33;4109:4;4098:9;4094:20;4087:63;4218:2;4210:4;4202:6;4198:17;4192:24;4188:33;4181:4;4170:9;4166:20;4159:63;;;4271:4;4263:6;4259:17;4253:24;-1:-1:-1;;;;;4388:2:1;4372:14;4368:23;4361:4;4350:9;4346:20;4339:53;4460:2;4452:4;4444:6;4440:17;4434:24;4430:33;4423:4;4412:9;4408:20;4401:63;;;3601:869;;;;;64116:181:0;;;:::i;65451:164::-;65584:23;;-1:-1:-1;;;65584:23:0;;-1:-1:-1;;;;;65584:23:0;65451:164;;78099:902;;;;;;:::i;:::-;;:::i;71425:5894::-;;;;;;:::i;:::-;;:::i;67648:301::-;;;;;;:::i;:::-;;:::i;67957:203::-;;;:::i;65623:120::-;;;:::i;:::-;;;;;;;:::i;77821:270::-;;;;;;:::i;:::-;;:::i;65280:163::-;65412:23;;-1:-1:-1;;;;;65412:23:0;65280:163;;64800:306;;;;;;:::i;:::-;;:::i;65751:330::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;69241:1387::-;;;;;;:::i;:::-;;:::i;62322:101::-;;;;;;:::i;:::-;;:::i;77327:486::-;;;;;;:::i;:::-;;:::i;66876:764::-;;;;;;:::i;:::-;;:::i;63321:787::-;;;;;;:::i;:::-;;:::i;64668:124::-;62288:5;;64723:7;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;64750:9:::1;::::0;:34:::1;::::0;-1:-1:-1;;;64750:34:0;;64778:4:::1;64750:34;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;64750:9:0;;::::1;::::0;:19:::1;::::0;10979:18:1;;64750:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64743:41;;64668:124:::0;:::o;66089:779::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;66346:1:::1;66326:21:::0;;66346:1;;66326:16:::1;::::0;:21:::1;::::0;66346:1;;-1:-1:-1;;;66326:21:0;::::1;;;;:::i;:::-;::::0;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;::::1;;::::0;;::::1;;::::0;;;-1:-1:-1;66394:16:0;;-1:-1:-1;;;66394:16:0;;;::::1;::::0;::::1;-1:-1:-1::0;66358:28:0;;;:10:::1;:28;::::0;;;;;;;:52;;;;;::::1;-1:-1:-1::0;;66358:52:0;;::::1;::::0;;;::::1;::::0;;;66432:16;;;;::::1;::::0;::::1;66421:28:::0;;;;;:45;;;::::1;;-1:-1:-1::0;;66421:45:0;;::::1;;::::0;;66488:16;;;;::::1;::::0;::::1;66477:28:::0;;;;;:65;;-1:-1:-1;;;;;66477:65:0;;::::1;::::0;::::1;-1:-1:-1::0;;66477:65:0;;::::1;;::::0;;66564:16;;;;::::1;::::0;::::1;66553:28:::0;;;;;:51;;;;::::1;-1:-1:-1::0;;;66553:51:0::1;-1:-1:-1::0;;;;66553:51:0;;::::1;::::0;;;::::1;::::0;;;66626:16;;;;::::1;::::0;::::1;66615:28:::0;;;;;:63;;;;;::::1;-1:-1:-1::0;;;66615:63:0::1;-1:-1:-1::0;;;;;66615:63:0;;::::1;::::0;;;::::1;::::0;;;66700:16;;;;::::1;::::0;::::1;66689:28:::0;;;;;:38;::::1;:51:::0;;-1:-1:-1;;;;;66689:51:0;;::::1;-1:-1:-1::0;;;;;;66689:51:0;;::::1;;::::0;;66762:16;;;;::::1;::::0;::::1;66751:28:::0;;;;;:38;::::1;:51:::0;;;;::::1;-1:-1:-1::0;;;66751:51:0::1;::::0;;;::::1;::::0;;;::::1;::::0;;;66836:16;;;;;::::1;::::0;;::::1;66813:40:::0;;:22:::1;:40:::0;;;;;:47;;;;::::1;;::::0;;;-1:-1:-1;66089:779:0:o;64305:166::-;62288:5;;64403:21;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;-1:-1:-1;64449:14:0::1;::::0;-1:-1:-1;;;64449:14:0;::::1;;;::::0;64305:166::o;63093:220::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;63232:6;63209:9:::1;:20;63219:9;::::0;;;::::1;::::0;::::1;;:::i;:::-;63209:20;;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;63209:20:0;:29:::1;::::0;:20;:29:::1;:::i;:::-;-1:-1:-1::0;63249:19:0::1;::::0;-1:-1:-1;63249:40:0::1;63269:19;::::0;;;::::1;::::0;::::1;;:::i;:::-;-1:-1:-1::0;;;;;63249:40:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;63249:40:0;63295:9:::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;63249:56:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;63249:56:0;;;::::1;::::0;;;::::1;::::0;::::1;;::::0;;;;;;::::1;;;;;::::0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;-1:-1:-1;63093:220:0:o;62630:455::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;62866:14:::1;:32:::0;;-1:-1:-1;;;;;62909:50:0;;::::1;-1:-1:-1::0;;;62909:50:0::1;-1:-1:-1::0;;;;;62866:32:0::1;::::0;;::::1;-1:-1:-1::0;;;62866:32:0::1;62909:50:::0;;;;-1:-1:-1;;;;;62909:50:0;;;;;;;::::1;::::0;;;62970:23:::1;:50:::0;;63031:46;;::::1;-1:-1:-1::0;;;63031:46:0::1;-1:-1:-1::0;;;;;;63031:46:0;;;62970:50;;;::::1;63031:46:::0;;;;::::1;::::0;;62630:455::o;64479:181::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62288:5:0;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;-1:-1:-1;64630:22:0::1;::::0;::::1;;::::0;;;:10:::1;:22;::::0;;;;;;;;64623:29;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;;;::::0;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;;-1:-1:-1;;;;;64623:29:0;;::::1;::::0;::::1;::::0;;;;;;;-1:-1:-1;;;64623:29:0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;64623:29:0;;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;-1:-1:-1;;;;;64623:29:0;;::::1;::::0;;;;-1:-1:-1;;;64623:29:0;;::::1;;::::0;;;;62305:1:::1;64479:181:::0;;;:::o;64116:::-;62288:5;;64224:24;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;-1:-1:-1;64273:16:0::1;::::0;-1:-1:-1;;;64273:16:0;::::1;;;::::0;64116:181::o;78099:902::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;78183:9:::1;78178:816;78202:9;:16;78198:1;:20;78178:816;;;78262:9;:23;78272:9;78282:1;78272:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;78262:23:::1;;::::0;;;::::1;::::0;;;;;;-1:-1:-1;78262:23:0;:30;::::1;;:38;;:30:::0;:38:::1;:108:::0;::::1;;;;78321:9;:23;78331:9;78341:1;78331:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;78321:23:::1;;::::0;;;::::1;::::0;;;;;;-1:-1:-1;78321:23:0;:40;::::1;::::0;::::1;;;:49;78262:108;78240:743;;;78432:9;:23;78442:9;78452:1;78442:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;78432:23:::1;;::::0;;;::::1;::::0;;;;;;-1:-1:-1;78432:23:0;:62:::1;;::::0;78405:23:::1;:89:::0;;-1:-1:-1;;;;;;;;78432:62:0;;::::1;::::0;::::1;::::0;78405:23:::1;::::0;:89:::1;::::0;78432:62;;-1:-1:-1;;;78405:89:0;::::1;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;;;;78405:89:0::1;;;;;-1:-1:-1::0;;;;;78405:89:0::1;;;;;;78546:5;78513:9;:23;78523:9;78533:1;78523:12;;;;;;;;:::i;:::-;;;;;;;78513:23;;;;;;;;;;;;;;;:30;;;:38;;;;;;;;;;;;;;;;;;78604:4;78570:9;:23;78580:9;78590:1;78580:12;;;;;;;;:::i;:::-;;;;;;;78570:23;;;;;;;;;;;;;;;:31;;;:38;;;;;;;;;;;;;;;;;;78629:9;;;;;;;;;-1:-1:-1::0;;;;;78629:9:0::1;-1:-1:-1::0;;;;;78629:17:0::1;;78669:9;:23;78679:9;78689:1;78679:12;;;;;;;;:::i;:::-;;;;;;;78669:23;;;;;;;;;;;;;;;:36;;;;;;;;;;-1:-1:-1::0;;;;;78669:36:0::1;78728:9;:23;78738:9;78748:1;78738:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;78728:23:::1;;::::0;;;::::1;::::0;;;;;;;;-1:-1:-1;78728:23:0;:40:::1;;::::0;78629:158;;-1:-1:-1;;;;;;78629:158:0::1;::::0;;;;;;-1:-1:-1;;;;;17063:32:1;;;78629:158:0::1;::::0;::::1;17045:51:1::0;-1:-1:-1;;;;;;;;78728:40:0;;::::1;;17112:18:1::0;;;17105:59;17018:18;;78629:158:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;78808:9:0::1;::::0;78859:12;;-1:-1:-1;;;;;78808:9:0;;::::1;::::0;:18:::1;::::0;78849:9:::1;::::0;78808::::1;::::0;78859;;78869:1;;78859:12;::::1;;;;;:::i;:::-;;;;;;;78849:23;;;;;;;;;;;;;;;:36;;;;;;;;;;-1:-1:-1::0;;;;;78849:36:0::1;78908:9;:23;78918:9;78928:1;78918:12;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;78908:23:::1;;::::0;;;::::1;::::0;;;;;;;;-1:-1:-1;78908:23:0;:40:::1;;::::0;78808:159;;-1:-1:-1;;;;;;78808:159:0::1;::::0;;;;;;-1:-1:-1;;;;;17063:32:1;;;78808:159:0::1;::::0;::::1;17045:51:1::0;-1:-1:-1;;;;;;;;78908:40:0;;::::1;;17112:18:1::0;;;17105:59;17018:18;;78808:159:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;78240:743;78220:3:::0;::::1;::::0;::::1;:::i;:::-;;;;78178:816;;;;78099:902:::0;:::o;71425:5894::-;59249:1;59845:7;;:19;;59837:63;;;;-1:-1:-1;;;59837:63:0;;17767:2:1;59837:63:0;;;17749:21:1;17806:2;17786:18;;;17779:30;17845:33;17825:18;;;17818:61;17896:18;;59837:63:0;;;;;;;;;59249:1;59978:7;:18;;;71585:19:::1;::::0;::::1;::::0;;:9:::1;:19;::::0;;;;:32;-1:-1:-1;;;71585:32:0;::::1;-1:-1:-1::0;;;;;71585:32:0::1;71621:10;71585:46;71563:120;;;::::0;-1:-1:-1;;;71563:120:0;;18127:2:1;71563:120:0::1;::::0;::::1;18109:21:1::0;18166:2;18146:18;;;18139:30;18205:26;18185:18;;;18178:54;18249:18;;71563:120:0::1;17925:348:1::0;71563:120:0::1;71702:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:26;::::1;;:34;;:26:::0;:34:::1;71694:64;;;::::0;-1:-1:-1;;;71694:64:0;;18480:2:1;71694:64:0::1;::::0;::::1;18462:21:1::0;18519:2;18499:18;;;18492:30;-1:-1:-1;;;18538:18:1;;;18531:47;18595:18;;71694:64:0::1;18278:341:1::0;71694:64:0::1;71850:19;::::0;;::::1;71769;71850::::0;;;:9:::1;:19;::::0;;;;:31;71769:19;;71791:141:::1;::::0;-1:-1:-1;;;71850:31:0;::::1;;71905:15;71791:36;:141::i;:::-;72066:19;::::0;::::1;71943:20;72066:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;72055:36:::0;;:10:::1;:36:::0;;;;;:46;71769:163;;-1:-1:-1;71943:20:0;;;;;-1:-1:-1;;;72055:46:0;::::1;-1:-1:-1::0;;;;;72055:46:0::1;72041:60:::0;::::1;72037:2727;;;72161:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;;;;:30:::1;::::0;::::1;::::0;72223:24;;;;::::1;;;72212:36:::0;;:10:::1;:36:::0;;;;;;:53;72133:178:::1;::::0;-1:-1:-1;;;72161:30:0;::::1;-1:-1:-1::0;;;;;72161:30:0::1;::::0;72212:53;;::::1;-1:-1:-1::0;;;;;72212:53:0::1;72285:11:::0;72133:8:::1;:178::i;:::-;72356:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:30:::1;;::::0;72118:193;;-1:-1:-1;72341:45:0::1;::::0;-1:-1:-1;;;72356:30:0;::::1;-1:-1:-1::0;;;;;72356:30:0::1;72118:193:::0;72341:45:::1;:::i;:::-;72326:60;;72037:2727;;;72448:19;::::0;::::1;72437:36;72448:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;72437:36:::0;;:10:::1;:36:::0;;;;;:46;-1:-1:-1;;;72437:46:0;::::1;-1:-1:-1::0;;;;;72437:46:0::1;72422:61:::0;::::1;72404:2360;;;72588:19;::::0;::::1;72577:36;72588:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;;::::1;;;72577:36:::0;;:10:::1;:36:::0;;;;;:52;72526:19;;;;;:30:::1;;::::0;:104:::1;::::0;-1:-1:-1;;;72577:52:0;::::1;-1:-1:-1::0;;;;;72577:52:0::1;::::0;-1:-1:-1;;;72526:30:0;::::1;-1:-1:-1::0;;;;;72526:30:0::1;:104;:::i;:::-;72677:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:30:::1;;::::0;-1:-1:-1;;;;;72510:121:0;;;::::1;::::0;-1:-1:-1;72661:47:0::1;::::0;-1:-1:-1;;;72677:30:0;::::1;-1:-1:-1::0;;;;;72677:30:0::1;72510:121:::0;72661:47:::1;:::i;72404:2360::-;72769:19;::::0;::::1;72758:36;72769:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;72758:36:::0;;:10:::1;:36:::0;;;;;:46;-1:-1:-1;;;72758:46:0;::::1;-1:-1:-1::0;;;;;72758:46:0::1;72744:60:::0;::::1;72726:2038;;;72916:19;::::0;;::::1;72831:29;72916:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;72905:36:::0;;:10:::1;:36:::0;;;;;:46;72831:29;;72863:104:::1;::::0;:11;;-1:-1:-1;;;72905:46:0;;::::1;-1:-1:-1::0;;;;;72905:46:0::1;::::0;72863:15:::1;:104;:::i;:::-;73089:19;::::0;;::::1;72982:22;73089:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;73078:36:::0;;:10:::1;:36:::0;;;;;:46;72831:136;;-1:-1:-1;72982:22:0;73007:119:::1;::::0;-1:-1:-1;;;73078:46:0;;::::1;-1:-1:-1::0;;;;;73078:46:0::1;::::0;73008:38:::1;::::0;:11;;72831:136;;73008:15:::1;:38;:::i;:::-;73007:62:::0;::::1;:119::i;:::-;73221:19;::::0;;::::1;;::::0;;;:9:::1;:19;::::0;;;;;;;:31;73369:24;;::::1;;;73358:36:::0;;:10:::1;:36:::0;;;;;;:46;72982:144;;-1:-1:-1;73159:280:0::1;::::0;-1:-1:-1;;;73221:31:0;;::::1;::::0;;::::1;::::0;-1:-1:-1;;;73358:46:0;::::1;-1:-1:-1::0;;;;;73358:46:0::1;73303:18;72982:144:::0;73320:1:::1;73303:18;:::i;:::-;73302:103;;;;:::i;:::-;73159:35;:280::i;:::-;73143:296;;73484:15;73460:13;:40;73456:633;;;73652:19;::::0;;::::1;;::::0;;;:9:::1;:19;::::0;;;;:31;73585:154:::1;::::0;-1:-1:-1;;;73652:31:0;;::::1;;73707:13:::0;73585:36:::1;:154::i;:::-;73841:19;::::0;;::::1;73830:36;73841:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;73830:36:::0;;:10:::1;:36:::0;;;;;:46;73571:168;;-1:-1:-1;73784:112:0::1;::::0;73571:168;;-1:-1:-1;;;73830:46:0;;::::1;-1:-1:-1::0;;;;;73830:46:0::1;::::0;73784:15:::1;:112;:::i;:::-;74018:19;::::0;;::::1;74007:36;74018:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;74007:36:::0;;:10:::1;:36:::0;;;;;:46;73760:136;;-1:-1:-1;73932:141:0::1;::::0;-1:-1:-1;;;74007:46:0;::::1;-1:-1:-1::0;;;;;74007:46:0::1;::::0;73933:38:::1;::::0;:11;;73760:136;;73933:15:::1;:38;:::i;73932:141::-;73915:158;;73456:633;74157:19;::::0;::::1;74105:12;74157:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;;::::1;;;74146:36:::0;;:10:::1;:36:::0;;;;;:52;74309:19;;;;;;:30:::1;;::::0;-1:-1:-1;;;74146:52:0;;::::1;-1:-1:-1::0;;;;;74146:52:0::1;::::0;74257:154:::1;::::0;-1:-1:-1;;;74309:30:0;::::1;-1:-1:-1::0;;;;;74309:30:0::1;74359:14:::0;74146:52;74257:25:::1;:154::i;:::-;74458:19;::::0;::::1;74428:16;74458:19:::0;;;:9:::1;:19;::::0;;;;;;;:24;;;::::1;;;74447:36:::0;;:10:::1;:36:::0;;;;;:71;74230:181;;-1:-1:-1;74447:71:0;;::::1;-1:-1:-1::0;;;;;74447:71:0::1;74550:125;74230:181:::0;74447:71;74639:21;74550:8:::1;:125::i;:::-;74721:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:30:::1;;::::0;74535:140;;-1:-1:-1;74705:47:0::1;::::0;-1:-1:-1;;;74721:30:0;::::1;-1:-1:-1::0;;;;;74721:30:0::1;74535:140:::0;74705:47:::1;:::i;:::-;74690:62;;72816:1948;;;;;72726:2038;74789:4;74780:13:::0;::::1;;;74776:475;;;74810:19;::::0;::::1;74849:5;74810:19:::0;;;:9:::1;:19;::::0;;;;:44;;-1:-1:-1;;74810:44:0::1;::::0;;:36:::1;74869;:59:::0;;-1:-1:-1;;;;;74943:55:0;;::::1;-1:-1:-1::0;;;74943:55:0::1;-1:-1:-1::0;;;;;74869:59:0;;::::1;-1:-1:-1::0;;;74869:59:0::1;74943:55:::0;;;;-1:-1:-1;;;;;74943:55:0;;;;;;;::::1;::::0;;74776:475:::1;;;75083:12;-1:-1:-1::0;;;;;75057:39:0::1;:15;-1:-1:-1::0;;;;;75057:39:0::1;;;75031:139;;;::::0;-1:-1:-1;;;75031:139:0;;19541:2:1;75031:139:0::1;::::0;::::1;19523:21:1::0;19580:2;19560:18;;;19553:30;19619:34;19599:18;;;19592:62;-1:-1:-1;;;19670:18:1;;;19663:36;19716:19;;75031:139:0::1;19339:402:1::0;75031:139:0::1;75185:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:36:::1;;:54:::0;;-1:-1:-1;;;;75185:54:0::1;-1:-1:-1::0;;;;;;;;75185:54:0;::::1;;;::::0;;74776:475:::1;75290:4;75281:13:::0;::::1;;;:117:::0;::::1;;;-1:-1:-1::0;75364:9:0::1;::::0;:34:::1;::::0;-1:-1:-1;;;75364:34:0;;75392:4:::1;75364:34;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;75364:9:0;;::::1;::::0;:19:::1;::::0;10979:18:1;;75364:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75311:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:36:::1;;::::0;-1:-1:-1;;;75311:36:0;::::1;-1:-1:-1::0;;;;;75311:36:0::1;:87;;75281:117;75263:2049;;;75495:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:30:::1;;::::0;75468:23:::1;:57:::0;;-1:-1:-1;;;;;;;;75495:30:0;;::::1;::::0;::::1;::::0;75468:23:::1;::::0;:57:::1;::::0;75495:30;;-1:-1:-1;;;75468:57:0;::::1;;;:::i;:::-;::::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;;75468:57:0;;::::1;;::::0;;::::1;::::0;;::::1;;;::::0;;;75567:19:::1;::::0;::::1;-1:-1:-1::0;75567:19:0;;;:9:::1;:19;::::0;;;;-1:-1:-1;75567:32:0::1;::::0;75540:23:::1;:59:::0;;-1:-1:-1;;;75567:32:0;;::::1;::::0;::::1;::::0;-1:-1:-1;75540:23:0;:59:::1;::::0;75567:32;;75540:59:::1;;:::i;:::-;::::0;;-1:-1:-1;;;;;75540:59:0;;::::1;;::::0;;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;-1:-1:-1;75655:19:0::1;::::0;::::1;-1:-1:-1::0;75655:19:0;;;:9:::1;:19;::::0;;;;:34;;-1:-1:-1;;75704:34:0;;::::1;::::0;;75753:22:::1;75665:8:::0;75753:12:::1;:22::i;:::-;75790:27;75808:8;75790:17;:27::i;:::-;75263:2049;;;75862:4;75853:13:::0;::::1;;;:117:::0;::::1;;;-1:-1:-1::0;75936:9:0::1;::::0;:34:::1;::::0;-1:-1:-1;;;75936:34:0;;75964:4:::1;75936:34;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;75936:9:0;;::::1;::::0;:19:::1;::::0;10979:18:1;;75936:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75883:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:36:::1;;::::0;-1:-1:-1;;;75883:36:0;::::1;-1:-1:-1::0;;;;;75883:36:0::1;:87;;75853:117;75835:1477;;;76038:19;::::0;::::1;76067:5;76038:19:::0;;;:9:::1;:19;::::0;;;;:34;;-1:-1:-1;;76038:34:0::1;::::0;;76087:27:::1;76048:8:::0;76087:17:::1;:27::i;75835:1477::-;76150:14:::0;::::1;::::0;::::1;:118;;-1:-1:-1::0;76234:9:0::1;::::0;:34:::1;::::0;-1:-1:-1;;;76234:34:0;;76262:4:::1;76234:34;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;76234:9:0;;::::1;::::0;:19:::1;::::0;10979:18:1;;76234:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76181:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:36:::1;;::::0;-1:-1:-1;;;76181:36:0;::::1;-1:-1:-1::0;;;;;76181:36:0::1;:87;;76150:118;76132:1180;;;76366:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:30:::1;;::::0;76339:23:::1;:57:::0;;-1:-1:-1;;;;;;;;76366:30:0;;::::1;::::0;::::1;::::0;76339:23:::1;::::0;:57:::1;::::0;76366:30;;-1:-1:-1;;;76339:57:0;::::1;;;:::i;:::-;::::0;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;;76339:57:0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;-1:-1:-1;76452:19:0::1;::::0;::::1;-1:-1:-1::0;76452:19:0;;;:9:::1;:19;::::0;;;;:34;;-1:-1:-1;;76559:34:0;;;;;76608:22:::1;76452:19:::0;76608:12:::1;:22::i;:::-;76645:27;76663:8;76645:17;:27::i;:::-;76750:19;::::0;::::1;76737:10;76750:19:::0;;;:9:::1;:19;::::0;;;;:24;;76846:36:::1;::::0;;::::1;::::0;76750:24;;;::::1;;;::::0;76737:10;76813:70:::1;::::0;-1:-1:-1;;;76846:36:0;::::1;-1:-1:-1::0;;;;;76846:36:0::1;76813:12:::0;:70:::1;:::i;:::-;76789:94;;76898:46;76913:13;76929:4;76935:8;76898:7;:46::i;:::-;76280:676;;76132:1180;;;76980:14:::0;::::1;::::0;::::1;:118;;-1:-1:-1::0;77064:9:0::1;::::0;:34:::1;::::0;-1:-1:-1;;;77064:34:0;;77092:4:::1;77064:34;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;77064:9:0;;::::1;::::0;:19:::1;::::0;10979:18:1;;77064:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;77011:19;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:36:::1;;::::0;-1:-1:-1;;;77011:36:0;::::1;-1:-1:-1::0;;;;;77011:36:0::1;:87;;76980:118;76962:350;;;77166:19;::::0;::::1;77195:5;77166:19:::0;;;:9:::1;:19;::::0;;;;:34;;-1:-1:-1;;77215:43:0;77166:34:::1;77215:43;::::0;;77273:27:::1;77176:8:::0;77273:17:::1;:27::i;:::-;-1:-1:-1::0;;59205:1:0;60157:7;:22;-1:-1:-1;;;;;71425:5894:0:o;67648:301::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;67732:15:::1;:34:::0;;-1:-1:-1;;;;67732:34:0::1;-1:-1:-1::0;;;67732:34:0;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;67777:165:::1;;-1:-1:-1::0;67823:22:0::1;:48:::0;;-1:-1:-1;;;;67823:48:0::1;-1:-1:-1::0;;;67855:15:0::1;67823:48;;;;::::0;;67648:301::o;67777:165::-:1;67904:22;:26:::0;;-1:-1:-1;;;;67904:26:0::1;::::0;;67777:165:::1;67648:301:::0;:::o;67957:203::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;68012:9:::1;::::0;68045:34:::1;::::0;-1:-1:-1;;;68045:34:0;;68038:4:::1;68045:34;::::0;::::1;11006:51:1::0;;;-1:-1:-1;;;;;68012:9:0;;::::1;::::0;:17:::1;::::0;:9;;68045:19:::1;::::0;10979:18:1;;68045:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68012:68;::::0;-1:-1:-1;;;;;;68012:68:0::1;::::0;;;;;;-1:-1:-1;;;;;20179:32:1;;;68012:68:0::1;::::0;::::1;20161:51:1::0;20228:18;;;20221:34;20134:18;;68012:68:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;68091:9:0::1;::::0;68110:5:::1;::::0;68117:34:::1;::::0;-1:-1:-1;;;68117:34:0;;68145:4:::1;68117:34;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;68091:9:0;;::::1;::::0;:18:::1;::::0;68110:5:::1;::::0;68091:9;;68117:19:::1;::::0;10979:18:1;;68117:34:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68091:61;::::0;-1:-1:-1;;;;;;68091:61:0::1;::::0;;;;;;-1:-1:-1;;;;;20179:32:1;;;68091:61:0::1;::::0;::::1;20161:51:1::0;20228:18;;;20221:34;20134:18;;68091:61:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;65623:120::-:0;65724:10;65704:31;;;;:19;:31;;;;;;;;;65697:38;;;;;;;;;;;;;;;;;65669:15;;65697:38;;;65704:31;65697:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65623:120;:::o;77821:270::-;77976:7;78016:67;78025:6;78035:23;78053:5;78035:15;:23;:::i;:::-;78034:31;;78062:3;78034:31;:::i;:::-;78068:14;78016:8;:67::i;:::-;77996:87;77821:270;-1:-1:-1;;;;77821:270:0:o;64800:306::-;62288:5;;64912:15;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;-1:-1:-1;;;;;64967:19:0;::::1;64945:109;;;::::0;-1:-1:-1;;;64945:109:0;;20468:2:1;64945:109:0::1;::::0;::::1;20450:21:1::0;20507:2;20487:18;;;20480:30;20546:34;20526:18;;;20519:62;-1:-1:-1;;;20597:18:1;;;20590:38;20645:19;;64945:109:0::1;20266:404:1::0;64945:109:0::1;-1:-1:-1::0;;;;;65072:26:0;::::1;;::::0;;;:19:::1;:26;::::0;;;;;;;;65065:33;;;;;;::::1;::::0;;;;;;;;;;65072:26;;65065:33;::::1;65072:26:::0;65065:33;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64800:306:::0;;;:::o;65751:330::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65918:5:0;;-1:-1:-1;;;;;65918:5:0;65904:10;:19;;:86;;-1:-1:-1;65958:19:0;;;;;;;:9;:19;;;;;:32;-1:-1:-1;;;65958:32:0;;-1:-1:-1;;;;;65958:32:0;65944:10;:46;65904:86;65882:154;;;;-1:-1:-1;;;65882:154:0;;20877:2:1;65882:154:0;;;20859:21:1;20916:2;20896:18;;;20889:30;-1:-1:-1;;;20935:18:1;;;20928:48;20993:18;;65882:154:0;20675:342:1;65882:154:0;-1:-1:-1;66054:19:0;;;;;;;;:9;:19;;;;;;;;;66047:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;66047:26:0;;;-1:-1:-1;;;;;66047:26:0;;;;;-1:-1:-1;;;66047:26:0;;;;;;;;;-1:-1:-1;;;66047:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;66047:26:0;;-1:-1:-1;;;;;66047:26:0;;;;;;;-1:-1:-1;;;66047:26:0;;;;;;;;;;;;;;;;;65751:330::o;69241:1387::-;59249:1;59845:7;;:19;;59837:63;;;;-1:-1:-1;;;59837:63:0;;17767:2:1;59837:63:0;;;17749:21:1;17806:2;17786:18;;;17779:30;17845:33;17825:18;;;17818:61;17896:18;;59837:63:0;17565:355:1;59837:63:0;59249:1;59978:7;:18;69329:15:::1;::::0;-1:-1:-1;;;69329:15:0;::::1;;;69321:93;;;::::0;-1:-1:-1;;;69321:93:0;;21224:2:1;69321:93:0::1;::::0;::::1;21206:21:1::0;21263:2;21243:18;;;21236:30;21302:34;21282:18;;;21275:62;21373:34;21353:18;;;21346:62;-1:-1:-1;;;21424:19:1;;;21417:32;21466:19;;69321:93:0::1;21022:469:1::0;69321:93:0::1;69447:17;::::0;;::::1;;::::0;;;:10:::1;:17;::::0;;;;:24;::::1;69425:119;;;::::0;-1:-1:-1;;;69425:119:0;;21698:2:1;69425:119:0::1;::::0;::::1;21680:21:1::0;21737:2;21717:18;;;21710:30;21776:34;21756:18;;;21749:62;-1:-1:-1;;;21827:18:1;;;21820:43;21880:19;;69425:119:0::1;21496:409:1::0;69425:119:0::1;69563:29;::::0;;::::1;;::::0;;;:22:::1;:29;::::0;;;;;::::1;69555:70;;;::::0;-1:-1:-1;;;69555:70:0;;22112:2:1;69555:70:0::1;::::0;::::1;22094:21:1::0;22151:2;22131:18;;;22124:30;22190;22170:18;;;22163:58;22238:18;;69555:70:0::1;21910:352:1::0;69555:70:0::1;69671:17;::::0;::::1;;::::0;;;:10:::1;:17;::::0;;;;:27:::1;;::::0;-1:-1:-1;;;;;69671:27:0::1;-1:-1:-1::0;;;;;69660:38:0;::::1;;::::0;::::1;::::0;:97:::1;;-1:-1:-1::0;69730:17:0::1;::::0;::::1;;::::0;;;:10:::1;:17;::::0;;;;:27:::1;;::::0;-1:-1:-1;;;69730:27:0;::::1;-1:-1:-1::0;;;;;69730:27:0::1;-1:-1:-1::0;;;;;69719:38:0;::::1;;;69660:97;69638:212;;;::::0;-1:-1:-1;;;69638:212:0;;22469:2:1;69638:212:0::1;::::0;::::1;22451:21:1::0;22508:2;22488:18;;;22481:30;22547:34;22527:18;;;22520:62;22618:34;22598:18;;;22591:62;-1:-1:-1;;;22669:19:1;;;22662:32;22711:19;;69638:212:0::1;22267:469:1::0;69638:212:0::1;69885:9;::::0;:31:::1;::::0;-1:-1:-1;;;69885:31:0;;69905:10:::1;69885:31;::::0;::::1;11006:51:1::0;-1:-1:-1;;;;;69885:42:0;::::1;::::0;-1:-1:-1;;;;;69885:9:0::1;::::0;:19:::1;::::0;10979:18:1;;69885:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:42;;69863:147;;;::::0;-1:-1:-1;;;69863:147:0;;22943:2:1;69863:147:0::1;::::0;::::1;22925:21:1::0;22982:2;22962:18;;;22955:30;23021:34;23001:18;;;22994:62;23092:25;23072:18;;;23065:53;23135:19;;69863:147:0::1;22741:419:1::0;69863:147:0::1;70074:1;70056:14;;:19;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;70167:128;70228:7;70250:5;70270:14;;;;;;;;;;;70167:46;:128::i;:::-;70306:9;::::0;:58:::1;::::0;-1:-1:-1;;;70306:58:0;;70329:10:::1;70306:58;::::0;::::1;23637:34:1::0;70349:4:0::1;23687:18:1::0;;;23680:43;-1:-1:-1;;;;;23759:31:1;;23739:18;;;23732:59;-1:-1:-1;;;;;70306:9:0;;::::1;::::0;:22:::1;::::0;23572:18:1;;70306:58:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;70435:14:0::1;::::0;-1:-1:-1;;;70435:14:0;::::1;;::::0;;::::1;70425:25;::::0;;;:9:::1;:25;::::0;;;;;;;;:38;;70530:28:::1;::::0;;::::1;::::0;70382:238;;24081:4:1;24069:17;;24051:36;;-1:-1:-1;;;70425:38:0;::::1;-1:-1:-1::0;;;;;70425:38:0::1;24103:18:1::0;;;24096:60;;;;-1:-1:-1;;;70478:37:0;;::::1;::::0;::::1;24201:18:1::0;;;24194:43;;;;70530:28:0;;::::1;24268:2:1::0;24253:18;;24246:43;-1:-1:-1;;;70573:36:0;::::1;-1:-1:-1::0;;;;;70573:36:0::1;24320:3:1::0;24305:19;;24298:60;70382:238:0::1;::::0;24038:3:1;24023:19;70382:238:0::1;;;;;;;-1:-1:-1::0;;59205:1:0;60157:7;:22;69241:1387::o;62322:101::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;62398:5:::1;:17:::0;;-1:-1:-1;;;;;;62398:17:0::1;-1:-1:-1::0;;;;;62398:17:0;;;::::1;::::0;;;::::1;::::0;;62322:101::o;77327:486::-;77445:7;77485:320;77522:240;77562:157;77606:25;77629:1;77606:22;:25::i;:::-;77658:38;77677:5;77684:11;77658:18;:38::i;:::-;77562:17;:157::i;:::-;77742:1;77522:17;:240::i;:::-;77781:9;77485:18;:320::i;66876:764::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;67165:34:::1;::::0;;::::1;;::::0;;;:22:::1;:34;::::0;;;;;::::1;:42;;:34:::0;:42:::1;67143:121;;;::::0;-1:-1:-1;;;67143:121:0;;24571:2:1;67143:121:0::1;::::0;::::1;24553:21:1::0;24610:2;24590:18;;;24583:30;24649:31;24629:18;;;24622:59;24698:18;;67143:121:0::1;24369:353:1::0;67143:121:0::1;67286:16;::::0;;::::1;-1:-1:-1::0;;;67286:16:0;;;::::1;::::0;::::1;67275:28;::::0;;;:10:::1;:28;::::0;;;;;:45;;;::::1;;-1:-1:-1::0;;67275:45:0;;::::1;::::0;;;::::1;::::0;;;67331:22;;::::1;::::0;;;;;;:59;;-1:-1:-1;;;;;67401:45:0;;::::1;-1:-1:-1::0;;;67401:45:0::1;-1:-1:-1::0;;;;67331:59:0;;::::1;::::0;::::1;67401:45:::0;;;;-1:-1:-1;;;;;;67401:45:0;;;;;;;::::1;::::0;;67468:16;;;;;::::1;;67457:28:::0;;;;;:63;;;;;::::1;-1:-1:-1::0;;;67457:63:0::1;-1:-1:-1::0;;;;;67457:63:0;;::::1;::::0;;;::::1;::::0;;;67531:22;;;;-1:-1:-1;;;;;67587:45:0;;::::1;-1:-1:-1::0;;;67587:45:0::1;67531::::0;::::1;67587::::0;;;::::1;67531:32:::0;::::1;67587:45:::0;66876:764::o;63321:787::-;62288:5;;-1:-1:-1;;;;;62288:5:0;62274:10;:19;62266:28;;;;;;63428:19:::1;::::0;::::1;;::::0;;;:9:::1;:19;::::0;;;;:26;::::1;;63420:59;;;::::0;-1:-1:-1;;;63420:59:0;;24929:2:1;63420:59:0::1;::::0;::::1;24911:21:1::0;24968:2;24948:18;;;24941:30;-1:-1:-1;;;24987:18:1;;;24980:50;25047:18;;63420:59:0::1;24727:344:1::0;63420:59:0::1;63608:19;::::0;::::1;63559:26;63608:19:::0;;;:9:::1;:19;::::0;;;;;;;:32;-1:-1:-1;;;63608:32:0;::::1;-1:-1:-1::0;;;;;63608:32:0::1;63588:53:::0;;:19:::1;:53:::0;;;;;63559:82;;;;;;::::1;::::0;;;;;;;;;;;;63588:53;;63559:82;;::::1;63588:53:::0;63559:82;;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63652:25;63713:1;63693:10;:17;:21;;;;:::i;:::-;-1:-1:-1::0;;;;;63680:35:0::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;63680:35:0::1;;63652:63;;63726:15;63761:6:::0;63756:171:::1;63777:10;:17;63773:1;:21;63756:171;;;63837:8;63820:25;;:10;63831:1;63820:13;;;;;;;;:::i;:::-;;;;;;;:25;;;63816:100;;63892:8:::0;63866:9;63876:12;::::1;::::0;::::1;:::i;:::-;;;63866:23;;;;;;;;:::i;:::-;;;;;;:34;;;;;;;;;::::0;::::1;63816:100;63796:3;::::0;::::1;:::i;:::-;;;63756:171;;;-1:-1:-1::0;63957:19:0::1;::::0;::::1;63937:53;63957:19:::0;;;:9:::1;:19;::::0;;;;;;;:32;-1:-1:-1;;;63957:32:0;::::1;-1:-1:-1::0;;;;;63957:32:0::1;63937:53:::0;;:19:::1;:53:::0;;;;;:65;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;;;;64079:19:0::1;;;::::0;;;:9:::1;:19;::::0;;;;64072:26;;;;::::1;::::0;63321:787::o;15127:254::-;15239:13;15295:11;15278:13;:28;;15270:37;;;;;;1101:12;15327:27;15341:13;15327:11;:27;:::i;:::-;15326:47;;;;:::i;:::-;15318:55;15127:254;-1:-1:-1;;;15127:254:0:o;55031:98::-;55089:7;55116:5;55120:1;55116;:5;:::i;55031:98::-;;;;;:::o;53710:::-;53768:7;53795:5;53799:1;53795;:5;:::i;54466:98::-;54524:7;54551:5;54555:1;54551;:5;:::i;10864:242::-;10965:20;11030:23;1101:12;11030:5;:23;:::i;:::-;11018:35;;:9;:35;:::i;:::-;11003:50;;11088:9;11072:12;:25;;11064:34;;;;;62431:191;62546:9;;;62577:19;;;62546:9;62577:19;;;:9;:19;;;;;;;;;:36;;;;62546:68;;-1:-1:-1;;;62546:68:0;;62565:10;62546:68;;;17045:51:1;;;;-1:-1:-1;;;62577:36:0;;-1:-1:-1;;;;;62577:36:0;17112:18:1;;;17105:59;-1:-1:-1;;;;;62546:9:0;;:18;;17018::1;;62546:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;68778:455::-;68841:19;;;;;;;;:9;:19;;;;;;;;;:55;;-1:-1:-1;;;;;68841:55:0;;-1:-1:-1;;;68880:15:0;68841:55;;;;;;;;;;-1:-1:-1;69178:36:0;;;;68949:276;;68977:26;;;;;;;;;;;25738:14:1;25731:22;25713:41;;68841:55:0;69018:36;;;;25797:14:1;25790:22;25770:18;;;25763:50;;;;69069:27:0;;;;;;25856:14:1;25849:22;25829:18;;;25822:50;25932:2;25917:18;;25910:43;;;;69134:29:0;;;;;25984:3:1;25969:19;;25962:44;-1:-1:-1;;;69178:36:0;;;-1:-1:-1;;;;;69178:36:0;26037:3:1;26022:19;;26015:60;68949:276:0;;;;25700:3:1;68949:276:0;;;;;;;68778:455;:::o;70636:781::-;70767:29;;;;;;;;:22;:29;;;;;;;70759:70;;;;-1:-1:-1;;;70759:70:0;;22112:2:1;70759:70:0;;;22094:21:1;22151:2;22131:18;;;22124:30;22190;22170:18;;;22163:58;22238:18;;70759:70:0;21910:352:1;70759:70:0;70893:1;70875:14;;:19;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;70905:128;70966:7;70988:5;71008:14;;;;;;;;;;;70905:46;:128::i;:::-;71054:14;;;-1:-1:-1;;;71054:14:0;;;;;;;;71044:25;;;;:9;:25;;;;;;;;:39;;;;:56;;-1:-1:-1;;71044:56:0;-1:-1:-1;;;71044:56:0;;;;;;;;;;;;71170:14;;;;;;;;71160:25;;;;;;:38;;71265:28;;;71118:291;;26391:4:1;26379:17;;26361:36;;71160:38:0;;;-1:-1:-1;;;;;71160:38:0;26413:18:1;;;26406:60;;;;-1:-1:-1;;;71213:37:0;;;;;26511:18:1;;;26504:43;71265:28:0;;;26578:2:1;26563:18;;26556:43;-1:-1:-1;;;71308:36:0;;-1:-1:-1;;;;;71308:36:0;26630:3:1;26615:19;;26608:60;71359:39:0;;;;;26453:3:1;26684:19;;26677:44;71118:291:0;;;26348:3:1;71118:291:0;;;;;;;70636:781;;;:::o;68168:602::-;68351:14;;;;;;;;:9;:14;;;;;;;;:28;;68375:4;-1:-1:-1;;68390:27:0;;;;68351:28;68390:27;;;;;;-1:-1:-1;;;;;;68479:52:0;68458:10;-1:-1:-1;;;68428:40:0;;-1:-1:-1;;;;68479:52:0;;;;;-1:-1:-1;;;68515:15:0;68479:52;;;;;;68562:14;;68542:17;;;:34;;-1:-1:-1;;;68562:14:0;;;;;-1:-1:-1;;68587:35:0;;;;;;;-1:-1:-1;;;;;;;;68587:35:0;;;;;;;;;;;;68633:31;;;:19;:31;;;;;:41;;;;;;;;;;;;;68587:25;68633:41;;;;;;;;;;;;;;;68351:28;68633:41;;;;;;;;;;;;;;;;;;68390:19;68685:32;;68587:35;;68390:19;;68587:25;;68685:32;;68587:35;;68685:32;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;68685:32:0;;;;;-1:-1:-1;;;;;68685:32:0;;;;;;68755:7;68728:23;;:34;;;;;;;;;;-1:-1:-1;;;;;68728:34:0;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;68728:34:0;;;;;-1:-1:-1;;;;;68728:34:0;;;;;;68168:602;;;:::o;18282:192::-;18334:6;18391:18;18386:1;:23;;18378:32;;;;;;-1:-1:-1;18451:2:0;18446:7;;18282:192::o;26226:268::-;26285:6;26337;26329:15;;;;;;26359:14;26376:11;26382:1;26385;26376:5;:11::i;:::-;26359:28;-1:-1:-1;;;;;;;;;;;26410:28:0;;;;26402:37;;;;;20036:250;20092:6;20152:13;:9;;;:13;;;;;-1:-1:-1;;;;;;20188:19:0;;;;;:42;;-1:-1:-1;;;;;;20211:19:0;;;20188:42;20180:51;;;;;29187:3319;29244:6;29288:13;29308:1;29304;:5;;;:19;;;;;29313:1;29317;29313:5;29322:1;29313:10;29304:19;29288:35;;29340:12;29367:1;29363;:5;;;:14;;29376:1;29363:14;;;29372:1;29371:2;;29363:14;-1:-1:-1;;;;;29340:38:0;;-1:-1:-1;;;;;;;29493:27:0;;29489:2817;;29550:2;29541:11;;;;;29571:785;29578:6;;29571:785;;29617:3;29613:7;;:12;29609:106;;29667:16;;29688:3;29666:25;29609:106;29745:11;;;29761:3;29744:20;;29797:3;29793:7;;:12;29789:106;;29847:16;;29868:3;29846:25;29789:106;29925:11;;;29941:3;29924:20;;29977:3;29973:7;;:12;29969:106;;30027:16;;30048:3;30026:25;29969:106;30105:11;;;30121:3;30104:20;;30157:3;30153:7;;:12;30149:106;;30207:16;;30228:3;30206:25;30149:106;30335:1;30329:7;;;;;30285:11;;;30301:3;30284:20;;29571:785;;;30390:2;30376:16;29489:2817;;;30453:2;-1:-1:-1;;;30478:34:0;;30474:132;;;30546:2;30537:11;;;;;-1:-1:-1;;30571:15:0;30474:132;-1:-1:-1;;;30628:4:0;:38;30624:136;;;30700:2;30691:11;;;;;-1:-1:-1;;30725:15:0;30624:136;-1:-1:-1;;;30782:4:0;:40;30778:136;;;30856:1;30847:10;;;;;-1:-1:-1;;30880:14:0;30778:136;-1:-1:-1;;;30936:4:0;:41;30932:137;;;31011:1;31002:10;;;;;-1:-1:-1;;31035:14:0;30932:137;-1:-1:-1;;;31091:4:0;:41;31087:137;;;31166:1;31157:10;;;;;-1:-1:-1;;31190:14:0;31087:137;-1:-1:-1;;;31246:4:0;:41;31242:137;;;31321:1;31312:10;;;;;-1:-1:-1;;31345:14:0;31242:137;31399:19;31441:755;31448:6;;31441:755;;31499:2;31487:9;:14;31479:23;;;;;;31535:3;31531:7;;:12;31527:357;;31585:16;;;31606:3;31584:25;;31636:24;;-1:-1:-1;;;31691:47:0;;31687:174;;;31785:1;31771:15;;;;31817:16;31687:174;31914:11;;;31930:3;31913:20;;31970:1;31956:15;;;;;-1:-1:-1;;;31998:43:0;;31994:151;;32079:1;32070:10;;;;32107:14;;;;;31994:151;32175:1;32169:7;;;;;31441:755;;;32238:2;32224:11;:16;32216:25;;;;;;32274:2;:16;32260:30;;;;;-1:-1:-1;29489:2817:0;32320:13;32336:8;:49;;32375:9;32336:49;;;32355:9;32347:18;;32336:49;32320:65;-1:-1:-1;;;;;;;32408:19:0;;;;;:42;;-1:-1:-1;;;;;;32431:19:0;;;32408:42;32400:51;;;;;;32480:6;29187:3319;-1:-1:-1;;;;;;29187:3319:0:o;23385:665::-;23443:7;23492:6;23488:20;;-1:-1:-1;23507:1:0;23500:8;;23488:20;23538:1;23533;:6;;;;23525:15;;;;;;23579:9;;;;-1:-1:-1;;;;;23610:38:0;;23571:78;;23654:2;23570:86;;23711:3;23706:8;;;23684:31;-1:-1:-1;;;;;23740:56:0;;;23732:65;;;;;;23819:2;23812:9;23891:96;;23864:123;;;23838:164;;;;;;24024:7;;23385:665;-1:-1:-1;;;23385:665:0:o;44128:1861::-;44187:7;44240:6;44232:15;;;;;;44264:14;-1:-1:-1;;;;;44299:1:0;:55;44295:1569;;44394:1;44388:2;44383:1;:7;;44382:13;;;;;:::i;:::-;;44373:22;;44295:1569;;;44448:3;44483:8;;;-1:-1:-1;;;44514:17:0;;44510:107;;44563:2;44588:9;;;;44556;44510:107;44645:7;44639:2;:13;44635:103;;44684:2;44709:9;;;;44677;44635:103;44766:5;44760:2;:11;44756:99;;44803:1;44827:8;;;;44796;44756:99;44883:4;44877:2;:10;44873:98;;44919:1;44943:8;;;;44912;44873:98;44999:3;44993:2;:9;44989:97;;45034:1;45058:8;;;;45027;44989:97;45114:3;45108:2;:9;45104:23;;45126:1;45119:8;;;;45104:23;45229:3;45223;:9;45216:1;45212;:5;45211:22;;45237:1;45210:28;45201:3;45195;:9;45189:1;:16;;45188:51;;;;;:::i;:::-;;45179:60;;-1:-1:-1;;;;;45266:6:0;:44;;45258:53;;;;;;45360:3;45355:8;;;45345:19;;-1:-1:-1;;;;;45406:38:0;;45396:49;;45484:3;45479:8;;;45524:2;45519:7;;;45551;;;45547:20;;;45566:1;45560:7;;;;45547:20;45661:3;45655:9;;;;45586:8;;45687:7;;;45683:20;;;45702:1;45696:7;;;;45683:20;45722:8;;;45807:3;45801:9;;;45795:15;;45788:23;;;;:::i;:::-;45847:1;45842:2;:6;;;;;:::i;:::-;;45832:16;;;;44415:1449;;;;;;44295:1569;-1:-1:-1;;;;;45888:6:0;:44;;45880:53;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;508:118:1;594:5;587:13;580:21;573:5;570:32;560:60;;616:1;613;606:12;631:175;698:20;;-1:-1:-1;;;;;747:34:1;;737:45;;727:73;;796:1;793;786:12;811:188;879:20;;-1:-1:-1;;;;;928:46:1;;918:57;;908:85;;989:1;986;979:12;1004:608;1102:6;1110;1118;1126;1134;1142;1195:3;1183:9;1174:7;1170:23;1166:33;1163:53;;;1212:1;1209;1202:12;1163:53;1251:9;1238:23;1270:28;1292:5;1270:28;:::i;:::-;1317:5;-1:-1:-1;1341:37:1;1374:2;1359:18;;1341:37;:::i;:::-;1331:47;;1397:37;1430:2;1419:9;1415:18;1397:37;:::i;:::-;1387:47;;1453:37;1486:2;1475:9;1471:18;1453:37;:::i;:::-;1443:47;;1509:39;1543:3;1532:9;1528:19;1509:39;:::i;:::-;1499:49;;1567:39;1601:3;1590:9;1586:19;1567:39;:::i;:::-;1557:49;;1004:608;;;;;;;;:::o;1913:192::-;1997:6;2050:3;2038:9;2029:7;2025:23;2021:33;2018:53;;;2067:1;2064;2057:12;2018:53;-1:-1:-1;2090:9:1;1913:192;-1:-1:-1;1913:192:1:o;2110:121::-;2195:10;2188:5;2184:22;2177:5;2174:33;2164:61;;2221:1;2218;2211:12;2236:132;2303:20;;2332:30;2303:20;2332:30;:::i;2373:129::-;-1:-1:-1;;;;;2451:5:1;2447:30;2440:5;2437:41;2427:69;;2492:1;2489;2482:12;2507:663;2589:6;2597;2605;2613;2666:3;2654:9;2645:7;2641:23;2637:33;2634:53;;;2683:1;2680;2673:12;2634:53;2722:9;2709:23;2741:30;2765:5;2741:30;:::i;:::-;2790:5;-1:-1:-1;2847:2:1;2832:18;;2819:32;2860;2819;2860;:::i;:::-;2911:7;-1:-1:-1;2970:2:1;2955:18;;2942:32;2983;2942;2983;:::i;:::-;3034:7;-1:-1:-1;3093:2:1;3078:18;;3065:32;3106;3065;3106;:::i;:::-;2507:663;;;;-1:-1:-1;2507:663:1;;-1:-1:-1;;2507:663:1:o;3175:245::-;3233:6;3286:2;3274:9;3265:7;3261:23;3257:32;3254:52;;;3302:1;3299;3292:12;3254:52;3341:9;3328:23;3360:30;3384:5;3360:30;:::i;4475:127::-;4536:10;4531:3;4527:20;4524:1;4517:31;4567:4;4564:1;4557:15;4591:4;4588:1;4581:15;4607:1119;4690:6;4721:2;4764;4752:9;4743:7;4739:23;4735:32;4732:52;;;4780:1;4777;4770:12;4732:52;4820:9;4807:23;-1:-1:-1;;;;;4890:2:1;4882:6;4879:14;4876:34;;;4906:1;4903;4896:12;4876:34;4944:6;4933:9;4929:22;4919:32;;4989:7;4982:4;4978:2;4974:13;4970:27;4960:55;;5011:1;5008;5001:12;4960:55;5047:2;5034:16;5069:2;5065;5062:10;5059:36;;;5075:18;;:::i;:::-;5121:2;5118:1;5114:10;5153:2;5147:9;5216:2;5212:7;5207:2;5203;5199:11;5195:25;5187:6;5183:38;5271:6;5259:10;5256:22;5251:2;5239:10;5236:18;5233:46;5230:72;;;5282:18;;:::i;:::-;5318:2;5311:22;5368:18;;;5402:15;;;;-1:-1:-1;5444:11:1;;;5440:20;;;5472:19;;;5469:39;;;5504:1;5501;5494:12;5469:39;5528:11;;;;5548:147;5564:6;5559:3;5556:15;5548:147;;;5630:22;5648:3;5630:22;:::i;:::-;5618:35;;5581:12;;;;5673;;;;5548:147;;;5714:6;4607:1119;-1:-1:-1;;;;;;;;4607:1119:1:o;5731:519::-;5803:6;5811;5819;5872:2;5860:9;5851:7;5847:23;5843:32;5840:52;;;5888:1;5885;5878:12;5840:52;5927:9;5914:23;5946:30;5970:5;5946:30;:::i;:::-;5995:5;-1:-1:-1;6052:2:1;6037:18;;6024:32;6065:30;6024:32;6065:30;:::i;:::-;6114:7;-1:-1:-1;6173:2:1;6158:18;;6145:32;6186;6145;6186;:::i;:::-;6237:7;6227:17;;;5731:519;;;;;:::o;6255:241::-;6311:6;6364:2;6352:9;6343:7;6339:23;6335:32;6332:52;;;6380:1;6377;6370:12;6332:52;6419:9;6406:23;6438:28;6460:5;6438:28;:::i;6501:647::-;6670:2;6722:21;;;6792:13;;6695:18;;;6814:22;;;6641:4;;6670:2;6893:15;;;;6867:2;6852:18;;;6641:4;6936:186;6950:6;6947:1;6944:13;6936:186;;;7015:13;;7030:10;7011:30;6999:43;;7097:15;;;;7062:12;;;;6972:1;6965:9;6936:186;;;-1:-1:-1;7139:3:1;;6501:647;-1:-1:-1;;;;;;6501:647:1:o;7153:316::-;7230:6;7238;7246;7299:2;7287:9;7278:7;7274:23;7270:32;7267:52;;;7315:1;7312;7305:12;7267:52;-1:-1:-1;;7338:23:1;;;7408:2;7393:18;;7380:32;;-1:-1:-1;7459:2:1;7444:18;;;7431:32;;7153:316;-1:-1:-1;7153:316:1:o;7474:131::-;-1:-1:-1;;;;;7549:31:1;;7539:42;;7529:70;;7595:1;7592;7585:12;7610:247;7669:6;7722:2;7710:9;7701:7;7697:23;7693:32;7690:52;;;7738:1;7735;7728:12;7690:52;7777:9;7764:23;7796:31;7821:5;7796:31;:::i;7971:1627::-;8180:13;;3495;3488:21;3476:34;;8151:3;8136:19;;8252:4;8244:6;8240:17;8234:24;8267:51;8312:4;8301:9;8297:20;8283:12;3495:13;3488:21;3476:34;;3425:91;8267:51;;8367:4;8359:6;8355:17;8349:24;8382:53;8429:4;8418:9;8414:20;8398:14;3495:13;3488:21;3476:34;;3425:91;8382:53;;8484:4;8476:6;8472:17;8466:24;8499:54;8547:4;8536:9;8532:20;8516:14;3588:4;3577:16;3565:29;;3521:75;8499:54;;8602:4;8594:6;8590:17;8584:24;8617:56;8667:4;8656:9;8652:20;8636:14;-1:-1:-1;;;;;7928:31:1;7916:44;;7862:104;8617:56;;8722:4;8714:6;8710:17;8704:24;8737:55;8786:4;8775:9;8771:20;8755:14;1693:10;1682:22;1670:35;;1617:94;8737:55;;8841:4;8833:6;8829:17;8823:24;8856:55;8905:4;8894:9;8890:20;8874:14;1693:10;1682:22;1670:35;;1617:94;8856:55;;8960:4;8952:6;8948:17;8942:24;8975:55;9024:4;9013:9;9009:20;8993:14;1693:10;1682:22;1670:35;;1617:94;8975:55;-1:-1:-1;9049:6:1;9092:15;;;9086:22;1693:10;1682:22;9151:18;;;1670:35;9189:6;9232:15;;;9226:22;-1:-1:-1;;;;;79:30:1;;;9291:18;;;67:43;;;;9329:6;9372:15;;;9366:22;79:30;;9431:18;;;67:43;9469:6;9513:15;;;9507:22;79:30;9573:18;;;;67:43;;;;7971:1627;:::o;9603:114::-;9687:4;9680:5;9676:16;9669:5;9666:27;9656:55;;9707:1;9704;9697:12;9722:382;9787:6;9795;9848:2;9836:9;9827:7;9823:23;9819:32;9816:52;;;9864:1;9861;9854:12;9816:52;9903:9;9890:23;9922:30;9946:5;9922:30;:::i;:::-;9971:5;-1:-1:-1;10028:2:1;10013:18;;10000:32;10041:31;10000:32;10041:31;:::i;:::-;10091:7;10081:17;;;9722:382;;;;;:::o;10109:746::-;10214:6;10222;10230;10238;10246;10254;10262;10315:3;10303:9;10294:7;10290:23;10286:33;10283:53;;;10332:1;10329;10322:12;10283:53;10371:9;10358:23;10390:29;10413:5;10390:29;:::i;:::-;10438:5;-1:-1:-1;10495:2:1;10480:18;;10467:32;10508:30;10467:32;10508:30;:::i;:::-;10557:7;-1:-1:-1;10583:37:1;10616:2;10601:18;;10583:37;:::i;:::-;10573:47;;10639:37;10672:2;10661:9;10657:18;10639:37;:::i;:::-;10629:47;;10695:38;10728:3;10717:9;10713:19;10695:38;:::i;:::-;10685:48;;10752:39;10786:3;10775:9;10771:19;10752:39;:::i;:::-;10742:49;;10810:39;10844:3;10833:9;10829:19;10810:39;:::i;:::-;10800:49;;10109:746;;;;;;;;;;:::o;11068:184::-;11138:6;11191:2;11179:9;11170:7;11166:23;11162:32;11159:52;;;11207:1;11204;11197:12;11159:52;-1:-1:-1;11230:16:1;;11068:184;-1:-1:-1;11068:184:1:o;11257:127::-;11318:10;11313:3;11309:20;11306:1;11299:31;11349:4;11346:1;11339:15;11373:4;11370:1;11363:15;11389:204;11427:3;11463:4;11460:1;11456:12;11495:4;11492:1;11488:12;11530:3;11524:4;11520:14;11515:3;11512:23;11509:49;;;11538:18;;:::i;11598:170::-;11640:11;11692:3;11679:17;11705:28;11727:5;11705:28;:::i;12379:172::-;12422:11;12474:3;12461:17;12487:29;12510:5;12487:29;:::i;12752:176::-;12797:11;12849:3;12836:17;12862:31;12887:5;12862:31;:::i;13173:174::-;13217:11;13269:3;13256:17;13282:30;13306:5;13282:30;:::i;14172:174::-;14216:11;14268:3;14255:17;14281:30;14305:5;14281:30;:::i;15058:1443::-;15191:82;15241:31;15266:5;15241:31;:::i;:::-;11872:11;;11939:13;;11932:21;11889:3;11928:31;-1:-1:-1;;11868:26:1;;;;11916:44;11903:58;;11773:194;15191:82;15282:89;15330:40;15366:2;15359:5;15355:14;15330:40;:::i;:::-;15324:4;12060:11;;-1:-1:-1;;12096:19:1;12135:13;;12128:21;12125:1;12121:29;12152:5;12117:41;12093:66;;;;12080:80;;11972:194;15282:89;15380:91;15430:40;15466:2;15459:5;15455:14;15430:40;:::i;:::-;15424:4;12261:11;;-1:-1:-1;;12297:22:1;12340:13;;12333:21;12329:2;12325:30;12357:8;12321:45;12294:73;;;;12281:87;;12171:203;15380:91;15480:92;15530:41;15567:2;15560:5;15556:14;15530:41;:::i;:::-;12646:11;;-1:-1:-1;;12682:24:1;12716:2;12712:14;;;;12728:10;12708:31;12679:61;12666:75;;12556:191;15480:92;15581:99;15635:44;15674:3;15667:5;15663:15;15635:44;:::i;:::-;15629:4;13027:11;;-1:-1:-1;;;;;;13063:44:1;13117:2;13113:14;;;;-1:-1:-1;;;;;13109:51:1;13060:101;;;;13047:115;;12933:235;15581:99;15689:98;15743:43;15781:3;15774:5;15770:15;15743:43;:::i;:::-;15737:4;13446:11;;-1:-1:-1;;;;13482:34:1;13543:3;13522:15;;;;-1:-1:-1;;;13518:42:1;13479:82;;;;13466:96;;13352:216;15689:98;15796:96;15848:43;15886:3;15879:5;15875:15;15848:43;:::i;:::-;15842:4;13665:11;;-1:-1:-1;;;;;13701:28:1;13756:3;13735:15;;;;-1:-1:-1;;;;;;13731:42:1;13698:76;;;;13685:90;;13573:208;15796:96;15929:1;15923:4;15919:12;15940:104;16000:43;16038:3;16031:5;16027:15;16000:43;:::i;:::-;13890:11;;-1:-1:-1;;13886:33:1;13932:10;13921:22;;;;13883:61;13870:75;;13786:165;15940:104;16053;16113:43;16151:3;16144:5;16140:15;16113:43;:::i;:::-;14050:11;;-1:-1:-1;;14086:32:1;14128:2;14124:14;;;;14140:18;14120:39;14083:77;14070:91;;13956:211;16053:104;16166:102;16224:43;16262:3;16255:5;16251:15;16224:43;:::i;:::-;14443:11;;-1:-1:-1;;14479:48:1;14537:2;14533:14;;;;14549:34;14529:55;14476:109;14463:123;;14351:241;16166:102;16277:105;16338:43;16376:3;16369:5;16365:15;16338:43;:::i;:::-;16326:10;14692:11;;-1:-1:-1;;;;14728:42:1;14797:3;14776:15;;;;-1:-1:-1;;;14772:50:1;14725:98;;;;14712:112;;14597:233;16277:105;16391:104;16451:43;16489:3;16482:5;16478:15;16451:43;:::i;:::-;16439:10;14929:11;;-1:-1:-1;;;;;14965:28:1;15020:3;14999:15;;;;-1:-1:-1;;;;;;14995:50:1;14962:84;;;;14949:98;;14835:218;16391:104;;15058:1443;;:::o;16506:127::-;16567:10;16562:3;16558:20;16555:1;16548:31;16598:4;16595:1;16588:15;16622:4;16619:1;16612:15;16638:229;16677:4;-1:-1:-1;;;;;16774:10:1;;;;16744;;16796:12;;;16793:38;;;16811:18;;:::i;:::-;16848:13;;16638:229;-1:-1:-1;;;16638:229:1:o;17175:245::-;17242:6;17295:2;17283:9;17274:7;17270:23;17266:32;17263:52;;;17311:1;17308;17301:12;17263:52;17343:9;17337:16;17362:28;17384:5;17362:28;:::i;17425:135::-;17464:3;-1:-1:-1;;17485:17:1;;17482:43;;;17505:18;;:::i;:::-;-1:-1:-1;17552:1:1;17541:13;;17425:135::o;18624:125::-;18664:4;18692:1;18689;18686:8;18683:34;;;18697:18;;:::i;:::-;-1:-1:-1;18734:9:1;;18624:125::o;18754:274::-;18793:7;-1:-1:-1;;;;;18874:2:1;18871:1;18867:10;18904:2;18901:1;18897:10;18960:3;18956:2;18952:12;18947:3;18944:21;18937:3;18930:11;18923:19;18919:47;18916:73;;;18969:18;;:::i;:::-;19009:13;;18754:274;-1:-1:-1;;;;18754:274:1:o;19033:128::-;19073:3;19104:1;19100:6;19097:1;19094:13;19091:39;;;19110:18;;:::i;:::-;-1:-1:-1;19146:9:1;;19033:128::o;19166:168::-;19206:7;19272:1;19268;19264:6;19260:14;19257:1;19254:21;19249:1;19242:9;19235:17;19231:45;19228:71;;;19279:18;;:::i;:::-;-1:-1:-1;19319:9:1;;19166:168::o;19746:236::-;19785:3;-1:-1:-1;;;;;19858:2:1;19855:1;19851:10;19888:2;19885:1;19881:10;19919:3;19915:2;19911:12;19906:3;19903:21;19900:47;;;19927:18;;:::i;:::-;19963:13;;19746:236;-1:-1:-1;;;;19746:236:1:o;23165:228::-;23204:3;23232:10;23269:2;23266:1;23262:10;23299:2;23296:1;23292:10;23330:3;23326:2;23322:12;23317:3;23314:21;23311:47;;;23338:18;;:::i;25076:127::-;25137:10;25132:3;25128:20;25125:1;25118:31;25168:4;25165:1;25158:15;25192:4;25189:1;25182:15;25208:120;25248:1;25274;25264:35;;25279:18;;:::i;:::-;-1:-1:-1;25313:9:1;;25208:120::o;25333:112::-;25365:1;25391;25381:35;;25396:18;;:::i;:::-;-1:-1:-1;25430:9:1;;25333:112::o;26732:127::-;26793:10;26788:3;26784:20;26781:1;26774:31;26824:4;26821:1;26814:15;26848:4;26845:1;26838:15

Swarm Source

ipfs://6db16fbbde263090fdb449aeaf28fa7992f5ef78106a31234bd72f825d69ab44

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.