Contract 0x776dFe7Ec5D74526Aa65898B7d77FCfdf15ffBe6

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x61f3a3053a75012af89cd82c434ee14fa20eec48c468b082a1eb71e02e44fcfcAdd Node Operato...93368922021-09-22 11:17:15373 days 10 hrs ago0x0d54195d55385824f7a2d2b9045285cf3b489e95 IN  0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether0.00008291 1.00000001
0xb2cff61acdf3510b20a00645ed39f335b37444c16616ad12b380138458836b3eAdd Signing Keys92451732021-09-06 12:31:17389 days 8 hrs ago0xada83afc0380a63f6b6d1bf6576c2da5fb954b6f IN  0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether0.002393251.00000003
0xa4f1458e8cb195f0f9e4adcd646352eebb1e38b3ee98b0d08a2658c6333aa2beAdd Node Operato...92451722021-09-06 12:31:02389 days 8 hrs ago0xada83afc0380a63f6b6d1bf6576c2da5fb954b6f IN  0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether0.000136921.00000003
0x35519dd93284299f45ae96bb87426e1b3041bb7346553ee126a1b8c5648161ecSet Lido92450302021-09-06 11:55:32389 days 9 hrs ago0xada83afc0380a63f6b6d1bf6576c2da5fb954b6f IN  0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether0.000044041
0x28c070cd721bc6234438e9cb16114bd934bd92f1089f15a5af8a9a8a72fab78a0x6080604092450232021-09-06 11:53:47389 days 9 hrs ago0xada83afc0380a63f6b6d1bf6576c2da5fb954b6f IN  Create: NodeOperatorsRegistry0 Ether0.002486471
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x7bd47d9a360d1c7cc8fc5a418fe379ac87ebecd1041f5b05a2a7f39fb54b1adc93380712021-09-22 16:12:22373 days 5 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xe783ea5933e4a64cef98687292baede2e264edef97c2d5b44c026251a1c96fbe93380712021-09-22 16:12:22373 days 5 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x15a31d5897f4fc3efec30ec0caf530845b924c3dfc8848a7a1cef2fc2bdb0f1d93380692021-09-22 16:11:52373 days 5 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x2c8755369162e516e202dfc55906e6bc3ab3dcd7a639cd6a23a44d777cb595e393380512021-09-22 16:07:22373 days 5 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x440efb8af2d4df5fc435a896c7703e3c48a470d7c3a20e2ac6e3823c7d43fb5b93380512021-09-22 16:07:22373 days 5 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x4cefa0d8e8319f520ca577b17d99fd2524084b55f70796d6c7ee14ba9c0562ba93377682021-09-22 14:56:29373 days 6 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x446b9ee723865b73f4a23e8f0e4794715d1a97c4764b96b4074f981f4cb2aac293376462021-09-22 14:25:56373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x017ace629baace717069099a986cbafcbb3818c757e968b0f6db2ce1ba48e5b793376452021-09-22 14:25:41373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x7e7cea9046cb10d3270de75f590441ce9e7537a4e9fb78b55de6cd3e12c98b3b93376422021-09-22 14:24:55373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xb25954eede48c164e11d380e782e479701e63047faaac1746856025a4421756693376242021-09-22 14:20:25373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x369519d37db854dfceeb65356a7b87efc75ce0e9cd61fd17532b886c52d1b72293376222021-09-22 14:19:55373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xe931f6fa692e474f9587541500f6b8c32d5e35f9dc324a8d2c52c410a113e23093376182021-09-22 14:18:55373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xb333d453b7b7112a811400d1949f80efe955fe7b328daadc70f3f6428e9a733593375942021-09-22 14:12:55373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xb438d188bcd53d9097fac92386907fc6a223f090a4c8579146961a681c52fa6f93375912021-09-22 14:12:10373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x0edf0ad484d9512689cc082adcc2be117cb98a027660036657c8e17bb6857fe193375862021-09-22 14:10:55373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x9222610aafe26484687aeb8d405f40f49fd3c2dc159340aae7c3a60be354b8b693375762021-09-22 14:08:25373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xe47d5cda836a3dbefba623bdeb3b2e030d91e1aa5e0b195209b694902c54c38493375732021-09-22 14:07:40373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x79c898cfe1494f4770c9dbaced5c91bf4642e30e9013f0617dce1f027c40c7e793375562021-09-22 14:03:25373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xba9fb3d1f2657bc14b194d8530ccff8dd116f2ab80b993577648fb1b74c7822393375542021-09-22 14:02:54373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xff98e3ca38a4a10775acbee55c9470e175ec63184776de9d020e10c11a52374693375492021-09-22 14:01:39373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x6dde7af8ad83cb68c11f5b683f11afd1fc0db73b6e9cf50666aef8b8487a5b5893375112021-09-22 13:52:09373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x2a36787d1f9c7653b9fbeaf4f217a8439f85329e09c4bd6a68c463c61f06740c93374852021-09-22 13:45:39373 days 7 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xffe4d26eb04c63fdb7ffe7dfc223a2bffc847a74b11b192a9057671683b913a093373442021-09-22 13:10:20373 days 8 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0xca4ec9e9988baa2c357d472e7c779a82763c239eb153e3ca766be1d78e9d51b693373312021-09-22 13:07:05373 days 8 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
0x6448619877f3c8a9b0a32749eed687883ffdb36f3a9fb28a992c7493a30dd96093372882021-09-22 12:56:20373 days 8 hrs ago 0x5442f014f8b0b6630b5619d615ad46a017239297 0x776dfe7ec5d74526aa65898b7d77fcfdf15ffbe60 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
NodeOperatorsRegistry

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-06
*/

// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.4.24;



// Part: GNSPS/[email protected]/BytesLib

library BytesLib {
    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes) {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add 
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(0x40, and(
              add(add(end, iszero(add(length, mload(_preBytes)))), 31),
              not(31) // Round down to the nearest 32 bytes.
            ))
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes_slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes_slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes_slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes_slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(
                            fslot,
                            0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00
                        ),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes_slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes_slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))
                
                for { 
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(bytes _bytes, uint _start, uint _length) internal  pure returns (bytes) {
        require(_bytes.length >= (_start + _length));

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes _bytes, uint _start) internal  pure returns (address) {
        require(_bytes.length >= (_start + 20));
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes _bytes, uint _start) internal  pure returns (uint8) {
        require(_bytes.length >= (_start + 1));
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes _bytes, uint _start) internal  pure returns (uint16) {
        require(_bytes.length >= (_start + 2));
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes _bytes, uint _start) internal  pure returns (uint32) {
        require(_bytes.length >= (_start + 4));
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint(bytes _bytes, uint _start) internal  pure returns (uint256) {
        require(_bytes.length >= (_start + 32));
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes _bytes, uint _start) internal  pure returns (bytes32) {
        require(_bytes.length >= (_start + 32));
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                // the next line is the loop condition:
                // while(uint(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes_slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes_slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

// Part: INodeOperatorsRegistry

/**
  * @title Node Operator registry
  *
  * Node Operator registry manages signing keys and other node operator data.
  * It's also responsible for distributing rewards to node operators.
  */
interface INodeOperatorsRegistry {
    /**
      * @notice Add node operator named `name` with reward address `rewardAddress` and staking limit `stakingLimit` validators
      * @param _name Human-readable name
      * @param _rewardAddress Ethereum 1 address which receives stETH rewards for this operator
      * @param _stakingLimit the maximum number of validators to stake for this operator
      * @return a unique key of the added operator
      */
    function addNodeOperator(string _name, address _rewardAddress, uint64 _stakingLimit) external returns (uint256 id);

    /**
      * @notice `_active ? 'Enable' : 'Disable'` the node operator #`_id`
      */
    function setNodeOperatorActive(uint256 _id, bool _active) external;

    /**
      * @notice Change human-readable name of the node operator #`_id` to `_name`
      */
    function setNodeOperatorName(uint256 _id, string _name) external;

    /**
      * @notice Change reward address of the node operator #`_id` to `_rewardAddress`
      */
    function setNodeOperatorRewardAddress(uint256 _id, address _rewardAddress) external;

    /**
      * @notice Set the maximum number of validators to stake for the node operator #`_id` to `_stakingLimit`
      */
    function setNodeOperatorStakingLimit(uint256 _id, uint64 _stakingLimit) external;

    /**
      * @notice Report `_stoppedIncrement` more stopped validators of the node operator #`_id`
      */
    function reportStoppedValidators(uint256 _id, uint64 _stoppedIncrement) external;

    /**
      * @notice Remove unused signing keys
      * @dev Function is used by the pool
      */
    function trimUnusedKeys() external;

    /**
      * @notice Returns total number of node operators
      */
    function getNodeOperatorsCount() external view returns (uint256);

    /**
      * @notice Returns number of active node operators
      */
    function getActiveNodeOperatorsCount() external view returns (uint256);

    /**
      * @notice Returns the n-th node operator
      * @param _id Node Operator id
      * @param _fullInfo If true, name will be returned as well
      */
    function getNodeOperator(uint256 _id, bool _fullInfo) external view returns (
        bool active,
        string name,
        address rewardAddress,
        uint64 stakingLimit,
        uint64 stoppedValidators,
        uint64 totalSigningKeys,
        uint64 usedSigningKeys);

    /**
      * @notice Returns the rewards distribution proportional to the effective stake for each node operator.
      * @param _totalRewardShares Total amount of reward shares to distribute.
      */
    function getRewardsDistribution(uint256 _totalRewardShares) external view returns (
        address[] memory recipients,
        uint256[] memory shares
    );

    event NodeOperatorAdded(uint256 id, string name, address rewardAddress, uint64 stakingLimit);
    event NodeOperatorActiveSet(uint256 indexed id, bool active);
    event NodeOperatorNameSet(uint256 indexed id, string name);
    event NodeOperatorRewardAddressSet(uint256 indexed id, address rewardAddress);
    event NodeOperatorStakingLimitSet(uint256 indexed id, uint64 stakingLimit);
    event NodeOperatorTotalStoppedValidatorsReported(uint256 indexed id, uint64 totalStopped);

    /**
     * @notice Selects and returns at most `_numKeys` signing keys (as well as the corresponding
     *         signatures) from the set of active keys and marks the selected keys as used.
     *         May only be called by the pool contract.
     *
     * @param _numKeys The number of keys to select. The actual number of selected keys may be less
     *        due to the lack of active keys.
     */
    function assignNextSigningKeys(uint256 _numKeys) external returns (bytes memory pubkeys, bytes memory signatures);

    /**
      * @notice Add `_quantity` validator signing keys to the keys of the node operator #`_operator_id`. Concatenated keys are: `_pubkeys`
      * @dev Along with each key the DAO has to provide a signatures for the
      *      (pubkey, withdrawal_credentials, 32000000000) message.
      *      Given that information, the contract'll be able to call
      *      deposit_contract.deposit on-chain.
      * @param _operator_id Node Operator id
      * @param _quantity Number of signing keys provided
      * @param _pubkeys Several concatenated validator signing keys
      * @param _signatures Several concatenated signatures for (pubkey, withdrawal_credentials, 32000000000) messages
      */
    function addSigningKeys(uint256 _operator_id, uint256 _quantity, bytes _pubkeys, bytes _signatures) external;

    /**
      * @notice Removes a validator signing key #`_index` from the keys of the node operator #`_operator_id`
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      */
    function removeSigningKey(uint256 _operator_id, uint256 _index) external;

    /**
      * @notice Returns total number of signing keys of the node operator #`_operator_id`
      */
    function getTotalSigningKeyCount(uint256 _operator_id) external view returns (uint256);

    /**
      * @notice Returns number of usable signing keys of the node operator #`_operator_id`
      */
    function getUnusedSigningKeyCount(uint256 _operator_id) external view returns (uint256);

    /**
      * @notice Returns n-th signing key of the node operator #`_operator_id`
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      * @return key Key
      * @return depositSignature Signature needed for a deposit_contract.deposit call
      * @return used Flag indication if the key was used in the staking
      */
    function getSigningKey(uint256 _operator_id, uint256 _index) external view returns
            (bytes key, bytes depositSignature, bool used);

    event SigningKeyAdded(uint256 indexed operatorId, bytes pubkey);
    event SigningKeyRemoved(uint256 indexed operatorId, bytes pubkey);
}

// Part: MemUtils

library MemUtils {
    /**
     * @dev Allocates a memory byte array of `_len` bytes without zeroing it out.
     */
    function unsafeAllocateBytes(uint256 _len) internal pure returns (bytes memory result) {
        assembly {
            result := mload(0x40)
            mstore(result, _len)
            mstore(0x40, add(add(result, _len), 32))
        }
    }

    /**
     * Performs a memory copy of `_len` bytes from position `_src` to position `_dst`.
     */
    function memcpy(uint256 _src, uint256 _dst, uint256 _len) internal pure {
        assembly {
            // while al least 32 bytes left, copy in 32-byte chunks
            for { } gt(_len, 31) { } {
                mstore(_dst, mload(_src))
                _src := add(_src, 32)
                _dst := add(_dst, 32)
                _len := sub(_len, 32)
            }
            if gt(_len, 0) {
                // read the next 32-byte chunk from _dst, replace the first N bytes
                // with those left in the _src, and write the transformed chunk back
                let mask := sub(shl(1, mul(8, sub(32, _len))), 1) // 2 ** (8 * (32 - _len)) - 1
                let srcMasked := and(mload(_src), not(mask))
                let dstMasked := and(mload(_dst), mask)
                mstore(_dst, or(dstMasked, srcMasked))
            }
        }
    }

    /**
     * Copies bytes from `_src` to `_dst`, starting at position `_dstStart` into `_dst`.
     */
    function copyBytes(bytes memory _src, bytes memory _dst, uint256 _dstStart) internal pure {
        require(_dstStart + _src.length <= _dst.length, "BYTES_ARRAY_OUT_OF_BOUNDS");
        uint256 srcStartPos;
        uint256 dstStartPos;
        assembly {
            srcStartPos := add(_src, 32)
            dstStartPos := add(add(_dst, 32), _dstStart)
        }
        memcpy(srcStartPos, dstStartPos, _src.length);
    }
}

// Part: aragon/[email protected]/IsContract

contract IsContract {
    /*
    * NOTE: this should NEVER be used for authentication
    * (see pitfalls: https://github.com/fergarrui/ethereum-security/tree/master/contracts/extcodesize).
    *
    * This is only intended to be used as a sanity check that an address is actually a contract,
    * RATHER THAN an address not being a contract.
    */
    function isContract(address _target) internal view returns (bool) {
        if (_target == address(0)) {
            return false;
        }

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

// Part: aragon/[email protected]/SafeMath

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {
    string private constant ERROR_ADD_OVERFLOW = "MATH_ADD_OVERFLOW";
    string private constant ERROR_SUB_UNDERFLOW = "MATH_SUB_UNDERFLOW";
    string private constant ERROR_MUL_OVERFLOW = "MATH_MUL_OVERFLOW";
    string private constant ERROR_DIV_ZERO = "MATH_DIV_ZERO";

    /**
    * @dev Multiplies two numbers, reverts on overflow.
    */
    function mul(uint256 _a, uint256 _b) internal pure returns (uint256) {
        // 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-solidity/pull/522
        if (_a == 0) {
            return 0;
        }

        uint256 c = _a * _b;
        require(c / _a == _b, ERROR_MUL_OVERFLOW);

        return c;
    }

    /**
    * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
    */
    function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
        require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0
        uint256 c = _a / _b;
        // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
        require(_b <= _a, ERROR_SUB_UNDERFLOW);
        uint256 c = _a - _b;

        return c;
    }

    /**
    * @dev Adds two numbers, reverts on overflow.
    */
    function add(uint256 _a, uint256 _b) internal pure returns (uint256) {
        uint256 c = _a + _b;
        require(c >= _a, ERROR_ADD_OVERFLOW);

        return c;
    }

    /**
    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, ERROR_DIV_ZERO);
        return a % b;
    }
}

// Part: aragon/[email protected]/SafeMath64

/**
 * @title SafeMath64
 * @dev Math operations for uint64 with safety checks that revert on error
 */
library SafeMath64 {
    string private constant ERROR_ADD_OVERFLOW = "MATH64_ADD_OVERFLOW";
    string private constant ERROR_SUB_UNDERFLOW = "MATH64_SUB_UNDERFLOW";
    string private constant ERROR_MUL_OVERFLOW = "MATH64_MUL_OVERFLOW";
    string private constant ERROR_DIV_ZERO = "MATH64_DIV_ZERO";

    /**
    * @dev Multiplies two numbers, reverts on overflow.
    */
    function mul(uint64 _a, uint64 _b) internal pure returns (uint64) {
        uint256 c = uint256(_a) * uint256(_b);
        require(c < 0x010000000000000000, ERROR_MUL_OVERFLOW); // 2**64 (less gas this way)

        return uint64(c);
    }

    /**
    * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
    */
    function div(uint64 _a, uint64 _b) internal pure returns (uint64) {
        require(_b > 0, ERROR_DIV_ZERO); // Solidity only automatically asserts when dividing by 0
        uint64 c = _a / _b;
        // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold

        return c;
    }

    /**
    * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
    */
    function sub(uint64 _a, uint64 _b) internal pure returns (uint64) {
        require(_b <= _a, ERROR_SUB_UNDERFLOW);
        uint64 c = _a - _b;

        return c;
    }

    /**
    * @dev Adds two numbers, reverts on overflow.
    */
    function add(uint64 _a, uint64 _b) internal pure returns (uint64) {
        uint64 c = _a + _b;
        require(c >= _a, ERROR_ADD_OVERFLOW);

        return c;
    }

    /**
    * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
    * reverts when dividing by zero.
    */
    function mod(uint64 a, uint64 b) internal pure returns (uint64) {
        require(b != 0, ERROR_DIV_ZERO);
        return a % b;
    }
}

// Part: aragon/[email protected]/UnstructuredStorage

library UnstructuredStorage {
    function getStorageBool(bytes32 position) internal view returns (bool data) {
        assembly { data := sload(position) }
    }

    function getStorageAddress(bytes32 position) internal view returns (address data) {
        assembly { data := sload(position) }
    }

    function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) {
        assembly { data := sload(position) }
    }

    function getStorageUint256(bytes32 position) internal view returns (uint256 data) {
        assembly { data := sload(position) }
    }

    function setStorageBool(bytes32 position, bool data) internal {
        assembly { sstore(position, data) }
    }

    function setStorageAddress(bytes32 position, address data) internal {
        assembly { sstore(position, data) }
    }

    function setStorageBytes32(bytes32 position, bytes32 data) internal {
        assembly { sstore(position, data) }
    }

    function setStorageUint256(bytes32 position, uint256 data) internal {
        assembly { sstore(position, data) }
    }
}

// File: NodeOperatorsRegistry.sol

/**
  * @title Node Operator registry implementation
  *
  * See the comment of `INodeOperatorsRegistry`.
  *
  * NOTE: the code below assumes moderate amount of node operators, e.g. up to 50.
  */
contract NodeOperatorsRegistry is INodeOperatorsRegistry, IsContract {
    using SafeMath for uint256;
    using SafeMath64 for uint64;
    using UnstructuredStorage for bytes32;

    uint256 constant public PUBKEY_LENGTH = 48;
    uint256 constant public SIGNATURE_LENGTH = 96;

    uint256 internal constant UINT64_MAX = uint256(uint64(-1));

    bytes32 internal constant SIGNING_KEYS_MAPPING_NAME = keccak256("lido.NodeOperatorsRegistry.signingKeysMappingName");


    /// @dev Node Operator parameters and internal state
    struct NodeOperator {
        bool active;    // a flag indicating if the operator can participate in further staking and reward distribution
        address rewardAddress;  // Ethereum 1 address which receives steth rewards for this operator
        string name;    // human-readable name
        uint64 stakingLimit;    // the maximum number of validators to stake for this operator
        uint64 stoppedValidators;   // number of signing keys which stopped validation (e.g. were slashed)

        uint64 totalSigningKeys;    // total amount of signing keys of this operator
        uint64 usedSigningKeys;     // number of signing keys of this operator which were used in deposits to the Ethereum 2
    }

    /// @dev Memory cache entry used in the assignNextKeys function
    struct DepositLookupCacheEntry {
        // Makes no sense to pack types since reading memory is as fast as any op
        uint256 id;
        uint256 stakingLimit;
        uint256 stoppedValidators;
        uint256 totalSigningKeys;
        uint256 usedSigningKeys;
        uint256 initialUsedSigningKeys;
    }

    /// @dev Mapping of all node operators. Mapping is used to be able to extend the struct.
    mapping(uint256 => NodeOperator) internal operators;

    // @dev Total number of operators
    bytes32 internal constant TOTAL_OPERATORS_COUNT_POSITION = keccak256("lido.NodeOperatorsRegistry.totalOperatorsCount");

    // @dev Cached number of active operators
    bytes32 internal constant ACTIVE_OPERATORS_COUNT_POSITION = keccak256("lido.NodeOperatorsRegistry.activeOperatorsCount");

    /// @dev link to the Lido contract
    bytes32 internal constant LIDO_POSITION = keccak256("lido.NodeOperatorsRegistry.lido");


    modifier onlyLido() {
        require(msg.sender == LIDO_POSITION.getStorageAddress(), "APP_AUTH_FAILED");
        _;
    }

    modifier validAddress(address _a) {
        require(_a != address(0), "EMPTY_ADDRESS");
        _;
    }

    modifier operatorExists(uint256 _id) {
        require(_id < getNodeOperatorsCount(), "NODE_OPERATOR_NOT_FOUND");
        _;
    }

    constructor() public {
        TOTAL_OPERATORS_COUNT_POSITION.setStorageUint256(0);
        ACTIVE_OPERATORS_COUNT_POSITION.setStorageUint256(0);
    }

    function setLido(address _lido) external {
        LIDO_POSITION.setStorageAddress(_lido);
    }

    /**
      * @notice Add node operator named `_name` with reward address `_rewardAddress` and staking limit `_stakingLimit`
      * @param _name Human-readable name
      * @param _rewardAddress Ethereum 1 address which receives stETH rewards for this operator
      * @param _stakingLimit the maximum number of validators to stake for this operator
      * @return a unique key of the added operator
      */
    function addNodeOperator(string _name, address _rewardAddress, uint64 _stakingLimit) external
        validAddress(_rewardAddress)
        returns (uint256 id)
    {
        id = getNodeOperatorsCount();
        TOTAL_OPERATORS_COUNT_POSITION.setStorageUint256(id.add(1));

        NodeOperator storage operator = operators[id];

        uint256 activeOperatorsCount = getActiveNodeOperatorsCount();
        ACTIVE_OPERATORS_COUNT_POSITION.setStorageUint256(activeOperatorsCount.add(1));

        operator.active = true;
        operator.name = _name;
        operator.rewardAddress = _rewardAddress;
        operator.stakingLimit = _stakingLimit;

        emit NodeOperatorAdded(id, _name, _rewardAddress, _stakingLimit);

        return id;
    }

    /**
      * @notice `_active ? 'Enable' : 'Disable'` the node operator #`_id`
      */
    function setNodeOperatorActive(uint256 _id, bool _active) external
        operatorExists(_id)
    {
        if (operators[_id].active != _active) {
            uint256 activeOperatorsCount = getActiveNodeOperatorsCount();
            if (_active)
                ACTIVE_OPERATORS_COUNT_POSITION.setStorageUint256(activeOperatorsCount.add(1));
            else
                ACTIVE_OPERATORS_COUNT_POSITION.setStorageUint256(activeOperatorsCount.sub(1));
        }

        operators[_id].active = _active;

        emit NodeOperatorActiveSet(_id, _active);
    }

    /**
      * @notice Change human-readable name of the node operator #`_id` to `_name`
      */
    function setNodeOperatorName(uint256 _id, string _name) external
        operatorExists(_id)
    {
        operators[_id].name = _name;
        emit NodeOperatorNameSet(_id, _name);
    }

    /**
      * @notice Change reward address of the node operator #`_id` to `_rewardAddress`
      */
    function setNodeOperatorRewardAddress(uint256 _id, address _rewardAddress) external
        operatorExists(_id)
        validAddress(_rewardAddress)
    {
        operators[_id].rewardAddress = _rewardAddress;
        emit NodeOperatorRewardAddressSet(_id, _rewardAddress);
    }

    /**
      * @notice Set the maximum number of validators to stake for the node operator #`_id` to `_stakingLimit`
      */
    function setNodeOperatorStakingLimit(uint256 _id, uint64 _stakingLimit) external
        operatorExists(_id)
    {
        operators[_id].stakingLimit = _stakingLimit;
        emit NodeOperatorStakingLimitSet(_id, _stakingLimit);
    }

    /**
      * @notice Report `_stoppedIncrement` more stopped validators of the node operator #`_id`
      */
    function reportStoppedValidators(uint256 _id, uint64 _stoppedIncrement) external
        operatorExists(_id)
    {
        require(0 != _stoppedIncrement, "EMPTY_VALUE");
        operators[_id].stoppedValidators = operators[_id].stoppedValidators.add(_stoppedIncrement);
        require(operators[_id].stoppedValidators <= operators[_id].usedSigningKeys, "STOPPED_MORE_THAN_LAUNCHED");

        emit NodeOperatorTotalStoppedValidatorsReported(_id, operators[_id].stoppedValidators);
    }

    /**
      * @notice Remove unused signing keys
      * @dev Function is used by the Lido contract
      */
    function trimUnusedKeys() external onlyLido {
        uint256 length = getNodeOperatorsCount();
        for (uint256 operatorId = 0; operatorId < length; ++operatorId) {
            if (operators[operatorId].totalSigningKeys != operators[operatorId].usedSigningKeys)  // write only if update is needed
                operators[operatorId].totalSigningKeys = operators[operatorId].usedSigningKeys;  // discard unused keys
        }
    }

    /**
      * @notice Add `_quantity` validator signing keys of operator #`_id` to the set of usable keys. Concatenated keys are: `_pubkeys`. Can be done by the DAO in question by using the designated rewards address.
      * @dev Along with each key the DAO has to provide a signatures for the
      *      (pubkey, withdrawal_credentials, 32000000000) message.
      *      Given that information, the contract'll be able to call
      *      deposit_contract.deposit on-chain.
      * @param _operator_id Node Operator id
      * @param _quantity Number of signing keys provided
      * @param _pubkeys Several concatenated validator signing keys
      * @param _signatures Several concatenated signatures for (pubkey, withdrawal_credentials, 32000000000) messages
      */
    function addSigningKeys(uint256 _operator_id, uint256 _quantity, bytes _pubkeys, bytes _signatures) external {
        _addSigningKeys(_operator_id, _quantity, _pubkeys, _signatures);
    }

    /**
      * @notice Add `_quantity` validator signing keys of operator #`_id` to the set of usable keys. Concatenated keys are: `_pubkeys`. Can be done by node operator in question by using the designated rewards address.
      * @dev Along with each key the DAO has to provide a signatures for the
      *      (pubkey, withdrawal_credentials, 32000000000) message.
      *      Given that information, the contract'll be able to call
      *      deposit_contract.deposit on-chain.
      * @param _operator_id Node Operator id
      * @param _quantity Number of signing keys provided
      * @param _pubkeys Several concatenated validator signing keys
      * @param _signatures Several concatenated signatures for (pubkey, withdrawal_credentials, 32000000000) messages
      */
    function addSigningKeysOperatorBH(
        uint256 _operator_id,
        uint256 _quantity,
        bytes _pubkeys,
        bytes _signatures
    )
        external
    {
        require(msg.sender == operators[_operator_id].rewardAddress, "APP_AUTH_FAILED");
        _addSigningKeys(_operator_id, _quantity, _pubkeys, _signatures);
    }

    /**
      * @notice Removes a validator signing key #`_index` of operator #`_id` from the set of usable keys. Executed on behalf of DAO.
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      */
    function removeSigningKey(uint256 _operator_id, uint256 _index)
        external
    {
        _removeSigningKey(_operator_id, _index);
    }

    /**
      * @notice Removes a validator signing key #`_index` of operator #`_id` from the set of usable keys. Executed on behalf of Node Operator.
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      */
    function removeSigningKeyOperatorBH(uint256 _operator_id, uint256 _index) external {
        require(msg.sender == operators[_operator_id].rewardAddress, "APP_AUTH_FAILED");
        _removeSigningKey(_operator_id, _index);
    }

    /**
     * @notice Selects and returns at most `_numKeys` signing keys (as well as the corresponding
     *         signatures) from the set of active keys and marks the selected keys as used.
     *         May only be called by the Lido contract.
     *
     * @param _numKeys The number of keys to select. The actual number of selected keys may be less
     *        due to the lack of active keys.
     */
    function assignNextSigningKeys(uint256 _numKeys) external onlyLido returns (bytes memory pubkeys, bytes memory signatures) {
        // Memory is very cheap, although you don't want to grow it too much
        DepositLookupCacheEntry[] memory cache = _loadOperatorCache();
        if (0 == cache.length)
            return (new bytes(0), new bytes(0));

        uint256 numAssignedKeys = 0;
        DepositLookupCacheEntry memory entry;

        while (numAssignedKeys < _numKeys) {
            // Finding the best suitable operator
            uint256 bestOperatorIdx = cache.length;   // 'not found' flag
            uint256 smallestStake;
            // The loop is ligthweight comparing to an ether transfer and .deposit invocation
            for (uint256 idx = 0; idx < cache.length; ++idx) {
                entry = cache[idx];

                assert(entry.usedSigningKeys <= entry.totalSigningKeys);
                if (entry.usedSigningKeys == entry.totalSigningKeys)
                    continue;

                uint256 stake = entry.usedSigningKeys.sub(entry.stoppedValidators);
                if (stake + 1 > entry.stakingLimit)
                    continue;

                if (bestOperatorIdx == cache.length || stake < smallestStake) {
                    bestOperatorIdx = idx;
                    smallestStake = stake;
                }
            }

            if (bestOperatorIdx == cache.length)  // not found
                break;

            entry = cache[bestOperatorIdx];
            assert(entry.usedSigningKeys < UINT64_MAX);

            ++entry.usedSigningKeys;
            ++numAssignedKeys;
        }

        if (numAssignedKeys == 0) {
            return (new bytes(0), new bytes(0));
        }

        if (numAssignedKeys > 1) {
            // we can allocate without zeroing out since we're going to rewrite the whole array
            pubkeys = MemUtils.unsafeAllocateBytes(numAssignedKeys * PUBKEY_LENGTH);
            signatures = MemUtils.unsafeAllocateBytes(numAssignedKeys * SIGNATURE_LENGTH);
        }

        uint256 numLoadedKeys = 0;

        for (uint256 i = 0; i < cache.length; ++i) {
            entry = cache[i];

            if (entry.usedSigningKeys == entry.initialUsedSigningKeys) {
                continue;
            }

            operators[entry.id].usedSigningKeys = uint64(entry.usedSigningKeys);

            for (uint256 keyIndex = entry.initialUsedSigningKeys; keyIndex < entry.usedSigningKeys; ++keyIndex) {
                (bytes memory pubkey, bytes memory signature) = _loadSigningKey(entry.id, keyIndex);
                if (numAssignedKeys == 1) {
                    return (pubkey, signature);
                } else {
                    MemUtils.copyBytes(pubkey, pubkeys, numLoadedKeys * PUBKEY_LENGTH);
                    MemUtils.copyBytes(signature, signatures, numLoadedKeys * SIGNATURE_LENGTH);
                    ++numLoadedKeys;
                }
            }

            if (numLoadedKeys == numAssignedKeys) {
                break;
            }
        }

        assert(numLoadedKeys == numAssignedKeys);
        return (pubkeys, signatures);
    }

    /**
      * @notice Returns the rewards distribution proportional to the effective stake for each node operator.
      * @param _totalRewardShares Total amount of reward shares to distribute.
      */
    function getRewardsDistribution(uint256 _totalRewardShares) external view
        returns (
            address[] memory recipients,
            uint256[] memory shares
        )
    {
        uint256 nodeOperatorCount = getNodeOperatorsCount();

        uint256 activeCount = getActiveNodeOperatorsCount();
        recipients = new address[](activeCount);
        shares = new uint256[](activeCount);
        uint256 idx = 0;

        uint256 effectiveStakeTotal = 0;
        for (uint256 operatorId = 0; operatorId < nodeOperatorCount; ++operatorId) {
            NodeOperator storage operator = operators[operatorId];
            if (!operator.active)
                continue;

            uint256 effectiveStake = operator.usedSigningKeys.sub(operator.stoppedValidators);
            effectiveStakeTotal = effectiveStakeTotal.add(effectiveStake);

            recipients[idx] = operator.rewardAddress;
            shares[idx] = effectiveStake;

            ++idx;
        }

        if (effectiveStakeTotal == 0)
            return (recipients, shares);

        uint256 perValidatorReward = _totalRewardShares.div(effectiveStakeTotal);

        for (idx = 0; idx < activeCount; ++idx) {
            shares[idx] = shares[idx].mul(perValidatorReward);
        }

        return (recipients, shares);
    }

    /**
      * @notice Returns number of active node operators
      */
    function getActiveNodeOperatorsCount() public view returns (uint256) {
        return ACTIVE_OPERATORS_COUNT_POSITION.getStorageUint256();
    }

    /**
      * @notice Returns the n-th node operator
      * @param _id Node Operator id
      * @param _fullInfo If true, name will be returned as well
      */
    function getNodeOperator(uint256 _id, bool _fullInfo) external view
        operatorExists(_id)
        returns
        (
            bool active,
            string name,
            address rewardAddress,
            uint64 stakingLimit,
            uint64 stoppedValidators,
            uint64 totalSigningKeys,
            uint64 usedSigningKeys
        )
    {
        NodeOperator storage operator = operators[_id];

        active = operator.active;
        name = _fullInfo ? operator.name : "";    // reading name is 2+ SLOADs
        rewardAddress = operator.rewardAddress;
        stakingLimit = operator.stakingLimit;
        stoppedValidators = operator.stoppedValidators;
        totalSigningKeys = operator.totalSigningKeys;
        usedSigningKeys = operator.usedSigningKeys;
    }

    /**
      * @notice Returns total number of signing keys of the node operator #`_operator_id`
      */
    function getTotalSigningKeyCount(uint256 _operator_id) external view operatorExists(_operator_id) returns (uint256) {
        return operators[_operator_id].totalSigningKeys;
    }

    /**
      * @notice Returns number of usable signing keys of the node operator #`_operator_id`
      */
    function getUnusedSigningKeyCount(uint256 _operator_id) external view operatorExists(_operator_id) returns (uint256) {
        return operators[_operator_id].totalSigningKeys.sub(operators[_operator_id].usedSigningKeys);
    }

    /**
      * @notice Returns n-th signing key of the node operator #`_operator_id`
      * @param _operator_id Node Operator id
      * @param _index Index of the key, starting with 0
      * @return key Key
      * @return depositSignature Signature needed for a deposit_contract.deposit call
      * @return used Flag indication if the key was used in the staking
      */
    function getSigningKey(uint256 _operator_id, uint256 _index) external view
        operatorExists(_operator_id)
        returns (bytes key, bytes depositSignature, bool used)
    {
        require(_index < operators[_operator_id].totalSigningKeys, "KEY_NOT_FOUND");

        (bytes memory key_, bytes memory signature) = _loadSigningKey(_operator_id, _index);

        return (key_, signature, _index < operators[_operator_id].usedSigningKeys);
    }

    /**
      * @notice Returns total number of node operators
      */
    function getNodeOperatorsCount() public view returns (uint256) {
        return TOTAL_OPERATORS_COUNT_POSITION.getStorageUint256();
    }

    function _isEmptySigningKey(bytes memory _key) internal pure returns (bool) {
        assert(_key.length == PUBKEY_LENGTH);
        // algorithm applicability constraint
        assert(PUBKEY_LENGTH >= 32 && PUBKEY_LENGTH <= 64);

        uint256 k1;
        uint256 k2;
        assembly {
            k1 := mload(add(_key, 0x20))
            k2 := mload(add(_key, 0x40))
        }

        return 0 == k1 && 0 == (k2 >> ((2 * 32 - PUBKEY_LENGTH) * 8));
    }

    function to64(uint256 v) internal pure returns (uint64) {
        assert(v <= uint256(uint64(-1)));
        return uint64(v);
    }

    function _signingKeyOffset(uint256 _operator_id, uint256 _keyIndex) internal pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(SIGNING_KEYS_MAPPING_NAME, _operator_id, _keyIndex)));
    }

    function _storeSigningKey(uint256 _operator_id, uint256 _keyIndex, bytes memory _key, bytes memory _signature) internal {
        assert(_key.length == PUBKEY_LENGTH);
        assert(_signature.length == SIGNATURE_LENGTH);
        // algorithm applicability constraints
        assert(PUBKEY_LENGTH >= 32 && PUBKEY_LENGTH <= 64);
        assert(0 == SIGNATURE_LENGTH % 32);

        // key
        uint256 offset = _signingKeyOffset(_operator_id, _keyIndex);
        uint256 keyExcessBits = (2 * 32 - PUBKEY_LENGTH) * 8;
        assembly {
            sstore(offset, mload(add(_key, 0x20)))
            sstore(add(offset, 1), shl(keyExcessBits, shr(keyExcessBits, mload(add(_key, 0x40)))))
        }
        offset += 2;

        // signature
        for (uint256 i = 0; i < SIGNATURE_LENGTH; i += 32) {
            assembly {
                sstore(offset, mload(add(_signature, add(0x20, i))))
            }
            offset++;
        }
    }

    function _addSigningKeys(uint256 _operator_id, uint256 _quantity, bytes _pubkeys, bytes _signatures) internal
        operatorExists(_operator_id)
    {
        require(_quantity != 0, "NO_KEYS");
        require(_pubkeys.length == _quantity.mul(PUBKEY_LENGTH), "INVALID_LENGTH");
        require(_signatures.length == _quantity.mul(SIGNATURE_LENGTH), "INVALID_LENGTH");

        for (uint256 i = 0; i < _quantity; ++i) {
            bytes memory key = BytesLib.slice(_pubkeys, i * PUBKEY_LENGTH, PUBKEY_LENGTH);
            require(!_isEmptySigningKey(key), "EMPTY_KEY");
            bytes memory sig = BytesLib.slice(_signatures, i * SIGNATURE_LENGTH, SIGNATURE_LENGTH);

            _storeSigningKey(_operator_id, operators[_operator_id].totalSigningKeys + i, key, sig);
            emit SigningKeyAdded(_operator_id, key);
        }

        operators[_operator_id].totalSigningKeys = operators[_operator_id].totalSigningKeys.add(to64(_quantity));
    }

    function _removeSigningKey(uint256 _operator_id, uint256 _index) internal
        operatorExists(_operator_id)
    {
        require(_index < operators[_operator_id].totalSigningKeys, "KEY_NOT_FOUND");
        require(_index >= operators[_operator_id].usedSigningKeys, "KEY_WAS_USED");

        (bytes memory removedKey, ) = _loadSigningKey(_operator_id, _index);

        uint256 lastIndex = operators[_operator_id].totalSigningKeys.sub(1);
        if (_index < lastIndex) {
            (bytes memory key, bytes memory signature) = _loadSigningKey(_operator_id, lastIndex);
            _storeSigningKey(_operator_id, _index, key, signature);
        }

        _deleteSigningKey(_operator_id, lastIndex);
        operators[_operator_id].totalSigningKeys = operators[_operator_id].totalSigningKeys.sub(1);

        emit SigningKeyRemoved(_operator_id, removedKey);
    }

    function _deleteSigningKey(uint256 _operator_id, uint256 _keyIndex) internal {
        uint256 offset = _signingKeyOffset(_operator_id, _keyIndex);
        for (uint256 i = 0; i < (PUBKEY_LENGTH + SIGNATURE_LENGTH) / 32 + 1; ++i) {
            assembly {
                sstore(add(offset, i), 0)
            }
        }
    }

    function _loadSigningKey(uint256 _operator_id, uint256 _keyIndex) internal view returns (bytes memory key, bytes memory signature) {
        // algorithm applicability constraints
        assert(PUBKEY_LENGTH >= 32 && PUBKEY_LENGTH <= 64);
        assert(0 == SIGNATURE_LENGTH % 32);

        uint256 offset = _signingKeyOffset(_operator_id, _keyIndex);

        // key
        bytes memory tmpKey = new bytes(64);
        assembly {
            mstore(add(tmpKey, 0x20), sload(offset))
            mstore(add(tmpKey, 0x40), sload(add(offset, 1)))
        }
        offset += 2;
        key = BytesLib.slice(tmpKey, 0, PUBKEY_LENGTH);

        // signature
        signature = new bytes(SIGNATURE_LENGTH);
        for (uint256 i = 0; i < SIGNATURE_LENGTH; i += 32) {
            assembly {
                mstore(add(signature, add(0x20, i)), sload(offset))
            }
            offset++;
        }

        return (key, signature);
    }

    function _loadOperatorCache() internal view returns (DepositLookupCacheEntry[] memory cache) {
        cache = new DepositLookupCacheEntry[](getActiveNodeOperatorsCount());
        if (0 == cache.length)
            return cache;

        uint256 totalOperators = getNodeOperatorsCount();
        uint256 idx = 0;
        for (uint256 operatorId = 0; operatorId < totalOperators; ++operatorId) {
            NodeOperator storage operator = operators[operatorId];

            if (!operator.active)
                continue;

            DepositLookupCacheEntry memory entry = cache[idx++];
            entry.id = operatorId;
            entry.stakingLimit = operator.stakingLimit;
            entry.stoppedValidators = operator.stoppedValidators;
            entry.totalSigningKeys = operator.totalSigningKeys;
            entry.usedSigningKeys = operator.usedSigningKeys;
            entry.initialUsedSigningKeys = entry.usedSigningKeys;
        }
        require(idx == cache.length, "INCOSISTENT_ACTIVE_COUNT");

        return cache;
    }
}

Contract ABI

[{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_rewardAddress","type":"address"},{"name":"_stakingLimit","type":"uint64"}],"name":"addNodeOperator","outputs":[{"name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator_id","type":"uint256"},{"name":"_quantity","type":"uint256"},{"name":"_pubkeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_numKeys","type":"uint256"}],"name":"assignNextSigningKeys","outputs":[{"name":"pubkeys","type":"bytes"},{"name":"signatures","type":"bytes"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"SIGNATURE_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_name","type":"string"}],"name":"setNodeOperatorName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_totalRewardShares","type":"uint256"}],"name":"getRewardsDistribution","outputs":[{"name":"recipients","type":"address[]"},{"name":"shares","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_active","type":"bool"}],"name":"setNodeOperatorActive","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator_id","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_lido","type":"address"}],"name":"setLido","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator_id","type":"uint256"},{"name":"_quantity","type":"uint256"},{"name":"_pubkeys","type":"bytes"},{"name":"_signatures","type":"bytes"}],"name":"addSigningKeysOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getActiveNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_operator_id","type":"uint256"}],"name":"getUnusedSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_rewardAddress","type":"address"}],"name":"setNodeOperatorRewardAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"},{"name":"_fullInfo","type":"bool"}],"name":"getNodeOperator","outputs":[{"name":"active","type":"bool"},{"name":"name","type":"string"},{"name":"rewardAddress","type":"address"},{"name":"stakingLimit","type":"uint64"},{"name":"stoppedValidators","type":"uint64"},{"name":"totalSigningKeys","type":"uint64"},{"name":"usedSigningKeys","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"PUBKEY_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNodeOperatorsCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_stakingLimit","type":"uint64"}],"name":"setNodeOperatorStakingLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_operator_id","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"getSigningKey","outputs":[{"name":"key","type":"bytes"},{"name":"depositSignature","type":"bytes"},{"name":"used","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_stoppedIncrement","type":"uint64"}],"name":"reportStoppedValidators","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_operator_id","type":"uint256"}],"name":"getTotalSigningKeyCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_operator_id","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"removeSigningKeyOperatorBH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"trimUnusedKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"id","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"rewardAddress","type":"address"},{"indexed":false,"name":"stakingLimit","type":"uint64"}],"name":"NodeOperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"NodeOperatorActiveSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"name","type":"string"}],"name":"NodeOperatorNameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"rewardAddress","type":"address"}],"name":"NodeOperatorRewardAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"stakingLimit","type":"uint64"}],"name":"NodeOperatorStakingLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"totalStopped","type":"uint64"}],"name":"NodeOperatorTotalStoppedValidatorsReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"operatorId","type":"uint256"},{"indexed":false,"name":"pubkey","type":"bytes"}],"name":"SigningKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"operatorId","type":"uint256"},{"indexed":false,"name":"pubkey","type":"bytes"}],"name":"SigningKeyRemoved","type":"event"}]

60806040523480156200001157600080fd5b50604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e746f74616c81527f4f70657261746f7273436f756e740000000000000000000000000000000000006020820152905190819003602e0190206200008590600064010000000062001c18620000fe82021704565b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e616374697681527f654f70657261746f7273436f756e7400000000000000000000000000000000006020820152905190819003602f019020620000f890600064010000000062001c18620000fe82021704565b62000102565b9055565b612bf980620001126000396000f3006080604052600436106101275763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166309573fd4811461012c578063096b7b351461017957806341bc716f146101af578063540bc5ea146102a55780635e57d742146102ba57806362dcfda1146102de578063687ca3371461038f5780636ef355f1146103ac5780637d774e31146103c7578063805911ae146103e85780638469cbd31461041c5780638ca7c05214610431578063973e9328146104495780639a56983c1461046d578063a4d55d1d14610549578063a70c70e41461055e578063ae962acf14610573578063b449402a14610598578063be726da21461069c578063db9887ea146106c1578063ed5cfa41146106d9578063f778021e146106f4575b600080fd5b34801561013857600080fd5b506101676024600480358281019291013590600160a060020a0390351667ffffffffffffffff60443516610709565b60408051918252519081900360200190f35b34801561018557600080fd5b506101ad60048035906024803591604435808301929082013591606435918201910135610966565b005b3480156101bb57600080fd5b506101c76004356109d7565b604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156102085781810151838201526020016101f0565b50505050905090810190601f1680156102355780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b3480156102b157600080fd5b50610167610d38565b3480156102c657600080fd5b506101ad600480359060248035908101910135610d3d565b3480156102ea57600080fd5b506102f6600435610dfe565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561033a578181015183820152602001610322565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015610379578181015183820152602001610361565b5050505090500194505050505060405180910390f35b34801561039b57600080fd5b506101ad6004356024351515610fe3565b3480156103b857600080fd5b506101ad6004356024356110e2565b3480156103d357600080fd5b506101ad600160a060020a03600435166110f0565b3480156103f457600080fd5b506101ad60048035906024803591604435808301929082013591606435918201910135611135565b34801561042857600080fd5b50610167611196565b34801561043d57600080fd5b50610167600435611200565b34801561045557600080fd5b506101ad600435600160a060020a0360243516611296565b34801561047957600080fd5b5061048a60043560243515156113bd565b604080518815158152600160a060020a0387169181019190915267ffffffffffffffff8086166060830152848116608083015283811660a0830152821660c082015260e0602080830182815289519284019290925288516101008401918a019080838360005b838110156105085781810151838201526020016104f0565b50505050905090810190601f1680156105355780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34801561055557600080fd5b5061016761152b565b34801561056a57600080fd5b50610167611530565b34801561057f57600080fd5b506101ad60043567ffffffffffffffff60243516611594565b3480156105a457600080fd5b506105b3600435602435611649565b60405180806020018060200184151515158152602001838103835286818151815260200191508051906020019080838360005b838110156105fe5781810151838201526020016105e6565b50505050905090810190601f16801561062b5780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b8381101561065e578181015183820152602001610646565b50505050905090810190601f16801561068b5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156106a857600080fd5b506101ad60043567ffffffffffffffff60243516611755565b3480156106cd57600080fd5b50610167600435611940565b3480156106e557600080fd5b506101ad6004356024356119b7565b34801561070057600080fd5b506101ad611a18565b6000808084600160a060020a038116151561076e576040805160e560020a62461bcd02815260206004820152600d60248201527f454d5054595f4144445245535300000000000000000000000000000000000000604482015290519081900360640190fd5b610776611530565b93506107f061078c85600163ffffffff611b4216565b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e746f74616c81527f4f70657261746f7273436f756e740000000000000000000000000000000000006020820152905190819003602e0190209063ffffffff611c1816565b60008481526020819052604090209250610808611196565b915061088261081e83600163ffffffff611b4216565b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e616374697681527f654f70657261746f7273436f756e7400000000000000000000000000000000006020820152905190819003602f0190209063ffffffff611c1816565b825460ff19166001908117845561089c9084018989612ac2565b50825474ffffffffffffffffffffffffffffffffffffffff001916610100600160a060020a03881690810291909117845560028401805467ffffffffffffffff191667ffffffffffffffff8816908117909155604080518781529081019290925260608201526080602082018181529082018990527fc52ec0ad7872dae440d886040390c13677df7bf3cca136d8d81e5e5e7dd62ff19186918b918b918b918b9160a0820186868082843760405192018290039850909650505050505050a1505050949350505050565b6109cf868686868080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a815294508a9350899250829150840183828082843750611c1c945050505050565b505050505050565b606080606060006109e6612b3c565b6000806000806000806000606080610a3660405180807f6c69646f2e4e6f64654f70657261746f727352656769737472792e6c69646f00815250601f019050604051809103902060001916611f83565b600160a060020a03163314610a83576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020612b8e833981519152604482015290519081900360640190fd5b610a8b611f87565b9b508b5160001415610ac35760408051600080825260208201909252905b50604080516000815260208101909152909e509c50610d27565b60009a505b8e8b1015610bcf578b519850600096505b8b51871015610b79578b87815181101515610af057fe5b90602001906020020151995089606001518a6080015111151515610b1057fe5b89606001518a608001511415610b2557610b6e565b60408a015160808b0151610b3e9163ffffffff61210216565b95508960200151866001011115610b5457610b6e565b8b51891480610b6257508786105b15610b6e578698508597505b866001019650610ad9565b8b51891415610b8757610bcf565b8b89815181101515610b9557fe5b602090810290910101516080810151909a5067ffffffffffffffff11610bb757fe5b60808a01805160019081019091529a909a0199610ac8565b8a1515610bec576040805160008082526020820190925290610aa9565b60018b1115610c1257610c0160308c02612196565b9d50610c0f60608c02612196565b9c505b60009450600093505b8b51841015610d1e578b84815181101515610c3257fe5b9060200190602002015199508960a001518a608001511415610c5357610d13565b60808a01518a516000908152602081905260409020600201805467ffffffffffffffff90921660c060020a0277ffffffffffffffffffffffffffffffffffffffffffffffff90921691909117905560a08a015192505b8960800151831015610d06578951610cc190846121a8565b915091508a60011415610cd95781819d509d50610d27565b610ce7828f60308802612252565b610cf5818e60608802612252565b846001019450826001019250610ca9565b8a851415610d1357610d1e565b836001019350610c1b565b848b14610d2757fe5b505050505050505050505050915091565b606081565b82610d46611530565b8110610d8a576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b6000848152602081905260409020610da6906001018484612ac2565b50837fcb16868f4831cc58a28d413f658752a2958bd1f50e94ed6391716b936c48093b84846040518080602001828103825284848281815260200192508082843760405192018290039550909350505050a250505050565b606080600080600080600080600080610e15611530565b9750610e1f611196565b965086604051908082528060200260200182016040528015610e4b578160200160208202803883390190505b50995086604051908082528060200260200182016040528015610e78578160200160208202803883390190505b5098506000955060009450600093505b87841015610f60576000848152602081905260409020805490935060ff161515610eb157610f55565b6002830154610edf9067ffffffffffffffff60c060020a8204811691680100000000000000009004166122d4565b67ffffffffffffffff169150610efb858363ffffffff611b4216565b83548b519196506101009004600160a060020a0316908b9088908110610f1d57fe5b600160a060020a03909216602092830290910190910152885182908a9088908110610f4457fe5b602090810290910101526001909501945b836001019350610e88565b841515610f6c57610fd6565b610f7c8b8663ffffffff61236d16565b9050600095505b86861015610fd657610fb3818a88815181101515610f9d57fe5b602090810290910101519063ffffffff61240d16565b8987815181101515610fc157fe5b60209081029091010152600190950194610f83565b5050505050505050915091565b600082610fee611530565b8110611032576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b60008481526020819052604090205460ff1615158315151461108b57611056611196565b915082156110775761107261081e83600163ffffffff611b4216565b61108b565b61108b61081e83600163ffffffff61210216565b60008481526020818152604091829020805460ff19168615159081179091558251908152915186927fecdf08e8a6c4493efb460f6abc7d14532074fa339c3a6410623a1d3ee0fb2cac92908290030190a250505050565b6110ec82826124b8565b5050565b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e6c69646f008152905190819003601f019020611132908263ffffffff611c1816565b50565b6000868152602081905260409020546101009004600160a060020a03163314610966576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020612b8e833981519152604482015290519081900360640190fd5b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e616374697681527f654f70657261746f7273436f756e7400000000000000000000000000000000006020820152905190819003602f0190206000906111fa90611f83565b90505b90565b60008161120b611530565b811061124f576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b6000838152602081905260409020600201546112859067ffffffffffffffff608060020a820481169160c060020a9004166122d4565b67ffffffffffffffff169392505050565b8161129f611530565b81106112e3576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b81600160a060020a0381161515611344576040805160e560020a62461bcd02815260206004820152600d60248201527f454d5054595f4144445245535300000000000000000000000000000000000000604482015290519081900360640190fd5b60008481526020818152604091829020805474ffffffffffffffffffffffffffffffffffffffff001916610100600160a060020a038816908102919091179091558251908152915186927f9a52205165d510fc1e428886d52108725dc01ed544da1702dc7bd3fdb3f243b292908290030190a250505050565b60006060600080600080600080896113d3611530565b8110611417576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b60008b8152602081905260409020805460ff169950915089611447576040805160208101909152600081526114d4565b60018281018054604080516020600295841615610100026000190190931694909404601f8101839004830285018301909152808452908301828280156114ce5780601f106114a3576101008083540402835291602001916114ce565b820191906000526020600020905b8154815290600101906020018083116114b157829003601f168201915b50505050505b8254600290930154999c909b50610100909204600160a060020a031699505067ffffffffffffffff8089169868010000000000000000810482169850608060020a81048216975060c060020a900416945092505050565b603081565b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e746f74616c81527f4f70657261746f7273436f756e740000000000000000000000000000000000006020820152905190819003602e0190206000906111fa90611f83565b8161159d611530565b81106115e1576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b60008381526020818152604091829020600201805467ffffffffffffffff191667ffffffffffffffff86169081179091558251908152915185927f59d11713a8801e3ba782d59e757fbcef75ca2ecabce8ccd06a0827941230b9f292908290030190a2505050565b60608060006060808661165a611530565b811061169e576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b600088815260208190526040902060020154608060020a900467ffffffffffffffff168710611717576040805160e560020a62461bcd02815260206004820152600d60248201527f4b45595f4e4f545f464f554e4400000000000000000000000000000000000000604482015290519081900360640190fd5b61172188886121a8565b6000998a5260208a9052604090992060020154909960c060020a90910467ffffffffffffffff169097109695505050505050565b8161175e611530565b81106117a2576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b67ffffffffffffffff82161515611803576040805160e560020a62461bcd02815260206004820152600b60248201527f454d5054595f56414c5545000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000838152602081905260409020600201546118359068010000000000000000900467ffffffffffffffff168361277f565b600084815260208190526040902060020180546fffffffffffffffff000000000000000019166801000000000000000067ffffffffffffffff9384168102919091179182905560c060020a82048316910490911611156118df576040805160e560020a62461bcd02815260206004820152601a60248201527f53544f505045445f4d4f52455f5448414e5f4c41554e43484544000000000000604482015290519081900360640190fd5b600083815260208181526040918290206002015482516801000000000000000090910467ffffffffffffffff168152915185927fe6452c223b953d8ab5cb26c014095615322891268537911ba6fe1c939689703d92908290030190a2505050565b60008161194b611530565b811061198f576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b5050600090815260208190526040902060020154608060020a900467ffffffffffffffff1690565b6000828152602081905260409020546101009004600160a060020a031633146110e2576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020612b8e833981519152604482015290519081900360640190fd5b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e6c69646f008152905190819003601f0190206000908190611a5890611f83565b600160a060020a03163314611aa5576040805160e560020a62461bcd02815260206004820152600f6024820152600080516020612b8e833981519152604482015290519081900360640190fd5b611aad611530565b9150600090505b818110156110ec57600081815260208190526040902060020154608060020a810467ffffffffffffffff90811660c060020a9092041614611b3a5760008181526020819052604090206002018054608060020a67ffffffffffffffff60c060020a8304160277ffffffffffffffff00000000000000000000000000000000199091161790555b600101611ab4565b60408051808201909152601181527f4d4154485f4144445f4f564552464c4f5700000000000000000000000000000060208201526000908383019084821015611c0c5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611bd1578181015183820152602001611bb9565b50505050905090810190601f168015611bfe5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508091505b5092915050565b9055565b600060608086611c2a611530565b8110611c6e576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b861515611cc5576040805160e560020a62461bcd02815260206004820152600760248201527f4e4f5f4b45595300000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611cd687603063ffffffff61240d16565b865114611d2d576040805160e560020a62461bcd02815260206004820152600e60248201527f494e56414c49445f4c454e475448000000000000000000000000000000000000604482015290519081900360640190fd5b611d3e87606063ffffffff61240d16565b855114611d95576040805160e560020a62461bcd02815260206004820152600e60248201527f494e56414c49445f4c454e475448000000000000000000000000000000000000604482015290519081900360640190fd5b600093505b86841015611efa57611db18660308602603061281a565b9250611dbc8361289b565b15611e11576040805160e560020a62461bcd02815260206004820152600960248201527f454d5054595f4b45590000000000000000000000000000000000000000000000604482015290519081900360640190fd5b611e208560608602606061281a565b600089815260208190526040902060020154909250611e55908990608060020a900467ffffffffffffffff16860185856128d3565b877fc77a17d6b857abe6d6e6c37301621bc72c4dd52fa8830fb54dfa715c04911a89846040518080602001828103825283818151815260200191508051906020019080838360005b83811015611eb5578181015183820152602001611e9d565b50505050905090810190601f168015611ee25780820380516001836020036101000a031916815260200191505b509250505060405180910390a2836001019350611d9a565b611f2f611f0688612948565b60008a815260208190526040902060020154608060020a900467ffffffffffffffff169061277f565b600098895260208990526040909820600201805467ffffffffffffffff99909916608060020a0277ffffffffffffffff00000000000000000000000000000000199099169890981790975550505050505050565b5490565b6060600080600080611f97612b3c565b611f9f611196565b604051908082528060200260200182016040528015611fd857816020015b611fc5612b3c565b815260200190600190039081611fbd5790505b509550855160001415611fea576120fa565b611ff2611530565b945060009350600092505b848310156120a2576000838152602081905260409020805490925060ff16151561202657612097565b855160018501948791811061203757fe5b6020908102909101810151848152600284015467ffffffffffffffff8082169383019390935268010000000000000000810483166040830152608060020a81048316606083015260c060020a90049091166080820181905260a082015290505b826001019250611ffd565b855184146120fa576040805160e560020a62461bcd02815260206004820152601860248201527f494e434f53495354454e545f4143544956455f434f554e540000000000000000604482015290519081900360640190fd5b505050505090565b60408051808201909152601281527f4d4154485f5355425f554e444552464c4f570000000000000000000000000000602082015260009081908484111561218e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611bd1578181015183820152602001611bb9565b505050900390565b60408051828152918201602001905290565b606080600081816121b98787612960565b604080518181526060810182529194506020820161080080388339505084546020830152506001840154604082015260029093019291506121fd826000603061281a565b6040805160608082526080820190925291965060208201610c0080388339019050509350600090505b6060811015612248578254602082860181019190915260019093019201612226565b5050509250929050565b600080835185518401111515156122b3576040805160e560020a62461bcd02815260206004820152601960248201527f42595445535f41525241595f4f55545f4f465f424f554e445300000000000000604482015290519081900360640190fd5b60208501915082602085010190506122cd82828751612a43565b5050505050565b60408051808201909152601481527f4d41544836345f5355425f554e444552464c4f570000000000000000000000006020820152600090819067ffffffffffffffff808616908516111561218e5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611bd1578181015183820152602001611bb9565b60408051808201909152600d81527f4d4154485f4449565f5a45524f00000000000000000000000000000000000000602082015260009081908184116123f85760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611bd1578181015183820152602001611bb9565b50828481151561240457fe5b04949350505050565b6000808315156124205760009150611c11565b5082820282848281151561243057fe5b60408051808201909152601181527f4d4154485f4d554c5f4f564552464c4f5700000000000000000000000000000060208201529291900414611c0c5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611bd1578181015183820152602001611bb9565b60606000606080856124c8611530565b811061250c576040805160e560020a62461bcd0281526020600482015260176024820152600080516020612bae833981519152604482015290519081900360640190fd5b600087815260208190526040902060020154608060020a900467ffffffffffffffff168610612585576040805160e560020a62461bcd02815260206004820152600d60248201527f4b45595f4e4f545f464f554e4400000000000000000000000000000000000000604482015290519081900360640190fd5b60008781526020819052604090206002015460c060020a900467ffffffffffffffff168610156125ff576040805160e560020a62461bcd02815260206004820152600c60248201527f4b45595f5741535f555345440000000000000000000000000000000000000000604482015290519081900360640190fd5b61260987876121a8565b5060008881526020819052604090206002015490955061263b90608060020a900467ffffffffffffffff1660016122d4565b67ffffffffffffffff169350838610156126695761265987856121a8565b92509250612669878785856128d3565b6126738785612a91565b6000878152602081905260409020600201546126a190608060020a900467ffffffffffffffff1660016122d4565b60008089815260200190815260200160002060020160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550867fea4b75aaf57196f73d338cadf79ecd0a437902e2dd0d2c4c2cf3ea71b8ab27b9866040518080602001828103825283818151815260200191508051906020019080838360005b8381101561273c578181015183820152602001612724565b50505050905090810190601f1680156127695780820380516001836020036101000a031916815260200191505b509250505060405180910390a250505050505050565b60408051808201909152601381527f4d41544836345f4144445f4f564552464c4f570000000000000000000000000060208201526000908383019067ffffffffffffffff8086169083161015611c0c5760405160e560020a62461bcd02815260040180806020018281038252838181518152602001915080519060200190808383600083811015611bd1578181015183820152602001611bb9565b60608082840185511015151561282f57600080fd5b8215801561284857604051915060208201604052612892565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015612881578051835260209283019201612869565b5050858452601f01601f1916604052505b50949350505050565b6000806000603084511415156128ad57fe5b505060208201516040830151811580156128cb5750608060020a8104155b949350505050565b6000806000603085511415156128e557fe5b83516060146128f057fe5b6128fa8787612960565b602086015181556040860151608090811c811b6001830155600290910193509150600090505b606081101561293f576020818501810151845560019093019201612920565b50505050505050565b600067ffffffffffffffff82111561295c57fe5b5090565b604080517f6c69646f2e4e6f64654f70657261746f727352656769737472792e7369676e6981527f6e674b6579734d617070696e674e616d650000000000000000000000000000006020808301919091528251918290036031018220828201528183018590526060808301859052835180840390910181526080909201928390528151600093918291908401908083835b60208310612a105780518252601f1990920191602091820191016129f1565b5181516020939093036101000a600019018019909116921691909117905260405192018290039091209695505050505050565b5b601f811115612a64578251825260209283019290910190601f1901612a44565b6000811115612a8c5760018160200360080260011b0380198451168184511681811785525050505b505050565b600080612a9e8484612960565b9150600090505b6005811015612abc57600082820155600101612aa5565b50505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10612b035782800160ff19823516178555612b30565b82800160010185558215612b30579182015b82811115612b30578235825591602001919060010190612b15565b5061295c929150612b73565b60c0604051908101604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6111fd91905b8082111561295c5760008155600101612b7956004150505f415554485f4641494c454400000000000000000000000000000000004e4f44455f4f50455241544f525f4e4f545f464f554e44000000000000000000a165627a7a723058208947f650d43b255ac2f97bb7e4c991a4926576ca1b84d46bce7f1dd3b31616920029

Deployed ByteCode Sourcemap

32621:24415:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35998:768;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;35998:768:0;;;;;;;;;;;;;-1:-1:-1;;;;;35998:768:0;;;;;;;;;;;;;;;;;;;;;;;;;40509:191;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;40509:191:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43196:3232;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;43196:3232:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;43196:3232:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43196:3232:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;43196:3232:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32859:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32859:45:0;;;;37557:192;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;37557:192:0;;;;;;;;;;;;;;;;46645:1347;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;46645:1347:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;46645:1347:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;46645:1347:0;;;;;;;;;;;;;;;;;;;36868:579;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;36868:579:0;;;;;;;;;42116:145;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;42116:145:0;;;;;;;35472:98;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;35472:98:0;-1:-1:-1;;;;;35472:98:0;;;;;41504:348;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;41504:348:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48076:146;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48076:146:0;;;;49637:228;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;49637:228:0;;;;;37863:285;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;37863:285:0;;;-1:-1:-1;;;;;37863:285:0;;;;;48399:819;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;48399:819:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48399:819:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;48399:819:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32810:42;;8:9:-1;5:2;;;30:1;27;20:12;5:2;32810:42:0;;;;50801:139;;8:9:-1;5:2;;;30:1;27;20:12;5:2;50801:139:0;;;;38286:240;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38286:240:0;;;;;;;;;50259:459;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;50259:459:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;50259:459:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50259:459:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;50259:459:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38649:496;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;38649:496:0;;;;;;;;;49336:182;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;49336:182:0;;;;;42535:231;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;42535:231:0;;;;;;;39268:443;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39268:443:0;;;;35998:768;36148:10;;;36114:14;-1:-1:-1;;;;;35107:16:0;;;;35099:42;;;;;-1:-1:-1;;;;;35099:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;36181:23;:21;:23::i;:::-;36176:28;-1:-1:-1;36215:59:0;36264:9;36176:28;36271:1;36264:9;:6;:9;:::i;:::-;34539:59;;;;;;;;;;;;;;;;;;;;;;36215;:48;:59;:::i;:::-;36319:9;:13;;;;;;;;;;;-1:-1:-1;36376:29:0;:27;:29::i;:::-;36345:60;-1:-1:-1;36416:78:0;36466:27;36345:60;36491:1;36466:27;:24;:27;:::i;:::-;34714:60;;;;;;;;;;;;;;;;;;;;;;36416:78;:49;:78;:::i;:::-;36507:22;;-1:-1:-1;;36507:22:0;36525:4;36507:22;;;;;36540:21;;:13;;36556:5;;36540:21;:::i;:::-;-1:-1:-1;36572:39:0;;-1:-1:-1;;36572:39:0;;-1:-1:-1;;;;;36572:39:0;;;;;;;;;;;36622:21;;;:37;;-1:-1:-1;;36622:37:0;;;;;;;;;;36677:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36699:5;;36677:59;;36572:39;;36622:37;;36677:59;;;36699:5;36677:59;;36699:5;36677:59;;;;;;;;;;-1:-1:-1;36677:59:0;;-1:-1:-1;;;;;;;36677:59:0;35998:768;;;;;;;;;:::o;40509:191::-;40629:63;40645:12;40659:9;40670:8;;40629:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;40629:63:0;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40680:11:0;;-1:-1:-1;40680:11:0;;-1:-1:-1;40680:11:0;;-1:-1:-1;40629:63:0;;40680:11;;;;40629:63;;-1:-1:-1;40629:15:0;;-1:-1:-1;;;;;40629:63:0:i;:::-;40509:191;;;;;;:::o;43196:3232::-;43272:20;43294:23;43408:38;43564:23;43602:36;;:::i;:::-;43752:23;43827:21;43963:11;44242:13;45311:21;45354:9;45647:16;45762:19;45783:22;34973:33;34865:44;;;;;;;;;;;;;;;;;;;34973:31;;;;:33::i;:::-;-1:-1:-1;;;;;34959:47:0;:10;:47;34951:75;;;;;-1:-1:-1;;;;;34951:75:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34951:75:0;;;;;;;;;;;;;;;43449:20;:18;:20::i;:::-;43408:61;;43489:5;:12;43484:1;:17;43480:71;;;43524:12;;;43534:1;43524:12;;;;;;;;;;;-1:-1:-1;43538:12:0;;;43548:1;43538:12;;;;;;;;43516:35;;-1:-1:-1;43538:12:0;-1:-1:-1;43516:35:0;;43480:71;43590:1;43564:27;;43651:1224;43676:8;43658:15;:26;43651:1224;;;43778:5;:12;43752:38;;43977:1;43963:15;;43958:640;43986:5;:12;43980:3;:18;43958:640;;;44034:5;44040:3;44034:10;;;;;;;;;;;;;;;;;;44026:18;;44097:5;:22;;;44072:5;:21;;;:47;;44065:55;;;;;;44168:5;:22;;;44143:5;:21;;;:47;44139:82;;;44213:8;;44139:82;44284:23;;;;44258:21;;;;:50;;;:25;:50;:::i;:::-;44242:66;;44343:5;:18;;;44331:5;44339:1;44331:9;:30;44327:65;;;44384:8;;44327:65;44436:5;:12;44417:15;:31;:56;;;;44460:13;44452:5;:21;44417:56;44413:170;;;44516:3;44498:21;;44558:5;44542:21;;44413:170;44000:5;;;;;43958:640;;;44637:5;:12;44618:15;:31;44614:73;;;44682:5;;44614:73;44712:5;44718:15;44712:22;;;;;;;;;;;;;;;;;;;44756:21;;;;44712:22;;-1:-1:-1;32952:19:0;-1:-1:-1;44749:42:0;;;;44810:21;;;44808:23;;;;;;;;;44846:17;;;;;43651:1224;;;44891:20;;44887:88;;;44936:12;;;44946:1;44936:12;;;;;;;;;;;;44887:88;45009:1;44991:15;:19;44987:312;;;45134:61;32850:2;45163:15;:31;45134:28;:61::i;:::-;45124:71;;45223:64;32902:2;45252:15;:34;45223:28;:64::i;:::-;45210:77;;44987:312;45335:1;45311:25;;45366:1;45354:13;;45349:980;45373:5;:12;45369:1;:16;45349:980;;;45415:5;45421:1;45415:8;;;;;;;;;;;;;;;;;;45407:16;;45469:5;:28;;;45444:5;:21;;;:53;45440:102;;;45518:8;;45440:102;45603:21;;;;45568:8;;45558:9;:19;;;;;;;;;;:35;;:67;;;;;;-1:-1:-1;;;45558:67:0;;;;;;;;;;;45666:28;;;;;-1:-1:-1;45642:582:0;45707:5;:21;;;45696:8;:32;45642:582;;;45825:8;;45809:35;;45835:8;45809:15;:35::i;:::-;45761:83;;;;45867:15;45886:1;45867:20;45863:346;;;45920:6;45928:9;45912:26;;;;;;45863:346;45987:66;46006:6;46014:7;32850:2;46023:13;:29;45987:18;:66::i;:::-;46076:75;46095:9;46106:10;32902:2;46118:13;:32;46076:18;:75::i;:::-;46174:15;;;;;45730:10;;;;;45642:582;;;46261:15;46244:13;:32;46240:78;;;46297:5;;46240:78;45387:3;;;;;45349:980;;;46348:32;;;46341:40;;;;43196:3232;;;;;;;;;;;;;;;:::o;32859:45::-;32902:2;32859:45;:::o;37557:192::-;37646:3;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;37667:9;:14;;;;;;;;;;:27;;:19;;37689:5;;37667:27;:::i;:::-;;37730:3;37710:31;37735:5;;37710:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37710:31:0;;-1:-1:-1;;;;37710:31:0;37557:192;;;;:::o;46645:1347::-;46751:27;46793:23;46844:25;46908:19;47066:11;47094:27;47141:18;47226:29;47358:22;47744:26;46872:23;:21;:23::i;:::-;46844:51;;46930:29;:27;:29::i;:::-;46908:51;;46997:11;46983:26;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;46983:26:0;;46970:39;;47043:11;47029:26;;;;;;;;;;;;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;136:17;;-1:-1;47029:26:0;;47020:35;;47080:1;47066:15;;47124:1;47094:31;;47162:1;47141:22;;47136:513;47178:17;47165:10;:30;47136:513;;;47258:9;:21;;;;;;;;;;47299:15;;47258:21;;-1:-1:-1;47299:15:0;;47298:16;47294:47;;;47333:8;;47294:47;47412:26;;;;47383:56;;47412:26;-1:-1:-1;;;47383:24:0;;;;;47412:26;;;;47383:28;:56::i;:::-;47358:81;;;-1:-1:-1;47476:39:0;:19;47358:81;47476:39;:23;:39;:::i;:::-;47550:22;;47532:15;;47454:61;;-1:-1:-1;47550:22:0;;;-1:-1:-1;;;;;47550:22:0;;47532:15;;47543:3;;47532:15;;;;;;-1:-1:-1;;;;;47532:40:0;;;:15;;;;;;;;;;:40;47587:11;;47601:14;;47587:6;;47594:3;;47587:11;;;;;;;;;;;;;;:28;47632:5;;;;;47136:513;47197:12;;;;;47136:513;;;47665:24;;47661:70;;;47704:27;;47661:70;47773:43;:18;47796:19;47773:43;:22;:43;:::i;:::-;47744:72;;47840:1;47834:7;;47829:116;47849:11;47843:3;:17;47829:116;;;47898:35;47914:18;47898:6;47905:3;47898:11;;;;;;;;;;;;;;;;;;;;:35;:15;:35;:::i;:::-;47884:6;47891:3;47884:11;;;;;;;;;;;;;;;;;;:49;47862:5;;;;;47829:116;;;46645:1347;;;;;;;;;;;:::o;36868:579::-;37033:28;36959:3;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;36984:9;:14;;;;;;;;;;:21;;;:32;;;;;;36980:363;;37064:29;:27;:29::i;:::-;37033:60;;37112:7;37108:223;;;37138:78;37188:27;:20;37213:1;37188:27;:24;:27;:::i;37138:78::-;37108:223;;;37253:78;37303:27;:20;37328:1;37303:27;:24;:27;:::i;37253:78::-;37355:9;:14;;;;;;;;;;;;:31;;-1:-1:-1;;37355:31:0;;;;;;;;;;37404:35;;;;;;;37355:14;;37404:35;;;;;;;;;36868:579;;;;:::o;42116:145::-;42214:39;42232:12;42246:6;42214:17;:39::i;:::-;42116:145;;:::o;35472:98::-;34865:44;;;;;;;;;;;;;;;;35524:38;;35556:5;35524:38;:31;:38;:::i;:::-;35472:98;:::o;41504:348::-;41713:9;:23;;;;;;;;;;:37;;;;-1:-1:-1;;;;;41713:37:0;41699:10;:51;41691:79;;;;;-1:-1:-1;;;;;41691:79:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;41691:79:0;;;;;;;;;;;;;;48076:146;34714:60;;;;;;;;;;;;;;;;;;;;;48136:7;;48163:51;;:49;:51::i;:::-;48156:58;;48076:146;;:::o;49637:228::-;49745:7;49722:12;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;49817:9;:23;;;;;;;;;;:39;;;49772:85;;49817:39;-1:-1:-1;;;49772:40:0;;;;;-1:-1:-1;;;49817:39:0;;;49772:44;:85::i;:::-;49765:92;;;49637:228;-1:-1:-1;;;49637:228:0:o;37863:285::-;37971:3;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;37998:14;-1:-1:-1;;;;;35107:16:0;;;;35099:42;;;;;-1:-1:-1;;;;;35099:42:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;38030:9;:14;;;;;;;;;;;;:45;;-1:-1:-1;;38030:45:0;;-1:-1:-1;;;;;38030:45:0;;;;;;;;;;;;38091:49;;;;;;;38030:14;;38091:49;;;;;;;;;35293:1;37863:285;;;:::o;48399:819::-;48537:11;48563;48589:21;48625:19;48659:24;48698:23;48736:22;48786:29;48491:3;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;48818:9;:14;;;;;;;;;;48854:15;;;;;-1:-1:-1;48818:14:0;-1:-1:-1;48887:9:0;:30;;;;;;;;;;;-1:-1:-1;48887:30:0;;;;;48899:13;;;;48887:30;;;;;;;;;;;;;-1:-1:-1;;48887:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48899:13;48887:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48976:22;;49024:21;;;;;48399:819;;48880:37;;-1:-1:-1;48976:22:0;;;;-1:-1:-1;;;;;48976:22:0;;-1:-1:-1;;49024:21:0;;;;;49076:26;;;;;;-1:-1:-1;;;;49132:25:0;;;;;-1:-1:-1;;;;49186:24:0;;;;-1:-1:-1;48399:819:0;-1:-1:-1;;;48399:819:0:o;32810:42::-;32850:2;32810:42;:::o;50801:139::-;34539:59;;;;;;;;;;;;;;;;;;;;;50855:7;;50882:50;;:48;:50::i;38286:240::-;38391:3;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;38412:9;:14;;;;;;;;;;;;:27;;:43;;-1:-1:-1;;38412:43:0;;;;;;;;;;38471:47;;;;;;;38412:14;;38471:47;;;;;;;;;38286:240;;;:::o;50259:459::-;50390:9;50401:22;50425:9;50541:17;50560:22;50358:12;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;50469:9;:23;;;;;;;;;;:40;;;-1:-1:-1;;;50469:40:0;;;;50460:49;;50452:75;;;;;-1:-1:-1;;;;;50452:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50586:37;50602:12;50616:6;50586:15;:37::i;:::-;50670:9;:23;;;;;;;;;;;:39;;;50540:83;;-1:-1:-1;;;50670:39:0;;;;;50661:48;;;;50259:459;-1:-1:-1;;;;;;50259:459:0:o;38649:496::-;38754:3;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;38783:22;;;;;38775:46;;;;;-1:-1:-1;;;;;38775:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;38867:9;:14;;;;;;;;;;:32;;;:55;;:32;;;;;38904:17;38867:36;:55::i;:::-;38832:9;:14;;;;;;;;;;:32;;:90;;-1:-1:-1;;38832:90:0;;;;;;;;;;;;;;;;-1:-1:-1;;;38977:30:0;;;;38941:32;;;;;:66;;38933:105;;;;;-1:-1:-1;;;;;38933:105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;39104:9;:14;;;;;;;;;;;;:32;;;39056:81;;39104:32;;;;;;39056:81;;;;39104:14;;39056:81;;;;;;;;;38649:496;;;:::o;49336:182::-;49443:7;49420:12;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;-1:-1:-1;;49470:9:0;:23;;;;;;;;;;:40;;;-1:-1:-1;;;49470:40:0;;;;;49336:182::o;42535:231::-;42651:9;:23;;;;;;;;;;:37;;;;-1:-1:-1;;;;;42651:37:0;42637:10;:51;42629:79;;;;;-1:-1:-1;;;;;42629:79:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;42629:79:0;;;;;;;;;;;;;;39268:443;34865:44;;;;;;;;;;;;;;;;39323:14;;;;34973:33;;:31;:33::i;:::-;-1:-1:-1;;;;;34959:47:0;:10;:47;34951:75;;;;;-1:-1:-1;;;;;34951:75:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;34951:75:0;;;;;;;;;;;;;;;39340:23;:21;:23::i;:::-;39323:40;;39400:1;39379:22;;39374:330;39416:6;39403:10;:19;39374:330;;;39499:9;:21;;;;;;;;;;:37;;;-1:-1:-1;;;39457:38:0;;39499:37;39457:38;;;-1:-1:-1;;;39499:37:0;;;;39457:79;39453:215;;39631:9;:21;;;;;;;;;;:37;;;;-1:-1:-1;;;39631:37:0;-1:-1:-1;;;39631:37:0;;;39590:78;-1:-1:-1;;39590:78:0;;;;;;39453:215;39424:12;;39374:330;;28679:175;28806:18;;;;;;;;;;;;;;;;;28739:7;;28771;;;;28797;;;;28789:36;;;;-1:-1:-1;;;;;28789:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;28789:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28845:1;28838:8;;28679:175;;;;;;:::o;32250:121::-;32340:22;;32338:26::o;52770:974::-;53162:9;53212:16;53365;52904:12;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;52942:14;;;52934:34;;;;;-1:-1:-1;;;;;52934:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53006:28;:9;32850:2;53006:28;:13;:28;:::i;:::-;52987:15;;:47;52979:74;;;;;-1:-1:-1;;;;;52979:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53094:31;:9;32902:2;53094:31;:13;:31;:::i;:::-;53072:18;;:53;53064:80;;;;;-1:-1:-1;;;;;53064:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53174:1;53162:13;;53157:463;53181:9;53177:1;:13;53157:463;;;53231:58;53246:8;32850:2;53256:1;:17;32850:2;53231:14;:58::i;:::-;53212:77;;53313:23;53332:3;53313:18;:23::i;:::-;53312:24;53304:46;;;;;-1:-1:-1;;;;;53304:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53384:67;53399:11;32902:2;53412:1;:20;32902:2;53384:14;:67::i;:::-;53499:9;:23;;;;;;;;;;:40;;;53365:86;;-1:-1:-1;53468:86:0;;53499:23;;-1:-1:-1;;;53499:40:0;;;;:44;;53545:3;53365:86;53468:16;:86::i;:::-;53590:12;53574:34;53604:3;53574:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;53574:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53192:3;;;;;53157:463;;;53675:61;53720:15;53725:9;53720:4;:15::i;:::-;53675:9;:23;;;;;;;;;;:40;;;-1:-1:-1;;;53675:40:0;;;;;:44;:61::i;:::-;53632:9;:23;;;;;;;;;;;:40;;:104;;;;;;;-1:-1:-1;;;53632:104:0;-1:-1:-1;;53632:104:0;;;;;;;;;;-1:-1:-1;;;;;;;52770:974:0:o;31437:136::-;31549:15;;31539:27::o;55966:1067::-;56019:38;56210:22;56269:11;56300:18;56382:29;56516:36;;:::i;:::-;56108:29;:27;:29::i;:::-;56078:60;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;56070:68;;56158:5;:12;56153:1;:17;56149:48;;;56185:12;;56149:48;56235:23;:21;:23::i;:::-;56210:48;;56283:1;56269:15;;56321:1;56300:22;;56295:639;56337:14;56324:10;:27;56295:639;;;56414:9;:21;;;;;;;;;;56457:15;;56414:21;;-1:-1:-1;56457:15:0;;56456:16;56452:47;;;56491:8;;56452:47;56555:12;;56561:5;;;;56555;;:12;;;;;;;;;;;;;;;;56582:21;;;56639;;;;;;;;56618:18;;;:42;;;;56701:26;;;;;56675:23;;;:52;-1:-1:-1;;;56767:25:0;;;;56742:22;;;:50;-1:-1:-1;;;56831:24:0;;;;;56807:21;;;:48;;;56870:28;;;:52;56555:12;-1:-1:-1;56295:639:0;56353:12;;;;;56295:639;;;56959:12;;56952:19;;56944:56;;;;;-1:-1:-1;;;;;56944:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;55966:1067;;;;;;:::o;28426:177::-;28524:19;;;;;;;;;;;;;;;;;28486:7;;;;28514:8;;;;28506:38;;;;-1:-1:-1;;;;;28506:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;28506:38:0;-1:-1:-1;;;28567:7:0;;;28426:177::o;24414:249::-;24552:4;24546:11;;24571:20;;;24622:17;;;24641:2;24618:26;24605:40;;24546:11;24521:135::o;54989:969::-;55078:16;;55287:14;55078:16;55287:14;55304:42;55322:12;55336:9;55304:17;:42::i;:::-;55407:2;55397:13;;;;;;;;;;55287:59;;-1:-1:-1;55397:13:0;;;17:15:-1;;105:10;55397:13:0;88:34:-1;-1:-1;;55471:13:0;;55464:4;55452:17;;55445:40;-1:-1:-1;55543:1:0;55531:14;;55525:21;55518:4;55506:17;;55499:48;55578:1;55568:11;;;;55375:35;-1:-1:-1;55596:40:0;55375:35;-1:-1:-1;32850:2:0;55596:14;:40::i;:::-;55683:27;;;32902:2;55683:27;;;;;;;;;55590:46;;-1:-1:-1;55683:27:0;;;17:15:-1;;105:10;55683:27:0;88:34:-1;136:17;;-1:-1;55683:27:0;55671:39;;55738:1;55726:13;;55721:194;32902:2;55741:1;:20;55721:194;;;55852:13;;55841:4;55822:28;;;;;55815:51;;;;55895:8;;;;;55837:12;55721:194;;;54989:969;;;;;;;;:::o;25776:432::-;25964:19;25994;25912:4;:11;25897:4;:11;25885:9;:23;:38;;25877:76;;;;;;;-1:-1:-1;;;;;25877:76:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;26073:2;26067:4;26063:13;26048:28;;26124:9;26119:2;26113:4;26109:13;26105:29;26090:44;;26155:45;26162:11;26175;26188:4;:11;26155:6;:45::i;:::-;25776:432;;;;;:::o;30498:173::-;30593:19;;;;;;;;;;;;;;;;;30556:6;;;;30583:8;;;;;;;;;30575:38;;;;-1:-1:-1;;;;;30575:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;27981:319:0;28077:14;;;;;;;;;;;;;;;;;28041:7;;;;28069:6;;;28061:31;;;;-1:-1:-1;;;;;28061:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;28061:31:0;;28178:2;28173;:7;;;;;;;;;27981:319;-1:-1:-1;;;;27981:319:0:o;27398:460::-;27458:7;;27702;;27698:48;;;27733:1;27726:8;;;;27698:48;-1:-1:-1;27770:7:0;;;27775:2;27770;:7;27796:6;;;;;;;27810:18;;;;;;;;;;;;;;;;;;27796:6;;;:12;27788:41;;;;-1:-1:-1;;;;;27788:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;53752:888:0;54054:23;54133:17;54251:16;54269:22;53850:12;35231:23;:21;:23::i;:::-;35225:29;;35217:65;;;;;-1:-1:-1;;;;;35217:65:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;35217:65:0;;;;;;;;;;;;;;;53897:9;:23;;;;;;;;;;:40;;;-1:-1:-1;;;53897:40:0;;;;53888:49;;53880:75;;;;;-1:-1:-1;;;;;53880:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;53984:9;:23;;;;;;;;;;:39;;;-1:-1:-1;;;53984:39:0;;;;53974:49;;;53966:74;;;;;-1:-1:-1;;;;;53966:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;54083:37;54099:12;54113:6;54083:15;:37::i;:::-;-1:-1:-1;54153:9:0;:23;;;;;;;;;;:40;;;54053:67;;-1:-1:-1;54153:47:0;;-1:-1:-1;;;54153:40:0;;;;54198:1;54153:44;:47::i;:::-;54133:67;;;;54224:9;54215:6;:18;54211:205;;;54295:40;54311:12;54325:9;54295:15;:40::i;:::-;54250:85;;;;54350:54;54367:12;54381:6;54389:3;54394:9;54350:16;:54::i;:::-;54428:42;54446:12;54460:9;54428:17;:42::i;:::-;54524:9;:23;;;;;;;;;;:40;;;:47;;-1:-1:-1;;;54524:40:0;;;;54569:1;54524:44;:47::i;:::-;54481:9;:23;54491:12;54481:23;;;;;;;;;;;:40;;;:90;;;;;;;;;;;;;;;;;;54607:12;54589:43;54621:10;54589:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;54589:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53752:888;;;;;;;:::o;30747:171::-;30870:18;;;;;;;;;;;;;;;;;30805:6;;30835:7;;;;30861;;;;;;;;;30853:36;;;;-1:-1:-1;;;;;30853:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;9381:2520:0;9461:5;9536:22;9514:7;9505:6;:16;9487:6;:13;:35;;9479:44;;;;;;;;9602:15;;9631:2005;;;;11780:4;11774:11;11761:24;;11833:4;11822:9;11818:20;11812:4;11805:34;9595:2259;;9631:2005;9816:4;9810:11;9797:24;;10485:2;10476:7;10472:16;10873:9;10866:17;10860:4;10856:28;10844:9;10833;10829:25;10825:60;10922:7;10918:2;10914:16;11179:6;11165:9;11158:17;11152:4;11148:28;11136:9;11128:6;11124:22;11120:57;11116:70;10950:434;11213:3;11209:2;11206:11;10950:434;;;11355:9;;11344:21;;11255:4;11247:13;;;;11288;10950:434;;;-1:-1:-1;;11404:26:0;;;11616:2;11599:11;-1:-1:-1;;11595:25:0;11589:4;11582:39;-1:-1:-1;9595:2259:0;-1:-1:-1;11884:9:0;9381:2520;-1:-1:-1;;;;9381:2520:0:o;50948:472::-;51018:4;51192:10;51213;32850:2;51042:4;:11;:28;51035:36;;;;;;-1:-1:-1;;51280:4:0;51270:15;;51264:22;51322:4;51312:15;;51306:22;51358:7;;:54;;;;-1:-1:-1;;;;51375:36:0;;51369:43;51358:54;51351:61;50948:472;-1:-1:-1;;;;50948:472:0:o;51792:970::-;52198:14;52268:21;52565:9;32850:2;51930:4;:11;:28;51923:36;;;;;;51977:17;;32902:2;51977:37;51970:45;;;;52215:42;52233:12;52247:9;52215:17;:42::i;:::-;52386:4;52376:15;;52370:22;52355:38;;52293:6;52474:15;;52468:22;52292:28;52449:42;;;52430:62;;52426:1;52414:14;;52407:86;52524:1;52514:11;;;;-1:-1:-1;52292:28:0;-1:-1:-1;;;;52560:195:0;32902:2;52580:1;:20;52560:195;;;52695:4;52675:29;;;;;52669:36;52654:52;;52735:8;;;;;52691:12;52560:195;;;51792:970;;;;;;;:::o;51428:134::-;51476:6;51507:19;51502:24;;;51495:32;;;;-1:-1:-1;51552:1:0;51428:134::o;51570:214::-;33034:62;;;;;;;;;;;;;;;;;;;;;;;;;51706:68;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;51706:68:0;;;;;;;;51696:79;;51661:7;;51706:68;;;51696:79;;;;;51706:68;51696:79;36:153:-1;66:2;58:11;;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;299:10;344;;263:2;259:12;;;;254:3;250:22;-1:-1;;246:30;311:9;;295:26;;;340:21;;377:20;;;;365:33;;51696:79:0;;;;;;;;;;;51570:214;-1:-1:-1;;;;;;51570:214:0:o;24777:883::-;24953:201;24970:2;24964:4;24961:12;24953:201;;;25010:11;;24997:25;;25058:2;25048:13;;;;25087;;;;-1:-1:-1;;25126:13:0;24953:201;;;25180:1;25174:4;25171:11;25168:2;;;25420:1;25411:4;25407:2;25403:13;25400:1;25396:21;25393:1;25389:29;25385:37;25508:4;25504:9;25497:4;25491:11;25487:27;25566:4;25559;25553:11;25549:22;25616:9;25605;25602:24;25596:4;25589:38;25183:459;;;25168:2;24869:784;;;:::o;54648:333::-;54736:14;54811:9;54753:42;54771:12;54785:9;54753:17;:42::i;:::-;54736:59;;54823:1;54811:13;;54806:168;54830:43;54826:47;;54806:168;;;54946:1;54930:14;;;54923:25;54875:3;;54806:168;;;54648:333;;;;:::o;32621:24415::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;32621:24415:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32621:24415:0;;;-1:-1:-1;32621:24415:0;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://8947f650d43b255ac2f97bb7e4c991a4926576ca1b84d46bce7f1dd3b3161692
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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.