ETH Price: $3,454.35 (-1.89%)
Gas: 13 Gwei

Contract

0x4cE75eaFD588f36de4b4B6E15f5e4E44B2e67Aa0
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x61012060159491522022-11-11 20:27:23619 days ago1668198443IN
 Create: Firn
0 ETH0.0755068215

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Firn

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity Multiple files format)

File 1 of 7: Firn.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.8.17;

import "./EpochTree.sol";
import "./DepositVerifier.sol";
import "./TransferVerifier.sol";
import "./WithdrawalVerifier.sol";
import "./Utils.sol";

contract Firn is EpochTree {
    using Utils for uint256;
    using Utils for Utils.Point;

    mapping(bytes32 => Utils.Point[2]) _acc; // main account mapping
    mapping(bytes32 => Utils.Point[2]) _pending; // storage for pending transfers
    mapping(bytes32 => uint64) _lastRollOver;
    bytes32[] _nonces; // would be more natural to use a mapping (really a set), but they can't be deleted / reset!
    uint64 _lastGlobalUpdate = 0; // will be also used as a proxy for "current epoch", seeing as rollovers will be anticipated

    uint256 constant EPOCH_LENGTH = 60;

    DepositVerifier immutable _deposit;
    TransferVerifier immutable _transfer;
    WithdrawalVerifier immutable _withdrawal;

    event RegisterOccurred(address indexed sender, bytes32 indexed account, uint32 amount);
    event DepositOccurred(bytes32[N] Y, bytes32[N] C, bytes32 D, address indexed source, uint32 amount); // amount not indexed
    event TransferOccurred(bytes32[N] Y, bytes32[N] C, bytes32 D);
    event WithdrawalOccurred(bytes32[N] Y, bytes32[N] C, bytes32 D, uint32 amount, address indexed destination, bytes data);

    address _treasury;
    uint32 _fee;

    // some duplication here, but this is less painful than trying to retrieve it from the IP verifier / elsewhere.
    bytes32 immutable _gX;
    bytes32 immutable _gY;

    struct Info { // try to save storage space by using smaller int types here
        uint64 epoch;
        uint64 index; // index in the list
        uint64 amount;
    }
    mapping(bytes32 => Info) public info; // needs to be public, for reader
    mapping(uint64 => bytes32[]) public lists; // needs to be public, for reader

    function lengths(uint64 epoch) external view returns (uint256) { // see https://ethereum.stackexchange.com/a/20838.
        return lists[epoch].length;
    }

    bytes32 internal constant _ADMIN_SLOT = bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1);

    function _getAdmin() internal view returns (address) {
        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
    }

    modifier onlyOwner() {
        require(msg.sender == _getAdmin(), "Caller is not the owner.");
        _;
    }

    constructor(address deposit_, address transfer_, address withdrawal_) {
        _deposit = DepositVerifier(deposit_);
        _transfer = TransferVerifier(transfer_);
        _withdrawal = WithdrawalVerifier(withdrawal_);

        Utils.Point memory gTemp = Utils.mapInto("g");
        _gX = gTemp.x;
        _gY = gTemp.y;
    }

    function administrate(address treasury_, uint32 fee_) external onlyOwner {
        _treasury = treasury_;
        _fee = fee_;
    }

    function g() internal view returns (Utils.Point memory) {
        return Utils.Point(_gX, _gY);
    }

    function rollOver(bytes32 Y, uint64 epoch) internal {
        if (_lastRollOver[Y] < epoch) {
            _acc[Y][0] = _acc[Y][0].add(_pending[Y][0]);
            _acc[Y][1] = _acc[Y][1].add(_pending[Y][1]);
            delete _pending[Y]; // pending[Y] = [Utils.G1Point(0, 0), Utils.G1Point(0, 0)];
            _lastRollOver[Y] = epoch;
        }
    }

    function touch(bytes32 Y, uint32 credit, uint64 epoch) internal {
        // could save a few operations if we check for the special case that current.epoch == epoch.
        bytes32[] storage list; // declare here not for efficiency, but to avoid shadowing warning
        Info storage current = info[Y];
        if (current.epoch > 0) { // will only be false for registration...?
            list = lists[current.epoch];
            list[current.index] = list[list.length - 1];
            list.pop();
            if (list.length == 0) remove(current.epoch);
            else if (current.index < list.length) info[list[current.index]].index = current.index;
        }
        current.epoch = epoch;
        current.amount += credit; // implicit conversion of RHS to uint64?
        if (!exists(epoch)) {
            insert(epoch);
        }
        list = lists[epoch];
        current.index = uint32(list.length);
        list.push(Y);
    }

    function simulateAccounts(bytes32[] calldata Y, uint32 epoch) external view returns (bytes32[2][] memory result) {
        // interestingly, we lose no efficiency by accepting compressed, because we never have to decompress.
        result = new bytes32[2][](Y.length);
        for (uint256 i = 0; i < Y.length; i++) {
            Utils.Point[2] memory temp;
            temp[0] = _acc[Y[i]][0];
            temp[1] = _acc[Y[i]][1];
            if (_lastRollOver[Y[i]] < epoch) {
                temp[0] = temp[0].add(_pending[Y[i]][0]);
                temp[1] = temp[1].add(_pending[Y[i]][1]);
            }
            result[i][0] = Utils.compress(temp[0]);
            result[i][1] = Utils.compress(temp[1]);
        }
    }

    function register(bytes32 Y, bytes32[2] calldata signature) external payable {
        require(msg.value >= 1e16, "Must be at least 0.010 ETH.");
        require(msg.value % 1e15 == 0, "Must be a multiple of 0.001 ETH.");

        uint64 epoch = uint64(block.timestamp / EPOCH_LENGTH);

        require(address(this).balance <= 1e15 * 0xFFFFFFFF, "Escrow pool now too large.");
        uint32 credit = uint32(msg.value / 1e15); // >= 10.
        _pending[Y][0] = _pending[Y][0].add(g().mul(credit)); // convert to uint256?

        Utils.Point memory pub = Utils.decompress(Y);
        Utils.Point memory K = g().mul(uint256(signature[1])).add(pub.mul(uint256(signature[0]).neg()));
        uint256 c = uint256(keccak256(abi.encode("Welcome to Firn.", address(this), Y, K))).mod();
        require(bytes32(c) == signature[0], "Signature failed to verify.");
        touch(Y, credit, epoch);

        emit RegisterOccurred(msg.sender, Y, credit);
    }

    function deposit(bytes32[N] calldata Y, bytes32[N] calldata C, bytes32 D, bytes calldata proof) external payable {
        // not doing a minimum amount here... the idea is that this function can't be used to force your way into the tree.
        require(msg.value % 1e15 == 0, "Must be a multiple of 0.001 ETH.");
        uint64 epoch = uint64(block.timestamp / EPOCH_LENGTH);
        require(address(this).balance <= 1e15 * 0xFFFFFFFF, "Escrow pool now too large.");
        uint32 credit = uint32(msg.value / 1e15); // can't overflow, by the above.

        Utils.Statement memory statement;
        statement.D = Utils.decompress(D);
        for (uint256 i = 0; i < N; i++) {
            rollOver(Y[i], epoch);

            statement.Y[i] = Utils.decompress(Y[i]);
            statement.C[i] = Utils.decompress(C[i]);
            // mutate their pending, in advance of success.
            _pending[Y[i]][0] = _pending[Y[i]][0].add(statement.C[i]);
            _pending[Y[i]][1] = _pending[Y[i]][1].add(statement.D);
            require(info[Y[i]].epoch > 0, "Only cached accounts allowed.");
            touch(Y[i], credit, epoch); // weird question whether this should be 0 or credit... revisit.
        }

        _deposit.verify(credit, statement, Utils.deserializeDeposit(proof));

        emit DepositOccurred(Y, C, D, msg.sender, credit);
    }

    function transfer(bytes32[N] calldata Y, bytes32[N] calldata C, bytes32 D, bytes32 u, uint64 epoch, uint32 tip, bytes calldata proof) external {
        require(epoch == block.timestamp / EPOCH_LENGTH, "Wrong epoch."); // conversion of RHS to uint64 is unnecessary / redundant

        if (_lastGlobalUpdate < epoch) {
            _lastGlobalUpdate = epoch;
            delete _nonces;
        }
        for (uint256 i = 0; i < _nonces.length; i++) {
            require(_nonces[i] != u, "Nonce already seen.");
        }
        _nonces.push(u);

        Utils.Statement memory statement;
        statement.D = Utils.decompress(D);
        for (uint256 i = 0; i < N; i++) {
            rollOver(Y[i], epoch);

            statement.Y[i] = Utils.decompress(Y[i]);
            statement.C[i] = Utils.decompress(C[i]);
            statement.CLn[i] = _acc[Y[i]][0].add(statement.C[i]);
            statement.CRn[i] = _acc[Y[i]][1].add(statement.D);
            // mutate their pending, in advance of success.
            _pending[Y[i]][0] = _pending[Y[i]][0].add(statement.C[i]);
            _pending[Y[i]][1] = _pending[Y[i]][1].add(statement.D);
            require(info[Y[i]].epoch > 0, "Only cached accounts allowed.");
            touch(Y[i], 0, epoch);
        }
        statement.epoch = epoch;
        statement.u = Utils.decompress(u);
        statement.fee = tip;

        _transfer.verify(statement, Utils.deserializeTransfer(proof));

        payable(msg.sender).transfer(uint256(tip) * 1e15);

        emit TransferOccurred(Y, C, D);
    }

    function withdraw(bytes32[N] calldata Y, bytes32[N] calldata C, bytes32 D, bytes32 u, uint64 epoch, uint32 amount, uint32 tip, bytes calldata proof, address destination, bytes calldata data) external {
        require(epoch == block.timestamp / EPOCH_LENGTH, "Wrong epoch."); // conversion of RHS to uint64 is unnecessary. // could supply epoch ourselves; check early to save gas

        if (_lastGlobalUpdate < epoch) {
            _lastGlobalUpdate = epoch;
            delete _nonces;
        }
        for (uint256 i = 0; i < _nonces.length; i++) {
            require(_nonces[i] != u, "Nonce already seen.");
        }
        _nonces.push(u);

        emit WithdrawalOccurred(Y, C, D, amount, destination, data); // emit here, because of stacktoodeep.

        Utils.Statement memory statement;
        statement.D = Utils.decompress(D);
        for (uint256 i = 0; i < N; i++) {
            bytes32 Y_i = Y[i];
            rollOver(Y_i, epoch);

            statement.Y[i] = Utils.decompress(Y_i);
            statement.C[i] = Utils.decompress(C[i]);
            statement.CLn[i] = _acc[Y_i][0].add(statement.C[i]);
            statement.CRn[i] = _acc[Y_i][1].add(statement.D);
            // mutate their pending, in advance of success.
            _pending[Y_i][0] = _pending[Y_i][0].add(statement.C[i]);
            _pending[Y_i][1] = _pending[Y_i][1].add(statement.D);
            require(info[Y_i].epoch > 0, "Only cached accounts allowed.");
        }
        uint32 fee = amount / _fee;
        statement.epoch = epoch; // implicit conversion to uint256
        statement.u = Utils.decompress(u);
        statement.fee = tip + fee; // implicit conversion to uint256

        uint256 salt = uint256(keccak256(abi.encode(destination, data))); // .mod();
        _withdrawal.verify(amount, statement, Utils.deserializeWithdrawal(proof), salt);

        payable(msg.sender).transfer(uint256(tip) * 1e15);
        (bool success, ) = payable(_treasury).call{value: uint256(fee) * 1e15}("");
        require(success, "External treasury call failed.");
        (success, ) = payable(destination).call{value: uint256(amount) * 1e15}(data);
        require(success, "External withdrawal call failed.");
    }
}

library StorageSlot {
    struct AddressSlot {
        address value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }
}

File 2 of 7: DepositVerifier.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.8.17;

import "./InnerProductVerifier.sol";
import "./Utils.sol";

contract DepositVerifier {
    using Utils for uint256;
    using Utils for Utils.Point;

    InnerProductVerifier immutable _ip;

    constructor(address ip_) {
        _ip = InnerProductVerifier(ip_);
    }

    function g() internal view returns (Utils.Point memory) {
        return Utils.Point(_ip.gX(), _ip.gY());
    }

    function h() internal view returns (Utils.Point memory) {
        return Utils.Point(_ip.hX(), _ip.hY());
    }

    function gs(uint256 i) internal view returns (Utils.Point memory) {
        (bytes32 x, bytes32 y) = _ip.gs(i);
        return Utils.Point(x, y);
    }

    function hs(uint256 i) internal view returns (Utils.Point memory) {
        (bytes32 x, bytes32 y) = _ip.hs(i);
        return Utils.Point(x, y);
    }

    struct Locals {
        uint256 v;
        uint256 w;
        uint256 vPow;
        uint256 wPow;
        uint256[n][2] f; // could just allocate extra space in the proof?
        uint256[N] r; // each poly is an array of length N. evaluations of prods
        Utils.Point temp;
        Utils.Point C_XR;
        Utils.Point y_XR;

        uint256 c;
        Utils.Point A_D;
        Utils.Point A_X;
    }

    function verify(uint256 amount, Utils.Statement calldata statement, Utils.DepositProof calldata proof) external view {
        Locals memory locals;
        locals.v = uint256(keccak256(abi.encode(amount, statement.Y, statement.C, statement.D, proof.A, proof.B))).mod();
        locals.w = uint256(keccak256(abi.encode(locals.v, proof.C_XG, proof.y_XG))).mod();
        for (uint256 k = 0; k < n; k++) {
            locals.f[1][k] = proof.f[k];
            locals.f[0][k] = locals.w.sub(proof.f[k]);

            locals.temp = locals.temp.add(gs(k).mul(locals.f[1][k]));
            locals.temp = locals.temp.add(hs(k).mul(locals.f[1][k].mul(locals.f[0][k])));
        }
        require(proof.B.mul(locals.w).add(proof.A).eq(locals.temp.add(h().mul(proof.z_A))), "Bit-proof verification failed.");

        locals.r = Utils.assemblePolynomials(locals.f);
        locals.wPow = 1;
        for (uint256 k = 0; k < n; k++) {
            locals.C_XR = locals.C_XR.add(proof.C_XG[k].mul(locals.wPow.neg()));
            locals.y_XR = locals.y_XR.add(proof.y_XG[k].mul(locals.wPow.neg()));

            locals.wPow = locals.wPow.mul(locals.w);
        }
        locals.vPow = locals.v; // used to be 1
        for (uint256 i = 0; i < N; i++) {
            uint256 multiplier = locals.r[i].add(locals.vPow.mul(locals.wPow.sub(locals.r[i]))); // locals. ?
            locals.C_XR = locals.C_XR.add(statement.C[i].mul(multiplier));
            locals.y_XR = locals.y_XR.add(statement.Y[i].mul(multiplier));
            locals.vPow = locals.vPow.mul(locals.v); // used to do this only if (i > 0)
        }
        locals.C_XR = locals.C_XR.add(g().mul(amount.neg().mul(locals.wPow))); // this line is new

        locals.A_D = g().mul(proof.s_r).add(statement.D.mul(proof.c.neg())); // add(mul(locals.gR, proof.s_r), mul(locals.DR, proof.c.neg()));
        locals.A_X = locals.y_XR.mul(proof.s_r).add(locals.C_XR.mul(proof.c.neg()));

        locals.c = uint256(keccak256(abi.encode(locals.v, locals.A_D, locals.A_X))).mod();
        require(locals.c == proof.c, "Sigma protocol failure.");
    }
}

File 3 of 7: EpochTree.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

// ----------------------------------------------------------------------------
// BokkyPooBah's Red-Black Tree Library v1.0-pre-release-a
//
// A Solidity Red-Black Tree binary search library to store and access a sorted
// list of unsigned integer data. The Red-Black algorithm rebalances the binary
// search tree, resulting in O(log n) insert, remove and search time (and ~gas)
//
// https://github.com/bokkypoobah/BokkyPooBahsRedBlackTreeLibrary
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2020. The MIT Licence.
// ----------------------------------------------------------------------------
contract EpochTree {
    struct Node {
        uint64 parent;
        uint64 left;
        uint64 right;
        bool red;
    }

    uint64 public root;
    uint64 public blackHeight;
    uint64 constant EMPTY = 0;

    mapping(uint64 => Node) public nodes;

    function exists(uint64 key) public view returns (bool) { // need public for FirnLogic.sol
        return (key != EMPTY) && ((key == root) || (nodes[key].parent != EMPTY));
    }

    function rotateLeft(uint64 key) internal {
        uint64 cursor = nodes[key].right;
        uint64 keyParent = nodes[key].parent;
        uint64 cursorLeft = nodes[cursor].left;
        nodes[key].right = cursorLeft;
        if (cursorLeft != EMPTY) {
            nodes[cursorLeft].parent = key;
        }
        nodes[cursor].parent = keyParent;
        if (keyParent == EMPTY) {
            root = cursor;
        } else if (key == nodes[keyParent].left) {
            nodes[keyParent].left = cursor;
        } else {
            nodes[keyParent].right = cursor;
        }
        nodes[cursor].left = key;
        nodes[key].parent = cursor;
    }

    function rotateRight(uint64 key) internal {
        uint64 cursor = nodes[key].left;
        uint64 keyParent = nodes[key].parent;
        uint64 cursorRight = nodes[cursor].right;
        nodes[key].left = cursorRight;
        if (cursorRight != EMPTY) {
            nodes[cursorRight].parent = key;
        }
        nodes[cursor].parent = keyParent;
        if (keyParent == EMPTY) {
            root = cursor;
        } else if (key == nodes[keyParent].right) {
            nodes[keyParent].right = cursor;
        } else {
            nodes[keyParent].left = cursor;
        }
        nodes[cursor].right = key;
        nodes[key].parent = cursor;
    }

    function insertFixup(uint64 key) internal {
        uint64 cursor;
        while (key != root && nodes[nodes[key].parent].red) {
            uint64 keyParent = nodes[key].parent;
            if (keyParent == nodes[nodes[keyParent].parent].left) {
                cursor = nodes[nodes[keyParent].parent].right;
                if (nodes[cursor].red) {
                    nodes[keyParent].red = false;
                    nodes[cursor].red = false;
                    nodes[nodes[keyParent].parent].red = true;
                    key = nodes[keyParent].parent;
                } else {
                    if (key == nodes[keyParent].right) {
                        key = keyParent;
                        rotateLeft(key);
                    }
                    keyParent = nodes[key].parent;
                    nodes[keyParent].red = false;
                    nodes[nodes[keyParent].parent].red = true;
                    rotateRight(nodes[keyParent].parent);
                }
            } else {
                cursor = nodes[nodes[keyParent].parent].left;
                if (nodes[cursor].red) {
                    nodes[keyParent].red = false;
                    nodes[cursor].red = false;
                    nodes[nodes[keyParent].parent].red = true;
                    key = nodes[keyParent].parent;
                } else {
                    if (key == nodes[keyParent].left) {
                        key = keyParent;
                        rotateRight(key);
                    }
                    keyParent = nodes[key].parent;
                    nodes[keyParent].red = false;
                    nodes[nodes[keyParent].parent].red = true;
                    rotateLeft(nodes[keyParent].parent);
                }
            }
        }
        if (nodes[root].red) {
            nodes[root].red = false;
            blackHeight++;
        }
    }

    function insert(uint64 key) internal {
        uint64 cursor = EMPTY;
        uint64 probe = root;
        while (probe != EMPTY) {
            cursor = probe;
            if (key < probe) {
                probe = nodes[probe].left;
            } else {
                probe = nodes[probe].right;
            }
        }
        nodes[key] = Node({parent : cursor, left : EMPTY, right : EMPTY, red : true});
        if (cursor == EMPTY) {
            root = key;
        } else if (key < cursor) {
            nodes[cursor].left = key;
        } else {
            nodes[cursor].right = key;
        }
        insertFixup(key);
    }

    function replaceParent(uint64 a, uint64 b) internal {
        uint64 bParent = nodes[b].parent;
        nodes[a].parent = bParent;
        if (bParent == EMPTY) {
            root = a;
        } else {
            if (b == nodes[bParent].left) {
                nodes[bParent].left = a;
            } else {
                nodes[bParent].right = a;
            }
        }
    }

    function removeFixup(uint64 key) internal {
        uint64 cursor;
        while (key != root && !nodes[key].red) {
            uint64 keyParent = nodes[key].parent;
            if (key == nodes[keyParent].left) {
                cursor = nodes[keyParent].right;
                if (nodes[cursor].red) {
                    nodes[cursor].red = false;
                    nodes[keyParent].red = true;
                    rotateLeft(keyParent);
                    cursor = nodes[keyParent].right;
                }
                if (!nodes[nodes[cursor].left].red && !nodes[nodes[cursor].right].red) {
                    nodes[cursor].red = true;
                    key = keyParent;
                } else {
                    if (!nodes[nodes[cursor].right].red) {
                        nodes[nodes[cursor].left].red = false;
                        nodes[cursor].red = true;
                        rotateRight(cursor);
                        cursor = nodes[keyParent].right;
                    }
                    nodes[cursor].red = nodes[keyParent].red;
                    nodes[keyParent].red = false;
                    nodes[nodes[cursor].right].red = false;
                    rotateLeft(keyParent);
                    return; // key = root;
                }
            } else {
                cursor = nodes[keyParent].left;
                if (nodes[cursor].red) {
                    nodes[cursor].red = false;
                    nodes[keyParent].red = true;
                    rotateRight(keyParent);
                    cursor = nodes[keyParent].left;
                }
                if (!nodes[nodes[cursor].right].red && !nodes[nodes[cursor].left].red) {
                    nodes[cursor].red = true;
                    key = keyParent;
                } else {
                    if (!nodes[nodes[cursor].left].red) {
                        nodes[nodes[cursor].right].red = false;
                        nodes[cursor].red = true;
                        rotateLeft(cursor);
                        cursor = nodes[keyParent].left;
                    }
                    nodes[cursor].red = nodes[keyParent].red;
                    nodes[keyParent].red = false;
                    nodes[nodes[cursor].left].red = false;
                    rotateRight(keyParent);
                    return; // key = root;
                }
            }
        }
        if (nodes[key].red) nodes[key].red = false;
        else blackHeight--;
    }

    function remove(uint64 key) internal {
        uint64 probe;
        uint64 cursor;
        if (nodes[key].left == EMPTY || nodes[key].right == EMPTY) {
            cursor = key;
        } else {
            cursor = nodes[key].right;
            while (nodes[cursor].left != EMPTY) {
                cursor = nodes[cursor].left;
            }
        }
        if (nodes[cursor].left != EMPTY) {
            probe = nodes[cursor].left;
        } else {
            probe = nodes[cursor].right;
        }
        uint64 yParent = nodes[cursor].parent;
        nodes[probe].parent = yParent;
        if (yParent != EMPTY) {
            if (cursor == nodes[yParent].left) {
                nodes[yParent].left = probe;
            } else {
                nodes[yParent].right = probe;
            }
        } else {
            root = probe;
        }
        bool doFixup = !nodes[cursor].red;
        if (cursor != key) {
            replaceParent(cursor, key);
            nodes[cursor].left = nodes[key].left;
            nodes[nodes[cursor].left].parent = cursor;
            nodes[cursor].right = nodes[key].right;
            nodes[nodes[cursor].right].parent = cursor;
            nodes[cursor].red = nodes[key].red;
            (cursor, key) = (key, cursor);
        }
        if (doFixup) {
            removeFixup(probe);
        }
        delete nodes[cursor];
    }
}
// ----------------------------------------------------------------------------
// End - BokkyPooBah's Red-Black Tree Library
// ----------------------------------------------------------------------------

File 4 of 7: InnerProductVerifier.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.8.17;

import "./Utils.sol";

contract InnerProductVerifier {
    using Utils for uint256;
    using Utils for Utils.Point;

    bytes32 public immutable gX;
    bytes32 public immutable gY;
    bytes32 public immutable hX;
    bytes32 public immutable hY;
    // above, emulating immutable `Utils.Point`s using raw `bytes32`s. save some sloads later.
    Utils.Point[M << 1] public gs;
    Utils.Point[M << 1] public hs;
    // have to use storage, not immutable, because solidity doesn't support non-primitive immutable types

    constructor() {
        Utils.Point memory gTemp = Utils.mapInto("g");
        gX = gTemp.x;
        gY = gTemp.y;
        Utils.Point memory hTemp = Utils.mapInto("h");
        hX = hTemp.x;
        hY = hTemp.y;
        for (uint256 i = 0; i < M << 1; i++) {
            gs[i] = Utils.mapInto("g", i);
            hs[i] = Utils.mapInto("h", i);
        }
    }

    struct Locals {
        uint256 o;
        Utils.Point P;
        uint256[m + 1] challenges;
        uint256[M << 1] s;
    }

    function verify(Utils.InnerProductStatement calldata statement, Utils.InnerProductProof calldata proof, bool transfer) external view {
        Locals memory locals;
        locals.o = statement.salt;
        locals.P = statement.P;
        uint256 M_ = M << (transfer ? 1 : 0);
        uint256 m_ = m + (transfer ? 1 : 0);

        for (uint256 i = 0; i < m_; i++) {
            locals.o = uint256(keccak256(abi.encode(locals.o, proof.L[i], proof.R[i]))).mod(); // overwrites
            locals.challenges[i] = locals.o;
            uint256 inverse = locals.o.inv();
            locals.P = locals.P.add(proof.L[i].mul(locals.o.mul(locals.o))).add(proof.R[i].mul(inverse.mul(inverse)));
        }

        locals.s[0] = 1;
        for (uint256 i = 0; i < m_; i++) locals.s[0] = locals.s[0].mul(locals.challenges[i]);
        locals.s[0] = locals.s[0].inv();
        for (uint256 i = 0; i < m_; i++) {
            for (uint256 j = 0; j < M_; j += 1 << m_ - i) {
                locals.s[j + (1 << m_ - i - 1)] = locals.s[j].mul(locals.challenges[i]).mul(locals.challenges[i]);
            }
        }

        Utils.Point memory temp = statement.u.mul(proof.a.mul(proof.b));
        for (uint256 i = 0; i < M_; i++) {
            temp = temp.add(gs[i].mul(locals.s[i].mul(proof.a)));
            temp = temp.add(statement.hs[i].mul(locals.s[M_ - 1 - i].mul(proof.b)));
        }
        require(temp.eq(locals.P), "Inner product proof failed.");
    }
}

File 5 of 7: TransferVerifier.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.8.17;

import "./InnerProductVerifier.sol";
import "./Utils.sol";

contract TransferVerifier {
    using Utils for uint256;
    using Utils for Utils.Point;

    InnerProductVerifier immutable _ip;

    bytes32 immutable _gSumX; // 0x2fa4d012d8b2496ef27316c1447cd8958b034225a0fad7f9e9b944b7de8c5064 when Utils.m == 5
    bytes32 immutable _gSumY; // 0x0c648fe5b6fbbda8eec3d8ce13a891b005f4228f90638e84041b46a17bff0aae

    constructor(address ip_) {
        _ip = InnerProductVerifier(ip_);
        Utils.Point memory gSumTemp;
        for (uint256 i = 0; i < M << 1; i++) {
            gSumTemp = gSumTemp.add(gs(i));
        }
        _gSumX = gSumTemp.x;
        _gSumY = gSumTemp.y;
    }

    function g() internal view returns (Utils.Point memory) {
        return Utils.Point(_ip.gX(), _ip.gY());
    }

    function h() internal view returns (Utils.Point memory) {
        return Utils.Point(_ip.hX(), _ip.hY());
    }

    function gs(uint256 i) internal view returns (Utils.Point memory) {
        (bytes32 x, bytes32 y) = _ip.gs(i);
        return Utils.Point(x, y);
    }

    function hs(uint256 i) internal view returns (Utils.Point memory) {
        (bytes32 x, bytes32 y) = _ip.hs(i);
        return Utils.Point(x, y);
    }

    function gSum() private view returns (Utils.Point memory) {
        return Utils.Point(_gSumX, _gSumY);
    }

    struct Locals {
        uint256 v;
        uint256 w;
        uint256 vPow;
        uint256 wPow;
        uint256[n][2][2] f;
        uint256[N][2] r; // each poly is an array of length N. evaluations of prods
        Utils.Point temp;
        Utils.Point CLnR;
        Utils.Point CRnR;
        Utils.Point CR;
        Utils.Point DR;
        Utils.Point yR;
        Utils.Point gR;
        Utils.Point C_XR;
        Utils.Point y_XR;

        uint256 y;
        uint256[M << 1] ys;
        uint256 z;
        uint256[2] zs; // [z^2, z^3]
        uint256[M << 1] twoTimesZSquared;
        uint256 zSum;
        uint256 x;
        uint256 t;
        uint256 k;
        Utils.Point tEval;

        uint256 c;
        Utils.Point A_y;
        Utils.Point A_D;
        Utils.Point A_b;
        Utils.Point A_X;
        Utils.Point A_t;
        Utils.Point gEpoch;
        Utils.Point A_u;
    }

    function verify(Utils.Statement calldata statement, Utils.TransferProof calldata proof) external view {
        Locals memory locals;
        locals.v = uint256(keccak256(abi.encode(statement.Y, statement.CLn, statement.CRn, statement.C, statement.D, statement.epoch, statement.fee, proof.BA, proof.BS, proof.A, proof.B))).mod();
        locals.w = uint256(keccak256(abi.encode(locals.v, proof.CLnG, proof.CRnG, proof.C_0G, proof.DG, proof.y_0G, proof.gG, proof.C_XG, proof.y_XG))).mod();
        for (uint256 row = 0; row < 2; row++) {
            for (uint256 k = 0; k < n; k++) {
                locals.f[row][1][k] = proof.f[row][k];
                locals.f[row][0][k] = locals.w.sub(proof.f[row][k]);
                locals.temp = locals.temp.add(gs(k + n * row).mul(locals.f[row][1][k]));
                locals.temp = locals.temp.add(hs(k + n * row).mul(locals.f[row][1][k].mul(locals.f[row][0][k])));
            }
        }

        require(proof.B.mul(locals.w).add(proof.A).eq(locals.temp.add(h().mul(proof.z_A))), "Bit-proof verification failed.");

        locals.r[0] = Utils.assemblePolynomials(locals.f[0]);
        locals.r[1] = Utils.assemblePolynomials(locals.f[1]);
        locals.wPow = 1;
        for (uint256 k = 0; k < n; k++) {
            uint256 wNeg = locals.wPow.neg();
            locals.CLnR = locals.CLnR.add(proof.CLnG[k].mul(wNeg));
            locals.CRnR = locals.CRnR.add(proof.CRnG[k].mul(wNeg));
            locals.CR = locals.CR.add(proof.C_0G[k].mul(wNeg));
            locals.DR = locals.DR.add(proof.DG[k].mul(wNeg));
            locals.yR = locals.yR.add(proof.y_0G[k].mul(wNeg));
            locals.gR = locals.gR.add(proof.gG[k].mul(wNeg));
            locals.C_XR = locals.C_XR.add(proof.C_XG[k].mul(wNeg));
            locals.y_XR = locals.y_XR.add(proof.y_XG[k].mul(wNeg));

            locals.wPow = locals.wPow.mul(locals.w);
        }
        locals.vPow = locals.v;
        for (uint256 i = 0; i < N; i++) {
            locals.CLnR = locals.CLnR.add(statement.CLn[i].mul(locals.r[0][i]));
            locals.CRnR = locals.CRnR.add(statement.CRn[i].mul(locals.r[0][i]));
            locals.CR = locals.CR.add(statement.C[i].mul(locals.r[0][i]));
            locals.yR = locals.yR.add(statement.Y[i].mul(locals.r[0][i]));
            uint256 multiplier = locals.r[0][i].add(locals.r[1][i]);
            multiplier = multiplier.add(locals.vPow.mul(locals.wPow.sub(multiplier)));
            locals.C_XR = locals.C_XR.add(statement.C[i].mul(multiplier));
            locals.y_XR = locals.y_XR.add(statement.Y[i].mul(multiplier));

            locals.vPow = locals.vPow.mul(locals.v); // used to do this only if (i > 0)
        }
        locals.DR = locals.DR.add(statement.D.mul(locals.wPow));
        locals.gR = locals.gR.add(g().mul(locals.wPow));
        locals.C_XR = locals.C_XR.add(g().mul(statement.fee.mul(locals.wPow))); // this line is new

        locals.y = uint256(keccak256(abi.encode(locals.w))).mod();
        locals.ys[0] = 1;
        locals.k = 1;
        for (uint256 i = 1; i < M << 1; i++) {
            locals.ys[i] = locals.ys[i - 1].mul(locals.y);
            locals.k = locals.k.add(locals.ys[i]);
        }
        locals.z = uint256(keccak256(abi.encode(locals.y))).mod();
        locals.zs[0] = locals.z.mul(locals.z);
        locals.zs[1] = locals.zs[0].mul(locals.z);
        locals.zSum = locals.zs[0].add(locals.zs[1]).mul(locals.z);
        locals.k = locals.k.mul(locals.z.sub(locals.zs[0])).sub(locals.zSum.mul(1 << M).sub(locals.zSum));
        locals.t = proof.tHat.sub(locals.k); // t = tHat - delta(y, z)
        for (uint256 i = 0; i < M; i++) {
            locals.twoTimesZSquared[i] = locals.zs[0].mul(1 << i);
            locals.twoTimesZSquared[i + M] = locals.zs[1].mul(1 << i);
        }

        locals.x = uint256(keccak256(abi.encode(locals.z, proof.T_1, proof.T_2))).mod();
        locals.tEval = proof.T_1.mul(locals.x).add(proof.T_2.mul(locals.x.mul(locals.x))); // replace with "commit"?

        locals.A_y = locals.gR.mul(proof.s_sk).add(locals.yR.mul(proof.c.neg()));
        locals.A_D = g().mul(proof.s_r).add(statement.D.mul(proof.c.neg())); // add(mul(locals.gR, proof.s_r), mul(locals.DR, proof.c.neg()));
        locals.A_b = g().mul(proof.s_b).add(locals.DR.mul(locals.zs[0].neg()).add(locals.CRnR.mul(locals.zs[1])).mul(proof.s_sk).add(locals.CR.add(g().mul(statement.fee.mul(locals.wPow))).mul(locals.zs[0].neg()).add(locals.CLnR.mul(locals.zs[1])).mul(proof.c.neg())));
        locals.A_X = locals.y_XR.mul(proof.s_r).add(locals.C_XR.mul(proof.c.neg()));
        locals.A_t = g().mul(locals.t).add(locals.tEval.neg()).mul(proof.c.mul(locals.wPow)).add(h().mul(proof.s_tau)).add(g().mul(proof.s_b.neg()));
        locals.gEpoch = Utils.mapInto("Firn Epoch", statement.epoch); // TODO: cast my own address to string as well?
        locals.A_u = locals.gEpoch.mul(proof.s_sk).add(statement.u.mul(proof.c.neg()));

        locals.c = uint256(keccak256(abi.encode(locals.x, locals.A_y, locals.A_D, locals.A_b, locals.A_X, locals.A_t, locals.A_u))).mod();
        require(locals.c == proof.c, "Sigma protocol failure.");

        Utils.InnerProductStatement memory ip; // statement
        ip.salt = uint256(keccak256(abi.encode(locals.c))).mod();
        ip.u = h().mul(ip.salt);
        ip.P = proof.BA.add(proof.BS.mul(locals.x)).add(gSum().mul(locals.z.neg())).add(h().mul(proof.mu.neg())).add(ip.u.mul(proof.tHat));
        for (uint256 i = 0; i < M << 1; i++) {
            ip.hs[i] = hs(i).mul(locals.ys[i].inv());
            ip.P = ip.P.add(ip.hs[i].mul(locals.ys[i].mul(locals.z).add(locals.twoTimesZSquared[i])));
        }

        _ip.verify(ip, proof.ip, true);
    }
}

File 6 of 7: Utils.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.8.17;

uint256 constant n = 4;
uint256 constant N = 1 << n;
uint256 constant m = 5;
uint256 constant M = 1 << m;

library Utils {
    uint256 constant GROUP_ORDER = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001;
    uint256 constant FIELD_ORDER = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47;
    uint256 constant PPLUS1DIV4 = 0x0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52;

    function add(uint256 x, uint256 y) internal pure returns (uint256) {
        return addmod(x, y, GROUP_ORDER);
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulmod(x, y, GROUP_ORDER);
    }

    function inv(uint256 x) internal view returns (uint256) {
        return exp(x, GROUP_ORDER - 2);
    }

    function mod(uint256 x) internal pure returns (uint256) {
        return x % GROUP_ORDER;
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256) {
        return x >= y ? x - y : GROUP_ORDER - y + x;
    }

    function neg(uint256 x) internal pure returns (uint256) {
        return GROUP_ORDER - x;
    }

    function exp(uint256 base, uint256 exponent) internal view returns (uint256 output) {
        uint256 order = GROUP_ORDER;
        assembly {
            let location := mload(0x40)
            mstore(location, 0x20)
            mstore(add(location, 0x20), 0x20)
            mstore(add(location, 0x40), 0x20)
            mstore(add(location, 0x60), base)
            mstore(add(location, 0x80), exponent)
            mstore(add(location, 0xa0), order)
            if iszero(staticcall(gas(), 0x05, location, 0xc0, location, 0x20)) {
                revert(0, 0)
            }
            output := mload(location)
        }
    }

    function fieldExp(uint256 base, uint256 exponent) internal view returns (uint256 output) { // warning: mod p, not q
        uint256 order = FIELD_ORDER;
        assembly {
            let location := mload(0x40)
            mstore(location, 0x20)
            mstore(add(location, 0x20), 0x20)
            mstore(add(location, 0x40), 0x20)
            mstore(add(location, 0x60), base)
            mstore(add(location, 0x80), exponent)
            mstore(add(location, 0xa0), order)
            if iszero(staticcall(gas(), 0x05, location, 0xc0, location, 0x20)) {
                revert(0, 0)
            }
            output := mload(location)
        }
    }

    struct Point {
        bytes32 x;
        bytes32 y;
    }

    function add(Point memory p1, Point memory p2) internal view returns (Point memory r) {
        assembly {
            let location := mload(0x40)
            mstore(location, mload(p1))
            mstore(add(location, 0x20), mload(add(p1, 0x20)))
            mstore(add(location, 0x40), mload(p2))
            mstore(add(location, 0x60), mload(add(p2, 0x20)))
            if iszero(staticcall(gas(), 0x06, location, 0x80, r, 0x40)) {
                revert(0, 0)
            }
        }
    }

    function mul(Point memory p, uint256 s) internal view returns (Point memory r) {
        assembly {
            let location := mload(0x40)
            mstore(location, mload(p))
            mstore(add(location, 0x20), mload(add(p, 0x20)))
            mstore(add(location, 0x40), s)
            if iszero(staticcall(gas(), 0x07, location, 0x60, r, 0x40)) {
                revert(0, 0)
            }
        }
    }

    function neg(Point memory p) internal pure returns (Point memory) {
        return Point(p.x, bytes32(FIELD_ORDER - uint256(p.y))); // p.y should already be reduced mod P?
    }

    function eq(Point memory p1, Point memory p2) internal pure returns (bool) {
        return p1.x == p2.x && p1.y == p2.y;
    }

    function decompress(bytes32 input) internal view returns (Point memory) {
        if (input == 0x00) return Point(0x00, 0x00);
        uint256 x = uint256(input);
        uint256 sign = (x & 0x8000000000000000000000000000000000000000000000000000000000000000) >> 255;
        x &= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
        uint256 ySquared = fieldExp(x, 3) + 3;
        uint256 y = fieldExp(ySquared, PPLUS1DIV4);
        Point memory result = Point(bytes32(x), bytes32(y));
        if (sign != y & 0x01) return neg(result);
        return result;
    }

    function compress(Point memory input) internal pure returns (bytes32) {
        uint256 result = uint256(input.x);
        if (uint256(input.y) & 0x01 == 0x01) result |= 0x8000000000000000000000000000000000000000000000000000000000000000;
        return bytes32(result);
    }

    function mapInto(uint256 seed) internal view returns (Point memory) {
        uint256 y;
        while (true) {
            uint256 ySquared = fieldExp(seed, 3) + 3; // addmod instead of add: waste of gas, plus function overhead cost
            y = fieldExp(ySquared, PPLUS1DIV4);
            if (fieldExp(y, 2) == ySquared) {
                break;
            }
            seed += 1;
        }
        return Point(bytes32(seed), bytes32(y));
    }

    function mapInto(string memory input) internal view returns (Point memory) {
        return mapInto(uint256(keccak256(abi.encodePacked(input))) % FIELD_ORDER);
    }

    function mapInto(string memory input, uint256 i) internal view returns (Point memory) {
        return mapInto(uint256(keccak256(abi.encodePacked(input, i))) % FIELD_ORDER);
    }

    function slice(bytes memory input, uint256 start) internal pure returns (bytes32 result) {
        assembly {
            result := mload(add(add(input, 0x20), start))
        }
    }

    struct Statement {
        Point[N] Y;
        Point[N] CLn;
        Point[N] CRn;
        Point[N] C;
        Point D;
        uint256 epoch;
        Point u;
        uint256 fee;
    }

    struct DepositProof {
        Point A;
        Point B;

        Point[n] C_XG;
        Point[n] y_XG;

        uint256[n] f;
        uint256 z_A;

        uint256 c;
        uint256 s_r;
    }

    function deserializeDeposit(bytes memory arr) internal view returns (DepositProof memory proof) {
        proof.A = decompress(slice(arr, 0));
        proof.B = decompress(slice(arr, 32));

        for (uint256 k = 0; k < n; k++) {
            proof.C_XG[k] = decompress(slice(arr, 64 + k * 32));
            proof.y_XG[k] = decompress(slice(arr, 64 + (k + n) * 32));
            proof.f[k] = uint256(slice(arr, 64 + n * 64 + k * 32));
        }
        uint256 starting = n * 96;
        proof.z_A = uint256(slice(arr, 64 + starting));

        proof.c = uint256(slice(arr, 96 + starting));
        proof.s_r = uint256(slice(arr, 128 + starting));

        return proof;
    }

    struct TransferProof {
        Point BA;
        Point BS;
        Point A;
        Point B;

        Point[n] CLnG;
        Point[n] CRnG;
        Point[n] C_0G;
        Point[n] DG;
        Point[n] y_0G;
        Point[n] gG;
        Point[n] C_XG;
        Point[n] y_XG;

        uint256[n][2] f;
        uint256 z_A;

        Point T_1;
        Point T_2;
        uint256 tHat;
        uint256 mu;

        uint256 c;
        uint256 s_sk;
        uint256 s_r;
        uint256 s_b;
        uint256 s_tau;

        InnerProductProof ip;
    }

    function deserializeTransfer(bytes memory arr) internal view returns (TransferProof memory proof) {
        proof.BA = decompress(slice(arr, 0));
        proof.BS = decompress(slice(arr, 32));
        proof.A = decompress(slice(arr, 64));
        proof.B = decompress(slice(arr, 96));

        for (uint256 k = 0; k < n; k++) {
            proof.CLnG[k] = decompress(slice(arr, 128 + k * 32));
            proof.CRnG[k] = decompress(slice(arr, 128 + (k + n) * 32));
            proof.C_0G[k] = decompress(slice(arr, 128 + n * 64 + k * 32));
            proof.DG[k] = decompress(slice(arr, 128 + n * 96 + k * 32));
            proof.y_0G[k] = decompress(slice(arr, 128 + n * 128 + k * 32));
            proof.gG[k] = decompress(slice(arr, 128 + n * 160 + k * 32));
            proof.C_XG[k] = decompress(slice(arr, 128 + n * 192 + k * 32));
            proof.y_XG[k] = decompress(slice(arr, 128 + n * 224 + k * 32));
            proof.f[0][k] = uint256(slice(arr, 128 + n * 256 + k * 32));
            proof.f[1][k] = uint256(slice(arr, 128 + n * 288 + k * 32));
        }

        uint256 starting = n * 320;
        proof.z_A = uint256(slice(arr, 128 + starting));

        proof.T_1 = decompress(slice(arr, 160 + starting));
        proof.T_2 = decompress(slice(arr, 192 + starting));
        proof.tHat = uint256(slice(arr, 224 + starting));
        proof.mu = uint256(slice(arr, 256 + starting));

        proof.c = uint256(slice(arr, 288 + starting));
        proof.s_sk = uint256(slice(arr, 320 + starting));
        proof.s_r = uint256(slice(arr, 352 + starting));
        proof.s_b = uint256(slice(arr, 384 + starting));
        proof.s_tau = uint256(slice(arr, 416 + starting));

        for (uint256 i = 0; i < m + 1; i++) {
            proof.ip.L[i] = decompress(slice(arr, 448 + starting + i * 32));
            proof.ip.R[i] = decompress(slice(arr, 448 + starting + (i + m + 1) * 32));
        }
        proof.ip.a = uint256(slice(arr, 448 + starting + (m + 1) * 64));
        proof.ip.b = uint256(slice(arr, 480 + starting + (m + 1) * 64));

        return proof;
    }

    struct WithdrawalProof {
        Point BA;
        Point BS;
        Point A;
        Point B;

        Point[n] CLnG;
        Point[n] CRnG;
        Point[n] y_0G;
        Point[n] gG;
        Point[n] C_XG;
        Point[n] y_XG;

        uint256[n] f;
        uint256 z_A;

        Point T_1;
        Point T_2;
        uint256 tHat;
        uint256 mu;

        uint256 c;
        uint256 s_sk;
        uint256 s_r;
        uint256 s_b;
        uint256 s_tau;

        InnerProductProof ip;
    }

    function deserializeWithdrawal(bytes memory arr) internal view returns (WithdrawalProof memory proof) {
        proof.BA = decompress(slice(arr, 0));
        proof.BS = decompress(slice(arr, 32));
        proof.A = decompress(slice(arr, 64));
        proof.B = decompress(slice(arr, 96));

        for (uint256 k = 0; k < n; k++) {
            proof.CLnG[k] = decompress(slice(arr, 128 + k * 32));
            proof.CRnG[k] = decompress(slice(arr, 128 + (k + n) * 32));
            proof.y_0G[k] = decompress(slice(arr, 128 + n * 64 + k * 32));
            proof.gG[k] = decompress(slice(arr, 128 + n * 96 + k * 32));
            proof.C_XG[k] = decompress(slice(arr, 128 + n * 128 + k * 32));
            proof.y_XG[k] = decompress(slice(arr, 128 + n * 160 + k * 32));
            proof.f[k] = uint256(slice(arr, 128 + n * 192 + k * 32));
        }
        uint256 starting = n * 224;
        proof.z_A = uint256(slice(arr, 128 + starting));

        proof.T_1 = decompress(slice(arr, 160 + starting));
        proof.T_2 = decompress(slice(arr, 192 + starting));
        proof.tHat = uint256(slice(arr, 224 + starting));
        proof.mu = uint256(slice(arr, 256 + starting));

        proof.c = uint256(slice(arr, 288 + starting));
        proof.s_sk = uint256(slice(arr, 320 + starting));
        proof.s_r = uint256(slice(arr, 352 + starting));
        proof.s_b = uint256(slice(arr, 384 + starting));
        proof.s_tau = uint256(slice(arr, 416 + starting));

        for (uint256 i = 0; i < m; i++) { // will leave the `m`th element empty
            proof.ip.L[i] = decompress(slice(arr, 448 + starting + i * 32));
            proof.ip.R[i] = decompress(slice(arr, 448 + starting + (i + m) * 32));
        }
        proof.ip.a = uint256(slice(arr, 448 + starting + m * 64));
        proof.ip.b = uint256(slice(arr, 480 + starting + m * 64));

        return proof;
    }

    struct InnerProductStatement {
        uint256 salt;
        Point[M << 1] hs; // "overridden" parameters.
        Point u;
        Point P;
    }

    struct InnerProductProof {
        Point[m + 1] L;
        Point[m + 1] R;
        uint256 a;
        uint256 b;
    }

    function assemblePolynomials(uint256[n][2] memory f) internal pure returns (uint256[N] memory result) {
        // f is a 2m-by-2 array... containing the f's and x - f's, twice (i.e., concatenated).
        // output contains two "rows", each of length N.
        result[0] = 1;
        for (uint256 k = 0; k < n; k++) {
            for (uint256 i = 0; i < N; i += 1 << n - k) {
                result[i + (1 << n - 1 - k)] = mul(result[i], f[1][n - 1 - k]);
                result[i] = mul(result[i], f[0][n - 1 - k]);
            }
        }
    }
}

File 7 of 7: WithdrawalVerifier.sol
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.8.17;

import "./InnerProductVerifier.sol";
import "./Utils.sol";

contract WithdrawalVerifier {
    using Utils for uint256;
    using Utils for Utils.Point;

    InnerProductVerifier immutable _ip;

    bytes32 immutable _gSumX; // 0x1bcf9024624aef47656cdbd47d104a1b30efac20504e72d395e7e012727c73a3 when Utils.m == 5
    bytes32 immutable _gSumY; // 0x052d5b8798a0be8c27d47246f021c2e9841837904a92a33dc4f6c755fda097bd

    constructor(address ip_) {
        _ip = InnerProductVerifier(ip_);
        Utils.Point memory gSumTemp;
        for (uint256 i = 0; i < M; i++) {
            gSumTemp = gSumTemp.add(gs(i));
        }
        _gSumX = gSumTemp.x;
        _gSumY = gSumTemp.y;
    }

    function g() internal view returns (Utils.Point memory) {
        return Utils.Point(_ip.gX(), _ip.gY());
    }

    function h() internal view returns (Utils.Point memory) {
        return Utils.Point(_ip.hX(), _ip.hY());
    }

    function gs(uint256 i) internal view returns (Utils.Point memory) {
        (bytes32 x, bytes32 y) = _ip.gs(i);
        return Utils.Point(x, y);
    }

    function hs(uint256 i) internal view returns (Utils.Point memory) {
        (bytes32 x, bytes32 y) = _ip.hs(i);
        return Utils.Point(x, y);
    }

    function gSum() private view returns (Utils.Point memory) {
        return Utils.Point(_gSumX, _gSumY);
    }

    struct Locals {
        uint256 v;
        uint256 w;
        uint256 vPow;
        uint256 wPow;
        uint256[n][2] f; // could just allocate extra space in the proof?
        uint256[N] r; // each poly is an array of length N. evaluations of prods
        Utils.Point temp;
        Utils.Point CLnR;
        Utils.Point CRnR;
        Utils.Point yR;
        Utils.Point gR;
        Utils.Point C_XR;
        Utils.Point y_XR;

        uint256 y;
        uint256[M] ys;
        uint256 z;
        uint256[1] zs; // silly. just to match zether.
        uint256[M] twoTimesZSquared;
        uint256 zSum;
        uint256 x;
        uint256 t;
        uint256 k;
        Utils.Point tEval;

        uint256 c;
        Utils.Point A_y;
        Utils.Point A_D;
        Utils.Point A_b;
        Utils.Point A_X;
        Utils.Point A_t;
        Utils.Point gEpoch;
        Utils.Point A_u;
    }

    function verify(uint256 amount, Utils.Statement calldata statement, Utils.WithdrawalProof calldata proof, uint256 salt) external view {
        Locals memory locals;
        locals.v = uint256(keccak256(abi.encode(salt, amount, statement.Y, statement.CLn, statement.CRn, statement.C, statement.D, statement.epoch, statement.fee, proof.BA, proof.BS, proof.A, proof.B))).mod();
        locals.w = uint256(keccak256(abi.encode(locals.v, proof.CLnG, proof.CRnG, proof.y_0G, proof.gG, proof.C_XG, proof.y_XG))).mod();
        for (uint256 k = 0; k < n; k++) {
            locals.f[1][k] = proof.f[k];
            locals.f[0][k] = locals.w.sub(proof.f[k]);
            locals.temp = locals.temp.add(gs(k).mul(locals.f[1][k]));
            locals.temp = locals.temp.add(hs(k).mul(locals.f[1][k].mul(locals.f[0][k])));
        }
        require(proof.B.mul(locals.w).add(proof.A).eq(locals.temp.add(h().mul(proof.z_A))), "Bit-proof verification failed.");

        locals.r = Utils.assemblePolynomials(locals.f);
        locals.wPow = 1;
        for (uint256 k = 0; k < n; k++) {
            locals.CLnR = locals.CLnR.add(proof.CLnG[k].mul(locals.wPow.neg()));
            locals.CRnR = locals.CRnR.add(proof.CRnG[k].mul(locals.wPow.neg()));
            locals.yR = locals.yR.add(proof.y_0G[k].mul(locals.wPow.neg()));
            locals.gR = locals.gR.add(proof.gG[k].mul(locals.wPow.neg()));
            locals.C_XR = locals.C_XR.add(proof.C_XG[k].mul(locals.wPow.neg()));
            locals.y_XR = locals.y_XR.add(proof.y_XG[k].mul(locals.wPow.neg()));

            locals.wPow = locals.wPow.mul(locals.w);
        }
        locals.vPow = locals.v; // used to be 1
        for (uint256 i = 0; i < N; i++) {
            locals.CLnR = locals.CLnR.add(statement.CLn[i].mul(locals.r[i]));
            locals.CRnR = locals.CRnR.add(statement.CRn[i].mul(locals.r[i]));
            locals.yR = locals.yR.add(statement.Y[i].mul(locals.r[i]));
            uint256 multiplier = locals.r[i].add(locals.vPow.mul(locals.wPow.sub(locals.r[i]))); // locals. ?
            locals.C_XR = locals.C_XR.add(statement.C[i].mul(multiplier));
            locals.y_XR = locals.y_XR.add(statement.Y[i].mul(multiplier));
            locals.vPow = locals.vPow.mul(locals.v); // used to do this only if (i > 0)
        }
        locals.gR = locals.gR.add(g().mul(locals.wPow));
        locals.C_XR = locals.C_XR.add(g().mul(statement.fee.add(amount).mul(locals.wPow))); // this line is new

        locals.y = uint256(keccak256(abi.encode(locals.w))).mod();
        locals.ys[0] = 1;
        locals.k = 1;
        for (uint256 i = 1; i < M; i++) {
            locals.ys[i] = locals.ys[i - 1].mul(locals.y);
            locals.k = locals.k.add(locals.ys[i]);
        }
        locals.z = uint256(keccak256(abi.encode(locals.y))).mod();
        locals.zs[0] = locals.z.mul(locals.z);
        locals.zSum = locals.zs[0].mul(locals.z); // trivial sum
        locals.k = locals.k.mul(locals.z.sub(locals.zs[0])).sub(locals.zSum.mul(1 << M).sub(locals.zSum));
        locals.t = proof.tHat.sub(locals.k);
        for (uint256 i = 0; i < M; i++) {
            locals.twoTimesZSquared[i] = locals.zs[0].mul(1 << i);
        }

        locals.x = uint256(keccak256(abi.encode(locals.z, proof.T_1, proof.T_2))).mod();
        locals.tEval = proof.T_1.mul(locals.x).add(proof.T_2.mul(locals.x.mul(locals.x))); // replace with "commit"?

        locals.A_y = locals.gR.mul(proof.s_sk).add(locals.yR.mul(proof.c.neg()));
        locals.A_D = g().mul(proof.s_r).add(statement.D.mul(proof.c.neg())); // add(mul(locals.gR, proof.s_r), mul(locals.DR, proof.c.neg()));
        locals.A_b = g().mul(proof.s_b).add(locals.CRnR.mul(locals.zs[0]).mul(proof.s_sk).add(locals.CLnR.mul(locals.zs[0]).mul(proof.c.neg())));
        locals.A_X = locals.y_XR.mul(proof.s_r).add(locals.C_XR.mul(proof.c.neg()));
        locals.A_t = g().mul(locals.t).add(locals.tEval.neg()).mul(proof.c.mul(locals.wPow)).add(h().mul(proof.s_tau)).add(g().mul(proof.s_b.neg()));
        locals.gEpoch = Utils.mapInto("Firn Epoch", statement.epoch); // TODO: cast my own address to string as well?
        locals.A_u = locals.gEpoch.mul(proof.s_sk).add(statement.u.mul(proof.c.neg()));

        locals.c = uint256(keccak256(abi.encode(locals.x, locals.A_y, locals.A_D, locals.A_b, locals.A_X, locals.A_t, locals.A_u))).mod();
        require(locals.c == proof.c, "Sigma protocol failure.");

        Utils.InnerProductStatement memory ip; // statement
        ip.salt = uint256(keccak256(abi.encode(locals.c))).mod();
        ip.u = h().mul(ip.salt);
        ip.P = proof.BA.add(proof.BS.mul(locals.x)).add(gSum().mul(locals.z.neg())).add(h().mul(proof.mu.neg())).add(ip.u.mul(proof.tHat));
        for (uint256 i = 0; i < M; i++) {
            ip.hs[i] = hs(i).mul(locals.ys[i].inv());
            ip.P = ip.P.add(ip.hs[i].mul(locals.ys[i].mul(locals.z).add(locals.twoTimesZSquared[i])));
        }

        _ip.verify(ip, proof.ip, false);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"deposit_","type":"address"},{"internalType":"address","name":"transfer_","type":"address"},{"internalType":"address","name":"withdrawal_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32","name":"D","type":"bytes32"},{"indexed":true,"internalType":"address","name":"source","type":"address"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"DepositOccurred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"bytes32","name":"account","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"}],"name":"RegisterOccurred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32","name":"D","type":"bytes32"}],"name":"TransferOccurred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"indexed":false,"internalType":"bytes32","name":"D","type":"bytes32"},{"indexed":false,"internalType":"uint32","name":"amount","type":"uint32"},{"indexed":true,"internalType":"address","name":"destination","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"WithdrawalOccurred","type":"event"},{"inputs":[{"internalType":"address","name":"treasury_","type":"address"},{"internalType":"uint32","name":"fee_","type":"uint32"}],"name":"administrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blackHeight","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"internalType":"bytes32","name":"D","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"key","type":"uint64"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"info","outputs":[{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint64","name":"index","type":"uint64"},{"internalType":"uint64","name":"amount","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"epoch","type":"uint64"}],"name":"lengths","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lists","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"","type":"uint64"}],"name":"nodes","outputs":[{"internalType":"uint64","name":"parent","type":"uint64"},{"internalType":"uint64","name":"left","type":"uint64"},{"internalType":"uint64","name":"right","type":"uint64"},{"internalType":"bool","name":"red","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"Y","type":"bytes32"},{"internalType":"bytes32[2]","name":"signature","type":"bytes32[2]"}],"name":"register","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"Y","type":"bytes32[]"},{"internalType":"uint32","name":"epoch","type":"uint32"}],"name":"simulateAccounts","outputs":[{"internalType":"bytes32[2][]","name":"result","type":"bytes32[2][]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"internalType":"bytes32","name":"D","type":"bytes32"},{"internalType":"bytes32","name":"u","type":"bytes32"},{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint32","name":"tip","type":"uint32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[16]","name":"Y","type":"bytes32[16]"},{"internalType":"bytes32[16]","name":"C","type":"bytes32[16]"},{"internalType":"bytes32","name":"D","type":"bytes32"},{"internalType":"bytes32","name":"u","type":"bytes32"},{"internalType":"uint64","name":"epoch","type":"uint64"},{"internalType":"uint32","name":"amount","type":"uint32"},{"internalType":"uint32","name":"tip","type":"uint32"},{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"address","name":"destination","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610120604052600680546001600160401b03191690553480156200002257600080fd5b5060405162005d5a38038062005d5a833981016040819052620000459162000234565b6001600160a01b0380841660805282811660a052811660c0526040805180820190915260018152606760f81b602080830191909152600091620000919162001db2620000a9821b17901c565b805160e052602001516101005250620002f492505050565b60408051808201909152600080825260208201526200010f60008051602062005d3a83398151915283604051602001620000e491906200027e565b6040516020818303038152906040528051906020012060001c620001099190620002af565b62000115565b92915050565b604080518082019091526000808252602082015260005b60006200013b846003620001bf565b62000148906003620002d2565b905062000176817f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52620001bf565b91508062000186836002620001bf565b03620001935750620001a9565b620001a0600185620002d2565b9350506200012c565b6040805180820190915292835260208301525090565b60008060008051602062005d3a833981519152905060405160208152602080820152602060408201528460608201528360808201528160a082015260208160c08360055afa6200020e57600080fd5b51949350505050565b80516001600160a01b03811681146200022f57600080fd5b919050565b6000806000606084860312156200024a57600080fd5b620002558462000217565b9250620002656020850162000217565b9150620002756040850162000217565b90509250925092565b6000825160005b81811015620002a1576020818601810151858301520162000285565b506000920191825250919050565b600082620002cd57634e487b7160e01b600052601260045260246000fd5b500690565b808201808211156200010f57634e487b7160e01b600052601160045260246000fd5b60805160a05160c05160e051610100516159f36200034760003960008181610c750152610d45015260008181610c520152610d220152600061134b015260006109c80152600061194c01526159f36000f3fe6080604052600436106100d25760003560e01c806362ab46821161007f578063e220a18f11610059578063e220a18f146102e8578063e2226a7c14610315578063ebf0c71714610335578063f4859e571461036f57600080fd5b806362ab46821461023857806379a80fdb14610258578063b64a097e1461026b57600080fd5b806330d00012116100b057806330d0001214610163578063414962961461017657806359ca4af3146101a657600080fd5b80630d206705146100d75780630e040440146100f95780632316aa6c14610119575b600080fd5b3480156100e357600080fd5b506100f76100f2366004614b75565b61039c565b005b34801561010557600080fd5b506100f7610114366004614c1b565b6104aa565b34801561012557600080fd5b50610150610134366004614cbd565b67ffffffffffffffff1660009081526008602052604090205490565b6040519081526020015b60405180910390f35b6100f7610171366004614cdf565b610af0565b34801561018257600080fd5b50610196610191366004614cbd565b610e4e565b604051901515815260200161015a565b3480156101b257600080fd5b506102026101c1366004614cbd565b60016020526000908152604090205467ffffffffffffffff80821691680100000000000000008104821691600160801b82041690600160c01b900460ff1684565b60405161015a949392919067ffffffffffffffff9485168152928416602084015292166040820152901515606082015260800190565b34801561024457600080fd5b506100f7610253366004614d12565b610ea1565b6100f7610266366004614e10565b611613565b34801561027757600080fd5b506102bd610286366004614e85565b60076020526000908152604090205467ffffffffffffffff80821691680100000000000000008104821691600160801b9091041683565b6040805167ffffffffffffffff9485168152928416602084015292169181019190915260600161015a565b3480156102f457600080fd5b50610308610303366004614e9e565b611a73565b60405161015a9190614f22565b34801561032157600080fd5b50610150610330366004614f8b565b611d81565b34801561034157600080fd5b506000546103569067ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161015a565b34801561037b57600080fd5b506000546103569068010000000000000000900467ffffffffffffffff1681565b6103a4611e23565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104235760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064015b60405180910390fd5b6006805463ffffffff9092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff90941668010000000000000000029390931667ffffffffffffffff90921691909117919091179055565b6104b5603c42615013565b8467ffffffffffffffff161461050d5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e0000000000000000000000000000000000000000604482015260640161041a565b60065467ffffffffffffffff8086169116101561054d576006805467ffffffffffffffff191667ffffffffffffffff861617905561054d600560006146a4565b60005b6005548110156105d857856005828154811061056e5761056e615027565b9060005260206000200154036105c65760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e00000000000000000000000000604482015260640161041a565b806105d081615056565b915050610550565b50600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0018590556106166146c5565b61061f87611e72565b608082015260005b601081101561096d576106508a826010811061064557610645615027565b602002013587611f55565b61066f8a826010811061066557610665615027565b6020020135611e72565b8251826010811061068257610682615027565b602002015261069c89826010811061066557610665615027565b826060015182601081106106b2576106b2615027565b602002015260608201516107389082601081106106d1576106d1615027565b6020020151600260008d85601081106106ec576106ec615027565b6020020135815260200190815260200160002060006002811061071157610711615027565b60408051808201909152600291909102919091018054825260010154602082015290612065565b8260200151826010811061074e5761074e615027565b6020020152608082015161079790600260008d856010811061077257610772615027565b6020020135815260200190815260200160002060016002811061071157610711615027565b826040015182601081106107ad576107ad615027565b602002015260608201516107e79082601081106107cc576107cc615027565b6020020151600360008d85601081106106ec576106ec615027565b600360008c84601081106107fd576107fd615027565b6020020135815260200190815260200160002060006002811061082257610822615027565b60020201600082015181600001556020820151816001015590505061085b8260800151600360008d856010811061077257610772615027565b600360008c846010811061087157610871615027565b6020020135815260200190815260200160002060016002811061089657610896615027565b6002020160008201518160000155602082015181600101559050506000600760008c84601081106108c9576108c9615027565b6020908102919091013582528101919091526040016000205467ffffffffffffffff16116109395760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e000000604482015260640161041a565b61095b8a826010811061094e5761094e615027565b60200201356000886120b5565b8061096581615056565b915050610627565b5067ffffffffffffffff851660a082015261098786611e72565b60c082015263ffffffff841660e0820152604080516020601f850181900481028201810190925283815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163a00ceb12918491610a169190889088908190840183828082843760009201919091525061232892505050565b6040518363ffffffff1660e01b8152600401610a33929190615251565b60006040518083038186803b158015610a4b57600080fd5b505afa158015610a5f573d6000803e3d6000fd5b503392506108fc9150610a81905063ffffffff871666038d7ea4c68000615413565b6040518115909202916000818181858888f19350505050158015610aa9573d6000803e3d6000fd5b507ff6f8a48e4a3e66a7c69c76d4c466f5c8ecffc318c99005256a2630b44045c772898989604051610add9392919061542a565b60405180910390a1505050505050505050565b662386f26fc10000341015610b475760405162461bcd60e51b815260206004820152601b60248201527f4d757374206265206174206c6561737420302e303130204554482e0000000000604482015260640161041a565b610b5866038d7ea4c680003461544c565b15610ba55760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652061206d756c7469706c65206f6620302e303031204554482e604482015260640161041a565b6000610bb2603c42615013565b90506a038d7ea4c2f2815b398000471115610c0f5760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e000000000000604482015260640161041a565b6000610c2266038d7ea4c6800034615013565b9050610cb5610ca18263ffffffff16610c9b604080518082018252600080825260209182015281518083019092527f000000000000000000000000000000000000000000000000000000000000000082527f00000000000000000000000000000000000000000000000000000000000000009082015290565b90612825565b600086815260036020526040812090610711565b6000858152600360209081526040822083518155920151600190920191909155610cde85611e72565b90506000610d71610cf9610cf28735612863565b8490612825565b610d6b6020880135610c9b604080518082018252600080825260209182015281518083019092527f000000000000000000000000000000000000000000000000000000000000000082527f00000000000000000000000000000000000000000000000000000000000000009082015290565b90612065565b90506000610dab308884604051602001610d8d93929190615460565b6040516020818303038152906040528051906020012060001c61288f565b905085358114610dfd5760405162461bcd60e51b815260206004820152601b60248201527f5369676e6174757265206661696c656420746f207665726966792e0000000000604482015260640161041a565b610e088785876120b5565b60405163ffffffff85168152879033907f84628036fe71169f22b5c76e246fc456cfa786e31c780706f3fe13699adaa8199060200160405180910390a350505050505050565b600067ffffffffffffffff821615801590610e9b575060005467ffffffffffffffff83811691161480610e9b575067ffffffffffffffff8281166000908152600160205260409020541615155b92915050565b610eac603c42615013565b8867ffffffffffffffff1614610f045760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e0000000000000000000000000000000000000000604482015260640161041a565b60065467ffffffffffffffff808a1691161015610f44576006805467ffffffffffffffff191667ffffffffffffffff8a16179055610f44600560006146a4565b60005b600554811015610fcf578960058281548110610f6557610f65615027565b906000526020600020015403610fbd5760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e00000000000000000000000000604482015260640161041a565b80610fc781615056565b915050610f47565b50600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00189905560405173ffffffffffffffffffffffffffffffffffffffff8416907f455f9623b71a09d41c2aab8b7edd236e2a1ab057ad848f6be4290c5079c5934790611057908f908f908f908d9089908990615520565b60405180910390a26110676146c5565b6110708b611e72565b608082015260005b60108110156112aa5760008e826010811061109557611095615027565b602002013590506110a6818c611f55565b6110af81611e72565b835183601081106110c2576110c2615027565b60200201526110dc8e836010811061066557610665615027565b836060015183601081106110f2576110f2615027565b6020020152606083015161113b90836010811061111157611111615027565b60200201516002600084815260200190815260200160002060006002811061071157610711615027565b8360200151836010811061115157611151615027565b602002018190525061118683608001516002600084815260200190815260200160002060016002811061071157610711615027565b8360400151836010811061119c5761119c615027565b602002015260608301516111e59083601081106111bb576111bb615027565b60200201516003600084815260200190815260200160002060006002811061071157610711615027565b6000828152600360209081526040909120825181559101516001808301919091556080850151611216929091610711565b6000828152600360208181526040808420855160028201559482015194909201939093556007909252205467ffffffffffffffff166112975760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e000000604482015260640161041a565b50806112a281615056565b915050611078565b506006546000906112e1907c0100000000000000000000000000000000000000000000000000000000900463ffffffff168a615568565b67ffffffffffffffff8b1660a084015290506112fc8b611e72565b60c083015261130b818961558b565b63ffffffff1660e083015260405160009061132e908790879087906020016155a8565b6040516020818303038152906040528051906020012060001c90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f11b521f8b856113c68c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128bb92505050565b856040518563ffffffff1660e01b81526004016113e694939291906155e1565b60006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b503392506108fc9150611434905063ffffffff8c1666038d7ea4c68000615413565b6040518115909202916000818181858888f1935050505015801561145c573d6000803e3d6000fd5b5060065460009068010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661149c63ffffffff851666038d7ea4c68000615413565b604051600081818185875af1925050503d80600081146114d8576040519150601f19603f3d011682016040523d82523d6000602084013e6114dd565b606091505b505090508061152e5760405162461bcd60e51b815260206004820152601e60248201527f45787465726e616c2074726561737572792063616c6c206661696c65642e0000604482015260640161041a565b73ffffffffffffffffffffffffffffffffffffffff871661155c63ffffffff8d1666038d7ea4c68000615413565b878760405161156c929190615796565b60006040518083038185875af1925050503d80600081146115a9576040519150601f19603f3d011682016040523d82523d6000602084013e6115ae565b606091505b505080915050806116015760405162461bcd60e51b815260206004820181905260248201527f45787465726e616c207769746864726177616c2063616c6c206661696c65642e604482015260640161041a565b50505050505050505050505050505050565b61162466038d7ea4c680003461544c565b156116715760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652061206d756c7469706c65206f6620302e303031204554482e604482015260640161041a565b600061167e603c42615013565b90506a038d7ea4c2f2815b3980004711156116db5760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e000000000000604482015260640161041a565b60006116ee66038d7ea4c6800034615013565b90506116f86146c5565b61170186611e72565b608082015260005b60108110156119495761173289826010811061172757611727615027565b602002013585611f55565b61174789826010811061066557610665615027565b8251826010811061175a5761175a615027565b602002015261177488826010811061066557610665615027565b8260600151826010811061178a5761178a615027565b602002015260608201516117c49082601081106117a9576117a9615027565b6020020151600360008c85601081106106ec576106ec615027565b600360008b84601081106117da576117da615027565b602002013581526020019081526020016000206000600281106117ff576117ff615027565b6002020160008201518160000155602082015181600101559050506118388260800151600360008c856010811061077257610772615027565b600360008b846010811061184e5761184e615027565b6020020135815260200190815260200160002060016002811061187357611873615027565b6002020160008201518160000155602082015181600101559050506000600760008b84601081106118a6576118a6615027565b6020908102919091013582528101919091526040016000205467ffffffffffffffff16116119165760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e000000604482015260640161041a565b61193789826010811061192b5761192b615027565b602002013584866120b5565b8061194181615056565b915050611709565b507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166377f7335583836119c789898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b6040518463ffffffff1660e01b81526004016119e5939291906157a6565b60006040518083038186803b1580156119fd57600080fd5b505afa158015611a11573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff167fbdee54bab8aa68aecbb89de2313baaa387447195fe74aa236a4d9345799b330089898986604051611a619493929190615850565b60405180910390a25050505050505050565b60608267ffffffffffffffff811115611a8e57611a8e615880565b604051908082528060200260200182016040528015611ac757816020015b611ab4614747565b815260200190600190039081611aac5790505b50905060005b83811015611d7957611add614765565b60026000878785818110611af357611af3615027565b905060200201358152602001908152602001600020600060028110611b1a57611b1a615027565b60408051808201909152600291820292909201805483526001015460208301529082526000878785818110611b5157611b51615027565b905060200201358152602001908152602001600020600160028110611b7857611b78615027565b600202016040518060400160405290816000820154815260200160018201548152505081600160028110611bae57611bae615027565b602002015263ffffffff841660046000888886818110611bd057611bd0615027565b602090810292909201358352508101919091526040016000205467ffffffffffffffff161015611ce857611c6a60036000888886818110611c1357611c13615027565b905060200201358152602001908152602001600020600060028110611c3a57611c3a615027565b6040805180820190915260029190910291909101805482526001015460208201528260005b602002015190612065565b8152611ce260036000888886818110611c8557611c85615027565b905060200201358152602001908152602001600020600160028110611cac57611cac615027565b600202016040518060400160405290816000820154815260200160018201548152505082600160028110611c5f57611c5f615027565b60208201525b611cf98160005b6020020151612d82565b838381518110611d0b57611d0b615027565b6020026020010151600060028110611d2557611d25615027565b6020020152611d35816001611cef565b838381518110611d4757611d47615027565b6020026020010151600160028110611d6157611d61615027565b60200201525080611d7181615056565b915050611acd565b509392505050565b60086020528160005260406000208181548110611d9d57600080fd5b90600052602060002001600091509150505481565b6040805180820190915260008082526020820152610e9b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4783604051602001611dfb91906158af565b6040516020818303038152906040528051906020012060001c611e1e919061544c565b612dc0565b6000611e56611e5360017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61046158de565b90565b5473ffffffffffffffffffffffffffffffffffffffff16919050565b60408051808201909152600080825260208201526000829003611ea8575050604080518082019091526000808252602082015290565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821660ff83901c6000611edd836003612e5d565b611ee89060036158f1565b90506000611f16827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52612e5d565b6040805180820190915285815260208101829052909150600182168414611f4b57611f4081612ec5565b979650505050505050565b9695505050505050565b60008281526004602052604090205467ffffffffffffffff8083169116101561206157600082815260036020908152604080832081518083018352815481526001909101548184015285845260029092528220611fb192610711565b600083815260026020818152604080842085518155948201516001808701919091556003808452828620835180850190945280860154845201548284015293879052919052612001929091610711565b6000838152600260208181526040808420855181850155948201516003958601558482528084208481556001810185905592830184905591909301829055600490925220805467ffffffffffffffff191667ffffffffffffffff83161790555b5050565b60408051808201909152600080825260208201526040518351815260208401516020820152825160408201526020830151606082015260408260808360065afa6120ae57600080fd5b5092915050565b6000838152600760205260408120805467ffffffffffffffff161561223957805467ffffffffffffffff16600090815260086020526040902080549092508290612101906001906158de565b8154811061211157612111615027565b60009182526020909120015481548354849168010000000000000000900467ffffffffffffffff1690811061214857612148615027565b90600052602060002001819055508180548061216657612166615904565b6001900381819060005260206000200160009055905581805490506000036121a257805461219d9067ffffffffffffffff16612f23565b612239565b8154815468010000000000000000900467ffffffffffffffff16101561223957805482546801000000000000000090910467ffffffffffffffff16906007906000908590849081106121f6576121f6615027565b9060005260206000200154815260200190815260200160002060000160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b805467ffffffffffffffff191667ffffffffffffffff8481169190911780835563ffffffff861691839160109161227a918591600160801b90910416615933565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506122a983610e4e565b6122b6576122b683613357565b67ffffffffffffffff9290921660009081526008602090815260408220805485547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1663ffffffff90911668010000000000000000021790945583546001810185559382529020909101929092555050565b61233061479e565b602082015161234390611e72565b611e72565b8152604082015161235390611e72565b6020820152606082015161236690611e72565b6040820152608082015161237990611e72565b606082015260005b6004811015612621576123af61233e8461239c846020615413565b6123a79060806158f1565b016020015190565b826080015182600481106123c5576123c5615027565b60200201526123e761233e846123dc6004856158f1565b61239c906020615413565b8260a0015182600481106123fd576123fd615027565b602002018190525061243a61233e848360206124199190615413565b61242560046040615413565b6124309060806158f1565b6123a791906158f1565b8260c00151826004811061245057612450615027565b602002018190525061247861233e8483602061246c9190615413565b61242560046060615413565b8260e00151826004811061248e5761248e615027565b60200201819052506124b661233e848360206124aa9190615413565b61242560046080615413565b82610100015182600481106124cd576124cd615027565b60200201819052506124f561233e848360206124e99190615413565b612425600460a0615413565b826101200151826004811061250c5761250c615027565b602002018190525061253461233e848360206125289190615413565b612425600460c0615413565b826101400151826004811061254b5761254b615027565b602002018190525061257361233e848360206125679190615413565b612425600460e0615413565b826101600151826004811061258a5761258a615027565b60200201819052506125b0838260206125a39190615413565b6124256004610100615413565b6101808301515182600481106125c8576125c8615027565b6020020181815250506125ef838260206125e29190615413565b6124256004610120615413565b61018083015160200151826004811061260a5761260a615027565b60200201528061261981615056565b915050612381565b5060006126316004610140615413565b9050612642836123a78360806158f1565b6101a083015261265a61233e846123a78460a06158f1565b6101c083015261267261233e846123a78460c06158f1565b6101e0830152612687836123a78360e06158f1565b61020083015261269d836123a7836101006158f1565b6102208301526126b3836123a7836101206158f1565b6102408301526126c9836123a7836101406158f1565b6102608301526126df836123a7836101606158f1565b6102808301526126f5836123a7836101806158f1565b6102a083015261270b836123a7836101a06158f1565b6102c083015260005b612720600560016158f1565b8110156127bc5761274561233e85612739846020615413565b612430866101c06158f1565b6102e084015151826006811061275d5761275d615027565b602002015261278a61233e856127746005856158f1565b61277f9060016158f1565b612739906020615413565b836102e001516020015182600681106127a5576127a5615027565b6020020152806127b481615056565b915050612714565b506127e4836127cd600560016158f1565b6127d8906040615413565b612430846101c06158f1565b6102e083015160400152612815836127fe600560016158f1565b612809906040615413565b612430846101e06158f1565b6102e08301516060015250919050565b6040805180820190915260008082526020820152604051835181526020840151602082015282604082015260408260608360075afa6120ae57600080fd5b6000610e9b827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016158de565b6000610e9b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018361544c565b6128c36148ef565b60208201516128d190611e72565b815260408201516128e190611e72565b602082015260608201516128f490611e72565b6040820152608082015161290790611e72565b606082015260005b6004811015612a7e5761292a61233e8461239c846020615413565b8260800151826004811061294057612940615027565b602002015261295761233e846123dc6004856158f1565b8260a00151826004811061296d5761296d615027565b602002018190525061298961233e848360206124199190615413565b8260c00151826004811061299f5761299f615027565b60200201819052506129bb61233e8483602061246c9190615413565b8260e0015182600481106129d1576129d1615027565b60200201819052506129ed61233e848360206124aa9190615413565b8261010001518260048110612a0457612a04615027565b6020020181905250612a2061233e848360206124e99190615413565b8261012001518260048110612a3757612a37615027565b6020020181905250612a50838260206125289190615413565b6101408301518260048110612a6757612a67615027565b602002015280612a7681615056565b91505061290f565b506000612a8d600460e0615413565b9050612a9e836123a78360806158f1565b610160830152612ab661233e846123a78460a06158f1565b610180830152612ace61233e846123a78460c06158f1565b6101a0830152612ae3836123a78360e06158f1565b6101c0830152612af9836123a7836101006158f1565b6101e0830152612b0f836123a7836101206158f1565b610200830152612b25836123a7836101406158f1565b610220830152612b3b836123a7836101606158f1565b610240830152612b51836123a7836101806158f1565b610260830152612b67836123a7836101a06158f1565b61028083015260005b6005811015612bec57612b8b61233e85612739846020615413565b6102a0840151518260068110612ba357612ba3615027565b6020020152612bba61233e8561277f6005856158f1565b836102a00151602001518260068110612bd557612bd5615027565b602002015280612be481615056565b915050612b70565b50612bfd836127d860056040615413565b60001c826102a001516040018181525050612c2083600560406128099190615413565b6102a08301516060015250919050565b612c386149ab565b6020820151612c4690611e72565b81526040820151612c5690611e72565b602082015260005b6004811015612d2f57612c8461233e84612c79846020615413565b6123a79060406158f1565b82604001518260048110612c9a57612c9a615027565b6020020152612cbc61233e84612cb16004856158f1565b612c79906020615413565b82606001518260048110612cd257612cd2615027565b6020020181905250612d0283826020612ceb9190615413565b612cf760046040615413565b6124309060406158f1565b60808301518260048110612d1857612d18615027565b602002015280612d2781615056565b915050612c5e565b506000612d3e60046060615413565b9050612d4f836123a78360406158f1565b60a0830152612d63836123a78360606158f1565b60c0830152612d77836123a78360806158f1565b60e083015250919050565b805160208201516000919060019081169003610e9b577f80000000000000000000000000000000000000000000000000000000000000001792915050565b604080518082019091526000808252602082015260005b6000612de4846003612e5d565b612def9060036158f1565b9050612e1b817f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52612e5d565b915080612e29836002612e5d565b03612e345750612e47565b612e3f6001856158f1565b935050612dd7565b6040805180820190915292835260208301525090565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060405160208152602080820152602060408201528460608201528360808201528160a082015260208160c08360055afa612ebc57600080fd5b51949350505050565b6040805180820190915260008082526020820152604080518082019091528251815260208084015190820190612f1b907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476158de565b905292915050565b67ffffffffffffffff81811660009081526001602052604081205490918291680100000000000000009004161580612f7b575067ffffffffffffffff838116600090815260016020526040902054600160801b900416155b15612f87575081613006565b5067ffffffffffffffff808316600090815260016020526040902054600160801b9004165b67ffffffffffffffff81811660009081526001602052604090205468010000000000000000900416156130065767ffffffffffffffff90811660009081526001602052604090205468010000000000000000900416612fac565b67ffffffffffffffff81811660009081526001602052604090205468010000000000000000900416156130625767ffffffffffffffff808216600090815260016020526040902054680100000000000000009004169150613088565b67ffffffffffffffff808216600090815260016020526040902054600160801b90041691505b67ffffffffffffffff8082166000908152600160205260408082205485841683529120805467ffffffffffffffff19169190921690811790915580156131a65767ffffffffffffffff8082166000908152600160205260409020546801000000000000000090048116908316036131525767ffffffffffffffff8082166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790556131c4565b67ffffffffffffffff80821660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790556131c4565b6000805467ffffffffffffffff191667ffffffffffffffff85161790555b67ffffffffffffffff828116600081815260016020526040902054600160c01b900460ff161591861614613304576131fc83866135ca565b67ffffffffffffffff858116600090815260016020526040808220805487851680855283852080547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000009384900488168402178082559290920486168552838520805467ffffffffffffffff199081168317909155835483547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9182900489168202178085550490961685529284208054909516831790945554915281547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9182900460ff1615159091021790559193915b80156133135761331384613707565b505067ffffffffffffffff16600090815260016020526040902080547fffffffffffffff000000000000000000000000000000000000000000000000001690555050565b6000805467ffffffffffffffff165b67ffffffffffffffff8116156133ea578091508067ffffffffffffffff168367ffffffffffffffff1610156133c25767ffffffffffffffff90811660009081526001602052604090205468010000000000000000900416613366565b67ffffffffffffffff908116600090815260016020526040902054600160801b900416613366565b6040805160808101825267ffffffffffffffff808516808352600060208085018281528587018381526001606088018181528c88168652935296909220945185549251965191511515600160c01b027fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff928616600160801b02929092167fffffffffffffff000000000000000000ffffffffffffffffffffffffffffffff97861668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909516179190911794909416919091179290921790556134f7576000805467ffffffffffffffff191667ffffffffffffffff85161790556135bc565b8167ffffffffffffffff168367ffffffffffffffff16101561356c5767ffffffffffffffff8083166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790556135bc565b67ffffffffffffffff80831660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790555b6135c583613e24565b505050565b67ffffffffffffffff8082166000908152600160205260408082205485841683529120805467ffffffffffffffff1916919092169081179091558061362d576000805467ffffffffffffffff851667ffffffffffffffff19909116179055505050565b67ffffffffffffffff8082166000908152600160205260409020546801000000000000000090048116908316036136b55767ffffffffffffffff908116600090815260016020526040902080547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000094909216939093021790915550565b67ffffffffffffffff908116600090815260016020526040902080547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b94909216939093021790915550565b60005b60005467ffffffffffffffff83811691161480159061374a575067ffffffffffffffff8216600090815260016020526040902054600160c01b900460ff16155b15613d695767ffffffffffffffff808316600081815260016020526040808220548416808352912054909268010000000000000000909104169003613a6c5767ffffffffffffffff81811660009081526001602052604080822054600160801b900490921680825291902054909250600160c01b900460ff161561384f5767ffffffffffffffff80831660009081526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155928416825290208054909116600160c01b1790556138298161421e565b67ffffffffffffffff808216600090815260016020526040902054600160801b90041691505b67ffffffffffffffff8281166000908152600160205260408082205468010000000000000000900490921681522054600160c01b900460ff161580156138c6575067ffffffffffffffff82811660009081526001602052604080822054600160801b900490921681522054600160c01b900460ff16155b156139185767ffffffffffffffff8216600090815260016020526040902080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b179055915081613d63565b67ffffffffffffffff82811660009081526001602052604080822054600160801b900490921681522054600160c01b900460ff166139e65767ffffffffffffffff80831660008181526001602052604080822080546801000000000000000090049094168252812080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155919052815416600160c01b1790556139c082614466565b67ffffffffffffffff808216600090815260016020526040902054600160801b90041691505b67ffffffffffffffff80821660009081526001602052604080822080548685168452828420805460ff600160c01b938490041615159092027fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff928316178155825482169092559054600160801b900490931682529020805490911690556135c58161421e565b67ffffffffffffffff8181166000908152600160205260408082205468010000000000000000900490921680825291902054909250600160c01b900460ff1615613b3c5767ffffffffffffffff80831660009081526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155928416825290208054909116600160c01b179055613b1181614466565b67ffffffffffffffff8082166000908152600160205260409020546801000000000000000090041691505b67ffffffffffffffff82811660009081526001602052604080822054600160801b900490921681522054600160c01b900460ff16158015613bb3575067ffffffffffffffff8281166000908152600160205260408082205468010000000000000000900490921681522054600160c01b900460ff16155b15613c055767ffffffffffffffff8216600090815260016020526040902080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b179055915081613d63565b67ffffffffffffffff8281166000908152600160205260408082205468010000000000000000900490921681522054600160c01b900460ff16613cd85767ffffffffffffffff8083166000818152600160205260408082208054600160801b90049094168252812080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155919052815416600160c01b179055613cad8261421e565b67ffffffffffffffff8082166000908152600160205260409020546801000000000000000090041691505b67ffffffffffffffff80821660009081526001602052604080822080548685168452828420805460ff600160c01b938490041615159092027fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff92831617815582548216909255905468010000000000000000900490931682529020805490911690556135c581614466565b5061370a565b67ffffffffffffffff8216600090815260016020526040902054600160c01b900460ff1615613dd3575067ffffffffffffffff16600090815260016020526040902080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff169055565b6000805468010000000000000000900467ffffffffffffffff16906008613df983615954565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b60005b60005467ffffffffffffffff838116911614801590613e6f575067ffffffffffffffff8281166000908152600160205260408082205490921681522054600160c01b900460ff165b156141995767ffffffffffffffff80831660009081526001602052604080822054831680835281832054841683529120549091680100000000000000009091041681036140225767ffffffffffffffff818116600090815260016020526040808220548316825280822054600160801b900490921680825291902054909250600160c01b900460ff1615613f715767ffffffffffffffff80821660008181526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116825587861684528284208054821690558154861684529183208054909216600160c01b1790915591905254169250614193565b67ffffffffffffffff808216600090815260016020526040902054600160801b9004811690841603613fa957809250613fa98361421e565b5067ffffffffffffffff80831660009081526001602052604080822054831680835281832080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff808216835590861685529284208054909316600160c01b179092559182905254909161401d9116614466565b614193565b67ffffffffffffffff81811660009081526001602052604080822054831682528082205468010000000000000000900490921680825291902054909250600160c01b900460ff16156140e25767ffffffffffffffff80821660008181526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116825587861684528284208054821690558154861684529183208054909216600160c01b1790915591905254169250614193565b67ffffffffffffffff80821660009081526001602052604090205468010000000000000000900481169084160361411f5780925061411f83614466565b5067ffffffffffffffff80831660009081526001602052604080822054831680835281832080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff808216835590861685529284208054909316600160c01b1790925591829052549091614193911661421e565b50613e27565b6000805467ffffffffffffffff16815260016020526040902054600160c01b900460ff1615612061576000805467ffffffffffffffff908116825260016020526040822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff169055815468010000000000000000900416906008613df983615996565b67ffffffffffffffff8082166000818152600160205260408082208054600160801b808204871680865293852054959094526801000000000000000090940485169283027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff851617905592919091169080156142c55767ffffffffffffffff8181166000908152600160205260409020805467ffffffffffffffff19169186169190911790555b67ffffffffffffffff8381166000908152600160205260409020805467ffffffffffffffff1916918416918217905561431a576000805467ffffffffffffffff191667ffffffffffffffff85161790556143f4565b67ffffffffffffffff8083166000908152600160205260409020546801000000000000000090048116908516036143a45767ffffffffffffffff8083166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790556143f4565b67ffffffffffffffff80831660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790555b505067ffffffffffffffff90811660008181526001602052604080822080547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000096909516958602949094179093559283529120805467ffffffffffffffff19169091179055565b67ffffffffffffffff80821660008181526001602052604080822080546801000000000000000080820487168086529385205495909452600160801b90940485169283027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516179055929190911690801561450d5767ffffffffffffffff8181166000908152600160205260409020805467ffffffffffffffff19169186169190911790555b67ffffffffffffffff8381166000908152600160205260409020805467ffffffffffffffff19169184169182179055614562576000805467ffffffffffffffff191667ffffffffffffffff8516179055614637565b67ffffffffffffffff808316600090815260016020526040902054600160801b90048116908516036145e25767ffffffffffffffff80831660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff909216919091179055614637565b67ffffffffffffffff8083166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790555b505067ffffffffffffffff90811660008181526001602052604080822080547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b96909516958602949094179093559283529120805467ffffffffffffffff19169091179055565b50805460008255906000526020600020908101906146c29190614a21565b50565b6040518061010001604052806146d9614a3a565b81526020016146e6614a3a565b81526020016146f3614a3a565b8152602001614700614a3a565b815260408051808201825260008082526020808301829052808501929092528284018190528251808401909352808352908201819052606083019190915260809091015290565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b60408051808201909152600080825260208201528152602001906001900390816147745790505090565b60408051610340810182526000610300820181815261032083018290528252825180840184528181526020808201839052808401919091528351808501855282815280820183905283850152835180850190945281845283015260608101919091526080810161480c614a66565b8152602001614819614a66565b8152602001614826614a66565b8152602001614833614a66565b8152602001614840614a66565b815260200161484d614a66565b815260200161485a614a66565b8152602001614867614a66565b8152602001614874614a8f565b81526000602080830182905260408051808201825283815280830184905281850152805180820190915282815290810182905260608301526080820181905260a0820181905260c0820181905260e0820181905261010082018190526101208201819052610140820152610160016148ea614abc565b905290565b604080516103008101825260006102c082018181526102e083018290528252825180840184528181526020808201839052808401919091528351808501855282815280820183905283850152835180850190945281845283015260608101919091526080810161495d614a66565b815260200161496a614a66565b8152602001614977614a66565b8152602001614984614a66565b8152602001614991614a66565b815260200161499e614a66565b8152602001614874614af0565b6040805161014081018252600061010082018181526101208301829052825282518084018452818152602080820192909252908201529081016149ec614a66565b81526020016149f9614a66565b8152602001614a06614af0565b81526020016000815260200160008152602001600081525090565b5b80821115614a365760008155600101614a22565b5090565b604080516102408101909152600061020082018181526102208301919091528152600f60208201614774565b6040805160c0810190915260006080820181815260a08301919091528152600360208201614774565b60405180604001604052806002905b614aa6614af0565b815260200190600190039081614a9e5790505090565b6040518060800160405280614acf614b0e565b8152602001614adc614b0e565b815260200160008152602001600081525090565b60405180608001604052806004906020820280368337509192915050565b604080516101008101909152600060c0820181815260e08301919091528152600560208201614774565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b5c57600080fd5b919050565b803563ffffffff81168114614b5c57600080fd5b60008060408385031215614b8857600080fd5b614b9183614b38565b9150614b9f60208401614b61565b90509250929050565b806102008101831015610e9b57600080fd5b803567ffffffffffffffff81168114614b5c57600080fd5b60008083601f840112614be457600080fd5b50813567ffffffffffffffff811115614bfc57600080fd5b602083019150836020828501011115614c1457600080fd5b9250929050565b6000806000806000806000806104a0898b031215614c3857600080fd5b614c428a8a614ba8565b9750614c528a6102008b01614ba8565b965061040089013595506104208901359450614c716104408a01614bba565b9350614c806104608a01614b61565b925061048089013567ffffffffffffffff811115614c9d57600080fd5b614ca98b828c01614bd2565b999c989b5096995094979396929594505050565b600060208284031215614ccf57600080fd5b614cd882614bba565b9392505050565b60008060608385031215614cf257600080fd5b8235915083606084011115614d0657600080fd5b50926020919091019150565b6000806000806000806000806000806000806105008d8f031215614d3557600080fd5b614d3f8e8e614ba8565b9b50614d4f8e6102008f01614ba8565b9a506104008d013599506104208d01359850614d6e6104408e01614bba565b9750614d7d6104608e01614b61565b9650614d8c6104808e01614b61565b955067ffffffffffffffff6104a08e01351115614da857600080fd5b614db98e6104a08f01358f01614bd2565b9095509350614dcb6104c08e01614b38565b925067ffffffffffffffff6104e08e01351115614de757600080fd5b614df88e6104e08f01358f01614bd2565b81935080925050509295989b509295989b509295989b565b60008060008060006104408688031215614e2957600080fd5b614e338787614ba8565b9450614e43876102008801614ba8565b9350610400860135925061042086013567ffffffffffffffff811115614e6857600080fd5b614e7488828901614bd2565b969995985093965092949392505050565b600060208284031215614e9757600080fd5b5035919050565b600080600060408486031215614eb357600080fd5b833567ffffffffffffffff80821115614ecb57600080fd5b818601915086601f830112614edf57600080fd5b813581811115614eee57600080fd5b8760208260051b8501011115614f0357600080fd5b602092830195509350614f199186019050614b61565b90509250925092565b60208082528251828201819052600091906040908185019086840185805b83811015614f7d57825185835b6002811015614f6a57825182529189019190890190600101614f4d565b5050509385019391860191600101614f40565b509298975050505050505050565b60008060408385031215614f9e57600080fd5b614fa783614bba565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008261502257615022614fb5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508757615087614fe4565b5060010190565b8060005b60108110156150c6576150b084835180518252602090810151910152565b6040939093019260209190910190600101615092565b50505050565b6150d782825161508e565b60208101516150ea61040084018261508e565b5060408101516150fe61080084018261508e565b506060810151615112610c0084018261508e565b506080810151805161100084015260209081015161102084015260a082015161104084015260c08201518051611060850152015161108083015260e001516110a090910152565b8060005b60048110156150c65761517b84835180518252602090810151910152565b604093909301926020919091019060010161515d565b8060005b60048110156150c6578151845260209384019390910190600101615195565b8060005b60028110156150c6576151cc848351615191565b60809390930192602091909101906001016151b8565b8060005b60068110156150c65761520484835180518252602090810151910152565b60409390930192602091909101906001016151e6565b6152258282516151e2565b60208101516152386101808401826151e2565b5060408101516103008301526060015161032090910152565b611f80810161526082856150cc565b825180516110c08401526020908101516110e0840152808401518051611100850152810151611120840152604084015180516111408501528101516111608401526060840151805161118085015201516111a083015260808301516152c96111c0840182615159565b5060a08301516152dd6112c0840182615159565b5060c08301516152f16113c0840182615159565b5060e08301516153056114c0840182615159565b5061010083015161531a6115c0840182615159565b5061012083015161532f6116c0840182615159565b506101408301516153446117c0840182615159565b506101608301516153596118c0840182615159565b5061018083015161536e6119c08401826151b4565b506101a0830151611ac08301526101c08301518051611ae0840152602090810151611b008401526101e08401518051611b208501520151611b40830152610200830151611b60830152610220830151611b80830152610240830151611ba0830152610260830151611bc0830152610280830151611be08301526102a0830151611c008301526102c0830151611c208301526102e0830151611d79611c4084018261521a565b8082028115828204841417610e9b57610e9b614fe4565b6104208101610200808684378085828501375082610400830152949350505050565b60008261545b5761545b614fb5565b500690565b60a08082526010908201527f57656c636f6d6520746f204669726e2e0000000000000000000000000000000060c082015273ffffffffffffffffffffffffffffffffffffffff841660208201526040810183905260e081016154cf606083018480518252602090810151910152565b949350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6000610460610200808a8537808982860137508661040084015263ffffffff86166104208401528061044084015261555b81840185876154d7565b9998505050505050505050565b600063ffffffff8084168061557f5761557f614fb5565b92169190910492915050565b63ffffffff8181168382160190808211156120ae576120ae614fe4565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006155d86040830184866154d7565b95945050505050565b63ffffffff85168152611d4081016155fc60208301866150cc565b835180516110e084015260209081015161110084015280850151805161112085015281015161114084015260408501518051611160850152810151611180840152606085015180516111a085015201516111c083015260808401516156656111e0840182615159565b5060a08401516156796112e0840182615159565b5060c084015161568d6113e0840182615159565b5060e08401516156a16114e0840182615159565b506101008401516156b66115e0840182615159565b506101208401516156cb6116e0840182615159565b506101408401516156e06117e0840182615191565b5061016084015161186083015261018084015180516118808401526020908101516118a08401526101a085015180516118c085015201516118e08301526101c08401516119008301526101e08401516119208301526102008401516119408301526102208401516119608301526102408401516119808301526102608401516119a08301526102808401516119c08301526102a08401516157856119e084018261521a565b5082611d2083015295945050505050565b8183823760009101908152919050565b63ffffffff8416815261144081016157c160208301856150cc565b825180516110e0840152602090810151611100840152808401518051611120850152015161114083015260408301516157fe611160840182615159565b506060830151615812611260840182615159565b506080830151615826611360840182615191565b5060a08301516113e083015260c083015161140083015260e0830151611420830152949350505050565b610440810161020080878437808682850137508361040083015263ffffffff831661042083015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000825160005b818110156158d057602081860181015185830152016158b6565b506000920191825250919050565b81810381811115610e9b57610e9b614fe4565b80820180821115610e9b57610e9b614fe4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b67ffffffffffffffff8181168382160190808211156120ae576120ae614fe4565b600067ffffffffffffffff82168061596e5761596e614fe4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600067ffffffffffffffff8083168181036159b3576159b3614fe4565b600101939250505056fea2646970667358221220280c2b3a2c6454c3e1cda55ac6b6892693192e7ea459c34474d8ccf380d4e32064736f6c6343000811003330644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd470000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e63000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b680

Deployed Bytecode

0x6080604052600436106100d25760003560e01c806362ab46821161007f578063e220a18f11610059578063e220a18f146102e8578063e2226a7c14610315578063ebf0c71714610335578063f4859e571461036f57600080fd5b806362ab46821461023857806379a80fdb14610258578063b64a097e1461026b57600080fd5b806330d00012116100b057806330d0001214610163578063414962961461017657806359ca4af3146101a657600080fd5b80630d206705146100d75780630e040440146100f95780632316aa6c14610119575b600080fd5b3480156100e357600080fd5b506100f76100f2366004614b75565b61039c565b005b34801561010557600080fd5b506100f7610114366004614c1b565b6104aa565b34801561012557600080fd5b50610150610134366004614cbd565b67ffffffffffffffff1660009081526008602052604090205490565b6040519081526020015b60405180910390f35b6100f7610171366004614cdf565b610af0565b34801561018257600080fd5b50610196610191366004614cbd565b610e4e565b604051901515815260200161015a565b3480156101b257600080fd5b506102026101c1366004614cbd565b60016020526000908152604090205467ffffffffffffffff80821691680100000000000000008104821691600160801b82041690600160c01b900460ff1684565b60405161015a949392919067ffffffffffffffff9485168152928416602084015292166040820152901515606082015260800190565b34801561024457600080fd5b506100f7610253366004614d12565b610ea1565b6100f7610266366004614e10565b611613565b34801561027757600080fd5b506102bd610286366004614e85565b60076020526000908152604090205467ffffffffffffffff80821691680100000000000000008104821691600160801b9091041683565b6040805167ffffffffffffffff9485168152928416602084015292169181019190915260600161015a565b3480156102f457600080fd5b50610308610303366004614e9e565b611a73565b60405161015a9190614f22565b34801561032157600080fd5b50610150610330366004614f8b565b611d81565b34801561034157600080fd5b506000546103569067ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161015a565b34801561037b57600080fd5b506000546103569068010000000000000000900467ffffffffffffffff1681565b6103a4611e23565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104235760405162461bcd60e51b815260206004820152601860248201527f43616c6c6572206973206e6f7420746865206f776e65722e000000000000000060448201526064015b60405180910390fd5b6006805463ffffffff9092167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff90941668010000000000000000029390931667ffffffffffffffff90921691909117919091179055565b6104b5603c42615013565b8467ffffffffffffffff161461050d5760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e0000000000000000000000000000000000000000604482015260640161041a565b60065467ffffffffffffffff8086169116101561054d576006805467ffffffffffffffff191667ffffffffffffffff861617905561054d600560006146a4565b60005b6005548110156105d857856005828154811061056e5761056e615027565b9060005260206000200154036105c65760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e00000000000000000000000000604482015260640161041a565b806105d081615056565b915050610550565b50600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0018590556106166146c5565b61061f87611e72565b608082015260005b601081101561096d576106508a826010811061064557610645615027565b602002013587611f55565b61066f8a826010811061066557610665615027565b6020020135611e72565b8251826010811061068257610682615027565b602002015261069c89826010811061066557610665615027565b826060015182601081106106b2576106b2615027565b602002015260608201516107389082601081106106d1576106d1615027565b6020020151600260008d85601081106106ec576106ec615027565b6020020135815260200190815260200160002060006002811061071157610711615027565b60408051808201909152600291909102919091018054825260010154602082015290612065565b8260200151826010811061074e5761074e615027565b6020020152608082015161079790600260008d856010811061077257610772615027565b6020020135815260200190815260200160002060016002811061071157610711615027565b826040015182601081106107ad576107ad615027565b602002015260608201516107e79082601081106107cc576107cc615027565b6020020151600360008d85601081106106ec576106ec615027565b600360008c84601081106107fd576107fd615027565b6020020135815260200190815260200160002060006002811061082257610822615027565b60020201600082015181600001556020820151816001015590505061085b8260800151600360008d856010811061077257610772615027565b600360008c846010811061087157610871615027565b6020020135815260200190815260200160002060016002811061089657610896615027565b6002020160008201518160000155602082015181600101559050506000600760008c84601081106108c9576108c9615027565b6020908102919091013582528101919091526040016000205467ffffffffffffffff16116109395760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e000000604482015260640161041a565b61095b8a826010811061094e5761094e615027565b60200201356000886120b5565b8061096581615056565b915050610627565b5067ffffffffffffffff851660a082015261098786611e72565b60c082015263ffffffff841660e0820152604080516020601f850181900481028201810190925283815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c169163a00ceb12918491610a169190889088908190840183828082843760009201919091525061232892505050565b6040518363ffffffff1660e01b8152600401610a33929190615251565b60006040518083038186803b158015610a4b57600080fd5b505afa158015610a5f573d6000803e3d6000fd5b503392506108fc9150610a81905063ffffffff871666038d7ea4c68000615413565b6040518115909202916000818181858888f19350505050158015610aa9573d6000803e3d6000fd5b507ff6f8a48e4a3e66a7c69c76d4c466f5c8ecffc318c99005256a2630b44045c772898989604051610add9392919061542a565b60405180910390a1505050505050505050565b662386f26fc10000341015610b475760405162461bcd60e51b815260206004820152601b60248201527f4d757374206265206174206c6561737420302e303130204554482e0000000000604482015260640161041a565b610b5866038d7ea4c680003461544c565b15610ba55760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652061206d756c7469706c65206f6620302e303031204554482e604482015260640161041a565b6000610bb2603c42615013565b90506a038d7ea4c2f2815b398000471115610c0f5760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e000000000000604482015260640161041a565b6000610c2266038d7ea4c6800034615013565b9050610cb5610ca18263ffffffff16610c9b604080518082018252600080825260209182015281518083019092527f14bcc435f49d130d189737f9762feb25c44ef5b886bef833e31a702af6be474882527f10cd33954522ad058f00a2553fd4e10d859fe125997e98adba777910dddc53229082015290565b90612825565b600086815260036020526040812090610711565b6000858152600360209081526040822083518155920151600190920191909155610cde85611e72565b90506000610d71610cf9610cf28735612863565b8490612825565b610d6b6020880135610c9b604080518082018252600080825260209182015281518083019092527f14bcc435f49d130d189737f9762feb25c44ef5b886bef833e31a702af6be474882527f10cd33954522ad058f00a2553fd4e10d859fe125997e98adba777910dddc53229082015290565b90612065565b90506000610dab308884604051602001610d8d93929190615460565b6040516020818303038152906040528051906020012060001c61288f565b905085358114610dfd5760405162461bcd60e51b815260206004820152601b60248201527f5369676e6174757265206661696c656420746f207665726966792e0000000000604482015260640161041a565b610e088785876120b5565b60405163ffffffff85168152879033907f84628036fe71169f22b5c76e246fc456cfa786e31c780706f3fe13699adaa8199060200160405180910390a350505050505050565b600067ffffffffffffffff821615801590610e9b575060005467ffffffffffffffff83811691161480610e9b575067ffffffffffffffff8281166000908152600160205260409020541615155b92915050565b610eac603c42615013565b8867ffffffffffffffff1614610f045760405162461bcd60e51b815260206004820152600c60248201527f57726f6e672065706f63682e0000000000000000000000000000000000000000604482015260640161041a565b60065467ffffffffffffffff808a1691161015610f44576006805467ffffffffffffffff191667ffffffffffffffff8a16179055610f44600560006146a4565b60005b600554811015610fcf578960058281548110610f6557610f65615027565b906000526020600020015403610fbd5760405162461bcd60e51b815260206004820152601360248201527f4e6f6e636520616c7265616479207365656e2e00000000000000000000000000604482015260640161041a565b80610fc781615056565b915050610f47565b50600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00189905560405173ffffffffffffffffffffffffffffffffffffffff8416907f455f9623b71a09d41c2aab8b7edd236e2a1ab057ad848f6be4290c5079c5934790611057908f908f908f908d9089908990615520565b60405180910390a26110676146c5565b6110708b611e72565b608082015260005b60108110156112aa5760008e826010811061109557611095615027565b602002013590506110a6818c611f55565b6110af81611e72565b835183601081106110c2576110c2615027565b60200201526110dc8e836010811061066557610665615027565b836060015183601081106110f2576110f2615027565b6020020152606083015161113b90836010811061111157611111615027565b60200201516002600084815260200190815260200160002060006002811061071157610711615027565b8360200151836010811061115157611151615027565b602002018190525061118683608001516002600084815260200190815260200160002060016002811061071157610711615027565b8360400151836010811061119c5761119c615027565b602002015260608301516111e59083601081106111bb576111bb615027565b60200201516003600084815260200190815260200160002060006002811061071157610711615027565b6000828152600360209081526040909120825181559101516001808301919091556080850151611216929091610711565b6000828152600360208181526040808420855160028201559482015194909201939093556007909252205467ffffffffffffffff166112975760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e000000604482015260640161041a565b50806112a281615056565b915050611078565b506006546000906112e1907c0100000000000000000000000000000000000000000000000000000000900463ffffffff168a615568565b67ffffffffffffffff8b1660a084015290506112fc8b611e72565b60c083015261130b818961558b565b63ffffffff1660e083015260405160009061132e908790879087906020016155a8565b6040516020818303038152906040528051906020012060001c90507f0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b68073ffffffffffffffffffffffffffffffffffffffff1663f11b521f8b856113c68c8c8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506128bb92505050565b856040518563ffffffff1660e01b81526004016113e694939291906155e1565b60006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b503392506108fc9150611434905063ffffffff8c1666038d7ea4c68000615413565b6040518115909202916000818181858888f1935050505015801561145c573d6000803e3d6000fd5b5060065460009068010000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661149c63ffffffff851666038d7ea4c68000615413565b604051600081818185875af1925050503d80600081146114d8576040519150601f19603f3d011682016040523d82523d6000602084013e6114dd565b606091505b505090508061152e5760405162461bcd60e51b815260206004820152601e60248201527f45787465726e616c2074726561737572792063616c6c206661696c65642e0000604482015260640161041a565b73ffffffffffffffffffffffffffffffffffffffff871661155c63ffffffff8d1666038d7ea4c68000615413565b878760405161156c929190615796565b60006040518083038185875af1925050503d80600081146115a9576040519150601f19603f3d011682016040523d82523d6000602084013e6115ae565b606091505b505080915050806116015760405162461bcd60e51b815260206004820181905260248201527f45787465726e616c207769746864726177616c2063616c6c206661696c65642e604482015260640161041a565b50505050505050505050505050505050565b61162466038d7ea4c680003461544c565b156116715760405162461bcd60e51b815260206004820181905260248201527f4d7573742062652061206d756c7469706c65206f6620302e303031204554482e604482015260640161041a565b600061167e603c42615013565b90506a038d7ea4c2f2815b3980004711156116db5760405162461bcd60e51b815260206004820152601a60248201527f457363726f7720706f6f6c206e6f7720746f6f206c617267652e000000000000604482015260640161041a565b60006116ee66038d7ea4c6800034615013565b90506116f86146c5565b61170186611e72565b608082015260005b60108110156119495761173289826010811061172757611727615027565b602002013585611f55565b61174789826010811061066557610665615027565b8251826010811061175a5761175a615027565b602002015261177488826010811061066557610665615027565b8260600151826010811061178a5761178a615027565b602002015260608201516117c49082601081106117a9576117a9615027565b6020020151600360008c85601081106106ec576106ec615027565b600360008b84601081106117da576117da615027565b602002013581526020019081526020016000206000600281106117ff576117ff615027565b6002020160008201518160000155602082015181600101559050506118388260800151600360008c856010811061077257610772615027565b600360008b846010811061184e5761184e615027565b6020020135815260200190815260200160002060016002811061187357611873615027565b6002020160008201518160000155602082015181600101559050506000600760008b84601081106118a6576118a6615027565b6020908102919091013582528101919091526040016000205467ffffffffffffffff16116119165760405162461bcd60e51b815260206004820152601d60248201527f4f6e6c7920636163686564206163636f756e747320616c6c6f7765642e000000604482015260640161041a565b61193789826010811061192b5761192b615027565b602002013584866120b5565b8061194181615056565b915050611709565b507f0000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e6373ffffffffffffffffffffffffffffffffffffffff166377f7335583836119c789898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612c3092505050565b6040518463ffffffff1660e01b81526004016119e5939291906157a6565b60006040518083038186803b1580156119fd57600080fd5b505afa158015611a11573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff167fbdee54bab8aa68aecbb89de2313baaa387447195fe74aa236a4d9345799b330089898986604051611a619493929190615850565b60405180910390a25050505050505050565b60608267ffffffffffffffff811115611a8e57611a8e615880565b604051908082528060200260200182016040528015611ac757816020015b611ab4614747565b815260200190600190039081611aac5790505b50905060005b83811015611d7957611add614765565b60026000878785818110611af357611af3615027565b905060200201358152602001908152602001600020600060028110611b1a57611b1a615027565b60408051808201909152600291820292909201805483526001015460208301529082526000878785818110611b5157611b51615027565b905060200201358152602001908152602001600020600160028110611b7857611b78615027565b600202016040518060400160405290816000820154815260200160018201548152505081600160028110611bae57611bae615027565b602002015263ffffffff841660046000888886818110611bd057611bd0615027565b602090810292909201358352508101919091526040016000205467ffffffffffffffff161015611ce857611c6a60036000888886818110611c1357611c13615027565b905060200201358152602001908152602001600020600060028110611c3a57611c3a615027565b6040805180820190915260029190910291909101805482526001015460208201528260005b602002015190612065565b8152611ce260036000888886818110611c8557611c85615027565b905060200201358152602001908152602001600020600160028110611cac57611cac615027565b600202016040518060400160405290816000820154815260200160018201548152505082600160028110611c5f57611c5f615027565b60208201525b611cf98160005b6020020151612d82565b838381518110611d0b57611d0b615027565b6020026020010151600060028110611d2557611d25615027565b6020020152611d35816001611cef565b838381518110611d4757611d47615027565b6020026020010151600160028110611d6157611d61615027565b60200201525080611d7181615056565b915050611acd565b509392505050565b60086020528160005260406000208181548110611d9d57600080fd5b90600052602060002001600091509150505481565b6040805180820190915260008082526020820152610e9b7f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4783604051602001611dfb91906158af565b6040516020818303038152906040528051906020012060001c611e1e919061544c565b612dc0565b6000611e56611e5360017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61046158de565b90565b5473ffffffffffffffffffffffffffffffffffffffff16919050565b60408051808201909152600080825260208201526000829003611ea8575050604080518082019091526000808252602082015290565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821660ff83901c6000611edd836003612e5d565b611ee89060036158f1565b90506000611f16827f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52612e5d565b6040805180820190915285815260208101829052909150600182168414611f4b57611f4081612ec5565b979650505050505050565b9695505050505050565b60008281526004602052604090205467ffffffffffffffff8083169116101561206157600082815260036020908152604080832081518083018352815481526001909101548184015285845260029092528220611fb192610711565b600083815260026020818152604080842085518155948201516001808701919091556003808452828620835180850190945280860154845201548284015293879052919052612001929091610711565b6000838152600260208181526040808420855181850155948201516003958601558482528084208481556001810185905592830184905591909301829055600490925220805467ffffffffffffffff191667ffffffffffffffff83161790555b5050565b60408051808201909152600080825260208201526040518351815260208401516020820152825160408201526020830151606082015260408260808360065afa6120ae57600080fd5b5092915050565b6000838152600760205260408120805467ffffffffffffffff161561223957805467ffffffffffffffff16600090815260086020526040902080549092508290612101906001906158de565b8154811061211157612111615027565b60009182526020909120015481548354849168010000000000000000900467ffffffffffffffff1690811061214857612148615027565b90600052602060002001819055508180548061216657612166615904565b6001900381819060005260206000200160009055905581805490506000036121a257805461219d9067ffffffffffffffff16612f23565b612239565b8154815468010000000000000000900467ffffffffffffffff16101561223957805482546801000000000000000090910467ffffffffffffffff16906007906000908590849081106121f6576121f6615027565b9060005260206000200154815260200190815260200160002060000160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505b805467ffffffffffffffff191667ffffffffffffffff8481169190911780835563ffffffff861691839160109161227a918591600160801b90910416615933565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055506122a983610e4e565b6122b6576122b683613357565b67ffffffffffffffff9290921660009081526008602090815260408220805485547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1663ffffffff90911668010000000000000000021790945583546001810185559382529020909101929092555050565b61233061479e565b602082015161234390611e72565b611e72565b8152604082015161235390611e72565b6020820152606082015161236690611e72565b6040820152608082015161237990611e72565b606082015260005b6004811015612621576123af61233e8461239c846020615413565b6123a79060806158f1565b016020015190565b826080015182600481106123c5576123c5615027565b60200201526123e761233e846123dc6004856158f1565b61239c906020615413565b8260a0015182600481106123fd576123fd615027565b602002018190525061243a61233e848360206124199190615413565b61242560046040615413565b6124309060806158f1565b6123a791906158f1565b8260c00151826004811061245057612450615027565b602002018190525061247861233e8483602061246c9190615413565b61242560046060615413565b8260e00151826004811061248e5761248e615027565b60200201819052506124b661233e848360206124aa9190615413565b61242560046080615413565b82610100015182600481106124cd576124cd615027565b60200201819052506124f561233e848360206124e99190615413565b612425600460a0615413565b826101200151826004811061250c5761250c615027565b602002018190525061253461233e848360206125289190615413565b612425600460c0615413565b826101400151826004811061254b5761254b615027565b602002018190525061257361233e848360206125679190615413565b612425600460e0615413565b826101600151826004811061258a5761258a615027565b60200201819052506125b0838260206125a39190615413565b6124256004610100615413565b6101808301515182600481106125c8576125c8615027565b6020020181815250506125ef838260206125e29190615413565b6124256004610120615413565b61018083015160200151826004811061260a5761260a615027565b60200201528061261981615056565b915050612381565b5060006126316004610140615413565b9050612642836123a78360806158f1565b6101a083015261265a61233e846123a78460a06158f1565b6101c083015261267261233e846123a78460c06158f1565b6101e0830152612687836123a78360e06158f1565b61020083015261269d836123a7836101006158f1565b6102208301526126b3836123a7836101206158f1565b6102408301526126c9836123a7836101406158f1565b6102608301526126df836123a7836101606158f1565b6102808301526126f5836123a7836101806158f1565b6102a083015261270b836123a7836101a06158f1565b6102c083015260005b612720600560016158f1565b8110156127bc5761274561233e85612739846020615413565b612430866101c06158f1565b6102e084015151826006811061275d5761275d615027565b602002015261278a61233e856127746005856158f1565b61277f9060016158f1565b612739906020615413565b836102e001516020015182600681106127a5576127a5615027565b6020020152806127b481615056565b915050612714565b506127e4836127cd600560016158f1565b6127d8906040615413565b612430846101c06158f1565b6102e083015160400152612815836127fe600560016158f1565b612809906040615413565b612430846101e06158f1565b6102e08301516060015250919050565b6040805180820190915260008082526020820152604051835181526020840151602082015282604082015260408260608360075afa6120ae57600080fd5b6000610e9b827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016158de565b6000610e9b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018361544c565b6128c36148ef565b60208201516128d190611e72565b815260408201516128e190611e72565b602082015260608201516128f490611e72565b6040820152608082015161290790611e72565b606082015260005b6004811015612a7e5761292a61233e8461239c846020615413565b8260800151826004811061294057612940615027565b602002015261295761233e846123dc6004856158f1565b8260a00151826004811061296d5761296d615027565b602002018190525061298961233e848360206124199190615413565b8260c00151826004811061299f5761299f615027565b60200201819052506129bb61233e8483602061246c9190615413565b8260e0015182600481106129d1576129d1615027565b60200201819052506129ed61233e848360206124aa9190615413565b8261010001518260048110612a0457612a04615027565b6020020181905250612a2061233e848360206124e99190615413565b8261012001518260048110612a3757612a37615027565b6020020181905250612a50838260206125289190615413565b6101408301518260048110612a6757612a67615027565b602002015280612a7681615056565b91505061290f565b506000612a8d600460e0615413565b9050612a9e836123a78360806158f1565b610160830152612ab661233e846123a78460a06158f1565b610180830152612ace61233e846123a78460c06158f1565b6101a0830152612ae3836123a78360e06158f1565b6101c0830152612af9836123a7836101006158f1565b6101e0830152612b0f836123a7836101206158f1565b610200830152612b25836123a7836101406158f1565b610220830152612b3b836123a7836101606158f1565b610240830152612b51836123a7836101806158f1565b610260830152612b67836123a7836101a06158f1565b61028083015260005b6005811015612bec57612b8b61233e85612739846020615413565b6102a0840151518260068110612ba357612ba3615027565b6020020152612bba61233e8561277f6005856158f1565b836102a00151602001518260068110612bd557612bd5615027565b602002015280612be481615056565b915050612b70565b50612bfd836127d860056040615413565b60001c826102a001516040018181525050612c2083600560406128099190615413565b6102a08301516060015250919050565b612c386149ab565b6020820151612c4690611e72565b81526040820151612c5690611e72565b602082015260005b6004811015612d2f57612c8461233e84612c79846020615413565b6123a79060406158f1565b82604001518260048110612c9a57612c9a615027565b6020020152612cbc61233e84612cb16004856158f1565b612c79906020615413565b82606001518260048110612cd257612cd2615027565b6020020181905250612d0283826020612ceb9190615413565b612cf760046040615413565b6124309060406158f1565b60808301518260048110612d1857612d18615027565b602002015280612d2781615056565b915050612c5e565b506000612d3e60046060615413565b9050612d4f836123a78360406158f1565b60a0830152612d63836123a78360606158f1565b60c0830152612d77836123a78360806158f1565b60e083015250919050565b805160208201516000919060019081169003610e9b577f80000000000000000000000000000000000000000000000000000000000000001792915050565b604080518082019091526000808252602082015260005b6000612de4846003612e5d565b612def9060036158f1565b9050612e1b817f0c19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52612e5d565b915080612e29836002612e5d565b03612e345750612e47565b612e3f6001856158f1565b935050612dd7565b6040805180820190915292835260208301525090565b6000807f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47905060405160208152602080820152602060408201528460608201528360808201528160a082015260208160c08360055afa612ebc57600080fd5b51949350505050565b6040805180820190915260008082526020820152604080518082019091528251815260208084015190820190612f1b907f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd476158de565b905292915050565b67ffffffffffffffff81811660009081526001602052604081205490918291680100000000000000009004161580612f7b575067ffffffffffffffff838116600090815260016020526040902054600160801b900416155b15612f87575081613006565b5067ffffffffffffffff808316600090815260016020526040902054600160801b9004165b67ffffffffffffffff81811660009081526001602052604090205468010000000000000000900416156130065767ffffffffffffffff90811660009081526001602052604090205468010000000000000000900416612fac565b67ffffffffffffffff81811660009081526001602052604090205468010000000000000000900416156130625767ffffffffffffffff808216600090815260016020526040902054680100000000000000009004169150613088565b67ffffffffffffffff808216600090815260016020526040902054600160801b90041691505b67ffffffffffffffff8082166000908152600160205260408082205485841683529120805467ffffffffffffffff19169190921690811790915580156131a65767ffffffffffffffff8082166000908152600160205260409020546801000000000000000090048116908316036131525767ffffffffffffffff8082166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790556131c4565b67ffffffffffffffff80821660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790556131c4565b6000805467ffffffffffffffff191667ffffffffffffffff85161790555b67ffffffffffffffff828116600081815260016020526040902054600160c01b900460ff161591861614613304576131fc83866135ca565b67ffffffffffffffff858116600090815260016020526040808220805487851680855283852080547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff16680100000000000000009384900488168402178082559290920486168552838520805467ffffffffffffffff199081168317909155835483547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b9182900489168202178085550490961685529284208054909516831790945554915281547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9182900460ff1615159091021790559193915b80156133135761331384613707565b505067ffffffffffffffff16600090815260016020526040902080547fffffffffffffff000000000000000000000000000000000000000000000000001690555050565b6000805467ffffffffffffffff165b67ffffffffffffffff8116156133ea578091508067ffffffffffffffff168367ffffffffffffffff1610156133c25767ffffffffffffffff90811660009081526001602052604090205468010000000000000000900416613366565b67ffffffffffffffff908116600090815260016020526040902054600160801b900416613366565b6040805160808101825267ffffffffffffffff808516808352600060208085018281528587018381526001606088018181528c88168652935296909220945185549251965191511515600160c01b027fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff928616600160801b02929092167fffffffffffffff000000000000000000ffffffffffffffffffffffffffffffff97861668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909516179190911794909416919091179290921790556134f7576000805467ffffffffffffffff191667ffffffffffffffff85161790556135bc565b8167ffffffffffffffff168367ffffffffffffffff16101561356c5767ffffffffffffffff8083166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790556135bc565b67ffffffffffffffff80831660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790555b6135c583613e24565b505050565b67ffffffffffffffff8082166000908152600160205260408082205485841683529120805467ffffffffffffffff1916919092169081179091558061362d576000805467ffffffffffffffff851667ffffffffffffffff19909116179055505050565b67ffffffffffffffff8082166000908152600160205260409020546801000000000000000090048116908316036136b55767ffffffffffffffff908116600090815260016020526040902080547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000094909216939093021790915550565b67ffffffffffffffff908116600090815260016020526040902080547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b94909216939093021790915550565b60005b60005467ffffffffffffffff83811691161480159061374a575067ffffffffffffffff8216600090815260016020526040902054600160c01b900460ff16155b15613d695767ffffffffffffffff808316600081815260016020526040808220548416808352912054909268010000000000000000909104169003613a6c5767ffffffffffffffff81811660009081526001602052604080822054600160801b900490921680825291902054909250600160c01b900460ff161561384f5767ffffffffffffffff80831660009081526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155928416825290208054909116600160c01b1790556138298161421e565b67ffffffffffffffff808216600090815260016020526040902054600160801b90041691505b67ffffffffffffffff8281166000908152600160205260408082205468010000000000000000900490921681522054600160c01b900460ff161580156138c6575067ffffffffffffffff82811660009081526001602052604080822054600160801b900490921681522054600160c01b900460ff16155b156139185767ffffffffffffffff8216600090815260016020526040902080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b179055915081613d63565b67ffffffffffffffff82811660009081526001602052604080822054600160801b900490921681522054600160c01b900460ff166139e65767ffffffffffffffff80831660008181526001602052604080822080546801000000000000000090049094168252812080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155919052815416600160c01b1790556139c082614466565b67ffffffffffffffff808216600090815260016020526040902054600160801b90041691505b67ffffffffffffffff80821660009081526001602052604080822080548685168452828420805460ff600160c01b938490041615159092027fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff928316178155825482169092559054600160801b900490931682529020805490911690556135c58161421e565b67ffffffffffffffff8181166000908152600160205260408082205468010000000000000000900490921680825291902054909250600160c01b900460ff1615613b3c5767ffffffffffffffff80831660009081526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155928416825290208054909116600160c01b179055613b1181614466565b67ffffffffffffffff8082166000908152600160205260409020546801000000000000000090041691505b67ffffffffffffffff82811660009081526001602052604080822054600160801b900490921681522054600160c01b900460ff16158015613bb3575067ffffffffffffffff8281166000908152600160205260408082205468010000000000000000900490921681522054600160c01b900460ff16155b15613c055767ffffffffffffffff8216600090815260016020526040902080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b179055915081613d63565b67ffffffffffffffff8281166000908152600160205260408082205468010000000000000000900490921681522054600160c01b900460ff16613cd85767ffffffffffffffff8083166000818152600160205260408082208054600160801b90049094168252812080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116909155919052815416600160c01b179055613cad8261421e565b67ffffffffffffffff8082166000908152600160205260409020546801000000000000000090041691505b67ffffffffffffffff80821660009081526001602052604080822080548685168452828420805460ff600160c01b938490041615159092027fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff92831617815582548216909255905468010000000000000000900490931682529020805490911690556135c581614466565b5061370a565b67ffffffffffffffff8216600090815260016020526040902054600160c01b900460ff1615613dd3575067ffffffffffffffff16600090815260016020526040902080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff169055565b6000805468010000000000000000900467ffffffffffffffff16906008613df983615954565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b60005b60005467ffffffffffffffff838116911614801590613e6f575067ffffffffffffffff8281166000908152600160205260408082205490921681522054600160c01b900460ff165b156141995767ffffffffffffffff80831660009081526001602052604080822054831680835281832054841683529120549091680100000000000000009091041681036140225767ffffffffffffffff818116600090815260016020526040808220548316825280822054600160801b900490921680825291902054909250600160c01b900460ff1615613f715767ffffffffffffffff80821660008181526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116825587861684528284208054821690558154861684529183208054909216600160c01b1790915591905254169250614193565b67ffffffffffffffff808216600090815260016020526040902054600160801b9004811690841603613fa957809250613fa98361421e565b5067ffffffffffffffff80831660009081526001602052604080822054831680835281832080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff808216835590861685529284208054909316600160c01b179092559182905254909161401d9116614466565b614193565b67ffffffffffffffff81811660009081526001602052604080822054831682528082205468010000000000000000900490921680825291902054909250600160c01b900460ff16156140e25767ffffffffffffffff80821660008181526001602052604080822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff908116825587861684528284208054821690558154861684529183208054909216600160c01b1790915591905254169250614193565b67ffffffffffffffff80821660009081526001602052604090205468010000000000000000900481169084160361411f5780925061411f83614466565b5067ffffffffffffffff80831660009081526001602052604080822054831680835281832080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff808216835590861685529284208054909316600160c01b1790925591829052549091614193911661421e565b50613e27565b6000805467ffffffffffffffff16815260016020526040902054600160c01b900460ff1615612061576000805467ffffffffffffffff908116825260016020526040822080547fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff169055815468010000000000000000900416906008613df983615996565b67ffffffffffffffff8082166000818152600160205260408082208054600160801b808204871680865293852054959094526801000000000000000090940485169283027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff851617905592919091169080156142c55767ffffffffffffffff8181166000908152600160205260409020805467ffffffffffffffff19169186169190911790555b67ffffffffffffffff8381166000908152600160205260409020805467ffffffffffffffff1916918416918217905561431a576000805467ffffffffffffffff191667ffffffffffffffff85161790556143f4565b67ffffffffffffffff8083166000908152600160205260409020546801000000000000000090048116908516036143a45767ffffffffffffffff8083166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790556143f4565b67ffffffffffffffff80831660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9092169190911790555b505067ffffffffffffffff90811660008181526001602052604080822080547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000096909516958602949094179093559283529120805467ffffffffffffffff19169091179055565b67ffffffffffffffff80821660008181526001602052604080822080546801000000000000000080820487168086529385205495909452600160801b90940485169283027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff8516179055929190911690801561450d5767ffffffffffffffff8181166000908152600160205260409020805467ffffffffffffffff19169186169190911790555b67ffffffffffffffff8381166000908152600160205260409020805467ffffffffffffffff19169184169182179055614562576000805467ffffffffffffffff191667ffffffffffffffff8516179055614637565b67ffffffffffffffff808316600090815260016020526040902054600160801b90048116908516036145e25767ffffffffffffffff80831660009081526001602052604090208054918516600160801b027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff909216919091179055614637565b67ffffffffffffffff8083166000908152600160205260409020805491851668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9092169190911790555b505067ffffffffffffffff90811660008181526001602052604080822080547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16600160801b96909516958602949094179093559283529120805467ffffffffffffffff19169091179055565b50805460008255906000526020600020908101906146c29190614a21565b50565b6040518061010001604052806146d9614a3a565b81526020016146e6614a3a565b81526020016146f3614a3a565b8152602001614700614a3a565b815260408051808201825260008082526020808301829052808501929092528284018190528251808401909352808352908201819052606083019190915260809091015290565b60405180604001604052806002906020820280368337509192915050565b60405180604001604052806002905b60408051808201909152600080825260208201528152602001906001900390816147745790505090565b60408051610340810182526000610300820181815261032083018290528252825180840184528181526020808201839052808401919091528351808501855282815280820183905283850152835180850190945281845283015260608101919091526080810161480c614a66565b8152602001614819614a66565b8152602001614826614a66565b8152602001614833614a66565b8152602001614840614a66565b815260200161484d614a66565b815260200161485a614a66565b8152602001614867614a66565b8152602001614874614a8f565b81526000602080830182905260408051808201825283815280830184905281850152805180820190915282815290810182905260608301526080820181905260a0820181905260c0820181905260e0820181905261010082018190526101208201819052610140820152610160016148ea614abc565b905290565b604080516103008101825260006102c082018181526102e083018290528252825180840184528181526020808201839052808401919091528351808501855282815280820183905283850152835180850190945281845283015260608101919091526080810161495d614a66565b815260200161496a614a66565b8152602001614977614a66565b8152602001614984614a66565b8152602001614991614a66565b815260200161499e614a66565b8152602001614874614af0565b6040805161014081018252600061010082018181526101208301829052825282518084018452818152602080820192909252908201529081016149ec614a66565b81526020016149f9614a66565b8152602001614a06614af0565b81526020016000815260200160008152602001600081525090565b5b80821115614a365760008155600101614a22565b5090565b604080516102408101909152600061020082018181526102208301919091528152600f60208201614774565b6040805160c0810190915260006080820181815260a08301919091528152600360208201614774565b60405180604001604052806002905b614aa6614af0565b815260200190600190039081614a9e5790505090565b6040518060800160405280614acf614b0e565b8152602001614adc614b0e565b815260200160008152602001600081525090565b60405180608001604052806004906020820280368337509192915050565b604080516101008101909152600060c0820181815260e08301919091528152600560208201614774565b803573ffffffffffffffffffffffffffffffffffffffff81168114614b5c57600080fd5b919050565b803563ffffffff81168114614b5c57600080fd5b60008060408385031215614b8857600080fd5b614b9183614b38565b9150614b9f60208401614b61565b90509250929050565b806102008101831015610e9b57600080fd5b803567ffffffffffffffff81168114614b5c57600080fd5b60008083601f840112614be457600080fd5b50813567ffffffffffffffff811115614bfc57600080fd5b602083019150836020828501011115614c1457600080fd5b9250929050565b6000806000806000806000806104a0898b031215614c3857600080fd5b614c428a8a614ba8565b9750614c528a6102008b01614ba8565b965061040089013595506104208901359450614c716104408a01614bba565b9350614c806104608a01614b61565b925061048089013567ffffffffffffffff811115614c9d57600080fd5b614ca98b828c01614bd2565b999c989b5096995094979396929594505050565b600060208284031215614ccf57600080fd5b614cd882614bba565b9392505050565b60008060608385031215614cf257600080fd5b8235915083606084011115614d0657600080fd5b50926020919091019150565b6000806000806000806000806000806000806105008d8f031215614d3557600080fd5b614d3f8e8e614ba8565b9b50614d4f8e6102008f01614ba8565b9a506104008d013599506104208d01359850614d6e6104408e01614bba565b9750614d7d6104608e01614b61565b9650614d8c6104808e01614b61565b955067ffffffffffffffff6104a08e01351115614da857600080fd5b614db98e6104a08f01358f01614bd2565b9095509350614dcb6104c08e01614b38565b925067ffffffffffffffff6104e08e01351115614de757600080fd5b614df88e6104e08f01358f01614bd2565b81935080925050509295989b509295989b509295989b565b60008060008060006104408688031215614e2957600080fd5b614e338787614ba8565b9450614e43876102008801614ba8565b9350610400860135925061042086013567ffffffffffffffff811115614e6857600080fd5b614e7488828901614bd2565b969995985093965092949392505050565b600060208284031215614e9757600080fd5b5035919050565b600080600060408486031215614eb357600080fd5b833567ffffffffffffffff80821115614ecb57600080fd5b818601915086601f830112614edf57600080fd5b813581811115614eee57600080fd5b8760208260051b8501011115614f0357600080fd5b602092830195509350614f199186019050614b61565b90509250925092565b60208082528251828201819052600091906040908185019086840185805b83811015614f7d57825185835b6002811015614f6a57825182529189019190890190600101614f4d565b5050509385019391860191600101614f40565b509298975050505050505050565b60008060408385031215614f9e57600080fd5b614fa783614bba565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008261502257615022614fb5565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361508757615087614fe4565b5060010190565b8060005b60108110156150c6576150b084835180518252602090810151910152565b6040939093019260209190910190600101615092565b50505050565b6150d782825161508e565b60208101516150ea61040084018261508e565b5060408101516150fe61080084018261508e565b506060810151615112610c0084018261508e565b506080810151805161100084015260209081015161102084015260a082015161104084015260c08201518051611060850152015161108083015260e001516110a090910152565b8060005b60048110156150c65761517b84835180518252602090810151910152565b604093909301926020919091019060010161515d565b8060005b60048110156150c6578151845260209384019390910190600101615195565b8060005b60028110156150c6576151cc848351615191565b60809390930192602091909101906001016151b8565b8060005b60068110156150c65761520484835180518252602090810151910152565b60409390930192602091909101906001016151e6565b6152258282516151e2565b60208101516152386101808401826151e2565b5060408101516103008301526060015161032090910152565b611f80810161526082856150cc565b825180516110c08401526020908101516110e0840152808401518051611100850152810151611120840152604084015180516111408501528101516111608401526060840151805161118085015201516111a083015260808301516152c96111c0840182615159565b5060a08301516152dd6112c0840182615159565b5060c08301516152f16113c0840182615159565b5060e08301516153056114c0840182615159565b5061010083015161531a6115c0840182615159565b5061012083015161532f6116c0840182615159565b506101408301516153446117c0840182615159565b506101608301516153596118c0840182615159565b5061018083015161536e6119c08401826151b4565b506101a0830151611ac08301526101c08301518051611ae0840152602090810151611b008401526101e08401518051611b208501520151611b40830152610200830151611b60830152610220830151611b80830152610240830151611ba0830152610260830151611bc0830152610280830151611be08301526102a0830151611c008301526102c0830151611c208301526102e0830151611d79611c4084018261521a565b8082028115828204841417610e9b57610e9b614fe4565b6104208101610200808684378085828501375082610400830152949350505050565b60008261545b5761545b614fb5565b500690565b60a08082526010908201527f57656c636f6d6520746f204669726e2e0000000000000000000000000000000060c082015273ffffffffffffffffffffffffffffffffffffffff841660208201526040810183905260e081016154cf606083018480518252602090810151910152565b949350505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6000610460610200808a8537808982860137508661040084015263ffffffff86166104208401528061044084015261555b81840185876154d7565b9998505050505050505050565b600063ffffffff8084168061557f5761557f614fb5565b92169190910492915050565b63ffffffff8181168382160190808211156120ae576120ae614fe4565b73ffffffffffffffffffffffffffffffffffffffff841681526040602082015260006155d86040830184866154d7565b95945050505050565b63ffffffff85168152611d4081016155fc60208301866150cc565b835180516110e084015260209081015161110084015280850151805161112085015281015161114084015260408501518051611160850152810151611180840152606085015180516111a085015201516111c083015260808401516156656111e0840182615159565b5060a08401516156796112e0840182615159565b5060c084015161568d6113e0840182615159565b5060e08401516156a16114e0840182615159565b506101008401516156b66115e0840182615159565b506101208401516156cb6116e0840182615159565b506101408401516156e06117e0840182615191565b5061016084015161186083015261018084015180516118808401526020908101516118a08401526101a085015180516118c085015201516118e08301526101c08401516119008301526101e08401516119208301526102008401516119408301526102208401516119608301526102408401516119808301526102608401516119a08301526102808401516119c08301526102a08401516157856119e084018261521a565b5082611d2083015295945050505050565b8183823760009101908152919050565b63ffffffff8416815261144081016157c160208301856150cc565b825180516110e0840152602090810151611100840152808401518051611120850152015161114083015260408301516157fe611160840182615159565b506060830151615812611260840182615159565b506080830151615826611360840182615191565b5060a08301516113e083015260c083015161140083015260e0830151611420830152949350505050565b610440810161020080878437808682850137508361040083015263ffffffff831661042083015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000825160005b818110156158d057602081860181015185830152016158b6565b506000920191825250919050565b81810381811115610e9b57610e9b614fe4565b80820180821115610e9b57610e9b614fe4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b67ffffffffffffffff8181168382160190808211156120ae576120ae614fe4565b600067ffffffffffffffff82168061596e5761596e614fe4565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b600067ffffffffffffffff8083168181036159b3576159b3614fe4565b600101939250505056fea2646970667358221220280c2b3a2c6454c3e1cda55ac6b6892693192e7ea459c34474d8ccf380d4e32064736f6c63430008110033

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

0000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e63000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b680

-----Decoded View---------------
Arg [0] : deposit_ (address): 0x7940467Dde784c9836F95b264003a0ceB6e91e63
Arg [1] : transfer_ (address): 0xEd4f30624bFbe3B5F6660313B4a50bBf04Ef391C
Arg [2] : withdrawal_ (address): 0x7F72b657905f748D55Dd4dDC17e893C62499b680

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000007940467dde784c9836f95b264003a0ceb6e91e63
Arg [1] : 000000000000000000000000ed4f30624bfbe3b5f6660313b4a50bbf04ef391c
Arg [2] : 0000000000000000000000007f72b657905f748d55dd4ddc17e893c62499b680


Deployed Bytecode Sourcemap

214:10883:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2720:132;;;;;;;;;;-1:-1:-1;2720:132:2;;;;;:::i;:::-;;:::i;:::-;;7327:1549;;;;;;;;;;-1:-1:-1;7327:1549:2;;;;;:::i;:::-;;:::i;1876:157::-;;;;;;;;;;-1:-1:-1;1876:157:2;;;;;:::i;:::-;2007:12;;1930:7;2007:12;;;:5;:12;;;;;:19;;1876:157;;;;2629:25:7;;;2617:2;2602:18;1876:157:2;;;;;;;;5009:951;;;;;;:::i;:::-;;:::i;933:177:1:-;;;;;;;;;;-1:-1:-1;933:177:1;;;;;:::i;:::-;;:::i;:::-;;;3154:14:7;;3147:22;3129:41;;3117:2;3102:18;933:177:1;2989:187:7;890:36:1;;;;;;;;;;-1:-1:-1;890:36:1;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;890:36:1;;;;-1:-1:-1;;;890:36:1;;;;;;;;;;;;;;;3410:18:7;3455:15;;;3437:34;;3507:15;;;3502:2;3487:18;;3480:43;3559:15;;3554:2;3539:18;;3532:43;3618:14;;3611:22;3606:2;3591:18;;3584:50;3387:3;3372:19;;3181:459;8882:2213:2;;;;;;;;;;-1:-1:-1;8882:2213:2;;;;;:::i;:::-;;:::i;5966:1355::-;;;;;;:::i;:::-;;:::i;1718:36::-;;;;;;;;;;-1:-1:-1;1718:36:2;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1718:36:2;;;;;;;;;;6183:18:7;6228:15;;;6210:34;;6280:15;;;6275:2;6260:18;;6253:43;6332:15;;6312:18;;;6305:43;;;;6161:2;6146:18;1718:36:2;5977:377:7;4274:729:2;;;;;;;;;;-1:-1:-1;4274:729:2;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1794:41::-;;;;;;;;;;-1:-1:-1;1794:41:2;;;;;:::i;:::-;;:::i;803:18:1:-;;;;;;;;;;-1:-1:-1;803:18:1;;;;;;;;;;;8726::7;8714:31;;;8696:50;;8684:2;8669:18;803::1;8552:200:7;827:25:1;;;;;;;;;;-1:-1:-1;827:25:1;;;;;;;;;;;2720:132:2;2321:11;:9;:11::i;:::-;2307:25;;:10;:25;;;2299:62;;;;-1:-1:-1;;;2299:62:2;;8959:2:7;2299:62:2;;;8941:21:7;8998:2;8978:18;;;8971:30;9037:26;9017:18;;;9010:54;9081:18;;2299:62:2;;;;;;;;;2803:9:::1;:21:::0;;2834:11:::1;::::0;;::::1;::::0;::::1;::::0;2803:21:::1;::::0;;::::1;::::0;::::1;2834:11:::0;;;;;;;;;;;;;;;::::1;::::0;;2720:132::o;7327:1549::-;7497:30;783:2;7497:15;:30;:::i;:::-;7488:5;:39;;;7480:64;;;;-1:-1:-1;;;7480:64:2;;9815:2:7;7480:64:2;;;9797:21:7;9854:2;9834:18;;;9827:30;9893:14;9873:18;;;9866:42;9925:18;;7480:64:2;9613:336:7;7480:64:2;7617:17;;:25;;;;:17;;:25;7613:109;;;7658:17;:25;;-1:-1:-1;;7658:25:2;;;;;;;7697:14;7704:7;-1:-1:-1;7697:14:2;:::i;:::-;7736:9;7731:117;7755:7;:14;7751:18;;7731:117;;;7812:1;7798:7;7806:1;7798:10;;;;;;;;:::i;:::-;;;;;;;;;:15;7790:47;;;;-1:-1:-1;;;7790:47:2;;10345:2:7;7790:47:2;;;10327:21:7;10384:2;10364:18;;;10357:30;10423:21;10403:18;;;10396:49;10462:18;;7790:47:2;10143:343:7;7790:47:2;7771:3;;;;:::i;:::-;;;;7731:117;;;-1:-1:-1;7857:7:2;:15;;;;;;;-1:-1:-1;7857:15:2;;;;;;;;;7883:32;;:::i;:::-;7939:19;7956:1;7939:16;:19::i;:::-;7925:11;;;:33;7973:9;7968:624;110:6:5;7988:5:2;;7968:624;;;8014:21;8023:1;8025;8023:4;;;;;;;:::i;:::-;;;;;8029:5;8014:8;:21::i;:::-;8067:22;8084:1;8086;8084:4;;;;;;;:::i;:::-;;;;;8067:16;:22::i;:::-;8050:11;;8062:1;8050:14;;;;;;;:::i;:::-;;;;:39;8120:22;8137:1;8139;8137:4;;;;;;;:::i;8120:22::-;8103:9;:11;;;8115:1;8103:14;;;;;;;:::i;:::-;;;;:39;8193:11;;;;8175:33;;8205:1;8193:14;;;;;;;:::i;:::-;;;;;8175:4;:10;8180:1;8182;8180:4;;;;;;;:::i;:::-;;;;;8175:10;;;;;;;;;;;8186:1;8175:13;;;;;;;:::i;:::-;:17;;;;;;;;;:13;;;;;;;;;:17;;;;;;;;;;;;;:33::i;:::-;8156:9;:13;;;8170:1;8156:16;;;;;;;:::i;:::-;;;;:52;8259:11;;;;8241:30;;:4;:10;8246:1;8248;8246:4;;;;;;;:::i;:::-;;;;;8241:10;;;;;;;;;;;8252:1;8241:13;;;;;;;:::i;:30::-;8222:9;:13;;;8236:1;8222:16;;;;;;;:::i;:::-;;;;:49;8387:11;;;;8365:37;;8399:1;8387:14;;;;;;;:::i;:::-;;;;;8365:8;:14;8374:1;8376;8374:4;;;;;;;:::i;8365:37::-;8345:8;:14;8354:1;8356;8354:4;;;;;;;:::i;:::-;;;;;8345:14;;;;;;;;;;;8360:1;8345:17;;;;;;;:::i;:::-;;;;:57;;;;;;;;;;;;;;;;;;;8436:34;8458:9;:11;;;8436:8;:14;8445:1;8447;8445:4;;;;;;;:::i;8436:34::-;8416:8;:14;8425:1;8427;8425:4;;;;;;;:::i;:::-;;;;;8416:14;;;;;;;;;;;8431:1;8416:17;;;;;;;:::i;:::-;;;;:54;;;;;;;;;;;;;;;;;;;8511:1;8492:4;:10;8497:1;8499;8497:4;;;;;;;:::i;:::-;;;;;;;;;;8492:10;;;;;;;;;;-1:-1:-1;8492:10:2;:16;;;:20;8484:62;;;;-1:-1:-1;;;8484:62:2;;10893:2:7;8484:62:2;;;10875:21:7;10932:2;10912:18;;;10905:30;10971:31;10951:18;;;10944:59;11020:18;;8484:62:2;10691:353:7;8484:62:2;8560:21;8566:1;8568;8566:4;;;;;;;:::i;:::-;;;;;8572:1;8575:5;8560;:21::i;:::-;7995:3;;;;:::i;:::-;;;;7968:624;;;-1:-1:-1;8601:23:2;;;:15;;;:23;8648:19;8665:1;8648:16;:19::i;:::-;8634:11;;;:33;8677:19;;;:13;;;:19;8735:32;;;;;;;;;;;;;;;;;;;;;;8707:16;:9;:16;;;;8634:9;;8735:32;;;8761:5;;;;;;8735:32;;8761:5;;;;8735:32;;;;;;;;;-1:-1:-1;8735:25:2;;-1:-1:-1;;;8735:32:2:i;:::-;8707:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8787:10:2;;-1:-1:-1;8779:49:2;;-1:-1:-1;8808:19:2;;-1:-1:-1;8808:12:2;;;8823:4;8808:19;:::i;:::-;8779:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8844:25;8861:1;8864;8867;8844:25;;;;;;;;:::i;:::-;;;;;;;;7470:1406;7327:1549;;;;;;;;:::o;5009:951::-;5117:4;5104:9;:17;;5096:57;;;;-1:-1:-1;;;5096:57:2;;17999:2:7;5096:57:2;;;17981:21:7;18038:2;18018:18;;;18011:30;18077:29;18057:18;;;18050:57;18124:18;;5096:57:2;17797:351:7;5096:57:2;5171:16;5183:4;5171:9;:16;:::i;:::-;:21;5163:66;;;;-1:-1:-1;;;5163:66:2;;18472:2:7;5163:66:2;;;18454:21:7;;;18491:18;;;18484:30;18550:34;18530:18;;;18523:62;18602:18;;5163:66:2;18270:356:7;5163:66:2;5240:12;5262:30;783:2;5262:15;:30;:::i;:::-;5240:53;;5337:17;5312:21;:42;;5304:81;;;;-1:-1:-1;;;5304:81:2;;18833:2:7;5304:81:2;;;18815:21:7;18872:2;18852:18;;;18845:30;18911:28;18891:18;;;18884:56;18957:18;;5304:81:2;18631:350:7;5304:81:2;5395:13;5418:16;5430:4;5418:9;:16;:::i;:::-;5395:40;;5472:35;5491:15;5499:6;5491:15;;:3;-1:-1:-1;;;;;;;;;;;;;;;;;2931:21:2;;;;;;;;2943:3;2931:21;;2948:3;2931:21;;;;;2858:101;5491:3;:7;;:15::i;:::-;5472:11;;;;:8;:11;;;;;;:14;;:35;5455:11;;;;:8;:11;;;;;;;:52;;;;;;;;;;;;;;;5566:19;5455:11;5566:16;:19::i;:::-;5541:44;-1:-1:-1;5595:20:2;5618:72;5653:36;5661:27;5669:12;;5661:25;:27::i;:::-;5653:3;;:7;:36::i;:::-;5618:30;5634:12;;;;5618:3;-1:-1:-1;;;;;;;;;;;;;;;;;2931:21:2;;;;;;;;2943:3;2931:21;;2948:3;2931:21;;;;;2858:101;5618:30;:34;;:72::i;:::-;5595:95;;5700:9;5712:77;5769:4;5776:1;5779;5730:51;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5720:62;;;;;;5712:71;;:75;:77::i;:::-;5700:89;-1:-1:-1;5821:12:2;;5807:26;;5799:66;;;;-1:-1:-1;;;5799:66:2;;19864:2:7;5799:66:2;;;19846:21:7;19903:2;19883:18;;;19876:30;19942:29;19922:18;;;19915:57;19989:18;;5799:66:2;19662:351:7;5799:66:2;5875:23;5881:1;5884:6;5892:5;5875;:23::i;:::-;5914:39;;20192:10:7;20180:23;;20162:42;;5943:1:2;;5931:10;;5914:39;;20150:2:7;20135:18;5914:39:2;;;;;;;5086:874;;;;;5009:951;;:::o;933:177:1:-;982:4;1039:12;;;;;;;1038:65;;-1:-1:-1;1065:4:1;;;1058:11;;;1065:4;;1058:11;;1057:45;;-1:-1:-1;1075:26:1;:10;;;882:1;1075:10;;;:5;:10;;;;;:17;;:26;;1057:45;1031:72;933:177;-1:-1:-1;;933:177:1:o;8882:2213:2:-;9109:30;783:2;9109:15;:30;:::i;:::-;9100:5;:39;;;9092:64;;;;-1:-1:-1;;;9092:64:2;;9815:2:7;9092:64:2;;;9797:21:7;9854:2;9834:18;;;9827:30;9893:14;9873:18;;;9866:42;9925:18;;9092:64:2;9613:336:7;9092:64:2;9275:17;;:25;;;;:17;;:25;9271:109;;;9316:17;:25;;-1:-1:-1;;9316:25:2;;;;;;;9355:14;9362:7;-1:-1:-1;9355:14:2;:::i;:::-;9394:9;9389:117;9413:7;:14;9409:18;;9389:117;;;9470:1;9456:7;9464:1;9456:10;;;;;;;;:::i;:::-;;;;;;;;;:15;9448:47;;;;-1:-1:-1;;;9448:47:2;;10345:2:7;9448:47:2;;;10327:21:7;10384:2;10364:18;;;10357:30;10423:21;10403:18;;;10396:49;10462:18;;9448:47:2;10143:343:7;9448:47:2;9429:3;;;;:::i;:::-;;;;9389:117;;;-1:-1:-1;9515:7:2;:15;;;;;;;-1:-1:-1;9515:15:2;;;;;;;;;9546:54;;;;;;;;;;9565:1;;9568;;9571;;9574:6;;9595:4;;;;9546:54;:::i;:::-;;;;;;;;9650:32;;:::i;:::-;9706:19;9723:1;9706:16;:19::i;:::-;9692:11;;;:33;9740:9;9735:612;110:6:5;9755:5:2;;9735:612;;;9781:11;9795:1;9797;9795:4;;;;;;;:::i;:::-;;;;;9781:18;;9813:20;9822:3;9827:5;9813:8;:20::i;:::-;9865:21;9882:3;9865:16;:21::i;:::-;9848:11;;9860:1;9848:14;;;;;;;:::i;:::-;;;;:38;9917:22;9934:1;9936;9934:4;;;;;;;:::i;9917:22::-;9900:9;:11;;;9912:1;9900:14;;;;;;;:::i;:::-;;;;:39;9989:11;;;;9972:32;;10001:1;9989:14;;;;;;;:::i;:::-;;;;;9972:4;:9;9977:3;9972:9;;;;;;;;;;;9982:1;9972:12;;;;;;;:::i;:32::-;9953:9;:13;;;9967:1;9953:16;;;;;;;:::i;:::-;;;;:51;;;;10037:29;10054:9;:11;;;10037:4;:9;10042:3;10037:9;;;;;;;;;;;10047:1;10037:12;;;;;;;:::i;:29::-;10018:9;:13;;;10032:1;10018:16;;;;;;;:::i;:::-;;;;:48;10180:11;;;;10159:36;;10192:1;10180:14;;;;;;;:::i;:::-;;;;;10159:8;:13;10168:3;10159:13;;;;;;;;;;;10173:1;10159:16;;;;;;;:::i;:36::-;10140:13;;;;:8;:13;;;;;;;;:55;;;;;;;;;;;;;;;10249:11;;;;10228:33;;10249:11;;10228:16;;:33;10209:13;;;;:8;:13;;;;;;;;:52;;:16;;;:52;;;;;;;;;;;;;10283:4;:9;;;;:15;;;10275:61;;;;-1:-1:-1;;;10275:61:2;;10893:2:7;10275:61:2;;;10875:21:7;10932:2;10912:18;;;10905:30;10971:31;10951:18;;;10944:59;11020:18;;10275:61:2;10691:353:7;10275:61:2;-1:-1:-1;9762:3:2;;;;:::i;:::-;;;;9735:612;;;-1:-1:-1;10378:4:2;;10356:10;;10369:13;;10378:4;;;;;10369:6;:13;:::i;:::-;10392:23;;;:15;;;:23;10356:26;-1:-1:-1;10473:19:2;10490:1;10473:16;:19::i;:::-;10459:11;;;:33;10518:9;10524:3;10518;:9;:::i;:::-;10502:25;;:13;;;:25;10605:29;;10572:12;;10605:29;;10616:11;;10629:4;;;;10605:29;;;:::i;:::-;;;;;;;;;;;;;10595:40;;;;;;10587:49;;10572:64;;10657:11;:18;;;10676:6;10684:9;10695:34;10723:5;;10695:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10695:27:2;;-1:-1:-1;;;10695:34:2:i;:::-;10731:4;10657:79;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10755:10:2;;-1:-1:-1;10747:49:2;;-1:-1:-1;10776:19:2;;-1:-1:-1;10776:12:2;;;10791:4;10776:19;:::i;:::-;10747:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10833:9:2;;10807:12;;10833:9;;;;;10856:19;:12;;;10871:4;10856:19;:::i;:::-;10825:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10806:74;;;10898:7;10890:50;;;;-1:-1:-1;;;10890:50:2;;25209:2:7;10890:50:2;;;25191:21:7;25248:2;25228:18;;;25221:30;25287:32;25267:18;;;25260:60;25337:18;;10890:50:2;25007:354:7;10890:50:2;10964:25;;;10997:22;:15;;;11015:4;10997:22;:::i;:::-;11021:4;;10964:62;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10950:76;;;;;11044:7;11036:52;;;;-1:-1:-1;;;11036:52:2;;25844:2:7;11036:52:2;;;25826:21:7;;;25863:18;;;25856:30;25922:34;25902:18;;;25895:62;25974:18;;11036:52:2;25642:356:7;11036:52:2;9082:2013;;;;8882:2213;;;;;;;;;;;;:::o;5966:1355::-;6221:16;6233:4;6221:9;:16;:::i;:::-;:21;6213:66;;;;-1:-1:-1;;;6213:66:2;;18472:2:7;6213:66:2;;;18454:21:7;;;18491:18;;;18484:30;18550:34;18530:18;;;18523:62;18602:18;;6213:66:2;18270:356:7;6213:66:2;6289:12;6311:30;783:2;6311:15;:30;:::i;:::-;6289:53;;6385:17;6360:21;:42;;6352:81;;;;-1:-1:-1;;;6352:81:2;;18833:2:7;6352:81:2;;;18815:21:7;18872:2;18852:18;;;18845:30;18911:28;18891:18;;;18884:56;18957:18;;6352:81:2;18631:350:7;6352:81:2;6443:13;6466:16;6478:4;6466:9;:16;:::i;:::-;6443:40;;6527:32;;:::i;:::-;6583:19;6600:1;6583:16;:19::i;:::-;6569:11;;;:33;6617:9;6612:565;110:6:5;6632:5:2;;6612:565;;;6658:21;6667:1;6669;6667:4;;;;;;;:::i;:::-;;;;;6673:5;6658:8;:21::i;:::-;6711:22;6728:1;6730;6728:4;;;;;;;:::i;6711:22::-;6694:11;;6706:1;6694:14;;;;;;;:::i;:::-;;;;:39;6764:22;6781:1;6783;6781:4;;;;;;;:::i;6764:22::-;6747:9;:11;;;6759:1;6747:14;;;;;;;:::i;:::-;;;;:39;6902:11;;;;6880:37;;6914:1;6902:14;;;;;;;:::i;:::-;;;;;6880:8;:14;6889:1;6891;6889:4;;;;;;;:::i;6880:37::-;6860:8;:14;6869:1;6871;6869:4;;;;;;;:::i;:::-;;;;;6860:14;;;;;;;;;;;6875:1;6860:17;;;;;;;:::i;:::-;;;;:57;;;;;;;;;;;;;;;;;;;6951:34;6973:9;:11;;;6951:8;:14;6960:1;6962;6960:4;;;;;;;:::i;6951:34::-;6931:8;:14;6940:1;6942;6940:4;;;;;;;:::i;:::-;;;;;6931:14;;;;;;;;;;;6946:1;6931:17;;;;;;;:::i;:::-;;;;:54;;;;;;;;;;;;;;;;;;;7026:1;7007:4;:10;7012:1;7014;7012:4;;;;;;;:::i;:::-;;;;;;;;;;7007:10;;;;;;;;;;-1:-1:-1;7007:10:2;:16;;;:20;6999:62;;;;-1:-1:-1;;;6999:62:2;;10893:2:7;6999:62:2;;;10875:21:7;10932:2;10912:18;;;10905:30;10971:31;10951:18;;;10944:59;11020:18;;6999:62:2;10691:353:7;6999:62:2;7075:26;7081:1;7083;7081:4;;;;;;;:::i;:::-;;;;;7087:6;7095:5;7075;:26::i;:::-;6639:3;;;;:::i;:::-;;;;6612:565;;;;7187:8;:15;;;7203:6;7211:9;7222:31;7247:5;;7222:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7222:24:2;;-1:-1:-1;;;7222:31:2:i;:::-;7187:67;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7295:10;7270:44;;;7286:1;7289;7292;7307:6;7270:44;;;;;;;;;:::i;:::-;;;;;;;;6079:1242;;;5966:1355;;;;;:::o;4274:729::-;4359:26;4533:1;4516:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;4507:35;;4557:9;4552:445;4572:12;;;4552:445;;;4605:26;;:::i;:::-;4655:4;:10;4660:1;;4662;4660:4;;;;;;;:::i;:::-;;;;;;;4655:10;;;;;;;;;;;4666:1;4655:13;;;;;;;:::i;:::-;4645:23;;;;;;;;;4655:13;;;;;;;;4645:23;;;;;;;;;;;;;;-1:-1:-1;4697:1:2;;4699;4697:4;;;;;;;:::i;:::-;;;;;;;4692:10;;;;;;;;;;;4703:1;4692:13;;;;;;;:::i;:::-;;;;4682:23;;;;;;;;;;;;;;;;;;;;;;;;;:4;4687:1;4682:7;;;;;;;:::i;:::-;;;;:23;4723:27;;;:13;:19;4737:1;;4739;4737:4;;;;;;;:::i;:::-;;;;;;;;;;4723:19;;-1:-1:-1;4723:19:2;;;;;;;;-1:-1:-1;4723:19:2;;;;:27;4719:164;;;4780:30;4792:8;:14;4801:1;;4803;4801:4;;;;;;;:::i;:::-;;;;;;;4792:14;;;;;;;;;;;4807:1;4792:17;;;;;;;:::i;:::-;4780:30;;;;;;;;;4792:17;;;;;;;;;4780:30;;;;;;;;;;;:4;-1:-1:-1;4780:7:2;;;;;;:11;:30::i;:::-;4770:40;;4838:30;4850:8;4775:1;4859;;4861;4859:4;;;;;;;:::i;:::-;;;;;;;4850:14;;;;;;;;;;;4865:1;4850:17;;;;;;;:::i;:::-;;;;4838:30;;;;;;;;;;;;;;;;;;;;;;;;;:4;4843:1;4838:7;;;;;;;:::i;:30::-;4828:7;;;:40;4719:164;4911:23;4926:4;4931:1;4926:7;;;;;4911:14;:23::i;:::-;4896:6;4903:1;4896:9;;;;;;;;:::i;:::-;;;;;;;4906:1;4896:12;;;;;;;:::i;:::-;;;;:38;4963:23;4978:4;4983:1;4978:7;;4963:23;4948:6;4955:1;4948:9;;;;;;;;:::i;:::-;;;;;;;4958:1;4948:12;;;;;;;:::i;:::-;;;;:38;-1:-1:-1;4586:3:2;;;;:::i;:::-;;;;4552:445;;;;4274:729;;;;;:::o;1794:41::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5121:165:5:-;-1:-1:-1;;;;;;;;;;;;;;;;;5213:66:5;326;5256:5;5239:23;;;;;;;;:::i;:::-;;;;;;;;;;;;;5229:34;;;;;;5221:43;;:57;;;;:::i;:::-;5213:7;:66::i;2140:122:2:-;2184:7;2210:39;2087:45;2131:1;2095:32;2087:45;:::i;:::-;11442:4;11272:190;2210:39;:45;;;;2140:122;-1:-1:-1;2140:122:2:o;3790:586:5:-;-1:-1:-1;;;;;;;;;;;;;;;;;3885:4:5;3876:13;;;3872:43;;-1:-1:-1;;3898:17:5;;;;;;;;;-1:-1:-1;3898:17:5;;;;;;;;3790:586::o;3872:43::-;4070:66;4065:71;;4052:3;3976:79;;;3925:9;4165:14;4065:71;4177:1;4165:8;:14::i;:::-;:18;;4182:1;4165:18;:::i;:::-;4146:37;;4193:9;4205:30;4214:8;428:66;4205:8;:30::i;:::-;4267:29;;;;;;;;;;;;;;;;;;4193:42;;-1:-1:-1;4322:4:5;4318:8;;4310:16;;4306:40;;4335:11;4339:6;4335:3;:11::i;:::-;4328:18;3790:586;-1:-1:-1;;;;;;;3790:586:5:o;4306:40::-;4363:6;3790:586;-1:-1:-1;;;;;;3790:586:5:o;2965:353:2:-;3031:16;;;;:13;:16;;;;;;:24;;;;:16;;:24;3027:285;;;3099:11;;;;:8;:11;;;;;;;;3084:30;;;;;;;;;;;;;;;;;;;;:7;;;3099:14;3084:7;;;;;:30;;:10;;:30;3071:7;;;;:4;:7;;;;;;;;:43;;;;;;;;;;;;;;;;3156:8;:11;;;;;;3141:30;;;;;;;;3156:14;;;3141:30;;;;;;;;;:7;;;;;;;:30;;;;:10;;:30;3128:7;;;;:4;:7;;;;;;;;:43;;:10;;;:43;;;;;;;;;;3192:11;;;;;;-1:-1:-1;;;3136:1:2;-1:-1:-1;;;;;;;;;;;;;;;;;;3277:13:2;:16;;;;:24;;-1:-1:-1;;3277:24:2;;;;;;;3027:285;2965:353;;:::o;2553:494:5:-;-1:-1:-1;;;;;;;;;;;;;;;;;2694:4:5;2688:11;2735:2;2729:9;2719:8;2712:27;2794:4;2790:2;2786:13;2780:20;2773:4;2763:8;2759:19;2752:49;2848:2;2842:9;2835:4;2825:8;2821:19;2814:38;2907:4;2903:2;2899:13;2893:20;2886:4;2876:8;2872:19;2865:49;2980:4;2977:1;2971:4;2961:8;2955:4;2948:5;2937:48;2927:104;;3015:1;3012;3005:12;2927:104;;2553:494;;;;:::o;3324:944:2:-;3499:22;3621:7;;;:4;:7;;;;;3642:13;;;;:17;3638:355;;3731:13;;;;3725:20;;;;:5;:20;;;;;3786:11;;3725:20;;-1:-1:-1;3725:20:2;;3786:15;;3731:13;;3786:15;:::i;:::-;3781:21;;;;;;;;:::i;:::-;;;;;;;;;;;3764:13;;3759:19;;;;3764:13;;;;;;3759:19;;;;;;:::i;:::-;;;;;;;;:43;;;;3816:4;:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3844:4;:11;;;;3859:1;3844:16;3840:142;;3869:13;;3862:21;;3869:13;;3862:6;:21::i;:::-;3840:142;;;3922:11;;3906:13;;;;;;;:27;3902:80;;;3969:13;;3940:19;;3969:13;;;;;;;3935:4;;3969:13;;3940:19;;3969:13;;3940:19;;;;;;:::i;:::-;;;;;;;;;3935:25;;;;;;;;;;;:31;;;:47;;;;;;;;;;;;;;;;;;3902:80;4002:21;;-1:-1:-1;;4002:21:2;;;;;;;;;;;;4033:24;;;;4002:21;;4033:14;;:24;;;;-1:-1:-1;;;4033:24:2;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;4113:13;4120:5;4113:6;:13::i;:::-;4108:58;;4142:13;4149:5;4142:6;:13::i;:::-;4182:12;;;;;;;;;:5;:12;;;;;;;4227:11;;4204:35;;;;;;;;;;;;;;4249:12;;-1:-1:-1;4249:12:2;;;;;;;;;;;;;;;;-1:-1:-1;;3324:944:2:o;7291:2083:5:-;7361:26;;:::i;:::-;5630:4;5615:28;;5609:35;7410:25;;:10;:25::i;7421:13::-;7410:10;:25::i;:::-;7399:36;;5615:28;;;5609:35;7456:26;;7410:10;:25::i;7456:26::-;7445:8;;;:37;5615:28;;;5609:35;7502:26;;7410:10;:25::i;7502:26::-;7492:7;;;:36;5615:28;;;5609:35;7548:26;;7410:10;:25::i;7548:26::-;7538:7;;;:36;7590:9;7585:777;86:1;7605;:5;7585:777;;;7647:36;7658:24;7664:3;7675:6;:1;7679:2;7675:6;:::i;:::-;7669:12;;:3;:12;:::i;:::-;5615:28;5630:4;5615:28;5609:35;;5477:183;7647:36;7631:5;:10;;;7642:1;7631:13;;;;;;;:::i;:::-;;;;:52;7713:42;7724:30;7730:3;7742:5;86:1;7742;:5;:::i;:::-;7741:12;;7751:2;7741:12;:::i;7713:42::-;7697:5;:10;;;7708:1;7697:13;;;;;;;:::i;:::-;;;;:58;;;;7785:45;7796:33;7802:3;7822:1;7826:2;7822:6;;;;:::i;:::-;7813;86:1;7817:2;7813:6;:::i;:::-;7807:12;;:3;:12;:::i;:::-;:21;;;;:::i;7785:45::-;7769:5;:10;;;7780:1;7769:13;;;;;;;:::i;:::-;;;;:61;;;;7858:45;7869:33;7875:3;7895:1;7899:2;7895:6;;;;:::i;:::-;7886;86:1;7890:2;7886:6;:::i;7858:45::-;7844:5;:8;;;7853:1;7844:11;;;;;;;:::i;:::-;;;;:59;;;;7933:46;7944:34;7950:3;7971:1;7975:2;7971:6;;;;:::i;:::-;7961:7;86:1;7965:3;7961:7;:::i;7933:46::-;7917:5;:10;;;7928:1;7917:13;;;;;;;:::i;:::-;;;;:62;;;;8007:46;8018:34;8024:3;8045:1;8049:2;8045:6;;;;:::i;:::-;8035:7;86:1;8039:3;8035:7;:::i;8007:46::-;7993:5;:8;;;8002:1;7993:11;;;;;;;:::i;:::-;;;;:60;;;;8083:46;8094:34;8100:3;8121:1;8125:2;8121:6;;;;:::i;:::-;8111:7;86:1;8115:3;8111:7;:::i;8083:46::-;8067:5;:10;;;8078:1;8067:13;;;;;;;:::i;:::-;;;;:62;;;;8159:46;8170:34;8176:3;8197:1;8201:2;8197:6;;;;:::i;:::-;8187:7;86:1;8191:3;8187:7;:::i;8159:46::-;8143:5;:10;;;8154:1;8143:13;;;;;;;:::i;:::-;;;;:62;;;;8243:34;8249:3;8270:1;8274:2;8270:6;;;;:::i;:::-;8260:7;86:1;8264:3;8260:7;:::i;8243:34::-;8219:7;;;;:10;8230:1;8219:13;;;;;;;:::i;:::-;;;;:59;;;;;8316:34;8322:3;8343:1;8347:2;8343:6;;;;:::i;:::-;8333:7;86:1;8337:3;8333:7;:::i;8316:34::-;8292:7;;;;:10;;;8303:1;8292:13;;;;;;;:::i;:::-;;;;:59;7612:3;;;;:::i;:::-;;;;7585:777;;;-1:-1:-1;8372:16:5;8391:7;86:1;8395:3;8391:7;:::i;:::-;8372:26;-1:-1:-1;8428:26:5;8434:3;8439:14;8372:26;8439:3;:14;:::i;8428:26::-;8408:9;;;:47;8478:38;8489:26;8495:3;8500:14;8506:8;8500:3;:14;:::i;8478:38::-;8466:9;;;:50;8538:38;8549:26;8555:3;8560:14;8566:8;8560:3;:14;:::i;8538:38::-;8526:9;;;:50;8607:26;8613:3;8618:14;8624:8;8618:3;:14;:::i;8607:26::-;8586:10;;;:48;8663:26;8669:3;8674:14;8680:8;8674:3;:14;:::i;8663:26::-;8644:8;;;:46;8719:26;8725:3;8730:14;8736:8;8730:3;:14;:::i;8719:26::-;8701:7;;;:45;8777:26;8783:3;8788:14;8794:8;8788:3;:14;:::i;8777:26::-;8756:10;;;:48;8834:26;8840:3;8845:14;8851:8;8845:3;:14;:::i;8834:26::-;8814:9;;;:47;8891:26;8897:3;8902:14;8908:8;8902:3;:14;:::i;8891:26::-;8871:9;;;:47;8950:26;8956:3;8961:14;8967:8;8961:3;:14;:::i;8950:26::-;8928:11;;;:49;8942:35;8988:211;9012:5;139:1;9016;9012:5;:::i;:::-;9008:1;:9;8988:211;;;9054:47;9065:35;9071:3;9093:6;:1;9097:2;9093:6;:::i;:::-;9076:14;9082:8;9076:3;:14;:::i;9054:47::-;9038:8;;;;:10;9049:1;9038:13;;;;;;;:::i;:::-;;;;:63;9131:57;9142:45;9148:3;9171:5;139:1;9171;:5;:::i;:::-;:9;;9179:1;9171:9;:::i;:::-;9170:16;;9184:2;9170:16;:::i;9131:57::-;9115:5;:8;;;:10;;;9126:1;9115:13;;;;;;;:::i;:::-;;;;:73;9019:3;;;;:::i;:::-;;;;8988:211;;;-1:-1:-1;9229:41:5;9235:3;9258:5;139:1;9262;9258:5;:::i;:::-;9257:12;;9267:2;9257:12;:::i;:::-;9240:14;9246:8;9240:3;:14;:::i;9229:41::-;9208:8;;;;:10;;:63;9302:41;9308:3;9331:5;139:1;9335;9331:5;:::i;:::-;9330:12;;9340:2;9330:12;:::i;:::-;9313:14;9319:8;9313:3;:14;:::i;9302:41::-;9281:8;;;;:10;;:63;-1:-1:-1;9281:5:5;7291:2083;-1:-1:-1;7291:2083:5:o;3053:415::-;-1:-1:-1;;;;;;;;;;;;;;;;;3187:4:5;3181:11;3228:1;3222:8;3212;3205:26;3285:4;3282:1;3278:12;3272:19;3265:4;3255:8;3251:19;3244:48;3333:1;3326:4;3316:8;3312:19;3305:30;3401:4;3398:1;3392:4;3382:8;3376:4;3369:5;3358:48;3348:104;;3436:1;3433;3426:12;1088:95;1135:7;1161:15;1175:1;223:66;1161:15;:::i;854:95::-;901:7;927:15;223:66;927:1;:15;:::i;9886:1878::-;9958:28;;:::i;:::-;5630:4;5615:28;;5609:35;10009:25;;7410:10;:25::i;10009:::-;9998:36;;5615:28;;;5609:35;10055:26;;7410:10;:25::i;10055:26::-;10044:8;;;:37;5615:28;;;5609:35;10101:26;;7410:10;:25::i;10101:26::-;10091:7;;;:36;5615:28;;;5609:35;10147:26;;7410:10;:25::i;10147:26::-;10137:7;;;:36;10189:9;10184:551;86:1;10204;:5;10184:551;;;10246:36;10257:24;10263:3;10274:6;:1;10278:2;10274:6;:::i;10246:36::-;10230:5;:10;;;10241:1;10230:13;;;;;;;:::i;:::-;;;;:52;10312:42;10323:30;10329:3;10341:5;86:1;10341;:5;:::i;10312:42::-;10296:5;:10;;;10307:1;10296:13;;;;;;;:::i;:::-;;;;:58;;;;10384:45;10395:33;10401:3;10421:1;10425:2;10421:6;;;;:::i;10384:45::-;10368:5;:10;;;10379:1;10368:13;;;;;;;:::i;:::-;;;;:61;;;;10457:45;10468:33;10474:3;10494:1;10498:2;10494:6;;;;:::i;10457:45::-;10443:5;:8;;;10452:1;10443:11;;;;;;;:::i;:::-;;;;:59;;;;10532:46;10543:34;10549:3;10570:1;10574:2;10570:6;;;;:::i;10532:46::-;10516:5;:10;;;10527:1;10516:13;;;;;;;:::i;:::-;;;;:62;;;;10608:46;10619:34;10625:3;10646:1;10650:2;10646:6;;;;:::i;10608:46::-;10592:5;:10;;;10603:1;10592:13;;;;;;;:::i;:::-;;;;:62;;;;10689:34;10695:3;10716:1;10720:2;10716:6;;;;:::i;10689:34::-;10668:7;;;;10676:1;10668:10;;;;;;;:::i;:::-;;;;:56;10211:3;;;;:::i;:::-;;;;10184:551;;;-1:-1:-1;10744:16:5;10763:7;86:1;10767:3;10763:7;:::i;:::-;10744:26;-1:-1:-1;10800:26:5;10806:3;10811:14;10744:26;10811:3;:14;:::i;10800:26::-;10780:9;;;:47;10850:38;10861:26;10867:3;10872:14;10878:8;10872:3;:14;:::i;10850:38::-;10838:9;;;:50;10910:38;10921:26;10927:3;10932:14;10938:8;10932:3;:14;:::i;10910:38::-;10898:9;;;:50;10979:26;10985:3;10990:14;10996:8;10990:3;:14;:::i;10979:26::-;10958:10;;;:48;11035:26;11041:3;11046:14;11052:8;11046:3;:14;:::i;11035:26::-;11016:8;;;:46;11091:26;11097:3;11102:14;11108:8;11102:3;:14;:::i;11091:26::-;11073:7;;;:45;11149:26;11155:3;11160:14;11166:8;11160:3;:14;:::i;11149:26::-;11128:10;;;:48;11206:26;11212:3;11217:14;11223:8;11217:3;:14;:::i;11206:26::-;11186:9;;;:47;11263:26;11269:3;11274:14;11280:8;11274:3;:14;:::i;11263:26::-;11243:9;;;:47;11322:26;11328:3;11333:14;11339:8;11333:3;:14;:::i;11322:26::-;11300:11;;;:49;11314:35;11360:241;139:1;11380;:5;11360:241;;;11460:47;11471:35;11477:3;11499:6;:1;11503:2;11499:6;:::i;11460:47::-;11444:8;;;;:10;11455:1;11444:13;;;;;;;:::i;:::-;;;;:63;11537:53;11548:41;11554:3;11577:5;139:1;11577;:5;:::i;11537:53::-;11521:5;:8;;;:10;;;11532:1;11521:13;;;;;;;:::i;:::-;;;;:69;11387:3;;;;:::i;:::-;;;;11360:241;;;-1:-1:-1;11631:35:5;11637:3;11659:6;139:1;11663:2;11659:6;:::i;11631:35::-;11623:44;;11610:5;:8;;;:10;;:57;;;;;11698:35;11704:3;139:1;11730:2;11726:6;;;;:::i;11698:35::-;11677:8;;;;:10;;:57;-1:-1:-1;11677:5:5;9886:1878;-1:-1:-1;9886:1878:5:o;6057:677::-;6126:25;;:::i;:::-;5630:4;5615:28;;5609:35;6173:25;;7410:10;:25::i;6173:::-;6163:35;;5615:28;;;5609:35;6218:26;;7410:10;:25::i;6218:26::-;6208:7;;;:36;6260:9;6255:247;86:1;6275;:5;6255:247;;;6317:35;6328:23;6334:3;6344:6;:1;6348:2;6344:6;:::i;:::-;6339:11;;:2;:11;:::i;6317:35::-;6301:5;:10;;;6312:1;6301:13;;;;;;;:::i;:::-;;;;:51;6382:41;6393:29;6399:3;6410:5;86:1;6410;:5;:::i;:::-;6409:12;;6419:2;6409:12;:::i;6382:41::-;6366:5;:10;;;6377:1;6366:13;;;;;;;:::i;:::-;;;;:57;;;;6458:32;6464:3;6483:1;6487:2;6483:6;;;;:::i;:::-;6474;86:1;6478:2;6474:6;:::i;:::-;6469:11;;:2;:11;:::i;6458:32::-;6437:7;;;;6445:1;6437:10;;;;;;;:::i;:::-;;;;:54;6282:3;;;;:::i;:::-;;;;6255:247;;;-1:-1:-1;6511:16:5;6530:6;86:1;6534:2;6530:6;:::i;:::-;6511:25;-1:-1:-1;6566:25:5;6572:3;6577:13;6511:25;6577:2;:13;:::i;6566:25::-;6546:9;;;:46;6621:25;6627:3;6632:13;6637:8;6632:2;:13;:::i;6621:25::-;6603:7;;;:44;6677:26;6683:3;6688:14;6694:8;6688:3;:14;:::i;6677:26::-;6657:9;;;:47;-1:-1:-1;6657:5:5;6057:677;-1:-1:-1;6057:677:5:o;4382:275::-;4487:7;;4517;;;;4443;;4487;4528:4;4509:23;;;:31;;4505:113;;4552:66;4542:76;4643:6;4382:275;-1:-1:-1;;4382:275:5:o;4663:452::-;-1:-1:-1;;;;;;;;;;;;;;;;;4741:9:5;4760:300;4787:16;4806:17;4815:4;4821:1;4806:8;:17::i;:::-;:21;;4826:1;4806:21;:::i;:::-;4787:40;;4913:30;4922:8;428:66;4913:8;:30::i;:::-;4909:34;;4979:8;4961:14;4970:1;4973;4961:8;:14::i;:::-;:26;4957:70;;5007:5;;;4957:70;5040:9;5048:1;5040:9;;:::i;:::-;;;4773:287;4760:300;;;5076:32;;;;;;;;;;;;;;;;-1:-1:-1;5076:32:5;4663:452::o;1824:659::-;1897:14;1948:13;326:66;1948:27;;2030:4;2024:11;2065:4;2055:8;2048:22;2111:4;2104;2094:8;2090:19;2083:33;2157:4;2150;2140:8;2136:19;2129:33;2203:4;2196;2186:8;2182:19;2175:33;2249:8;2242:4;2232:8;2228:19;2221:37;2299:5;2292:4;2282:8;2278:19;2271:34;2378:4;2368:8;2362:4;2352:8;2346:4;2339:5;2328:55;2318:111;;2413:1;2410;2403:12;2318:111;2452:15;;1824:659;-1:-1:-1;;;;1824:659:5:o;3474:177::-;-1:-1:-1;;;;;;;;;;;;;;;;;3557:47:5;;;;;;;;;3563:3;;3557:47;;;3598:3;;;;3557:47;;;;3576:26;;326:66;3576:26;:::i;:::-;3557:47;;3550:54;3474:177;-1:-1:-1;;3474:177:5:o;7837:1377:1:-;7933:24;:10;;;7884:12;7933:10;;;:5;:10;;;;;:15;7884:12;;;;7933:15;;;;:24;;:53;;-1:-1:-1;7961:25:1;:10;;;882:1;7961:10;;;:5;:10;;;;;:16;-1:-1:-1;;;7961:16:1;;;:25;7933:53;7929:261;;;-1:-1:-1;8011:3:1;7929:261;;;-1:-1:-1;8054:10:1;;;;;;;;:5;:10;;;;;:16;-1:-1:-1;;;8054:16:1;;;8084:96;8091:27;:13;;;882:1;8091:13;;;:5;:13;;;;;:18;;;;;:27;8084:96;;8147:13;;;;;;;;:5;:13;;;;;:18;;;;;8084:96;;;8203:27;:13;;;882:1;8203:13;;;:5;:13;;;;;:18;;;;;:27;8199:142;;8254:13;;;;;;;;:5;:13;;;;;:18;;;;;;-1:-1:-1;8199:142:1;;;8311:13;;;;;;;;:5;:13;;;;;:19;-1:-1:-1;;;8311:19:1;;;;-1:-1:-1;8199:142:1;8367:13;;;;8350:14;8367:13;;;:5;:13;;;;;;:20;8397:12;;;;;;;:29;;-1:-1:-1;;8397:29:1;8367:20;;;;8397:29;;;;;;8440:16;;8436:251;;8486:14;;;;;;;;:5;:14;;;;;:19;;;;;;8476:29;;;;8472:162;;8525:14;;;;;;;;:5;:14;;;;;:27;;;;;;;;;;;;;;;;;8436:251;;8472:162;8591:14;;;;;;;;:5;:14;;;;;:28;;;;;-1:-1:-1;;;8591:28:1;;;;;;;;;;;8436:251;;;8664:4;:12;;-1:-1:-1;;8664:12:1;;;;;;;8436:251;8712:13;;;;8696:12;8712:13;;;:5;:13;;;;;:17;-1:-1:-1;;;8712:17:1;;;;8711:18;;8743:13;;;8739:374;;8772:26;8786:6;8794:3;8772:13;:26::i;:::-;8833:10;;;;;;;;:5;:10;;;;;;:15;;8812:13;;;;;;;;;:36;;;;8833:15;;;;;;;8812:36;;;;;;8868:18;;;;;;8862:25;;;;;:41;;-1:-1:-1;;8862:41:1;;;;;;;;8939:16;;8917:38;;;;-1:-1:-1;;;8939:16:1;;;;;;8917:38;;;;;;8975:19;;;;8969:26;;;;;:42;;;;;;;;;;9045:14;9025:13;;:34;;;;-1:-1:-1;;;9045:14:1;;;;;;9025:34;;;;;;;;8812:13;;8833:10;8739:374;9126:7;9122:56;;;9149:18;9161:5;9149:11;:18::i;:::-;-1:-1:-1;;9194:13:1;;;;;;:5;:13;;;;;9187:20;;;;;;-1:-1:-1;;7837:1377:1:o;4326:635::-;4373:13;4419:4;;;;4433:215;4440:14;;;;4433:215;;4479:5;4470:14;;4508:5;4502:11;;:3;:11;;;4498:140;;;4541:12;;;;;;;;:5;:12;;;;;:17;;;;;4433:215;;4498:140;4605:12;;;;;;;;:5;:12;;;;;:18;-1:-1:-1;;;4605:18:1;;;4433:215;;;4670:64;;;;;;;;;;;;;;;-1:-1:-1;4670:64:1;;;;;;;;;;;;;4728:4;4670:64;;;;;;4657:10;;;;;;;;;;;:77;;;;;;;;;;;;-1:-1:-1;;;4657:77:1;;;;;-1:-1:-1;;;4657:77:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4744:185;;4779:4;:10;;-1:-1:-1;;4779:10:1;;;;;;;4744:185;;;4816:6;4810:12;;:3;:12;;;4806:123;;;4838:13;;;;;;;;:5;:13;;;;;:24;;;;;;;;;;;;;;;;;4806:123;;;4893:13;;;;;;;;:5;:13;;;;;:25;;;;;-1:-1:-1;;;4893:25:1;;;;;;;;;;;4806:123;4938:16;4950:3;4938:11;:16::i;:::-;4363:598;;4326:635;:::o;4967:379::-;5046:8;;;;5029:14;5046:8;;;:5;:8;;;;;;:15;5071:8;;;;;;;:25;;-1:-1:-1;;5071:25:1;5046:15;;;;5071:25;;;;;;5046:15;5106:234;;5142:4;:8;;;;;-1:-1:-1;;5142:8:1;;;;;;4363:598;;4326:635;:::o;5106:234::-;5190:14;;;;;;;;:5;:14;;;;;:19;;;;;;5185:24;;;;5181:149;;5229:14;;;;;;;;:5;:14;;;;;:23;;;;;;;;;;;;;;;;;-1:-1:-1;4326:635:1:o;5181:149::-;5291:14;;;;;;;;:5;:14;;;;;:24;;;;-1:-1:-1;;;5291:24:1;;;;;;;;;;;;-1:-1:-1;4967:379:1:o;5352:2479::-;5404:13;5427:2318;5441:4;;;5434:11;;;5441:4;;5434:11;;;;:30;;-1:-1:-1;5450:10:1;;;;;;;:5;:10;;;;;:14;-1:-1:-1;;;5450:14:1;;;;5449:15;5434:30;5427:2318;;;5499:10;;;;5480:16;5499:10;;;:5;:10;;;;;;:17;;;5541:16;;;;;:21;5499:17;;5541:21;;;;;5534:28;;5530:2205;;5591:16;;;;;;;;:5;:16;;;;;;:22;-1:-1:-1;;;5591:22:1;;;;;5635:13;;;;;;:17;5591:22;;-1:-1:-1;;;;5635:17:1;;;;5631:234;;;5676:13;;;;5696:5;5676:13;;;:5;:13;;;;;;:25;;;;;;;;;5723:16;;;;;;;:27;;;;;-1:-1:-1;;;5723:27:1;;;5772:21;5729:9;5772:10;:21::i;:::-;5824:16;;;;;;;;:5;:16;;;;;:22;-1:-1:-1;;;5824:22:1;;;;-1:-1:-1;5631:234:1;5893:13;;;;5887:25;5893:13;;;5887:5;5893:13;;;;;;:18;;;;;;;5887:25;;;:29;-1:-1:-1;;;5887:29:1;;;;5886:30;:65;;;;-1:-1:-1;5927:13:1;;;;5921:26;5927:13;;;5921:5;5927:13;;;;;;:19;-1:-1:-1;;;5927:19:1;;;;;5921:26;;;:30;-1:-1:-1;;;5921:30:1;;;;5920:31;5886:65;5882:752;;;5975:13;;;;;;;5995:4;5975:13;;;;;:24;;;;-1:-1:-1;;;5975:24:1;;;6027:9;-1:-1:-1;6027:9:1;5530:2205;;5882:752;6094:13;;;;6088:26;6094:13;;;6088:5;6094:13;;;;;;:19;-1:-1:-1;;;6094:19:1;;;;;6088:26;;;:30;-1:-1:-1;;;6088:30:1;;;;6083:275;;6152:13;;;;6178:5;6152:13;;;6146:5;6152:13;;;;;;:18;;;;;;;;6146:25;;;;:37;;;;;;;;;6209:13;;;:24;;;-1:-1:-1;;;6209:24:1;;;6259:19;6158:6;6259:11;:19::i;:::-;6313:16;;;;;;;;:5;:16;;;;;:22;-1:-1:-1;;;6313:22:1;;;;-1:-1:-1;6083:275:1;6399:16;;;;;;;;:5;:16;;;;;;:20;;6379:13;;;;;;;;:40;;6399:20;-1:-1:-1;;;6399:20:1;;;;;6379:40;;;;;;;;;;;;6441:28;;;;;;;6497:19;;-1:-1:-1;;;6497:19:1;;;;;6491:26;;;;:38;;;;;;;6551:21;6405:9;6551:10;:21::i;5530:2205::-;6681:16;;;;;;;;:5;:16;;;;;;:21;;;;;;;6724:13;;;;;;:17;6681:21;;-1:-1:-1;;;;6724:17:1;;;;6720:234;;;6765:13;;;;6785:5;6765:13;;;:5;:13;;;;;;:25;;;;;;;;;6812:16;;;;;;;:27;;;;;-1:-1:-1;;;6812:27:1;;;6861:22;6818:9;6861:11;:22::i;:::-;6914:16;;;;;;;;:5;:16;;;;;:21;;;;;;-1:-1:-1;6720:234:1;6982:13;;;;6976:26;6982:13;;;6976:5;6982:13;;;;;;:19;-1:-1:-1;;;6982:19:1;;;;;6976:26;;;:30;-1:-1:-1;;;6976:30:1;;;;6975:31;:65;;;;-1:-1:-1;7017:13:1;;;;7011:25;7017:13;;;7011:5;7017:13;;;;;;:18;;;;;;;7011:25;;;:29;-1:-1:-1;;;7011:29:1;;;;7010:30;6975:65;6971:750;;;7064:13;;;;;;;7084:4;7064:13;;;;;:24;;;;-1:-1:-1;;;7064:24:1;;;7116:9;-1:-1:-1;7116:9:1;6971:750;;;7183:13;;;;7177:25;7183:13;;;7177:5;7183:13;;;;;;:18;;;;;;;7177:25;;;:29;-1:-1:-1;;;7177:29:1;;;;7172:273;;7240:13;;;;7267:5;7240:13;;;7234:5;7240:13;;;;;;:19;;-1:-1:-1;;;7240:19:1;;;;;7234:26;;;;:38;;;;;;;;;7298:13;;;:24;;;-1:-1:-1;;;7298:24:1;;;7348:18;7246:6;7348:10;:18::i;:::-;7401:16;;;;;;;;:5;:16;;;;;:21;;;;;;-1:-1:-1;7172:273:1;7486:16;;;;;;;;:5;:16;;;;;;:20;;7466:13;;;;;;;;:40;;7486:20;-1:-1:-1;;;7486:20:1;;;;;7466:40;;;;;;;;;;;;7528:28;;;;;;;7584:18;;;;;;;;7578:25;;;;:37;;;;;;;7637:22;7492:9;7637:11;:22::i;6971:750::-;5466:2279;5427:2318;;;7758:10;;;;;;;:5;:10;;;;;:14;-1:-1:-1;;;7758:14:1;;;;7754:70;;;-1:-1:-1;7774:10:1;;7791:5;7774:10;;;:5;:10;;;;;:22;;;;;;2965:353:2:o;7754:70:1:-;7811:11;:13;;;;;;;;:11;:13;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;5394:2437;5352:2479;:::o;2438:1882::-;2490:13;2513:1696;2527:4;;;2520:11;;;2527:4;;2520:11;;;;:43;;-1:-1:-1;2541:10:1;;;;2535:24;2541:10;;;2535:5;2541:10;;;;;;:17;;;;2535:24;;;:28;-1:-1:-1;;;2535:28:1;;;;2520:43;2513:1696;;;2598:10;;;;2579:16;2598:10;;;:5;:10;;;;;;:17;;;2652:16;;;;;;:23;;;2646:30;;;;:35;2598:17;;2646:35;;;;;2633:48;;2629:1570;;2716:16;;;;2710:30;2716:16;;;2710:5;2716:16;;;;;;:23;;;2710:30;;;;;:36;-1:-1:-1;;;2710:36:1;;;;;2768:13;;;;;;:17;2710:36;;-1:-1:-1;;;;2768:17:1;;;;2764:661;;;2809:16;;;;2832:5;2809:16;;;:5;:16;;;;;;:28;;;;;;;;2859:13;;;;;;;;:25;;;;;;2912:23;;;;2906:30;;;;;:41;;;;;-1:-1:-1;;;2906:41:1;;;;2975:16;;;:23;;;-1:-1:-1;2629:1570:1;;2764:661;3056:16;;;;;;;;:5;:16;;;;;:22;-1:-1:-1;;;3056:22:1;;;;3049:29;;;;3045:140;;3112:9;3106:15;;3147;3158:3;3147:10;:15::i;:::-;-1:-1:-1;3218:10:1;;;;;;;;:5;:10;;;;;;:17;;;3257:16;;;;;;:28;;;;;;;;3313:23;;;3307:30;;;;;:41;;;;;-1:-1:-1;;;3307:41:1;;;;3382:16;;;;:23;3218:17;;3370:36;;3382:23;3370:11;:36::i;:::-;2629:1570;;;3478:16;;;;3472:30;3478:16;;;3472:5;3478:16;;;;;;:23;;;3472:30;;;;;:35;;;;;;;3529:13;;;;;;:17;3472:35;;-1:-1:-1;;;;3529:17:1;;;;3525:660;;;3570:16;;;;3593:5;3570:16;;;:5;:16;;;;;;:28;;;;;;;;3620:13;;;;;;;;:25;;;;;;3673:23;;;;3667:30;;;;;:41;;;;;-1:-1:-1;;;3667:41:1;;;;3736:16;;;:23;;;-1:-1:-1;3525:660:1;;;3817:16;;;;;;;;:5;:16;;;;;:21;;;;;;3810:28;;;;3806:140;;3872:9;3866:15;;3907:16;3919:3;3907:11;:16::i;:::-;-1:-1:-1;3979:10:1;;;;;;;;:5;:10;;;;;;:17;;;4018:16;;;;;;:28;;;;;;;;4074:23;;;4068:30;;;;;:41;;;;;-1:-1:-1;;;4068:41:1;;;;4142:16;;;;:23;3979:17;;4131:35;;4142:23;4131:10;:35::i;:::-;2565:1644;2513:1696;;;4222:11;4228:4;;;;4222:11;;:5;:11;;;;;:15;-1:-1:-1;;;4222:15:1;;;;4218:96;;;4271:5;4259:4;;;;;;4253:11;;:5;:11;;;;;:23;;;;;;4290:13;;;;;;;:11;:13;;;:::i;1116:652::-;1183:10;;;;1167:13;1183:10;;;:5;:10;;;;;;:16;;-1:-1:-1;;;1183:16:1;;;;;1275:13;;;;;;:18;1303:10;;;;1275:18;;;;;;1303:29;;;;;;;;;1183:16;1228:17;;;;;1346:19;;1342:80;;1381:17;;;;;;;;:5;:17;;;;;:30;;-1:-1:-1;;1381:30:1;;;;;;;;;;1342:80;1431:13;;;;;;;;:5;:13;;;;;:32;;-1:-1:-1;;1431:32:1;;;;;;;;;1473:219;;1511:4;:13;;-1:-1:-1;;1511:13:1;;;;;;;1473:219;;;1552:16;;;;;;;;:5;:16;;;;;:21;;;;;;1545:28;;;;1541:151;;1589:16;;;;;;;;:5;:16;;;;;:30;;;;;;;;;;;;;;;;;1541:151;;;1650:16;;;;;;;;:5;:16;;;;;:31;;;;;-1:-1:-1;;;1650:31:1;;;;;;;;;;;1541:151;-1:-1:-1;;1701:13:1;;;;;;;;:5;:13;;;;;;:24;;;;;;;;;;;;;;;;;;;1735:10;;;;;:26;;-1:-1:-1;;1735:26:1;;;;;;1116:652::o;1774:658::-;1842:10;;;;1826:13;1842:10;;;:5;:10;;;;;;:15;;;;;;;;1934:13;;;;;;:19;1963:10;;;;-1:-1:-1;;;1934:19:1;;;;;1963:29;;;;;;;;;1842:15;1886:17;;;;;2006:20;;2002:82;;2042:18;;;;;;;;:5;:18;;;;;:31;;-1:-1:-1;;2042:31:1;;;;;;;;;;2002:82;2093:13;;;;;;;;:5;:13;;;;;:32;;-1:-1:-1;;2093:32:1;;;;;;;;;2135:220;;2173:4;:13;;-1:-1:-1;;2173:13:1;;;;;;;2135:220;;;2214:16;;;;;;;;:5;:16;;;;;:22;-1:-1:-1;;;2214:22:1;;;;2207:29;;;;2203:152;;2252:16;;;;;;;;:5;:16;;;;;:31;;;;;-1:-1:-1;;;2252:31:1;;;;;;;;;;;2203:152;;;2314:16;;;;;;;;:5;:16;;;;;:30;;;;;;;;;;;;;;;;;2203:152;-1:-1:-1;;2364:13:1;;;;;;;;:5;:13;;;;;;:25;;;;-1:-1:-1;;;2364:25:1;;;;;;;;;;;;;;2399:10;;;;;:26;;-1:-1:-1;;2399:26:1;;;;;;1774:658::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:196:7;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:163::-;282:20;;342:10;331:22;;321:33;;311:61;;368:1;365;358:12;383:258;450:6;458;511:2;499:9;490:7;486:23;482:32;479:52;;;527:1;524;517:12;479:52;550:29;569:9;550:29;:::i;:::-;540:39;;598:37;631:2;620:9;616:18;598:37;:::i;:::-;588:47;;383:258;;;;;:::o;646:160::-;740:6;773:3;761:16;;758:25;-1:-1:-1;755:45:7;;;796:1;793;786:12;811:171;878:20;;938:18;927:30;;917:41;;907:69;;972:1;969;962:12;987:347;1038:8;1048:6;1102:3;1095:4;1087:6;1083:17;1079:27;1069:55;;1120:1;1117;1110:12;1069:55;-1:-1:-1;1143:20:7;;1186:18;1175:30;;1172:50;;;1218:1;1215;1208:12;1172:50;1255:4;1247:6;1243:17;1231:29;;1307:3;1300:4;1291:6;1283;1279:19;1275:30;1272:39;1269:59;;;1324:1;1321;1314:12;1269:59;987:347;;;;;:::o;1339:950::-;1513:6;1521;1529;1537;1545;1553;1561;1569;1622:4;1610:9;1601:7;1597:23;1593:34;1590:54;;;1640:1;1637;1630:12;1590:54;1663:53;1708:7;1697:9;1663:53;:::i;:::-;1653:63;;1735;1790:7;1784:3;1773:9;1769:19;1735:63;:::i;:::-;1725:73;;1845:4;1834:9;1830:20;1817:34;1807:44;;1898:4;1887:9;1883:20;1870:34;1860:44;;1923:39;1956:4;1945:9;1941:20;1923:39;:::i;:::-;1913:49;;1981:39;2014:4;2003:9;1999:20;1981:39;:::i;:::-;1971:49;;2071:4;2060:9;2056:20;2043:34;2100:18;2092:6;2089:30;2086:50;;;2132:1;2129;2122:12;2086:50;2171:58;2221:7;2212:6;2201:9;2197:22;2171:58;:::i;:::-;1339:950;;;;-1:-1:-1;1339:950:7;;-1:-1:-1;1339:950:7;;;;;;2248:8;-1:-1:-1;;;1339:950:7:o;2294:184::-;2352:6;2405:2;2393:9;2384:7;2380:23;2376:32;2373:52;;;2421:1;2418;2411:12;2373:52;2444:28;2462:9;2444:28;:::i;:::-;2434:38;2294:184;-1:-1:-1;;;2294:184:7:o;2665:319::-;2758:6;2766;2819:2;2807:9;2798:7;2794:23;2790:32;2787:52;;;2835:1;2832;2825:12;2787:52;2871:9;2858:23;2848:33;;2916:7;2911:2;2900:9;2896:18;2893:31;2890:51;;;2937:1;2934;2927:12;2890:51;-1:-1:-1;2665:319:7;2975:2;2960:18;;;;;-1:-1:-1;2665:319:7:o;3645:1405::-;3856:6;3864;3872;3880;3888;3896;3904;3912;3920;3928;3936:7;3945;3999:4;3987:9;3978:7;3974:23;3970:34;3967:54;;;4017:1;4014;4007:12;3967:54;4040:53;4085:7;4074:9;4040:53;:::i;:::-;4030:63;;4112;4167:7;4161:3;4150:9;4146:19;4112:63;:::i;:::-;4102:73;;4222:4;4211:9;4207:20;4194:34;4184:44;;4275:4;4264:9;4260:20;4247:34;4237:44;;4300:39;4333:4;4322:9;4318:20;4300:39;:::i;:::-;4290:49;;4358:39;4391:4;4380:9;4376:20;4358:39;:::i;:::-;4348:49;;4416:39;4449:4;4438:9;4434:20;4416:39;:::i;:::-;4406:49;;4506:18;4498:4;4487:9;4483:20;4470:34;4467:58;4464:78;;;4538:1;4535;4528:12;4464:78;4577:86;4655:7;4646:4;4635:9;4631:20;4618:34;4607:9;4603:50;4577:86;:::i;:::-;4682:8;;-1:-1:-1;4709:8:7;-1:-1:-1;4736:40:7;4770:4;4755:20;;4736:40;:::i;:::-;4726:50;;4827:18;4819:4;4808:9;4804:20;4791:34;4788:58;4785:78;;;4859:1;4856;4849:12;4785:78;4900:86;4978:7;4969:4;4958:9;4954:20;4941:34;4930:9;4926:50;4900:86;:::i;:::-;5006:9;4995:20;;5035:9;5024:20;;;;3645:1405;;;;;;;;;;;;;;:::o;5055:732::-;5204:6;5212;5220;5228;5236;5289:4;5277:9;5268:7;5264:23;5260:34;5257:54;;;5307:1;5304;5297:12;5257:54;5330:53;5375:7;5364:9;5330:53;:::i;:::-;5320:63;;5402;5457:7;5451:3;5440:9;5436:19;5402:63;:::i;:::-;5392:73;;5512:4;5501:9;5497:20;5484:34;5474:44;;5569:4;5558:9;5554:20;5541:34;5598:18;5590:6;5587:30;5584:50;;;5630:1;5627;5620:12;5584:50;5669:58;5719:7;5710:6;5699:9;5695:22;5669:58;:::i;:::-;5055:732;;;;-1:-1:-1;5055:732:7;;-1:-1:-1;5746:8:7;;5643:84;5055:732;-1:-1:-1;;;5055:732:7:o;5792:180::-;5851:6;5904:2;5892:9;5883:7;5879:23;5875:32;5872:52;;;5920:1;5917;5910:12;5872:52;-1:-1:-1;5943:23:7;;5792:180;-1:-1:-1;5792:180:7:o;6359:693::-;6453:6;6461;6469;6522:2;6510:9;6501:7;6497:23;6493:32;6490:52;;;6538:1;6535;6528:12;6490:52;6578:9;6565:23;6607:18;6648:2;6640:6;6637:14;6634:34;;;6664:1;6661;6654:12;6634:34;6702:6;6691:9;6687:22;6677:32;;6747:7;6740:4;6736:2;6732:13;6728:27;6718:55;;6769:1;6766;6759:12;6718:55;6809:2;6796:16;6835:2;6827:6;6824:14;6821:34;;;6851:1;6848;6841:12;6821:34;6906:7;6899:4;6889:6;6886:1;6882:14;6878:2;6874:23;6870:34;6867:47;6864:67;;;6927:1;6924;6917:12;6864:67;6958:4;6950:13;;;;-1:-1:-1;6982:6:7;-1:-1:-1;7007:39:7;;7025:20;;;-1:-1:-1;7007:39:7;:::i;:::-;6997:49;;6359:693;;;;;:::o;7057:1051::-;7274:2;7326:21;;;7396:13;;7299:18;;;7418:22;;;7245:4;;7274:2;7459;;7477:18;;;;7518:15;;;7245:4;;7582:500;7598:6;7593:3;7590:15;7582:500;;;7661:13;;7700:3;7783:1;7797:205;7813:4;7808:3;7805:13;7797:205;;;7886:15;;7872:30;;7971:17;;;;7928:14;;;;7837:1;7828:11;7797:205;;;-1:-1:-1;;;8022:12:7;;;;8057:15;;;;7624:1;7615:11;7582:500;;;-1:-1:-1;8099:3:7;;7057:1051;-1:-1:-1;;;;;;;;7057:1051:7:o;8113:252::-;8180:6;8188;8241:2;8229:9;8220:7;8216:23;8212:32;8209:52;;;8257:1;8254;8247:12;8209:52;8280:28;8298:9;8280:28;:::i;:::-;8270:38;8355:2;8340:18;;;;8327:32;;-1:-1:-1;;;8113:252:7:o;9110:184::-;9162:77;9159:1;9152:88;9259:4;9256:1;9249:15;9283:4;9280:1;9273:15;9299:184;9351:77;9348:1;9341:88;9448:4;9445:1;9438:15;9472:4;9469:1;9462:15;9488:120;9528:1;9554;9544:35;;9559:18;;:::i;:::-;-1:-1:-1;9593:9:7;;9488:120::o;9954:184::-;10006:77;10003:1;9996:88;10103:4;10100:1;10093:15;10127:4;10124:1;10117:15;10491:195;10530:3;10561:66;10554:5;10551:77;10548:103;;10631:18;;:::i;:::-;-1:-1:-1;10678:1:7;10667:13;;10491:195::o;11200:347::-;11320:5;11343:1;11353:188;11367:4;11364:1;11361:11;11353:188;;;11414:43;11453:3;11444:6;11438:13;11120:12;;11108:25;;11182:4;11171:16;;;11165:23;11149:14;;11142:47;11049:146;11414:43;11486:4;11477:14;;;;;11526:4;11514:17;;;;;11387:1;11380:9;11353:188;;;11357:3;;11200:347;;:::o;11552:935::-;11615:70;11681:3;11673:5;11667:12;11615:70;:::i;:::-;11731:4;11724:5;11720:16;11714:23;11746:83;11821:6;11816:3;11812:16;11798:12;11746:83;:::i;:::-;;11877:4;11870:5;11866:16;11860:23;11892:85;11969:6;11964:3;11960:16;11944:14;11892:85;:::i;:::-;;12025:4;12018:5;12014:16;12008:23;12040:85;12117:6;12112:3;12108:16;12092:14;12040:85;:::i;:::-;-1:-1:-1;12173:4:7;12162:16;;12156:23;11120:12;;12237:6;12228:16;;11108:25;11182:4;11171:16;;;11165:23;11149:14;;;11142:47;12296:4;12285:16;;12279:23;12270:6;12261:16;;12254:49;12351:4;12340:16;;12334:23;11120:12;;12415:6;12406:16;;11108:25;11171:16;11165:23;11149:14;;;11142:47;12474:4;12463:16;12457:23;12448:6;12439:16;;;12432:49;11552:935::o;12492:325::-;12590:5;12613:1;12623:188;12637:4;12634:1;12631:11;12623:188;;;12684:43;12723:3;12714:6;12708:13;11120:12;;11108:25;;11182:4;11171:16;;;11165:23;11149:14;;11142:47;11049:146;12684:43;12756:4;12747:14;;;;;12796:4;12784:17;;;;;12657:1;12650:9;12623:188;;12822:326;12915:5;12938:1;12948:194;12962:4;12959:1;12956:11;12948:194;;;13021:13;;13009:26;;13058:4;13082:12;;;;13117:15;;;;12982:1;12975:9;12948:194;;13153:327;13252:5;13275:1;13285:189;13299:4;13296:1;13293:11;13285:189;;;13346:44;13386:3;13377:6;13371:13;13346:44;:::i;:::-;13419:4;13410:14;;;;;13459:4;13447:17;;;;;13319:1;13312:9;13285:189;;13485:347;13605:5;13628:1;13638:188;13652:4;13649:1;13646:11;13638:188;;;13699:43;13738:3;13729:6;13723:13;11120:12;;11108:25;;11182:4;11171:16;;;11165:23;11149:14;;11142:47;11049:146;13699:43;13771:4;13762:14;;;;;13811:4;13799:17;;;;;13672:1;13665:9;13638:188;;13837:407;13908:70;13974:3;13966:5;13960:12;13908:70;:::i;:::-;14024:4;14017:5;14013:16;14007:23;14039:83;14114:6;14109:3;14105:16;14091:12;14039:83;:::i;:::-;-1:-1:-1;14173:4:7;14162:16;;14156:23;14147:6;14138:16;;14131:49;14231:4;14220:16;14214:23;14205:6;14196:16;;;14189:49;13837:407::o;14249:2897::-;14527:4;14512:20;;14541:46;14516:9;14569:6;14541:46;:::i;:::-;14620:13;;11120:12;;14650:4;14635:20;;11108:25;11182:4;11171:16;;;11165:23;11149:14;;;11142:47;14691:17;;;14685:24;11120:12;;14771:4;14756:20;;11108:25;11171:16;;11165:23;11149:14;;;11142:47;14826:4;14814:17;;14808:24;11120:12;;14896:4;14881:20;;11108:25;11171:16;;11165:23;11149:14;;;11142:47;14951:4;14939:17;;14933:24;11120:12;;15021:4;15006:20;;11108:25;11171:16;11165:23;11149:14;;;11142:47;15076:4;15064:17;;15058:24;15091:67;15152:4;15137:20;;15058:24;15091:67;:::i;:::-;;15207:4;15199:6;15195:17;15189:24;15222:67;15283:4;15272:9;15268:20;15252:14;15222:67;:::i;:::-;;15338:4;15330:6;15326:17;15320:24;15353:67;15414:4;15403:9;15399:20;15383:14;15353:67;:::i;:::-;;15469:4;15461:6;15457:17;15451:24;15484:67;15545:4;15534:9;15530:20;15514:14;15484:67;:::i;:::-;;15600:6;15592;15588:19;15582:26;15617:67;15678:4;15667:9;15663:20;15647:14;15617:67;:::i;:::-;;15733:6;15725;15721:19;15715:26;15750:67;15811:4;15800:9;15796:20;15780:14;15750:67;:::i;:::-;;15866:6;15858;15854:19;15848:26;15883:67;15944:4;15933:9;15929:20;15913:14;15883:67;:::i;:::-;;16000:6;15992;15988:19;15982:26;16017:68;16079:4;16068:9;16064:20;16047:15;16017:68;:::i;:::-;;16135:6;16127;16123:19;16117:26;16152:69;16215:4;16204:9;16200:20;16183:15;16152:69;:::i;:::-;-1:-1:-1;16277:6:7;16265:19;;16259:26;16252:4;16237:20;;16230:56;16336:6;16324:19;;16318:26;11120:12;;16409:4;16394:20;;11108:25;11182:4;11171:16;;;11165:23;11149:14;;;11142:47;16465:6;16453:19;;16447:26;11120:12;;16538:4;16523:20;;11108:25;11171:16;11165:23;11149:14;;;11142:47;16600:6;16588:19;;16582:26;16575:4;16560:20;;16553:56;16665:6;16653:19;;16647:26;16640:4;16625:20;;16618:56;16730:6;16718:19;;16712:26;16705:4;16690:20;;16683:56;16795:6;16783:19;;16777:26;16770:4;16755:20;;16748:56;16860:6;16848:19;;16842:26;16835:4;16820:20;;16813:56;16925:6;16913:19;;16907:26;16900:4;16885:20;;16878:56;16990:6;16978:19;;16972:26;16965:4;16950:20;;16943:56;17049:6;17037:19;;17031:26;17066:74;17134:4;17119:20;;17031:26;17066:74;:::i;17151:168::-;17224:9;;;17255;;17272:15;;;17266:22;;17252:37;17242:71;;17293:18;;:::i;17324:468::-;17614:4;17599:20;;17638:6;;17677;17603:9;17653:35;17738:2;17730:6;17725:2;17714:9;17710:18;17697:44;;17779:6;17772:4;17761:9;17757:20;17750:36;17324:468;;;;;;:::o;18153:112::-;18185:1;18211;18201:35;;18216:18;;:::i;:::-;-1:-1:-1;18250:9:7;;18153:112::o;18986:671::-;19318:3;19300:22;;;19359:2;19338:19;;;19331:31;19399:18;19393:3;19378:19;;19371:47;19504:42;19492:55;;19485:4;19470:20;;19463:85;19579:2;19564:18;;19557:34;;;19450:3;19435:19;;19600:51;-1:-1:-1;19632:18:7;;19624:6;11120:12;;11108:25;;11182:4;11171:16;;;11165:23;11149:14;;11142:47;11049:146;19600:51;18986:671;;;;;;:::o;20215:325::-;20303:6;20298:3;20291:19;20355:6;20348:5;20341:4;20336:3;20332:14;20319:43;;20407:1;20400:4;20391:6;20386:3;20382:16;20378:27;20371:38;20273:3;20529:4;20459:66;20454:2;20446:6;20442:15;20438:88;20433:3;20429:98;20425:109;20418:116;;20215:325;;;;:::o;20545:717::-;20875:4;20904;20927:6;20974:2;20966:6;20955:9;20942:35;21027:2;21019:6;21014:2;21003:9;20999:18;20986:44;;21068:6;21061:4;21050:9;21046:20;21039:36;21125:10;21117:6;21113:23;21106:4;21095:9;21091:20;21084:53;21175:2;21168:4;21157:9;21153:20;21146:32;21195:61;21252:2;21241:9;21237:18;21229:6;21221;21195:61;:::i;:::-;21187:69;20545:717;-1:-1:-1;;;;;;;;;20545:717:7:o;21267:191::-;21306:1;21332:10;21369:2;21366:1;21362:10;21391:3;21381:37;;21398:18;;:::i;:::-;21436:10;;21432:20;;;;;21267:191;-1:-1:-1;;21267:191:7:o;21463:172::-;21530:10;21560;;;21572;;;21556:27;;21595:11;;;21592:37;;;21609:18;;:::i;21640:364::-;21837:42;21829:6;21825:55;21814:9;21807:74;21917:2;21912;21901:9;21897:18;21890:30;21788:4;21937:61;21994:2;21983:9;21979:18;21971:6;21963;21937:61;:::i;:::-;21929:69;21640:364;-1:-1:-1;;;;;21640:364:7:o;22009:2783::-;22390:10;22378:23;;22360:42;;22346:4;22331:20;;22411:55;22462:2;22447:18;;22439:6;22411:55;:::i;:::-;22499:13;;11120:12;;22529:4;22514:20;;11108:25;11182:4;11171:16;;;11165:23;11149:14;;;11142:47;22570:15;;;22564:22;11120:12;;22648:4;22633:20;;11108:25;11171:16;;11165:23;11149:14;;;11142:47;22703:4;22691:17;;22685:24;11120:12;;22773:4;22758:20;;11108:25;11171:16;;11165:23;11149:14;;;11142:47;22828:4;22816:17;;22810:24;11120:12;;22898:4;22883:20;;11108:25;11171:16;11165:23;11149:14;;;11142:47;22953:4;22941:17;;22935:24;22968:67;23029:4;23014:20;;22935:24;22968:67;:::i;:::-;;23084:4;23076:6;23072:17;23066:24;23099:67;23160:4;23149:9;23145:20;23129:14;23099:67;:::i;:::-;;23215:4;23207:6;23203:17;23197:24;23230:67;23291:4;23280:9;23276:20;23260:14;23230:67;:::i;:::-;;23346:4;23338:6;23334:17;23328:24;23361:67;23422:4;23411:9;23407:20;23391:14;23361:67;:::i;:::-;;23477:6;23469;23465:19;23459:26;23494:67;23555:4;23544:9;23540:20;23524:14;23494:67;:::i;:::-;;23610:6;23602;23598:19;23592:26;23627:67;23688:4;23677:9;23673:20;23657:14;23627:67;:::i;:::-;;23743:6;23735;23731:19;23725:26;23760:62;23816:4;23805:9;23801:20;23785:14;23760:62;:::i;:::-;-1:-1:-1;23878:6:7;23866:19;;23860:26;23853:4;23838:20;;23831:56;23937:6;23925:19;;23919:26;11120:12;;24010:4;23995:20;;11108:25;11182:4;11171:16;;;11165:23;11149:14;;;11142:47;24066:6;24054:19;;24048:26;11120:12;;24139:4;24124:20;;11108:25;11171:16;11165:23;11149:14;;;11142:47;24201:6;24189:19;;24183:26;24176:4;24161:20;;24154:56;24266:6;24254:19;;24248:26;24241:4;24226:20;;24219:56;24331:6;24319:19;;24313:26;24306:4;24291:20;;24284:56;24396:6;24384:19;;24378:26;24371:4;24356:20;;24349:56;24461:6;24449:19;;24443:26;24436:4;24421:20;;24414:56;24526:6;24514:19;;24508:26;24501:4;24486:20;;24479:56;24591:6;24579:19;;24573:26;24566:4;24551:20;;24544:56;24650:6;24638:19;;24632:26;24667:74;24735:4;24720:20;;24632:26;24667:74;:::i;:::-;;24779:6;24772:4;24761:9;24757:20;24750:36;22009:2783;;;;;;;:::o;25366:271::-;25549:6;25541;25536:3;25523:33;25505:3;25575:16;;25600:13;;;25575:16;25366:271;-1:-1:-1;25366:271:7:o;26003:1194::-;26350:10;26338:23;;26320:42;;26306:4;26291:20;;26371:55;26422:2;26407:18;;26399:6;26371:55;:::i;:::-;26459:13;;11120:12;;26489:4;26474:20;;11108:25;11182:4;11171:16;;;11165:23;11149:14;;;11142:47;26530:15;;;26524:22;11120:12;;26608:4;26593:20;;11108:25;11171:16;11165:23;11149:14;;;11142:47;26663:4;26651:17;;26645:24;26678:67;26739:4;26724:20;;26645:24;26678:67;:::i;:::-;;26794:4;26786:6;26782:17;26776:24;26809:67;26870:4;26859:9;26855:20;26839:14;26809:67;:::i;:::-;;26925:4;26917:6;26913:17;26907:24;26940:62;26996:4;26985:9;26981:20;26965:14;26940:62;:::i;:::-;;27058:4;27050:6;27046:17;27040:24;27033:4;27022:9;27018:20;27011:54;27121:4;27113:6;27109:17;27103:24;27096:4;27085:9;27081:20;27074:54;27184:4;27176:6;27172:17;27166:24;27159:4;27148:9;27144:20;27137:54;26003:1194;;;;;;:::o;27202:556::-;27518:4;27503:20;;27542:6;;27581;27507:9;27557:35;27642:2;27634:6;27629:2;27618:9;27614:18;27601:44;;27683:6;27676:4;27665:9;27661:20;27654:36;27740:10;27732:6;27728:23;27721:4;27710:9;27706:20;27699:53;27202:556;;;;;;;:::o;27763:184::-;27815:77;27812:1;27805:88;27912:4;27909:1;27902:15;27936:4;27933:1;27926:15;27952:414;28083:3;28121:6;28115:13;28146:1;28156:129;28170:6;28167:1;28164:13;28156:129;;;28268:4;28252:14;;;28248:25;;28242:32;28229:11;;;28222:53;28185:12;28156:129;;;-1:-1:-1;28340:1:7;28304:16;;28329:13;;;-1:-1:-1;28304:16:7;27952:414;-1:-1:-1;27952:414:7:o;28371:128::-;28438:9;;;28459:11;;;28456:37;;;28473:18;;:::i;28504:125::-;28569:9;;;28590:10;;;28587:36;;;28603:18;;:::i;28634:184::-;28686:77;28683:1;28676:88;28783:4;28780:1;28773:15;28807:4;28804:1;28797:15;28823:180;28890:18;28928:10;;;28940;;;28924:27;;28963:11;;;28960:37;;;28977:18;;:::i;29008:253::-;29046:3;29090:18;29083:5;29079:30;29128:7;29118:41;;29139:18;;:::i;:::-;29188:66;29175:80;;29008:253;-1:-1:-1;;29008:253:7:o;29266:209::-;29304:3;29332:18;29385:2;29378:5;29374:14;29412:2;29403:7;29400:15;29397:41;;29418:18;;:::i;:::-;29467:1;29454:15;;29266:209;-1:-1:-1;;;29266:209:7:o

Swarm Source

ipfs://280c2b3a2c6454c3e1cda55ac6b6892693192e7ea459c34474d8ccf380d4e320

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

Underlying implementation contract for Firn protocol.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

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