Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
2041108 | 41 days ago | Contract Creation | 0 S |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Trie
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 // Central Limit Order Book (CLOB) exchange // (c) Long Gamma Labs, 2023. pragma solidity ^0.8.26; import {Errors} from "./Errors.sol"; import {ITrie} from "./ITrie.sol"; struct Node { uint64 left; uint64 right; uint64 total_shares_value_ptr; } struct Leaf { uint64 trader_id; uint128 remain_shares; uint64 initial_shares_value_ptr; } struct ExecutionResult { uint128 executed_shares; uint128 executed_value; uint128 total_shares; uint128 total_value; uint64 right_child; uint64 xor_map; } /// @title Trie data structure for Protocol /// @dev This contract implements a trie for efficient order management in an on-chain limit order book. contract Trie is ITrie { address immutable lob_address; // Since we have a prefix tree, we can immediately get all the keys in the rightmost branch. // Each right key represents a part of best_offer, the length of which is determined // by the non-zero bit in rightmost_map. That is, the number of non-zero bits // in rightmost_map equals the number of nodes in the rightmost branch. uint64 public best_offer = 0; uint64 public rightmost_map = 0x0; // The rightmost branch is unique: it only stores the total_shares and total_amount of the left child, // so deleting or adding new nodes can start directly from the corresponding node on the rightmost branch. uint64 highest_allocated_pointer; uint64 last_free_pointer; mapping (uint64 => Leaf) leaves; mapping (uint64 => Node) nodes; mapping (uint64 => uint256) arena; modifier onlyLOBPermission() { require(msg.sender == lob_address, Errors.Forbidden()); _; } constructor(address _lob_address) { lob_address = _lob_address; } /// @dev Adds an order to the order book. /// @param trader_id The ID of the trader placing the order, must be be greater than 0. /// @param order_id The ID of the order being placed, must be unique and be pointer to leaf. /// @param shares The total number of shares in the order, must be greater than 0. /// @param value The total value of the order, must be greater than 0. /// All restrictions on parameters must be satisfied by the logic of the LOB contract function addOrder(uint64 trader_id, uint64 order_id, uint128 shares, uint128 value) virtual public onlyLOBPermission { uint64 ptr = allocateMemory(); saveSharesValueToArena(ptr, shares, value); leaves[order_id] = Leaf({ trader_id: trader_id, remain_shares: shares, initial_shares_value_ptr: ptr }); uint256 map = rightmost_map; if (map == 0x0) { // This means the trie is empty. best_offer = order_id; rightmost_map = 0x1; return; } // We climb the rightmost branch until we go through it all, which means we need to add a new root, // or to a node that matches our added order_id. (uint64 node_id, bool success) = findRightmostMatchingNode(order_id); if (success) { // We found the node that matches order_id. addOrderToNodes(order_id, node_id, shares, value); } else { // We have reached the root of the tree, we need to add a new node, which will become the new root // of the tree. New node`s descendant will be new order_id leaf. // note: node_id here is the root node_id addOrderAndUpdateRoot(order_id, node_id, shares, value); } } /// @dev Removes an order with a specific order_id associated with a trader identified by order_trader_id. /// @param order_id The ID of the order to be removed. /// @param order_trader_id The ID of the trader associated with the order. /// Only needed for verification purposes. /// @return total_shares The total number of shares for the order. /// @return remain_shares The remaining number of shares for the order. function removeOrder(uint64 order_id, uint64 order_trader_id) virtual public onlyLOBPermission returns (uint128 total_shares, uint128 remain_shares) { Leaf memory leaf = leaves[order_id]; require(leaf.trader_id != 0x0, Errors.EmptyOrderError()); // An important validation check for the provided address. It prevents unauthorized order removal. require(leaf.trader_id == order_trader_id, Errors.WrongOwner()); uint128 total_value; (total_shares, total_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); remain_shares = leaf.remain_shares; uint128 remain_value = uint128(uint256(remain_shares) * uint256(total_value) / uint256(total_shares)); // To prevent double claims. delete leaves[order_id]; freeMemory(leaf.initial_shares_value_ptr); uint64 local_best_offer = best_offer; if (order_id > local_best_offer) { return (total_shares, 0); } if (order_id == local_best_offer) { removeBestOffer(); return (total_shares, remain_shares); } (uint64 node_id, bool success) = findRightmostMatchingNode(order_id); if (!success) { return (total_shares, 0); } bool found = removeOrderFromNodes(order_id, node_id, remain_shares, remain_value); if (found) { return (total_shares, remain_shares); } else { return (total_shares, 0); } } /// @dev Claims executed shares for an order with a specific order_id associated with a trader identified /// by order_trader_id. This operation does not remove the order from the order book. /// @param order_id The ID of the order for which executed shares are being claimed. /// @param order_trader_id The ID of the trader associated with the order. /// Only needed for verification purposes. /// @return executed_shares The number of executed shares for the order. /// @return remain_shares The remaining number of shares for the order after execution. function claimExecuted(uint64 order_id, uint64 order_trader_id) virtual public onlyLOBPermission returns (uint128 executed_shares, uint128 remain_shares) { Leaf memory leaf = leaves[order_id]; if (leaf.trader_id == 0x0) { return (0, 0); } // An important validation check for the provided address. It prevents unauthorized order claim. require(leaf.trader_id == order_trader_id, Errors.WrongOwner()); remain_shares = leaf.remain_shares; (uint128 total_shares, uint128 total_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); uint64 local_best_offer = best_offer; if (order_id > local_best_offer) { remain_shares = 0; } else { (uint64 node_id, bool success) = findRightmostMatchingNode(order_id); if (!success || !isOrderInTree(node_id, order_id)) { remain_shares = 0; } } executed_shares = total_shares - remain_shares; if (executed_shares == 0) { return (0, remain_shares); } if (remain_shares == 0) { delete leaves[order_id]; freeMemory(leaf.initial_shares_value_ptr); } else { uint128 remain_value = uint128( uint256(remain_shares) * uint256(total_value) / uint256(total_shares) ); saveSharesValueToArena( leaf.initial_shares_value_ptr, remain_shares, remain_value ); } } /// @dev Retrieves information about an order based on the given order_id. /// @param order_id The ID of the order to retrieve information for. /// @return total_shares The total number of shares for the order. /// @return remain_shares The remaining number of shares for the order. /// Unlike removeOrder, it does not require the existence of an order and works even on claimed and canceled /// orders, returning zeros. function getOrderInfo(uint64 order_id) public view returns (uint128 total_shares, uint128 remain_shares) { Leaf memory leaf = leaves[order_id]; if (leaf.trader_id == 0x0) { return (0, 0); } remain_shares = leaf.remain_shares; (total_shares, ) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); // works correctly in case of empty trie too: best_offer = 0x0 if (order_id > best_offer) { return (total_shares, 0); } (uint64 node_id, bool success) = findRightmostMatchingNode(order_id); if (!success) { return (total_shares, 0); } if (isOrderInTree(node_id, order_id)) { return (total_shares, remain_shares); } else { return (total_shares, 0); } } /// @dev Executes matching orders using a "right" approach, striving to fulfill orders /// as much as possible towards the right side. /// @param order_id The price identifier of the order, not associated with a real order ID. /// @param order_total_shares The total number of shares for the order being executed. function executeRight(uint64 order_id, uint128 order_total_shares) virtual public onlyLOBPermission returns (uint128 executed_shares, uint128 executed_value) { // Conceptually the most complex function in the contract. // Since we have to rebuild rightmost branch. uint64 local_best_offer = best_offer; // Works correctly in case of empty trie too: best_offer = 0x0 if (order_id > local_best_offer) { return (0, 0); } // Here we climb up the rightmost branch, similar to how it happens in findRightmostMatchingNode. // But, unfortunately, here we can no longer limit yourself to just node_id, and we have to read the node // completely. This happens because node_id contains information only about the price of orders, // but not about volumes. // Starting with rightmost leaf. Leaf memory leaf = leaves[local_best_offer]; (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); uint128 remain_shares = leaf.remain_shares; if (order_total_shares < remain_shares) { executed_shares = order_total_shares; executed_value = uint128(uint256(executed_shares) * uint256(initial_value) / uint256(initial_shares)); // initial_value / initial_shares is exact price unchecked { leaf.remain_shares -= executed_shares; } leaves[local_best_offer] = leaf; return (executed_shares, executed_value); } // Full execution of rightmost leaf. executed_shares = remain_shares; executed_value = uint128(uint256(remain_shares) * uint256(initial_value) / uint256(initial_shares)); uint64 map = rightmost_map; (uint64 node_id, uint64 k) = calcNextRightMostNodeId(local_best_offer, map); uint64 xor_map = 0x1; // Now climbing on nodes. while (node_id != 0x0) { // We ascend along the rightmost branch from the bottom and attempt to execute the entire subtree at once. // Initially, we try to execute the order - the rightmost descendant. // Then, at each step, we essentially try to execute the entire subtree with the top at the left child // of the current node on the rightmost branch. // Since we have a prefix tree, we can guarantee that the keys of all descendants // of any node are not less than the key of the node itself. To improve this estimation, we can take // not the node_id of the node itself, but the node_id of its left child. xor_map ^= k; Node memory node = nodes[node_id]; uint64 ptr = node.total_shares_value_ptr; (uint128 node_total_shares, uint128 node_total_value) = loadSharesValueFromArena(ptr); uint64 price_key = extractKeyFrom(node.left); // we can fully execute subtree if if (((order_id ^ 0x1) <= price_key) // all its leaves has higher or equal price than our order's price && // (we are using price_key as lower bound) and (order_total_shares >= (node_total_shares + executed_shares)) // it has less or equal shares than our order's ) { // full execution executed_shares += node_total_shares; executed_value += node_total_value; eraseNode(node_id, ptr); } else { ExecutionResult memory execution_result = executeRightRec( order_id, node.left, (order_total_shares - executed_shares) ); executed_shares += execution_result.executed_shares; executed_value += execution_result.executed_value; xor_map ^= execution_result.xor_map; if (execution_result.right_child != 0x0) { // we are partially executed, dont need to execute anymore (node_id, ) = calcNextRightMostNodeId(node_id, map); if (node_id != 0x0) { nodes[node_id].right = execution_result.right_child; } break; } } (node_id, k) = calcNextRightMostNodeId(node_id, map); } if (xor_map != 0x0) { // we have to change the rightmost map rightmost_map ^= xor_map; if (rightmost_map == 0x0) { best_offer = 0x0; } } } /// @dev Preview the execution of an order on the right. /// @param order_id The ID of the order to be executed. /// @param max_shares The maximum number of shares to execute. /// @param max_value The maximum value of shares to execute. /// @return executed_shares The number of shares executed. /// @return executed_value The value of the executed shares. function previewExecuteRight(uint64 order_id, uint128 max_shares, uint128 max_value) public view returns (uint128 executed_shares, uint128 executed_value) { uint64 local_best_offer = best_offer; if (order_id > local_best_offer || max_shares == 0 || max_value == 0) { return (0, 0); } uint64 node_id = local_best_offer; uint64 k = 0x1; uint64 path_map = rightmost_map ^ 0x1; // This is a depth-first search implementation. Same idea in assembleOrderbookFromOrders. while (true) { if ((node_id & 0x1) == 0x1) { // leaf case (uint128 leaf_executed_shares, uint128 leaf_executed_value, bool full) = previewExecuteLeaf( order_id, node_id, max_shares - executed_shares, max_value - executed_value ); executed_shares += leaf_executed_shares; executed_value += leaf_executed_value; if (!full) { break; } } else { // node case (uint128 node_shares, uint128 node_value) = loadSharesValueFromArena( nodes[node_id].total_shares_value_ptr ); uint64 price_key = extractKeyFrom(nodes[node_id].left); // check if we can execute this node fully if (((order_id ^ 0x1) > price_key) || ((max_shares - executed_shares) < node_shares) || ((max_value - executed_value) < node_value) ) { // we cant unchecked { k = ~(node_id - 1) & node_id; } path_map ^= k; node_id = nodes[node_id].right; continue; } else { // we can executed_shares += node_shares; executed_value += node_value; } } (node_id, k) = calcNextRightMostNodeId(node_id, path_map); if (node_id == 0x0) { break; } path_map ^= k; node_id = nodes[node_id].left; } } /// @dev Assembles an order book from the orders in the trie. /// @param max_price_levels The maximum number of price levels to include in the order book. /// @return array_price_ids An array of price IDs for each level in the order book. /// @return array_shares An array of the total shares for each level in the order book. function assembleOrderbookFromOrders(uint24 max_price_levels) external view returns (uint24[] memory array_price_ids, uint128[] memory array_shares) { uint64 local_best_offer = best_offer; if (local_best_offer == 0x0 || max_price_levels == 0) { array_price_ids = new uint24[](0); array_shares = new uint128[](0); return (array_price_ids, array_shares); } array_price_ids = new uint24[](max_price_levels); array_shares = new uint128[](max_price_levels); array_price_ids[0] = uint24(local_best_offer >> 40); uint24 price_level = 0; uint64 node_id = local_best_offer; uint64 k = 0x1; uint64 path_map = rightmost_map ^ 0x1; // This is a depth-first search implementation. However, we don't start from the root, but // from the far right element, as if we had already descended here. while (true) { if ((node_id & type(uint40).max) != 0x0) { uint24 c_price = uint24(node_id >> 40); if (c_price != array_price_ids[price_level]) { ++price_level; if (price_level == max_price_levels) { return (array_price_ids, array_shares); } array_price_ids[price_level] = c_price; } (uint128 total_shares, ) = extractSharesValueForNode(node_id); array_shares[price_level] += total_shares; (node_id, k) = calcNextRightMostNodeId(node_id, path_map); if (node_id == 0x0) { break; } path_map ^= k; node_id = nodes[node_id].left; // this is why it works for rightmost branch nodes too } else { unchecked { k = ~(node_id - 1) & node_id; } path_map ^= k; node_id = nodes[node_id].right; } } uint24 actual_length = price_level + 1; if (actual_length < max_price_levels) { // Cropping the returned arrays to their actual length. uint24[] memory cropped_array_price_ids = new uint24[](actual_length); uint128[] memory cropped_array_shares = new uint128[](actual_length); for(uint24 i = 0; i < actual_length; ++i) { cropped_array_price_ids[i] = array_price_ids[i]; cropped_array_shares[i] = array_shares[i]; } return (cropped_array_price_ids, cropped_array_shares); } } /// @dev Finds the rightmost node that matches the given order_id. /// @param order_id The ID of the order to find the matching node for. /// @return node_id The ID of the found node or root. /// @return success Indicates whether the search was successful. /// This algo finds the lowest node in branch that meets the given criteria. function findRightmostMatchingNode(uint64 order_id) internal view returns (uint64 node_id, bool success) { uint256 map = rightmost_map; uint64 local_best_offer = best_offer; // We climb the rightmost branch until we go through it all. uint256 mask = ~uint256(0x1); while (true) { if (((local_best_offer ^ order_id) & mask) == 0x0) { // We found the node that matches order_id. uint256 k = (~mask & (mask >> 1)); // Extracts the bit that determines the length. // Shifting works correctly for the case of 64 bits. node_id = uint64((local_best_offer & mask) ^ k); return (node_id, true); } map = map & mask; if (map == 0x0) { // We have reached the root of the tree, uint256 k = (~mask & (mask >> 1)); // Extracts the bit that determines the length. // Shifting works correctly for the case of 64 bits. uint64 root_node_id = uint64((local_best_offer & mask) ^ k); return (root_node_id, false); } unchecked { // we just checked that map != 0 mask = ~(map ^ (map - 1)); } } } /// @dev Normalizes the branch of the tree up to the specified stop node. /// @param stop_node_id The ID of the node where normalization stops, must exist. /// @return extra_total_shares The total number of extra shares added during normalization. /// @return extra_total_value The total value associated with the extra shares added during normalization. /// @return new_rightmost_map The new rightmost map after normalization. function normalizeBranch(uint64 stop_node_id) internal returns (uint128 extra_total_shares, uint128 extra_total_value, uint64 new_rightmost_map) { uint256 map = rightmost_map; uint64 local_best_offer = best_offer; // loading leaf data Leaf memory leaf = leaves[local_best_offer]; (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); extra_total_shares = leaf.remain_shares; extra_total_value = uint128(uint256(extra_total_shares) * uint256(initial_value) / uint256(initial_shares)); map ^= 0x1; if (stop_node_id == local_best_offer) { return (extra_total_shares, extra_total_value, uint64(map)); } uint256 mask; unchecked { // we are guaranteed to have a stop order higher mask = ~(map ^ (map - 1)); } while (true) { uint256 k = (~mask & (mask >> 1)); // Shifting works correctly for the case of 64 bits. map ^= k; uint64 node_id = uint64((local_best_offer & mask) ^ k); uint64 node_ptr = nodes[node_id].total_shares_value_ptr; (uint128 node_total_shares, uint128 node_total_value) = loadSharesValueFromArena(node_ptr); uint128 initial_total_shares = node_total_shares; uint128 initial_total_value = node_total_value; node_total_shares += extra_total_shares; node_total_value += extra_total_value; saveSharesValueToArena(node_ptr, node_total_shares, node_total_value); extra_total_shares += initial_total_shares; extra_total_value += initial_total_value; if (node_id == stop_node_id) { break; } unchecked { // we are guaranteed to have a stop order higher mask = ~(map ^ (map - 1)); } } new_rightmost_map = uint64(map); } /// @dev Converts the regular right branch to rightmost branch starting from the given start_node_id. /// @param start_node_id The starting node_id for the conversion. Must me on the rightmost branch. /// @return xor_map The XOR diff with rightmost map generated during the conversion. function convertToRightmost(uint64 start_node_id) internal returns (uint64 xor_map) { xor_map = 0x1; // including leaf node uint64 node_id = start_node_id; Node memory node; while ((node_id & 0x1) != 0x1) { // untill we reach leaf node = nodes[node_id]; uint64 ptr = node.total_shares_value_ptr; uint64 child_node_id = node.right; (uint128 child_shares, uint128 child_value) = extractSharesValueForNode(child_node_id); removeFromArenaValues(ptr, child_shares, child_value); uint64 k; unchecked { k = ~(node_id - 1) & node_id; // Extracts the bit that determines the length. // Valid node always is greater than 0. } xor_map ^= k; node_id = child_node_id; } best_offer = node_id; } /// @dev Updates root node and adds a new order as a descendant of new root. /// @param order_id The ID of the new order. /// @param root_node_id The ID of the root node in the tree. /// @param shares The number of shares for the new order. /// @param value The value associated with the new order. function addOrderAndUpdateRoot(uint64 order_id, uint64 root_node_id, uint128 shares, uint128 value) internal { uint64 extra_node_id = calcCommonParent(order_id, root_node_id); Node memory extra_node; uint64 extra_node_k; unchecked { extra_node_k = ~(extra_node_id - 1) & extra_node_id; // Extracts the bit that determines the length. // Valid node always is greater than 0. } uint64 free_ptr = allocateMemory(); uint64 new_rightmost_map; if (root_node_id < order_id) { // inserting node to the right uint128 extra_total_shares; uint128 extra_total_value; (extra_total_shares, extra_total_value, new_rightmost_map) = normalizeBranch(root_node_id); saveSharesValueToArena(free_ptr, extra_total_shares, extra_total_value); extra_node = Node({ left: root_node_id, right: order_id, total_shares_value_ptr: free_ptr }); new_rightmost_map ^= extra_node_k ^ 0x1; // 0x1 for new leaf best_offer = order_id; } else { // inserting node to the left saveSharesValueToArena(free_ptr, shares, value); extra_node = Node({ left: order_id, right: root_node_id, total_shares_value_ptr: free_ptr }); new_rightmost_map = rightmost_map ^ extra_node_k; } rightmost_map = new_rightmost_map; nodes[extra_node_id] = extra_node; } /// @dev Adds an order to the nodes based on the provided order_id, node_id, shares, and value. /// @param order_id The ID of the order to add. /// @param node_id The ID of the node where the order should be added. Must be the lowest node in rightmost branch /// that matches order_id. /// @param shares The number of shares for the order. /// @param value The value associated with the order. function addOrderToNodes(uint64 order_id, uint64 node_id, uint128 shares, uint128 value) internal { // we now for sure that node_id is not a leaf Node memory node = nodes[node_id]; if (matchesNode(order_id, node.left)) { uint64 node_ptr = node.total_shares_value_ptr; addToArenaValues(node_ptr, shares, value); addOrderToNonRightmostNodeDescendants(node.left, order_id, shares, value); return; } // node.right can't match order_id // so no "else" logic needs here // so we are inserting new node here, in current node uint64 extra_node_id; Node memory extra_node; uint64 free_ptr = allocateMemory(); if (order_id < node_id) { uint64 node_ptr = node.total_shares_value_ptr; addToArenaValues(node_ptr, shares, value); extra_node_id = calcCommonParent(order_id, node.left); if (node.left > order_id) { extra_node = Node(order_id, node.left, free_ptr); } else { extra_node = Node(node.left, order_id, free_ptr); } (uint128 child_shares, uint128 child_value) = extractSharesValueForNode(node.left); saveSharesValueToArena(free_ptr, shares + child_shares, value + child_value); node.left = extra_node_id; } else { // here we must properly rebuild the rightmost branch extra_node_id = calcCommonParent(order_id, node.right); uint64 extra_node_k; unchecked { extra_node_k = ~(extra_node_id - 1) & extra_node_id; // Extracts the bit that determines the length. // Valid node always is greater than 0. } if (node.right > order_id) { saveSharesValueToArena(free_ptr, shares, value); extra_node = Node(order_id, node.right, free_ptr); rightmost_map ^= extra_node_k; } else { (uint128 extra_total_shares, uint128 extra_total_value, uint64 new_rightmost_map) = normalizeBranch(node.right); rightmost_map = new_rightmost_map ^ extra_node_k ^ 0x1; // 0x1 for new leaf; best_offer = order_id; saveSharesValueToArena(free_ptr, extra_total_shares, extra_total_value); extra_node = Node(node.right, order_id, free_ptr); } node.right = extra_node_id; } nodes[node_id] = node; nodes[extra_node_id] = extra_node; } /// @dev Adds an order to the descendants of a node that is not the rightmost node. /// @param node_id The ID of the node from which to start updating. It must match order_id. /// @param order_id The ID of the order to add. /// @param shares The total shares associated with the order. /// @param value The total value associated with the order. function addOrderToNonRightmostNodeDescendants( uint64 node_id, uint64 order_id, uint128 shares, uint128 value ) internal { uint64 next_node_id; Node memory node; // Descending the tree starting from node_id until neither child matches order_id, // indicating a new node insertion point. while (true) { node = nodes[node_id]; uint64 ptr = node.total_shares_value_ptr; addToArenaValues(ptr, shares, value); if (matchesNode(order_id, node.left)) { next_node_id = node.left; } else if (matchesNode(order_id, node.right)) { next_node_id = node.right; } else { break; } node_id = next_node_id; } uint64 extra_node_id; Node memory extra_node; uint64 free_ptr = allocateMemory(); uint64 child_node_id; if (order_id < node_id) { // Inserting new (extra) node to the left. extra_node_id = calcCommonParent(order_id, node.left); if (node.left > order_id) { extra_node = Node(order_id, node.left, free_ptr); } else { extra_node = Node(node.left, order_id, free_ptr); } child_node_id = node.left; node.left = extra_node_id; } else { // Inserting new (extra) node to the right. extra_node_id = calcCommonParent(order_id, node.right); if (node.right > order_id) { extra_node = Node(order_id, node.right, free_ptr); } else { extra_node = Node(node.right, order_id, free_ptr); } child_node_id = node.right; node.right = extra_node_id; } (uint128 child_shares, uint128 child_value) = extractSharesValueForNode(child_node_id); saveSharesValueToArena(free_ptr, shares + child_shares, value + child_value); nodes[node_id] = node; nodes[extra_node_id] = extra_node; } /// @dev Checks if a given order is present in the tree. /// @param node_id The ID of the starting node identifier from which the search begins. /// @param order_id The ID of the order to search for in the tree. /// @return isPresent A boolean value indicating whether the order is present in the tree. function isOrderInTree(uint64 node_id, uint64 order_id) internal view returns (bool isPresent) { if (node_id == order_id) { return true; } Node memory node; while (true) { node = nodes[node_id]; if (node.left == order_id || node.right == order_id) { return true; } if (matchesNode(order_id, node.left)) { node_id = node.left; } else if (matchesNode(order_id, node.right)) { node_id = node.right; } else { return false; } } } /// @dev Removes best offer order and rebuild rightmost branch if needed. function removeBestOffer() internal { uint64 local_best_offer = best_offer; uint64 map = rightmost_map; if (map == 0x1) { // This means there is only one order in the trie. // We remove it and leave the trie empty. rightmost_map = 0x0; best_offer = 0x0; return; } // We need to find the parent node and remove it as well. // It exists because there are more than one leaf in the tree. map ^= 0x1; uint64 mask; unchecked { // map > 0 since there are more than one leaf in the tree mask = ~(map ^ (map - 1)); } uint64 k = (((mask >> 1) | 0x8000000000000000) & ~mask); // Removing this node from rightmost map too. map ^= k; uint64 node_id = (local_best_offer & mask) ^ k; Node memory node = nodes[node_id]; eraseNode(node_id, node.total_shares_value_ptr); uint64 new_right_child = node.left; // and we have new rightmost branch uint64 new_rightmost_map = map ^ convertToRightmost(new_right_child); rightmost_map = new_rightmost_map; // This means that the node being removed has no "grandfather" node. if (new_rightmost_map == 0x1) { return; } // We also need to update the right child of the ancestor's ancestor of our order, as we have just removed it. unchecked { // map > 0 since there are at least one more ancestor mask = ~(map ^ (map - 1)); } k = (((mask >> 1) | 0x8000000000000000) & ~mask); node_id = (local_best_offer & mask) ^ k; nodes[node_id].right = new_right_child; } /// @dev Removes an order from the nodes based on the provided order_id, node_id, remaining shares, and remaining value. /// @param order_id The ID of the order to remove. /// @param node_id The ID of the node from which to remove the order. /// @param remain_shares The remaining shares of the order. /// @param remain_value The remaining value of the order. /// @return found Indicates if the order was found and removed. function removeOrderFromNodes( uint64 order_id, uint64 node_id, uint128 remain_shares, uint128 remain_value ) internal returns (bool found) { Node memory node = nodes[node_id]; if (node.left == order_id) { eraseNode(node_id, node.total_shares_value_ptr); uint64 k; unchecked { // valid node_id is always greater than 0 k = ~(node_id - 1) & node_id; } uint64 map = rightmost_map; rightmost_map = map ^ k; uint64 mask; unchecked { mask = ~(k ^ (k - 1)); // k > 0 } map = map & mask; if (map == 0x0) { // same case in removeBestOffer - no "grandfather" node. return true; } unchecked { k = ~(map - 1) & map; // we just checked that map > 0 mask = ~(k ^ (k - 1)); // k > 0 } uint64 new_right_child = node.right; node_id = (node_id & mask) ^ k; nodes[node_id].right = new_right_child; return true; } if (!matchesNode(order_id, node.left)) { return false; } uint64 returned_child; (found, returned_child) = removeOrderFromNonRightmostNodeDescendants( node.left, order_id, remain_shares, remain_value ); if (found) { removeFromArenaValues(node.total_shares_value_ptr, remain_shares, remain_value); if (node.left != returned_child){ node.left = returned_child; nodes[node_id] = node; } } } /// @dev Recursively removes an order from the descendants of a non-rightmost node. /// @param node_id The ID of the current node being processed. Must be not a leaf. /// @param order_id The ID of the order to be removed. /// @param shares The number of shares associated with the order. /// @param value The value associated with the order. /// @return found Indicates if the order was found and removed. /// @return returned_child The identifier of the child node returned after removal. function removeOrderFromNonRightmostNodeDescendants( uint64 node_id, uint64 order_id, uint128 shares, uint128 value ) internal returns (bool found, uint64 returned_child) { Node memory node = nodes[node_id]; if (node.left == order_id) { eraseNode(node_id, node.total_shares_value_ptr); return (true, node.right); } else if (node.right == order_id) { eraseNode(node_id, node.total_shares_value_ptr); return (true, node.left); } if (matchesNode(order_id, node.left)) { (found, returned_child) = removeOrderFromNonRightmostNodeDescendants(node.left, order_id, shares, value); if (!found) { return (false, 0x0); } removeFromArenaValues(node.total_shares_value_ptr, shares, value); if (node.left != returned_child){ node.left = returned_child; nodes[node_id] = node; } return (true, node_id); } else if (matchesNode(order_id, node.right)) { (found, returned_child) = removeOrderFromNonRightmostNodeDescendants(node.right, order_id, shares, value); if (!found) { return (false, 0x0); } removeFromArenaValues(node.total_shares_value_ptr, shares, value); if (node.left != returned_child){ node.right = returned_child; nodes[node_id] = node; } return (true, node_id); } else { return (false, 0x0); } } /// @dev Extracts key and mask from a given node_id. /// @param node_id The ID of the node from which to extract key and mask. /// @return key The extracted key. /// @return mask The extracted mask. function extractKeyAndMaskFrom(uint64 node_id) internal pure returns (uint64 key, uint64 mask) { unchecked { // valid node_id is always greater than 0 mask = ~((node_id - 1) ^ node_id); } key = node_id & mask; return (key, mask); } /// @dev Extracts key from a given node_id. /// @param node_id The ID of the node from which to extract key. /// @return key The extracted key. function extractKeyFrom(uint64 node_id) internal pure returns (uint64 key) { uint64 k; unchecked { // valid node_id is always greater than 0 k = ~(node_id - 1) & node_id; } return node_id ^ k; } /// @dev Calculates the common parent node for a given order_id and node_id. /// @param order_id The ID of the order to calculate the common parent for. /// @param node_id The ID of the node to calculate the common parent for. /// @return The calculated common parent node. function calcCommonParent(uint64 order_id, uint64 node_id) internal pure returns (uint64) { uint64 key = extractKeyFrom(node_id); uint256 diff = (order_id ^ 0x1) ^ key; uint256 mask = ~uint256(type(uint64).max); uint256 t; t = mask >> 32; if ((t & diff) == 0x0) { mask = t; } t = mask >> 16; if ((t & diff) == 0x0) { mask = t; } t = mask >> 8; if ((t & diff) == 0x0) { mask = t; } t = mask >> 4; if ((t & diff) == 0x0) { mask = t; } t = mask >> 2; if ((t & diff) == 0x0) { mask = t; } t = mask >> 1; if ((t & diff) == 0x0) { mask = t; } uint256 k = ((mask >> 1) & ~mask); return uint64((order_id & mask) ^ k); } /// @dev Checks if the order_id is a descendant of the node_id. /// @param order_id The ID of the order to compare with the node_id. /// @param node_id The ID of the node to compare with the order_id. /// @return True if the order_id matches the node_id, false otherwise. function matchesNode(uint64 order_id, uint64 node_id) internal pure returns (bool) { uint64 mask; unchecked { // valid node_id is always greater than 0 mask = ~((node_id - 1) ^ node_id); } return ((order_id ^ node_id) & mask) == 0x0; } /// @dev Erases the node with the specified node_id. /// @param node_id The ID of the node of the node to erase. function eraseNode(uint64 node_id, uint64 ptr) internal virtual { // Requires a more thoughtful strategy than just erasing everything. // if ((node_id & 0x1) != 0x1) { // delete nodes[node_id]; // } freeMemory(ptr); } /// @dev Recursively executes orders using a "right" approach within the order matching process. /// @param order_id The price identifier of the order, not necessarily associated with a real order ID. /// @param node_id The ID of the node within the order. /// @param rest_total_shares The remaining total shares to be executed. /// @return execution_result An ExecutionResult struct containing the result of the execution. function executeRightRec(uint64 order_id, uint64 node_id, uint128 rest_total_shares) internal returns (ExecutionResult memory execution_result) { if ((node_id & 0x1) == 0x1) { // leaf execution return executeLeaf(order_id, node_id, rest_total_shares); } // node execution Node memory node = nodes[node_id]; uint64 node_ptr = node.total_shares_value_ptr; (uint128 node_shares, uint128 node_value) = loadSharesValueFromArena(node_ptr); // node.left != 0x0 since it node, not a leaf uint64 price_key = extractKeyFrom(node.left); // the same condition in executeRight if (((order_id ^ 0x1) > price_key) || (rest_total_shares < node_shares)) { ExecutionResult memory right_execution_result = executeRightRec(order_id, node.right, rest_total_shares); rest_total_shares -= right_execution_result.executed_shares; if (right_execution_result.right_child != 0x0) { removeFromArenaValues( node_ptr, right_execution_result.total_shares + right_execution_result.executed_shares, right_execution_result.total_value + right_execution_result.executed_value ); if (node.right != right_execution_result.right_child) { node.right = right_execution_result.right_child; nodes[node_id] = node; } uint64 k; unchecked { k = ~(node_id - 1) & node_id; // Extracts the bit that determines the length. // Valid node always is greater than 0. } execution_result = ExecutionResult({ executed_shares: right_execution_result.executed_shares, executed_value: right_execution_result.executed_value, total_shares: node_shares - right_execution_result.executed_shares, total_value: node_value - right_execution_result.executed_value, right_child: node_id, xor_map: right_execution_result.xor_map ^ k }); } else { execution_result = executeRightRec(order_id, node.left, rest_total_shares); execution_result.executed_shares += right_execution_result.executed_shares; execution_result.executed_value += right_execution_result.executed_value; } } else { // full execution execution_result = ExecutionResult({ executed_shares: node_shares, executed_value: node_value, total_shares: 0, total_value: 0, right_child: 0x0, xor_map: 0x0 }); eraseNode(node_id, node_ptr); } } /// @dev Executes a leaf node within the order matching process. /// @param order_id The price identifier of the order, not associated with a real order ID. /// @param leaf_node_id The ID of the leaf node within the order. /// @param rest_total_shares The remaining total shares to be executed. /// @return execution_result An ExecutionResult struct containing the result of the execution. function executeLeaf(uint64 order_id, uint64 leaf_node_id, uint128 rest_total_shares) internal returns (ExecutionResult memory execution_result) { Leaf memory leaf = leaves[leaf_node_id]; (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); uint128 remain_shares = leaf.remain_shares; uint128 remain_value = uint128(uint256(remain_shares) * uint256(initial_value) / uint256(initial_shares)); if (leaf_node_id >= order_id) { // both end on 0x1 bit, so we can compare them // we can execute current leaf if (remain_shares <= rest_total_shares) { // full execution execution_result = ExecutionResult({ executed_shares: remain_shares, executed_value: remain_value, total_shares: 0, total_value: 0, right_child: 0x0, xor_map: 0x0 }); } else { // partial execution uint128 executed_shares = rest_total_shares; // Since the operation node.total_value = node.total_shares * price is expected, // the quotient will always be an integer. uint128 executed_value = uint128(uint256(rest_total_shares) * uint256(remain_value) / uint256(remain_shares)); // remain_value / remain_shares = price unchecked { leaf.remain_shares -= executed_shares; } leaves[leaf_node_id] = leaf; execution_result = ExecutionResult({ executed_shares: executed_shares, executed_value: executed_value, total_shares: remain_shares - executed_shares, total_value: remain_value - executed_value, right_child: leaf_node_id, xor_map: 0x1 }); best_offer = leaf_node_id; } } else { // we can't execute current leaf at all execution_result = ExecutionResult({ executed_shares: 0, executed_value: 0, total_shares: remain_shares, total_value: remain_value, right_child: leaf_node_id, xor_map: 0x1 }); best_offer = leaf_node_id; } // A brief comment explaining why in some cases we equate the best offer to the current leaf. // When executing multiple orders, only one of them may be partially executed. This partially executed order // becomes the best offer. // An entirely unexecuted order becomes the best because our algorithm, encountering such behavior, // stops trying to execute other orders - they are guaranteed to be worse. On the other hand, // all better orders have already been fully executed. } /// @dev Preview the execution of a leaf node. /// @param order_id The ID of the order to be executed. /// @param leaf_node_id The ID of the leaf node to be executed. /// @param rest_shares The remaining shares of the order. /// @param rest_value The remaining value of shares of the order. /// @return executed_shares The number of shares executed. /// @return executed_value The value of the executed shares. /// @return full A boolean indicating whether the leaf was fully executed (true) or partially executed (false). function previewExecuteLeaf(uint64 order_id, uint64 leaf_node_id, uint128 rest_shares, uint128 rest_value) internal view returns (uint128 executed_shares, uint128 executed_value, bool full) { Leaf memory leaf = leaves[leaf_node_id]; (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); uint128 leaf_shares = leaf.remain_shares; uint128 leaf_value = uint128(uint256(leaf_shares) * uint256(initial_value) / uint256(initial_shares)); if (leaf_node_id >= order_id) { // both end on 0x1 bit, so we can compare them // we can execute current leaf // The order of these checks is important and should not be changed. // We first check if we need to adjust shares based on value, // then we check if we need to adjust value based on shares. // This ensures correct handling of partial executions and rounding. if (rest_value < leaf_value) { uint128 shares = uint128(uint256(rest_value) * uint256(leaf_shares) / uint256(leaf_value)); // note: This division may not result in an integer, and rounding down is implied if (shares < rest_shares) { rest_shares = shares; } } if (rest_shares < leaf_shares) { uint128 value = uint128(uint256(rest_shares) * uint256(leaf_value) / uint256(leaf_shares)); if (value < rest_value) { rest_value = value; } } if (rest_shares < leaf_shares) { // partial execution return (rest_shares, rest_value, false); } else { // full execution return (leaf_shares, leaf_value, true); } } else { // we can't execute current leaf at all return (0, 0, false); } } /// @dev Calculates the next rightmost node ID and its associated k-bit based on the given node ID and map. /// @param node_id The node ID. /// @param map The map used for calculation. /// @return The next rightmost node ID and its associated k-bit. function calcNextRightMostNodeId(uint64 node_id, uint64 map) internal pure returns (uint64, uint64) { uint64 mask; unchecked { mask = ~(node_id ^ (node_id - 1)); // valid node_id is always greater than 0 map &= mask; } if (map == 0x0) { return (0, 0); } unchecked { mask = ~(map ^ (map - 1)); // we just checker map > 0 } uint64 k = (((mask >> 1) | 0x8000000000000000) & ~mask); return ((node_id & mask) ^ k, k); } /// @dev Packs two uint128 values into a single uint256. /// @param a The first uint128 value. /// @param b The second uint128 value. /// @return p The packed uint256 value. function packTwoUintsToWord(uint128 a, uint128 b) internal pure returns (uint256 p) { p = uint256(a) ^ (uint256(b) << 128); } /// @dev Unpacks a uint256 value into two uint128 values. /// @param p The packed uint256 value. /// @return a The first unpacked uint128 value. /// @return b The second unpacked uint128 value. function unPackTwoUintsFromWord(uint256 p) internal pure returns (uint128 a, uint128 b) { a = uint128(p & 0xffffffffffffffffffffffffffffffff); b = uint128(p >> 128); } /// @dev Allocates memory for storing data. /// @return ptr The pointer to the allocated memory. function allocateMemory() internal returns (uint64 ptr) { if (last_free_pointer == 0x0) { return (++highest_allocated_pointer); } ptr = last_free_pointer; last_free_pointer = uint64(arena[ptr]); } /// @dev Frees the memory at the given pointer. /// @param ptr The pointer to the memory to be freed. function freeMemory(uint64 ptr) internal { require(last_free_pointer != ptr, Errors.PointerAlreadyFreed()); arena[ptr] = packTwoUintsToWord(last_free_pointer, 0x1); last_free_pointer = ptr; } /// @dev Saves the shares and value to the memory at the given pointer. /// @param ptr The pointer to the memory where the data will be saved. /// @param shares The shares to be saved. /// @param value The value to be saved. function saveSharesValueToArena(uint64 ptr, uint128 shares, uint128 value) internal { arena[ptr] = packTwoUintsToWord(shares, value); } /// @dev Loads the shares and value from the memory at the given pointer. /// @param ptr The pointer to the memory from where the data will be loaded. /// @return The shares and value loaded from the memory. function loadSharesValueFromArena(uint64 ptr) internal view returns (uint128, uint128) { return unPackTwoUintsFromWord(arena[ptr]); } /// @dev Adds shares and value to the data at the given pointer in memory. /// @param ptr The pointer to the memory where the data will be added. /// @param adding_shares The shares to be added. /// @param adding_value The value to be added. function addToArenaValues(uint64 ptr, uint128 adding_shares, uint128 adding_value) internal { (uint128 shares, uint128 value) = unPackTwoUintsFromWord(arena[ptr]); shares += adding_shares; value += adding_value; arena[ptr] = packTwoUintsToWord(shares, value); } /// @dev Removes shares and value from the data at the given pointer in memory. /// @param ptr The pointer to the memory from where the data will be removed. /// @param removing_shares The shares to be removed. /// @param removing_value The value to be removed. function removeFromArenaValues(uint64 ptr, uint128 removing_shares, uint128 removing_value) internal { (uint128 shares, uint128 value) = unPackTwoUintsFromWord(arena[ptr]); shares -= removing_shares; value -= removing_value; arena[ptr] = packTwoUintsToWord(shares, value); } /// @dev Extracts the shares and value for a given node. /// @param node_id The ID of the node. /// @return The shares and value for the node. function extractSharesValueForNode(uint64 node_id) internal view returns (uint128, uint128) { if ((node_id & 0x1) == 0x1) { // leaf case Leaf memory leaf = leaves[node_id]; (uint128 initial_shares, uint128 initial_value) = loadSharesValueFromArena(leaf.initial_shares_value_ptr); uint128 remain_shares = leaf.remain_shares; uint128 remain_value = uint128(uint256(remain_shares) * uint256(initial_value) / uint256(initial_shares)); return (remain_shares, remain_value); } uint64 ptr = nodes[node_id].total_shares_value_ptr; return loadSharesValueFromArena(ptr); } }
// SPDX-License-Identifier: BUSL-1.1 // Central Limit Order Book (CLOB) exchange // (c) Long Gamma Labs, 2023. pragma solidity ^0.8.26; contract Errors { error AddressIsZero(); error ArrayLengthMismatch(); error ChainIsUnstableForTrades(); error ClaimNotAllowed(); error CommissionParamTooHigh(); error Disabled(); error EmptyOrderError(); error ExcessiveSignificantFigures(); error Expired(); error Forbidden(); error FractionalNumbersNotAllowed(); error InsufficientTokenXBalance(); error InsufficientTokenYBalance(); error InvalidCommissionRate(); error InvalidFloatingPointRepresentation(); error InvalidMarketMaker(); error InvalidPriceRange(); error InvalidTransfer(); error MarketOnlyAndPostOnlyFlagsConflict(); error MaxCommissionFailure(); error NativeETHDisabled(); error NonceExhaustedFailure(); error NotImplementedYet(); error OnlyOwnerCanCancelOrders(); error PointerAlreadyFreed(); error PriceExceedsMaximumAllowedValue(); error TransferFailed(); error UnknownOrderId(); error UnknownTrader(); error WrongOwner(); error ZeroMaxDelayNotAllowed(); error ZeroRecoveryTimeNotAllowed(); error ZeroTokenTransferNotAllowed(); }
// SPDX-License-Identifier: BUSL-1.1 // Central Limit Order Book (CLOB) exchange // (c) Long Gamma Labs, 2023. pragma solidity ^0.8.26; interface ITrie { function best_offer() external view returns (uint64); function rightmost_map() external view returns (uint64); function addOrder(uint64 trader_id, uint64 order_id, uint128 shares, uint128 value) external; function removeOrder(uint64 order_id, uint64 order_trader_id) external returns (uint128 total_shares, uint128 remain_shares); function claimExecuted(uint64 order_id, uint64 order_trader_id) external returns (uint128 executed_shares, uint128 remain_shares); function getOrderInfo(uint64 order_id) external view returns (uint128 total_shares, uint128 remain_shares); function executeRight(uint64 order_id, uint128 order_total_shares) external returns (uint128 executed_shares, uint128 executed_value); function previewExecuteRight(uint64 order_id, uint128 max_shares, uint128 max_value) external view returns (uint128 executed_shares, uint128 executed_value); function assembleOrderbookFromOrders(uint24 max_price_levels) external view returns (uint24[] memory array_price_ids, uint128[] memory array_shares); }
{ "remappings": [ "forge-std/=lib/forge-std/src/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@solmate/src/=lib/solmate/src/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_lob_address","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyOrderError","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[],"name":"PointerAlreadyFreed","type":"error"},{"inputs":[],"name":"WrongOwner","type":"error"},{"inputs":[{"internalType":"uint64","name":"trader_id","type":"uint64"},{"internalType":"uint64","name":"order_id","type":"uint64"},{"internalType":"uint128","name":"shares","type":"uint128"},{"internalType":"uint128","name":"value","type":"uint128"}],"name":"addOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint24","name":"max_price_levels","type":"uint24"}],"name":"assembleOrderbookFromOrders","outputs":[{"internalType":"uint24[]","name":"array_price_ids","type":"uint24[]"},{"internalType":"uint128[]","name":"array_shares","type":"uint128[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"best_offer","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"order_id","type":"uint64"},{"internalType":"uint64","name":"order_trader_id","type":"uint64"}],"name":"claimExecuted","outputs":[{"internalType":"uint128","name":"executed_shares","type":"uint128"},{"internalType":"uint128","name":"remain_shares","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"order_id","type":"uint64"},{"internalType":"uint128","name":"order_total_shares","type":"uint128"}],"name":"executeRight","outputs":[{"internalType":"uint128","name":"executed_shares","type":"uint128"},{"internalType":"uint128","name":"executed_value","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"order_id","type":"uint64"}],"name":"getOrderInfo","outputs":[{"internalType":"uint128","name":"total_shares","type":"uint128"},{"internalType":"uint128","name":"remain_shares","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"order_id","type":"uint64"},{"internalType":"uint128","name":"max_shares","type":"uint128"},{"internalType":"uint128","name":"max_value","type":"uint128"}],"name":"previewExecuteRight","outputs":[{"internalType":"uint128","name":"executed_shares","type":"uint128"},{"internalType":"uint128","name":"executed_value","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"order_id","type":"uint64"},{"internalType":"uint64","name":"order_trader_id","type":"uint64"}],"name":"removeOrder","outputs":[{"internalType":"uint128","name":"total_shares","type":"uint128"},{"internalType":"uint128","name":"remain_shares","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rightmost_map","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a03461008d57601f612d7b38819003918201601f19168301916001600160401b038311848410176100915780849260209460405283398101031261008d57516001600160a01b038116810361008d575f80546001600160801b0319169055608052604051612cd590816100a6823960805181818160a20152818161019a015281816101f601526102500152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c9081630d1cf14614610363575080632e2866831461033e5780635e9dd46a146102875780638f94fa521461022d578063a558898f146101d3578063b23264221461015b578063c4dca4221461013a578063e146af47146101085763fa1e9ec81461007f575f80fd5b3461010457604036600319011261010457610098610388565b6100a061039e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576100d9916111f8565b604080516001600160801b039384168152919092166020820152f35b631dd2188d60e31b5f5260045ffd5b5f80fd5b34610104576060366003190112610104576100d9610124610388565b61012c6103b4565b6101346103ca565b91610fd4565b34610104576020366003190112610104576100d9610156610388565b610f1e565b3461010457608036600319011261010457610174610388565b61017c61039e565b6101846103ca565b606435916001600160801b0383168303610104577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576101d193610d08565b005b34610104576040366003190112610104576101ec610388565b6101f46103b4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576100d991610985565b3461010457604036600319011261010457610246610388565b61024e61039e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031633036100f5576100d9916107af565b346101045760203660031901126101045760043562ffffff81168103610104576102b0906104f7565b90604051918291604083016040845281518091526020606085019201905f5b818110610320575050508281036020840152602080835192838152019201905f5b8181106102fe575050500390f35b82516001600160801b03168452859450602093840193909201916001016102f0565b825162ffffff168452869550602093840193909201916001016102cf565b34610104575f3660031901126101045760206001600160401b035f5416604051908152f35b34610104575f366003190112610104576020906001600160401b035f5460401c168152f35b600435906001600160401b038216820361010457565b602435906001600160401b038216820361010457565b602435906001600160801b038216820361010457565b604435906001600160801b038216820361010457565b60405190606082018281106001600160401b038211176103ff57604052565b634e487b7160e01b5f52604160045260245ffd5b6040519060c082018281106001600160401b038211176103ff57604052565b6040519190601f01601f191682016001600160401b038111838210176103ff57604052565b6001600160401b0381116103ff5760051b60200190565b9061048061047b83610457565b610432565b8281528092610491601f1991610457565b0190602036910137565b80518210156104af5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b906001600160801b03809116911601906001600160801b0382116104e357565b634e487b7160e01b5f52601160045260245ffd5b5f54916001600160401b0383169182158015610751575b6107245762ffffff16906105218261046e565b9061052b8361046e565b908251156104af576020839694960162ffffff8560281c16905260016001600160401b035f969560401c1618935b64ffffffffff8116156106ee5762ffffff8160281c1662ffffff871662ffffff610583828861049b565b511682036106a3575b50506105dc85826105a46001600160401b0394611323565b506001600160801b036105d36105cc62ffffff8d1693836105c5868d61049b565b51166104c3565b928961049b565b911690526113c7565b91169485156106045718935f5260026020526001600160401b0360405f205416955b95610559565b505092509262ffffff600191959295160162ffffff81116104e35762ffffff1690811061062e5750565b90916106398261046e565b6106428361046e565b945f5b62ffffff8116858110156106995762ffffff9181836106666001948761049b565b5116610672828861049b565b526106916001600160801b03610688838a61049b565b5116918b61049b565b520116610645565b5050509150509190565b90965062ffffff81146104e3576001019562ffffff87168881146106e1576001600160401b03926105dc926106d989938961049b565b52925061058c565b5050509350935090509190565b936001600160401b03908186815f198201161916161894165f5260026020526001600160401b0360405f205460401c16956105fe565b5091505060209061073482610432565b5f81525f36813761074483610432565b925f8452505f3681379190565b5062ffffff81161561050e565b906001600160801b03809116911603906001600160801b0382116104e357565b818102929181159184041417156104e357565b811561079b570490565b634e487b7160e01b5f52601260045260245ffd5b90916001600160401b038216805f52600160205260405f206107cf6103e0565b9054946001600160401b03861690818352604060208401936001600160801b0389831c168552019660c01c87528115610925576001600160401b031603610916576001600160801b039051169361082f6001600160401b03825116611428565b9590946001600160401b035f541684115f146108df5750505f935b610854858261075e565b956001600160801b038716156108d6578591906001600160801b038316908161089e57505050506001600160401b039061089c925f5260016020525f6040812055511661162b565b565b61089c95506001600160401b03926001600160801b036108c58194826108cd95169061077e565b911690610791565b169251166115fe565b505f9550505050565b6108eb8196929661144f565b1591908215610904575b50501561084a575f945061084a565b61090e92506114f2565b155f806108f5565b635d652eb160e01b5f5260045ffd5b505f9550859450505050565b906001600160401b036109426103e0565b92548181168452818160401c16602085015260801c166040830152565b90600160401b600160801b0382549160401b1690600160401b600160801b031916179055565b916001600160401b035f541691826001600160401b03851611610cff57825f52600160205260405f20936109b76103e0565b94546001600160401b038116865260208601906001600160801b038160401c16825260c01c956109ed6040820197808952611428565b9790916001600160801b03845116916001600160801b03871694838610610c5a575050506001600160801b0391826108c58382610a2c959c169061077e565b16610a456001600160401b035f5460401c1680976113c7565b906001915b6001600160401b038216928315610c4c5718915f52600260205260405f20986001600160401b03610a796103e0565b9a548181168c52818160401c1660208d015260801c16998a6040820152610a9f8b611428565b9290916001600160401b03610ac7818351166001600160401b0381815f198201161916161890565b166001600160401b0360018b1816111580610c30575b15610b125750610aff8b93610af9610b0a9694610b05946104c3565b976104c3565b9b61162b565b6113c7565b929892610a4a565b610b6991959c506001600160401b03935060809250610b4284610b54925116610b3b888d61075e565b908b611708565b956001600160801b03875116906104c3565b956001600160801b03602087015116906104c3565b9a8260a086015116189301511680610b86575087610b0a916113c7565b9450610ba09298979195506001600160401b0393506113c7565b50169081610c15575b50505b6001600160401b038116610bbd5750565b600160401b600160801b035f54916001600160401b038360401c161860401b16906001600160401b0382600160401b600160801b0319831617805f5560401c1615610c06575050565b6001600160801b031916175f55565b610c29915f52600260205260405f2061095f565b5f80610ba9565b506001600160801b03610c4383856104c3565b16881015610add565b965050505094505050610bac565b9250926001600160801b03919550610c8890826108c56001600160401b039782610cfb9b9c9d9e169061077e565b16976001600160801b038781845116031682525f526001602052828060405f2095511616831985541617845551600160401b600160c01b0384549160401b1690600160401b600160c01b03191617835551168154906001600160401b0360c01b9060c01b169060018060c01b0316179055565b9190565b505f9250829150565b92919092610d9f610d17611aec565b91610d238585856115fe565b6001600160401b03610d336103e0565b911681526001600160801b03841660208083019182526001600160401b0394851660408085019182528987165f8181526001909452928190209451935191516001600160c01b031960c09190911b1693909616600160401b600160c01b039190961b1694909417179055565b5f546001600160401b038160401c1615610f015750610dbd8461144f565b90919015610dcf575061089c93611b6d565b909291610ddf8461089c966127df565b92610de86114d8565b506001600160401b0384815f1982011619161694610e04611aec565b916001600160401b038216938585105f14610ec3575050946001600160401b0394939285600193610e37610e3f996128b1565b9a91836115fe565b610e476103e0565b9283528560208401521660408201529518189083195f5416175f555b600160401b600160801b035f549160401b1690600160401b600160801b031916175f55165f5260026020526001600160401b036040805f20928280825116168319855416178455610eba836020830151168561095f565b015116906116b1565b8392506001600160401b0396959491610edd9188956115fe565b610ee56103e0565b938452602084015216604082015292825f5460401c1618610e63565b6001600160801b0319161768010000000000000000175f55505050565b906040916001600160401b03811690815f526001602052835f20610f406103e0565b9054906001600160401b038216908181526001600160801b0383881c169283602083015260c01c968791015215610fc957610f7b9094611428565b5080926001600160401b035f541610610fc05750610f988161144f565b15610fb65790610fa7916114f2565b15610fb0579190565b91505f90565b5050909150905f90565b93505f92915050565b50505090505f905f90565b9291925f5f915f54956001600160401b038716806001600160401b0384161180156111e7575b80156111d6575b6111c857949660401c6001600160401b031660011893925b6001868116036110b2579461105a8661104b61103961105498998c61075e565b611043888761075e565b9085886120ca565b989190926104c3565b956104c3565b94156110a857611072866001600160401b03926113c7565b911695861561109d5718945f5260026020526001600160401b0360405f205416965b96949392611019565b505050509350919050565b5050509350919050565b92936001600160401b03861695865f5260026020526110e06001600160401b0360405f205460801c16611428565b90885f5260026020526001600160401b036111118160405f2054166001600160401b0381815f198201161916161890565b166001600160401b0360018818161180156111aa575b801561118c575b156111675750506001600160401b0390815f1982011619161618945f5260026020526001600160401b0360405f205460401c1696611094565b8398506001600160401b039391610af961118692611072959a996104c3565b966113c7565b50611197888661075e565b6001600160801b0380841691161061112e565b506111b5878c61075e565b6001600160801b03808316911610611127565b50505050505090505f905f90565b506001600160801b03821615611001565b506001600160801b03861615610ffa565b9190916001600160401b03811692835f52600160205260405f209161121b6103e0565b9254916001600160401b0383169384815260208101946001600160801b038560401c168652604082019460c01c855215611314576001600160401b0380915116911603610916576112756001600160401b03835116611428565b956112bd6001600160401b036001600160801b036112a661129d8280889b51169c168c61077e565b82871690610791565b1695835f5260016020525f6040812055511661162b565b6001600160401b035f5416918282116113085750146112fe576112df8161144f565b919091156112f357610fa7929186916123a7565b505050909150905f90565b5050610cfb6121fc565b96505f95945050505050565b63f37b890d60e01b5f5260045ffd5b60018082161461135a576001600160401b03165f5260026020526113566001600160401b0360405f205460801c16611428565b9091565b906001600160401b036001600160801b0392165f526001602052816113c360405f20826108c5816113b6604061138e6103e0565b9554956001600160401b038716815260208101968481841c16885260c01c9182910152611428565b989094511697168761077e565b1690565b91906001600160401b0390815f1985011684181916168015611420576001600160401b035f198201161819916001600160401b0380808516196001603f1b677fffffffffffffff8760011c161716169384921616189190565b505f91508190565b6001600160401b03165f52600360205260405f2054906001600160801b0382169160801c90565b905f546001600160401b038160401c166001600160401b038216600119915b6001600160401b03838784181616156114b957821691821561149857505f1982018218199161146e565b6001600160401b0394955084925080915060011c8119169216161816905f90565b50509081166001600160401b039081168219600193841c161816925090565b6114e06103e0565b905f82525f60208301525f6040830152565b90916001600160401b03831691826001600160401b038216146115f5576001600160401b03906115206114d8565b505b165f52600260205260405f206115366103e0565b9054906001600160401b038216908181526001600160401b03808460401c169384602084015260801c1660408201525083811480156115ec575b6115e25761159381866001600160401b039180835f198201161819911816161590565b156115a7576001600160401b039150611522565b506115c781856001600160401b039180835f198201161819911816161590565b156115da576001600160401b0390611522565b509150505f90565b5050915050600190565b50838214611570565b50915050600190565b91906001600160801b036001600160401b039281199060801b1691161891165f52600360205260405f2055565b5f5460c01c6001600160401b0382169081811461167657600160801b18905f52600360205260405f20555f54906001600160401b0360c01b9060c01b169060018060c01b0316175f55565b637fa3fb5160e01b5f5260045ffd5b61168d610413565b905f82525f60208301525f60408301525f60608301525f60808301525f60a0830152565b805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b6001600160401b03604061089c938280825116168319855416178455610eba836020830151168561095f565b90929192611714611685565b50600180821614611ae15761174261173d826001600160401b03165f52600260205260405f2090565b610931565b9061175760408301516001600160401b031690565b61176081611428565b9490936001600160401b0361179561177f83516001600160401b031690565b6001600160401b0381815f198201161916161890565b166001600160401b036001841816118015611ac6575b15611a7257602081016117cf896117c983516001600160401b031690565b85611708565b6117eb90996117e58b516001600160801b031690565b9061075e565b60808a01936001600160401b0361180986516001600160401b031690565b16156119d75750506119869493611976938a936119669361188661185161183f6119969d9e9f604001516001600160801b031690565b88516001600160801b03165b906104c3565b9461186660608901516001600160801b031690565b9561188060208a019761184b89516001600160801b031690565b9161278c565b6118a861189a82516001600160401b031690565b93516001600160401b031690565b926001600160401b03808516911603611999575b5050506119566119036118d685516001600160801b031690565b9a6117e56118f58d6118ef87516001600160801b031690565b9c61075e565b94516001600160801b031690565b9361192a60a06001600160401b0389815f198201161916169201516001600160401b031690565b1897611946611937610413565b6001600160801b03909c168c52565b6001600160801b031660208b0152565b6001600160801b03166040890152565b6001600160801b03166060870152565b6001600160401b03166080850152565b6001600160401b031660a0830152565b90565b6119cf926119af91906001600160401b03169052565b6119ca876001600160401b03165f52600260205260405f2090565b6116dc565b5f80806118bc565b955095505090506119fb94506119f59150516001600160401b031690565b90611708565b611a4c602061089c9294611a3e611a31611a1c83516001600160801b031690565b88516001600160801b03166104c3565b6104c3565b6001600160801b03168752565b01516001600160801b031690565b611a656020850191611a2c83516001600160801b031690565b6001600160801b03169052565b5050945050611aa861089c92611a98611a89610413565b6001600160801b039094168452565b6001600160801b03166020830152565b5f60408201525f60608201525f60808201525f60a08201529261162b565b506001600160801b0385166001600160801b038916106117ab565b61199692939161258b565b5f548060c01c15611b2a57505f54908160c01c91825f5260036020526001600160401b0360c01b60405f205460c01b169060018060c01b0316175f55565b6001600160401b038160801c166001600160401b0381146104e357600101906001600160401b0360801b8260801b16906001600160401b0360801b1916175f5590565b906001600160401b031690815f52600260205260405f2092611b8d6103e0565b9354946001600160401b0386168086526001600160401b036020870197818160401c16895260801c16611bdc6040880192828452866001600160401b039180835f198201161819911816161590565b611e7e5750611be96114d8565b50611bf2611aec565b926001600160401b03851686811015611d5257908291611c1f85836001600160401b038c98975116612a04565b611c346001600160401b0386511680986127df565b9681811115611d06575084516001600160401b0316611c516103e0565b91825260208201526001600160401b03861660408201529761089c996001600160401b0398611ca3611cd2988b97611c9d611cca97611c97611c978c809a5b5116611323565b926104c3565b916115fe565b82891687525b5f526002602052818060405f2097511616821987541617865551168461095f565b5116906116b1565b165f5260026020526001600160401b036040805f20928280825116168319855416178455610eba836020830151168561095f565b90611d0f6103e0565b91825260208201526001600160401b03861660408201529761089c996001600160401b0398611ca3611cd2988b97611c9d611cca97611c97611c978c809a611c90565b9094959693889293611d726001600160401b0361089c9b511680996127df565b966001600160401b0388815f19820116191616988481115f14611e045750936001600160401b039899611cd29796948a85611db48299968397611cca996115fe565b81855116611dc06103e0565b93845260208401521660408201529a600160401b600160801b035f5491858360401c161860401b1690600160401b600160801b031916175f555b8289168252611ca9565b6001600160401b03809a8197935081945094611e5d611cca96600189600160401b600160801b03611e3a611cd29f9e9c986128b1565b92919490955f5493181860401b16906001600160801b03191617175f55836115fe565b8184511692611e6a6103e0565b938452602084015216604082015299611dfa565b8397506001600160401b039495508298969390611e9c939250612a04565b5116611ea66114d8565b505b6001600160401b0381165f52600260205260405f2090611ec66103e0565b9154916001600160401b03831681526001600160401b03806020830194818160401c16865260801c1691826040820152611f0289898395612a04565b511692611f2484866001600160401b039180835f198201161819911816161590565b15611f3157505050611ea8565b516001600160401b0390811693509091908484185f19850182168518191616611f5b575050611ea8565b61089c9593925095909395611f6e6114d8565b506001600160401b03611f7f611aec565b9116916001600160401b03841683811015612040578692611cd29492611c9d611ff593611fb96001600160401b03809b9c5116809a6127df565b9881811115612021575089875116611fcf6103e0565b91825260208201528984166040820152995b611c97611c978b8951168c8c168a52611323565b5f526002602052836040805f20928280825116168319855416178455610eba836020830151168561095f565b9061202a6103e0565b9182526020820152898416604082015299611fe1565b8692611cd29492611c9d6001600160401b0398611c97611c978b9a611ff59760206120739f019e8f9d8e511680936127df565b9c818311156120ab578e919250511661208a6103e0565b91825260208201528c871660408201529c5b8c815116908d8d169052611323565b506120b46103e0565b91825260208201528c871660408201529c61209c565b906001600160401b036001600160801b039195949516805f5260016020526001600160401b038261213860405f20826108c58161212b604061210a6103e0565b955495898716815260208101968481841c16885260c01c9182910152611428565b999094511698168861077e565b169316116121ef57806001600160801b0386168381106121b6575b6001600160801b038516848382109384612183575b505050505f1461217a57505091905f90565b93509160019150565b61219861219d926001600160801b039461077e565b610791565b169081106121ae575b808484612168565b95505f6121a6565b906121cd846121986001600160801b03938561077e565b166001600160801b03851681106121e7575b508190612153565b9350816121df565b50505090505f905f905f90565b5f546001600160401b038160401c1660018114612398576001600160401b036001815f19828518011683181819918180808516196001603f1b677fffffffffffffff8760011c161716168092189385161618165f5260026020526001600160401b0360405f2061228f8261226e6103e0565b92548181168452818160401c16602085015260801c1680604084015261162b565b51169081600161229d6114d8565b505b600180831603612335576001600160401b0390600192835f54928618189183600160401b600160801b038460401b169216906001600160801b03191617175f5516146123305761089c926001600160401b0360018193825f19838318011618181981808216196001603f1b677fffffffffffffff8460011c1617161692161618165f52600260205260405f2061095f565b505050565b6001600160401b0382165f5260026020526001600160401b0360405f209261238961235e6103e0565b945494838616815283808760401c169687602084015260801c16908160408201525061188086611323565b5f19810182161916161861229f565b506001600160801b0319165f55565b9392936001600160401b03821691825f52600260205260405f20926123ca6103e0565b9354926001600160401b038416928386526001600160401b036020870195818160401c16875260801c1660408701948186526001600160401b038416146124c757505084516001600160401b03908116908282185f198301821683181916166124bb5786612439928a92612a3e565b9590978861244b575b50505050505050565b61245f916001600160401b0385511661278c565b6001600160401b0380855116951680950361247c575b8080612442565b6001600160401b038093611cca926124b19787525f526002602052818060405f2097511616821987541617865551168461095f565b5f80808080612475565b505f9750505050505050565b9497985095505050506124da915061162b565b6001600160401b0381815f198201161916165f54908160401c91600160401b600160801b03826001600160401b0385161860401b1690600160401b600160801b031916175f556001600160401b035f19820116181916916001600160401b038316908115612582576001600160401b0380808061257d978180975f1901161916161692511693815f19840116831819161618165f52600260205260405f2061095f565b600190565b50505050600190565b90916001600160401b03612613936125a1611685565b501690815f52600160205260405f20906125b96103e0565b9154906001600160401b038216835260208301916001600160801b038160401c16835260c01c926001600160401b036001600160801b036126006040840196808852611428565b9990826108c581808a51169d168d61077e565b169616851061274a576001600160801b0382169384881161265f5750505050505061263c610413565b91825260208201525f60408201525f60608201525f60808201525f60a082015290565b9461270887938961270361270e956001600160401b036001600160801b039b879f9e6126958d9f918f9d9e8e936121989161077e565b169b8c988c8881845116031682525f526001602052828060405f2095511616831985541617845551600160401b600160c01b0384549160401b1690600160401b600160c01b03191617835551168154906001600160401b0360c01b9060c01b169060018060c01b0316179055565b61075e565b9261075e565b92612717610413565b9586526020860152166040840152166060820152826080820152600160a0820152916001600160401b03195f5416175f55565b50505050929190612759610413565b915f83525f602084015260408301526060820152826080820152600160a0820152916001600160401b03195f5416175f55565b6127c66001600160401b036001600160801b03921693845f5260036020526127c060405f2054948486169560801c9561075e565b9361075e565b81199060801b16911618905f52600360205260405f2055565b6001600160401b0391829067ffffffffffffffff19905f1981018316198116831618831860011867ffffffff0000000081161561289e575b8160101c838282161615612896575b508160081c83828216161561288e575b508160041c838282161615612886575b508160021c83828216161561287e575b50828260011c9182161615612876575b5080198160011c16921616181690565b90505f612866565b91505f612856565b91505f612846565b91505f612836565b91505f612826565b640100000000600160e01b039150612817565b6001600160801b035f54926001600160401b038460401c169283906001600160401b03861691825f5260016020526001600160401b0360018661293160405f20826108c58161292460406129036103e0565b9554958a8716815260208101968481841c16885260c01c9182910152611428565b9d909451169c168c61077e565b16971892169283146129f1576129b2611a2c6129ac6001600160401b03600187955f9b9a9b505f198801181819955b818760011c881916809218978d1616181698895f5260026020526001600160401b0360405f205460801c169061299582611428565b9490926129a283856104c3565b611c9d8d886104c3565b966104c3565b95146129df579293925f1981018118199082906129b290611a2c906129ac906001600160401b0390612960565b90506001600160401b03919294501690565b50929450506001600160401b0390911690565b6127c66001600160401b036001600160801b03921693845f526003602052612a3860405f2054948486169560801c956104c3565b936104c3565b9190612a5e61173d846001600160401b03165f52600260205260405f2090565b936001600160401b03612a7886516001600160401b031690565b83821691168103612abd575050505050602081612aaa612aa56040612ab89501516001600160401b031690565b61162b565b01516001600160401b031690565b600191565b612ae4612ad86020889697999801516001600160401b031690565b6001600160401b031690565b14612c715783612b19612afe85516001600160401b031690565b846001600160401b039180835f198201161819911816161590565b15612bc15790612b3b918193612b3686516001600160401b031690565b612a3e565b939015612bb55790612b6091612b5b60408501516001600160401b031690565b61278c565b80516001600160401b03838116911603612b7d575b505060019190565b612b93612bae9282906001600160401b03169052565b6119ca846001600160401b03165f52600260205260405f2090565b5f80612b75565b5050505090505f905f90565b506020830191612bd883516001600160401b031690565b612bf781836001600160401b039180835f198201161819911816161590565b156111c85785612c08928492612a3e565b949015612c645790612c2891612b5b60408601516001600160401b031690565b81516001600160401b03848116911603612c46575b50505060019190565b612c5c92612b9391906001600160401b03169052565b5f8080612c3d565b505050505090505f905f90565b50509050612ab8919250612c92612aa560408301516001600160401b031690565b516001600160401b03169056fea26469706673582212208cfcacc5e1a529ebf0fcdf9254e84504f7511e5db7c567bdad1b03249b26671764736f6c634300081c00330000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a90
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c9081630d1cf14614610363575080632e2866831461033e5780635e9dd46a146102875780638f94fa521461022d578063a558898f146101d3578063b23264221461015b578063c4dca4221461013a578063e146af47146101085763fa1e9ec81461007f575f80fd5b3461010457604036600319011261010457610098610388565b6100a061039e565b7f0000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a906001600160a01b031633036100f5576100d9916111f8565b604080516001600160801b039384168152919092166020820152f35b631dd2188d60e31b5f5260045ffd5b5f80fd5b34610104576060366003190112610104576100d9610124610388565b61012c6103b4565b6101346103ca565b91610fd4565b34610104576020366003190112610104576100d9610156610388565b610f1e565b3461010457608036600319011261010457610174610388565b61017c61039e565b6101846103ca565b606435916001600160801b0383168303610104577f0000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a906001600160a01b031633036100f5576101d193610d08565b005b34610104576040366003190112610104576101ec610388565b6101f46103b4565b7f0000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a906001600160a01b031633036100f5576100d991610985565b3461010457604036600319011261010457610246610388565b61024e61039e565b7f0000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a906001600160a01b031633036100f5576100d9916107af565b346101045760203660031901126101045760043562ffffff81168103610104576102b0906104f7565b90604051918291604083016040845281518091526020606085019201905f5b818110610320575050508281036020840152602080835192838152019201905f5b8181106102fe575050500390f35b82516001600160801b03168452859450602093840193909201916001016102f0565b825162ffffff168452869550602093840193909201916001016102cf565b34610104575f3660031901126101045760206001600160401b035f5416604051908152f35b34610104575f366003190112610104576020906001600160401b035f5460401c168152f35b600435906001600160401b038216820361010457565b602435906001600160401b038216820361010457565b602435906001600160801b038216820361010457565b604435906001600160801b038216820361010457565b60405190606082018281106001600160401b038211176103ff57604052565b634e487b7160e01b5f52604160045260245ffd5b6040519060c082018281106001600160401b038211176103ff57604052565b6040519190601f01601f191682016001600160401b038111838210176103ff57604052565b6001600160401b0381116103ff5760051b60200190565b9061048061047b83610457565b610432565b8281528092610491601f1991610457565b0190602036910137565b80518210156104af5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b906001600160801b03809116911601906001600160801b0382116104e357565b634e487b7160e01b5f52601160045260245ffd5b5f54916001600160401b0383169182158015610751575b6107245762ffffff16906105218261046e565b9061052b8361046e565b908251156104af576020839694960162ffffff8560281c16905260016001600160401b035f969560401c1618935b64ffffffffff8116156106ee5762ffffff8160281c1662ffffff871662ffffff610583828861049b565b511682036106a3575b50506105dc85826105a46001600160401b0394611323565b506001600160801b036105d36105cc62ffffff8d1693836105c5868d61049b565b51166104c3565b928961049b565b911690526113c7565b91169485156106045718935f5260026020526001600160401b0360405f205416955b95610559565b505092509262ffffff600191959295160162ffffff81116104e35762ffffff1690811061062e5750565b90916106398261046e565b6106428361046e565b945f5b62ffffff8116858110156106995762ffffff9181836106666001948761049b565b5116610672828861049b565b526106916001600160801b03610688838a61049b565b5116918b61049b565b520116610645565b5050509150509190565b90965062ffffff81146104e3576001019562ffffff87168881146106e1576001600160401b03926105dc926106d989938961049b565b52925061058c565b5050509350935090509190565b936001600160401b03908186815f198201161916161894165f5260026020526001600160401b0360405f205460401c16956105fe565b5091505060209061073482610432565b5f81525f36813761074483610432565b925f8452505f3681379190565b5062ffffff81161561050e565b906001600160801b03809116911603906001600160801b0382116104e357565b818102929181159184041417156104e357565b811561079b570490565b634e487b7160e01b5f52601260045260245ffd5b90916001600160401b038216805f52600160205260405f206107cf6103e0565b9054946001600160401b03861690818352604060208401936001600160801b0389831c168552019660c01c87528115610925576001600160401b031603610916576001600160801b039051169361082f6001600160401b03825116611428565b9590946001600160401b035f541684115f146108df5750505f935b610854858261075e565b956001600160801b038716156108d6578591906001600160801b038316908161089e57505050506001600160401b039061089c925f5260016020525f6040812055511661162b565b565b61089c95506001600160401b03926001600160801b036108c58194826108cd95169061077e565b911690610791565b169251166115fe565b505f9550505050565b6108eb8196929661144f565b1591908215610904575b50501561084a575f945061084a565b61090e92506114f2565b155f806108f5565b635d652eb160e01b5f5260045ffd5b505f9550859450505050565b906001600160401b036109426103e0565b92548181168452818160401c16602085015260801c166040830152565b90600160401b600160801b0382549160401b1690600160401b600160801b031916179055565b916001600160401b035f541691826001600160401b03851611610cff57825f52600160205260405f20936109b76103e0565b94546001600160401b038116865260208601906001600160801b038160401c16825260c01c956109ed6040820197808952611428565b9790916001600160801b03845116916001600160801b03871694838610610c5a575050506001600160801b0391826108c58382610a2c959c169061077e565b16610a456001600160401b035f5460401c1680976113c7565b906001915b6001600160401b038216928315610c4c5718915f52600260205260405f20986001600160401b03610a796103e0565b9a548181168c52818160401c1660208d015260801c16998a6040820152610a9f8b611428565b9290916001600160401b03610ac7818351166001600160401b0381815f198201161916161890565b166001600160401b0360018b1816111580610c30575b15610b125750610aff8b93610af9610b0a9694610b05946104c3565b976104c3565b9b61162b565b6113c7565b929892610a4a565b610b6991959c506001600160401b03935060809250610b4284610b54925116610b3b888d61075e565b908b611708565b956001600160801b03875116906104c3565b956001600160801b03602087015116906104c3565b9a8260a086015116189301511680610b86575087610b0a916113c7565b9450610ba09298979195506001600160401b0393506113c7565b50169081610c15575b50505b6001600160401b038116610bbd5750565b600160401b600160801b035f54916001600160401b038360401c161860401b16906001600160401b0382600160401b600160801b0319831617805f5560401c1615610c06575050565b6001600160801b031916175f55565b610c29915f52600260205260405f2061095f565b5f80610ba9565b506001600160801b03610c4383856104c3565b16881015610add565b965050505094505050610bac565b9250926001600160801b03919550610c8890826108c56001600160401b039782610cfb9b9c9d9e169061077e565b16976001600160801b038781845116031682525f526001602052828060405f2095511616831985541617845551600160401b600160c01b0384549160401b1690600160401b600160c01b03191617835551168154906001600160401b0360c01b9060c01b169060018060c01b0316179055565b9190565b505f9250829150565b92919092610d9f610d17611aec565b91610d238585856115fe565b6001600160401b03610d336103e0565b911681526001600160801b03841660208083019182526001600160401b0394851660408085019182528987165f8181526001909452928190209451935191516001600160c01b031960c09190911b1693909616600160401b600160c01b039190961b1694909417179055565b5f546001600160401b038160401c1615610f015750610dbd8461144f565b90919015610dcf575061089c93611b6d565b909291610ddf8461089c966127df565b92610de86114d8565b506001600160401b0384815f1982011619161694610e04611aec565b916001600160401b038216938585105f14610ec3575050946001600160401b0394939285600193610e37610e3f996128b1565b9a91836115fe565b610e476103e0565b9283528560208401521660408201529518189083195f5416175f555b600160401b600160801b035f549160401b1690600160401b600160801b031916175f55165f5260026020526001600160401b036040805f20928280825116168319855416178455610eba836020830151168561095f565b015116906116b1565b8392506001600160401b0396959491610edd9188956115fe565b610ee56103e0565b938452602084015216604082015292825f5460401c1618610e63565b6001600160801b0319161768010000000000000000175f55505050565b906040916001600160401b03811690815f526001602052835f20610f406103e0565b9054906001600160401b038216908181526001600160801b0383881c169283602083015260c01c968791015215610fc957610f7b9094611428565b5080926001600160401b035f541610610fc05750610f988161144f565b15610fb65790610fa7916114f2565b15610fb0579190565b91505f90565b5050909150905f90565b93505f92915050565b50505090505f905f90565b9291925f5f915f54956001600160401b038716806001600160401b0384161180156111e7575b80156111d6575b6111c857949660401c6001600160401b031660011893925b6001868116036110b2579461105a8661104b61103961105498998c61075e565b611043888761075e565b9085886120ca565b989190926104c3565b956104c3565b94156110a857611072866001600160401b03926113c7565b911695861561109d5718945f5260026020526001600160401b0360405f205416965b96949392611019565b505050509350919050565b5050509350919050565b92936001600160401b03861695865f5260026020526110e06001600160401b0360405f205460801c16611428565b90885f5260026020526001600160401b036111118160405f2054166001600160401b0381815f198201161916161890565b166001600160401b0360018818161180156111aa575b801561118c575b156111675750506001600160401b0390815f1982011619161618945f5260026020526001600160401b0360405f205460401c1696611094565b8398506001600160401b039391610af961118692611072959a996104c3565b966113c7565b50611197888661075e565b6001600160801b0380841691161061112e565b506111b5878c61075e565b6001600160801b03808316911610611127565b50505050505090505f905f90565b506001600160801b03821615611001565b506001600160801b03861615610ffa565b9190916001600160401b03811692835f52600160205260405f209161121b6103e0565b9254916001600160401b0383169384815260208101946001600160801b038560401c168652604082019460c01c855215611314576001600160401b0380915116911603610916576112756001600160401b03835116611428565b956112bd6001600160401b036001600160801b036112a661129d8280889b51169c168c61077e565b82871690610791565b1695835f5260016020525f6040812055511661162b565b6001600160401b035f5416918282116113085750146112fe576112df8161144f565b919091156112f357610fa7929186916123a7565b505050909150905f90565b5050610cfb6121fc565b96505f95945050505050565b63f37b890d60e01b5f5260045ffd5b60018082161461135a576001600160401b03165f5260026020526113566001600160401b0360405f205460801c16611428565b9091565b906001600160401b036001600160801b0392165f526001602052816113c360405f20826108c5816113b6604061138e6103e0565b9554956001600160401b038716815260208101968481841c16885260c01c9182910152611428565b989094511697168761077e565b1690565b91906001600160401b0390815f1985011684181916168015611420576001600160401b035f198201161819916001600160401b0380808516196001603f1b677fffffffffffffff8760011c161716169384921616189190565b505f91508190565b6001600160401b03165f52600360205260405f2054906001600160801b0382169160801c90565b905f546001600160401b038160401c166001600160401b038216600119915b6001600160401b03838784181616156114b957821691821561149857505f1982018218199161146e565b6001600160401b0394955084925080915060011c8119169216161816905f90565b50509081166001600160401b039081168219600193841c161816925090565b6114e06103e0565b905f82525f60208301525f6040830152565b90916001600160401b03831691826001600160401b038216146115f5576001600160401b03906115206114d8565b505b165f52600260205260405f206115366103e0565b9054906001600160401b038216908181526001600160401b03808460401c169384602084015260801c1660408201525083811480156115ec575b6115e25761159381866001600160401b039180835f198201161819911816161590565b156115a7576001600160401b039150611522565b506115c781856001600160401b039180835f198201161819911816161590565b156115da576001600160401b0390611522565b509150505f90565b5050915050600190565b50838214611570565b50915050600190565b91906001600160801b036001600160401b039281199060801b1691161891165f52600360205260405f2055565b5f5460c01c6001600160401b0382169081811461167657600160801b18905f52600360205260405f20555f54906001600160401b0360c01b9060c01b169060018060c01b0316175f55565b637fa3fb5160e01b5f5260045ffd5b61168d610413565b905f82525f60208301525f60408301525f60608301525f60808301525f60a0830152565b805467ffffffffffffffff60801b191660809290921b67ffffffffffffffff60801b16919091179055565b6001600160401b03604061089c938280825116168319855416178455610eba836020830151168561095f565b90929192611714611685565b50600180821614611ae15761174261173d826001600160401b03165f52600260205260405f2090565b610931565b9061175760408301516001600160401b031690565b61176081611428565b9490936001600160401b0361179561177f83516001600160401b031690565b6001600160401b0381815f198201161916161890565b166001600160401b036001841816118015611ac6575b15611a7257602081016117cf896117c983516001600160401b031690565b85611708565b6117eb90996117e58b516001600160801b031690565b9061075e565b60808a01936001600160401b0361180986516001600160401b031690565b16156119d75750506119869493611976938a936119669361188661185161183f6119969d9e9f604001516001600160801b031690565b88516001600160801b03165b906104c3565b9461186660608901516001600160801b031690565b9561188060208a019761184b89516001600160801b031690565b9161278c565b6118a861189a82516001600160401b031690565b93516001600160401b031690565b926001600160401b03808516911603611999575b5050506119566119036118d685516001600160801b031690565b9a6117e56118f58d6118ef87516001600160801b031690565b9c61075e565b94516001600160801b031690565b9361192a60a06001600160401b0389815f198201161916169201516001600160401b031690565b1897611946611937610413565b6001600160801b03909c168c52565b6001600160801b031660208b0152565b6001600160801b03166040890152565b6001600160801b03166060870152565b6001600160401b03166080850152565b6001600160401b031660a0830152565b90565b6119cf926119af91906001600160401b03169052565b6119ca876001600160401b03165f52600260205260405f2090565b6116dc565b5f80806118bc565b955095505090506119fb94506119f59150516001600160401b031690565b90611708565b611a4c602061089c9294611a3e611a31611a1c83516001600160801b031690565b88516001600160801b03166104c3565b6104c3565b6001600160801b03168752565b01516001600160801b031690565b611a656020850191611a2c83516001600160801b031690565b6001600160801b03169052565b5050945050611aa861089c92611a98611a89610413565b6001600160801b039094168452565b6001600160801b03166020830152565b5f60408201525f60608201525f60808201525f60a08201529261162b565b506001600160801b0385166001600160801b038916106117ab565b61199692939161258b565b5f548060c01c15611b2a57505f54908160c01c91825f5260036020526001600160401b0360c01b60405f205460c01b169060018060c01b0316175f55565b6001600160401b038160801c166001600160401b0381146104e357600101906001600160401b0360801b8260801b16906001600160401b0360801b1916175f5590565b906001600160401b031690815f52600260205260405f2092611b8d6103e0565b9354946001600160401b0386168086526001600160401b036020870197818160401c16895260801c16611bdc6040880192828452866001600160401b039180835f198201161819911816161590565b611e7e5750611be96114d8565b50611bf2611aec565b926001600160401b03851686811015611d5257908291611c1f85836001600160401b038c98975116612a04565b611c346001600160401b0386511680986127df565b9681811115611d06575084516001600160401b0316611c516103e0565b91825260208201526001600160401b03861660408201529761089c996001600160401b0398611ca3611cd2988b97611c9d611cca97611c97611c978c809a5b5116611323565b926104c3565b916115fe565b82891687525b5f526002602052818060405f2097511616821987541617865551168461095f565b5116906116b1565b165f5260026020526001600160401b036040805f20928280825116168319855416178455610eba836020830151168561095f565b90611d0f6103e0565b91825260208201526001600160401b03861660408201529761089c996001600160401b0398611ca3611cd2988b97611c9d611cca97611c97611c978c809a611c90565b9094959693889293611d726001600160401b0361089c9b511680996127df565b966001600160401b0388815f19820116191616988481115f14611e045750936001600160401b039899611cd29796948a85611db48299968397611cca996115fe565b81855116611dc06103e0565b93845260208401521660408201529a600160401b600160801b035f5491858360401c161860401b1690600160401b600160801b031916175f555b8289168252611ca9565b6001600160401b03809a8197935081945094611e5d611cca96600189600160401b600160801b03611e3a611cd29f9e9c986128b1565b92919490955f5493181860401b16906001600160801b03191617175f55836115fe565b8184511692611e6a6103e0565b938452602084015216604082015299611dfa565b8397506001600160401b039495508298969390611e9c939250612a04565b5116611ea66114d8565b505b6001600160401b0381165f52600260205260405f2090611ec66103e0565b9154916001600160401b03831681526001600160401b03806020830194818160401c16865260801c1691826040820152611f0289898395612a04565b511692611f2484866001600160401b039180835f198201161819911816161590565b15611f3157505050611ea8565b516001600160401b0390811693509091908484185f19850182168518191616611f5b575050611ea8565b61089c9593925095909395611f6e6114d8565b506001600160401b03611f7f611aec565b9116916001600160401b03841683811015612040578692611cd29492611c9d611ff593611fb96001600160401b03809b9c5116809a6127df565b9881811115612021575089875116611fcf6103e0565b91825260208201528984166040820152995b611c97611c978b8951168c8c168a52611323565b5f526002602052836040805f20928280825116168319855416178455610eba836020830151168561095f565b9061202a6103e0565b9182526020820152898416604082015299611fe1565b8692611cd29492611c9d6001600160401b0398611c97611c978b9a611ff59760206120739f019e8f9d8e511680936127df565b9c818311156120ab578e919250511661208a6103e0565b91825260208201528c871660408201529c5b8c815116908d8d169052611323565b506120b46103e0565b91825260208201528c871660408201529c61209c565b906001600160401b036001600160801b039195949516805f5260016020526001600160401b038261213860405f20826108c58161212b604061210a6103e0565b955495898716815260208101968481841c16885260c01c9182910152611428565b999094511698168861077e565b169316116121ef57806001600160801b0386168381106121b6575b6001600160801b038516848382109384612183575b505050505f1461217a57505091905f90565b93509160019150565b61219861219d926001600160801b039461077e565b610791565b169081106121ae575b808484612168565b95505f6121a6565b906121cd846121986001600160801b03938561077e565b166001600160801b03851681106121e7575b508190612153565b9350816121df565b50505090505f905f905f90565b5f546001600160401b038160401c1660018114612398576001600160401b036001815f19828518011683181819918180808516196001603f1b677fffffffffffffff8760011c161716168092189385161618165f5260026020526001600160401b0360405f2061228f8261226e6103e0565b92548181168452818160401c16602085015260801c1680604084015261162b565b51169081600161229d6114d8565b505b600180831603612335576001600160401b0390600192835f54928618189183600160401b600160801b038460401b169216906001600160801b03191617175f5516146123305761089c926001600160401b0360018193825f19838318011618181981808216196001603f1b677fffffffffffffff8460011c1617161692161618165f52600260205260405f2061095f565b505050565b6001600160401b0382165f5260026020526001600160401b0360405f209261238961235e6103e0565b945494838616815283808760401c169687602084015260801c16908160408201525061188086611323565b5f19810182161916161861229f565b506001600160801b0319165f55565b9392936001600160401b03821691825f52600260205260405f20926123ca6103e0565b9354926001600160401b038416928386526001600160401b036020870195818160401c16875260801c1660408701948186526001600160401b038416146124c757505084516001600160401b03908116908282185f198301821683181916166124bb5786612439928a92612a3e565b9590978861244b575b50505050505050565b61245f916001600160401b0385511661278c565b6001600160401b0380855116951680950361247c575b8080612442565b6001600160401b038093611cca926124b19787525f526002602052818060405f2097511616821987541617865551168461095f565b5f80808080612475565b505f9750505050505050565b9497985095505050506124da915061162b565b6001600160401b0381815f198201161916165f54908160401c91600160401b600160801b03826001600160401b0385161860401b1690600160401b600160801b031916175f556001600160401b035f19820116181916916001600160401b038316908115612582576001600160401b0380808061257d978180975f1901161916161692511693815f19840116831819161618165f52600260205260405f2061095f565b600190565b50505050600190565b90916001600160401b03612613936125a1611685565b501690815f52600160205260405f20906125b96103e0565b9154906001600160401b038216835260208301916001600160801b038160401c16835260c01c926001600160401b036001600160801b036126006040840196808852611428565b9990826108c581808a51169d168d61077e565b169616851061274a576001600160801b0382169384881161265f5750505050505061263c610413565b91825260208201525f60408201525f60608201525f60808201525f60a082015290565b9461270887938961270361270e956001600160401b036001600160801b039b879f9e6126958d9f918f9d9e8e936121989161077e565b169b8c988c8881845116031682525f526001602052828060405f2095511616831985541617845551600160401b600160c01b0384549160401b1690600160401b600160c01b03191617835551168154906001600160401b0360c01b9060c01b169060018060c01b0316179055565b61075e565b9261075e565b92612717610413565b9586526020860152166040840152166060820152826080820152600160a0820152916001600160401b03195f5416175f55565b50505050929190612759610413565b915f83525f602084015260408301526060820152826080820152600160a0820152916001600160401b03195f5416175f55565b6127c66001600160401b036001600160801b03921693845f5260036020526127c060405f2054948486169560801c9561075e565b9361075e565b81199060801b16911618905f52600360205260405f2055565b6001600160401b0391829067ffffffffffffffff19905f1981018316198116831618831860011867ffffffff0000000081161561289e575b8160101c838282161615612896575b508160081c83828216161561288e575b508160041c838282161615612886575b508160021c83828216161561287e575b50828260011c9182161615612876575b5080198160011c16921616181690565b90505f612866565b91505f612856565b91505f612846565b91505f612836565b91505f612826565b640100000000600160e01b039150612817565b6001600160801b035f54926001600160401b038460401c169283906001600160401b03861691825f5260016020526001600160401b0360018661293160405f20826108c58161292460406129036103e0565b9554958a8716815260208101968481841c16885260c01c9182910152611428565b9d909451169c168c61077e565b16971892169283146129f1576129b2611a2c6129ac6001600160401b03600187955f9b9a9b505f198801181819955b818760011c881916809218978d1616181698895f5260026020526001600160401b0360405f205460801c169061299582611428565b9490926129a283856104c3565b611c9d8d886104c3565b966104c3565b95146129df579293925f1981018118199082906129b290611a2c906129ac906001600160401b0390612960565b90506001600160401b03919294501690565b50929450506001600160401b0390911690565b6127c66001600160401b036001600160801b03921693845f526003602052612a3860405f2054948486169560801c956104c3565b936104c3565b9190612a5e61173d846001600160401b03165f52600260205260405f2090565b936001600160401b03612a7886516001600160401b031690565b83821691168103612abd575050505050602081612aaa612aa56040612ab89501516001600160401b031690565b61162b565b01516001600160401b031690565b600191565b612ae4612ad86020889697999801516001600160401b031690565b6001600160401b031690565b14612c715783612b19612afe85516001600160401b031690565b846001600160401b039180835f198201161819911816161590565b15612bc15790612b3b918193612b3686516001600160401b031690565b612a3e565b939015612bb55790612b6091612b5b60408501516001600160401b031690565b61278c565b80516001600160401b03838116911603612b7d575b505060019190565b612b93612bae9282906001600160401b03169052565b6119ca846001600160401b03165f52600260205260405f2090565b5f80612b75565b5050505090505f905f90565b506020830191612bd883516001600160401b031690565b612bf781836001600160401b039180835f198201161819911816161590565b156111c85785612c08928492612a3e565b949015612c645790612c2891612b5b60408601516001600160401b031690565b81516001600160401b03848116911603612c46575b50505060019190565b612c5c92612b9391906001600160401b03169052565b5f8080612c3d565b505050505090505f905f90565b50509050612ab8919250612c92612aa560408301516001600160401b031690565b516001600160401b03169056fea26469706673582212208cfcacc5e1a529ebf0fcdf9254e84504f7511e5db7c567bdad1b03249b26671764736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a90
-----Decoded View---------------
Arg [0] : _lob_address (address): 0x5e0C6FAa00667A6A155e0d3548344cAF03226A90
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000005e0c6faa00667a6a155e0d3548344caf03226a90
Deployed Bytecode Sourcemap
735:56436:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;735:56436:2;;;;;;:::i;:::-;;;:::i;:::-;1681:11;-1:-1:-1;;;;;735:56436:2;1667:10;:25;735:56436;;4074:1515;;;:::i;:::-;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;735:56436:2;;;;;;;:::i;:::-;;;:::i;:::-;;;:::i;:::-;;;:::i;:::-;;;;;;-1:-1:-1;;735:56436:2;;;;;;;:::i;:::-;;:::i;:::-;;;;;;-1:-1:-1;;735:56436:2;;;;;;:::i;:::-;;;:::i;:::-;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;1681:11;-1:-1:-1;;;;;735:56436:2;1667:10;:25;735:56436;;1723:1;;;:::i;:::-;735:56436;;;;;;;-1:-1:-1;;735:56436:2;;;;;;:::i;:::-;;;:::i;:::-;1681:11;-1:-1:-1;;;;;735:56436:2;1667:10;:25;735:56436;;9382:4731;;;:::i;735:56436::-;;;;;;-1:-1:-1;;735:56436:2;;;;;;:::i;:::-;;;:::i;:::-;1681:11;-1:-1:-1;;;;;735:56436:2;1667:10;:25;735:56436;;6181:1568;;;:::i;735:56436::-;;;;;;-1:-1:-1;;735:56436:2;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;;;;;;-1:-1:-1;;735:56436:2;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;-1:-1:-1;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;:::o;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;:::o;:::-;;;;-1:-1:-1;735:56436:2;;;;;-1:-1:-1;735:56436:2;;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;735:56436:2;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;:::o;:::-;-1:-1:-1;;;;;735:56436:2;;;;;;;;;:::o;:::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;:::o;:::-;;;;;;;;;;;;17185:2659;17378:10;735:56436;;-1:-1:-1;;;;;735:56436:2;;17402:23;;;:48;;;;17185:2659;17398:209;;735:56436;;17635:30;;;;:::i;:::-;17690:31;;;;:::i;:::-;17732:51;735:56436;;;;;;;;;;;;;17780:2;735:56436;;;;17881:3;-1:-1:-1;;;;;17378:10:2;17827:33;735:56436;;;;17912:19;18118:1116;;735:56436;18150:26;;18149:35;735:56436;;;;17780:2;735:56436;;;;;;18276:28;;;;:::i;:::-;735:56436;;18265:39;;18261:304;;18145:1079;18626:34;;18753:42;18626:34;;;-1:-1:-1;;;;;18626:34:2;;:::i;:::-;735:56436;-1:-1:-1;;;;;18678:41:2;;735:56436;;;18678:41;;;;;;:::i;:::-;735:56436;;18678:41;:::i;:::-;;;;:::i;:::-;735:56436;;;;18753:42;:::i;:::-;735:56436;;18817:14;;;18813:66;;18896:13;735:56436;17378:10;735:56436;18938:5;735:56436;;-1:-1:-1;;;;;735:56436:2;17378:10;735:56436;;;18145:1079;;18118:1116;;;18813:66;18855:5;;;;;735:56436;17881:3;18855:5;;;;735:56436;;;;;;;;;19296:32;;;19292:546;;17185:2659;:::o;19292:546::-;19454:27;;;;;:::i;:::-;19535:28;;;:::i;:::-;19582:12;17378:10;19615:3;735:56436;;;19596:17;;;;;;735:56436;19667:18;;;;17881:3;19667:18;;;:::i;:::-;735:56436;;19638:47;;;;:::i;:::-;735:56436;19703:41;-1:-1:-1;;;;;19729:15:2;;;;:::i;:::-;735:56436;;19703:41;;;:::i;:::-;735:56436;;;19582:12;;19596:17;;;;;;;19773:54;;:::o;18261:304::-;735:56436;;;;;;;;17881:3;735:56436;;;;;18367:31;;;18363:124;;-1:-1:-1;;;;;18508:38:2;18753:42;18508:38;;;;;;:::i;:::-;735:56436;18261:304;;;;18363:124;18426:38;;;;;;;;;;;:::o;18145:1079::-;735:56436;-1:-1:-1;;;;;735:56436:2;;;;;;;;;19088:14;:24;;19148:13;735:56436;;17378:10;735:56436;19189:5;735:56436;;-1:-1:-1;;;;;735:56436:2;17378:10;735:56436;;;;;18145:1079;;;17398:209;735:56436;;;;;;;;;:::i;:::-;17378:10;735:56436;;17378:10;735:56436;;;;;;:::i;:::-;;17378:10;735:56436;;;17378:10;735:56436;;;17558:38;;:::o;17402:48::-;735:56436;;;;17429:21;17402:48;;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;:::o;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;:::o;:::-;;;;;;;;;;;;6181:1568;;;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;735:56436:2;6372:6;735:56436;;;-1:-1:-1;735:56436:2;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;6403:21;;6399:65;;-1:-1:-1;;;;;735:56436:2;6587:33;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;6743:55;-1:-1:-1;;;;;735:56436:2;;;6743:55;:::i;:::-;735:56436;;;-1:-1:-1;;;;;;735:56436:2;;6859:27;;6855:289;735:56436;;;6902:17;;-1:-1:-1;6855:289:2;;7172:28;;;;:::i;:::-;735:56436;-1:-1:-1;;;;;735:56436:2;;7214:20;7210:76;;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;7300:18;735:56436;;;;;;-1:-1:-1;;;;;735:56436:2;7382:29;735:56436;-1:-1:-1;735:56436:2;6372:6;735:56436;;-1:-1:-1;735:56436:2;;;;;;7382:29;:::i;:::-;6181:1568::o;7296:447::-;7706:12;735:56436;;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;;;;;7491:45:2;735:56436;;;7491:69;735:56436;;7491:45;;:::i;:::-;735:56436;;7491:69;;:::i;:::-;735:56436;;;;7706:12;:::i;7210:76::-;-1:-1:-1;;;;;;;7250:25:2:o;6855:289::-;6983:35;;;;;;:::i;:::-;7037:8;;;735:56436;;7037:45;;6855:289;7033:101;;;6855:289;7033:101;-1:-1:-1;;;6855:289:2;;7037:45;7050:32;;;;:::i;:::-;7049:33;7037:45;;;;735:56436;;;;-1:-1:-1;735:56436:2;;-1:-1:-1;735:56436:2;6399:65;-1:-1:-1;;;;;;;;;;6440:13:2:o;735:56436::-;;-1:-1:-1;;;;;735:56436:2;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;:::o;9382:4731::-;;-1:-1:-1;;;;;9707:10:2;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;9803:27;9799:71;;735:56436;9707:10;735:56436;10302:6;735:56436;;;9707:10;735:56436;;;;:::i;:::-;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;10386:55;735:56436;;;;;;;10386:55;:::i;:::-;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;10508:34;;;;10504:526;;11085:31;;;-1:-1:-1;;;;;11085:31:2;;11151:47;11085:31;;11151:73;11085:31;735:56436;;11151:47;;:::i;:73::-;735:56436;11309:46;-1:-1:-1;;;;;9707:10:2;735:56436;;;;11309:46;;;:::i;:::-;11366:20;10302:6;11431:2457;;-1:-1:-1;;;;;735:56436:2;;11438:14;;;;;12140:12;735:56436;9707:10;735:56436;12185:5;735:56436;;;9707:10;735:56436;;-1:-1:-1;;;;;735:56436:2;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;12323:29;;;:::i;:::-;735:56436;;;-1:-1:-1;;;;;12386:25:2;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;40670:14;:24;;40721:11;40485:254;;12386:25;735:56436;-1:-1:-1;;;;;10302:6:2;12491:14;;735:56436;12490:29;;12489:265;;;11431:2457;12485:1326;;;12885:36;12939:34;12885:36;;;13840:37;12885:36;;42719:3;12885:36;;:::i;:::-;12939:34;;:::i;:::-;42719:3;;:::i;:::-;13840:37;:::i;:::-;11431:2457;;;;;12485:1326;13296:49;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;;13095:114;735:56436;13227:51;735:56436;;;13154:36;;;;:::i;:::-;13095:114;;;:::i;:::-;735:56436;-1:-1:-1;;;;;735:56436:2;;;13227:51;;:::i;:::-;13314:31;-1:-1:-1;;;;;735:56436:2;13314:31;;735:56436;;13296:49;;:::i;:::-;13375:24;;;;;735:56436;;13364:35;13421:28;;735:56436;;13421:35;13417:380;;12485:1326;;13840:37;12485:1326;13840:37;:::i;13417:380::-;13573:37;;;;;;;;;-1:-1:-1;;;;;13573:37:2;;;:::i;:::-;735:56436;;13636:14;;13632:120;;13417:380;13773:5;;11431:2457;-1:-1:-1;;;;;735:56436:2;;13899:208;;9382:4731;:::o;13899:208::-;-1:-1:-1;;;;;;;9707:10:2;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;13984:24;735:56436;;;;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;;;;;;;735:56436:2;;;;;9707:10;735:56436;;;;14026:20;14022:75;;13899:208;9382:4731;:::o;14022:75::-;-1:-1:-1;;;;;;735:56436:2;;9707:10;735:56436;9382:4731::o;13632:120::-;13678:51;735:56436;9707:10;735:56436;12185:5;735:56436;;;9707:10;735:56436;13678:51;:::i;:::-;13632:120;;;;12489:265;12717:35;-1:-1:-1;;;;;12717:35:2;;;;:::i;:::-;735:56436;12694:59;;;12489:265;;11438:14;;;;;;;;;;;;10504:526;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;10633:75;735:56436;;10633:49;-1:-1:-1;;;;;735:56436:2;;;;;;;;10633:49;;:::i;:75::-;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;9707:10;735:56436;10302:6;735:56436;;;;;9707:10;735:56436;;;;;;;;;;;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;10979:40;;:::o;9799:71::-;-1:-1:-1;9707:10:2;;-1:-1:-1;9707:10:2;;-1:-1:-1;9846:13:2:o;2307:1317::-;;;;;735:56436;2447:16;;:::i;:::-;2509:5;;;;;;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;:::i;:::-;;;;;-1:-1:-1;;;;;735:56436:2;;2553:128;;;;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;2553:128;;;;735:56436;;;;;;-1:-1:-1;735:56436:2;;;2534:6;735:56436;;;;;;;;;;;;;-1:-1:-1;;;;;;735:56436:2;;;;;;;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;;;;;;;;-1:-1:-1;735:56436:2;-1:-1:-1;;;;;735:56436:2;2553:128;735:56436;;2734:10;2730:160;;3099:35;;;;:::i;:::-;3144:474;;;;;;3270:5;;;;:::i;3144:474::-;25683:40;;;;;735:56436;25683:40;;:::i;:::-;25733:22;735:56436;;:::i;:::-;;-1:-1:-1;;;;;735:56436:2;;;;;;;25834:20;:36;;26021:16;;;:::i;:::-;26048:24;-1:-1:-1;;;;;735:56436:2;;26086:23;;;;26082:978;735:56436;;;26309:29;;;-1:-1:-1;;;;;26309:29:2;;;;2534:6;26309:29;;26405:17;26309:29;;:::i;:::-;26405:17;;;;:::i;:::-;735:56436;;:::i;:::-;;;;26450:140;2553:128;26450:140;;735:56436;;2553:128;26450:140;;735:56436;26605:39;;;735:56436;;;-1:-1:-1;735:56436:2;;;-1:-1:-1;735:56436:2;26082:978;-1:-1:-1;;;;;;;;735:56436:2;;2553:128;735:56436;;;-1:-1:-1;;;;;;;735:56436:2;;;-1:-1:-1;735:56436:2;;-1:-1:-1;735:56436:2;27113:5;2553:128;735:56436;-1:-1:-1;;;;;2553:128:2;735:56436;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;;;;;2553:128;735:56436;;;;;;:::i;:::-;;;;;;:::i;26082:978::-;26815:5;;;-1:-1:-1;;;;;26815:5:2;;;;;;;;;:::i;:::-;735:56436;;:::i;:::-;;;;2553:128;26848:139;;735:56436;;2553:128;26848:139;;735:56436;;;-1:-1:-1;735:56436:2;2553:128;735:56436;;27021:28;26082:978;;2730:160;-1:-1:-1;;;;;;735:56436:2;;;;-1:-1:-1;735:56436:2;-1:-1:-1;;;2873:7:2:o;8201:844::-;;735:56436;8201:844;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;735:56436:2;8344:6;735:56436;;;-1:-1:-1;735:56436:2;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;8375:21;8371:65;;8509:55;8446:34;8509:55;;:::i;:::-;8490:74;;735:56436;-1:-1:-1;;;;;;735:56436:2;;-1:-1:-1;8646:76:2;;8765:35;;;;:::i;:::-;8815:8;8811:64;;8889:32;;;;:::i;:::-;;;;8937:36;;:::o;8885:154::-;9004:24;-1:-1:-1;;;9004:24:2:o;8811:64::-;8840:24;;;;;;-1:-1:-1;8840:24:2;:::o;8646:76::-;8687:24;-1:-1:-1;;;8687:24:2;-1:-1:-1;;8687:24:2:o;8371:65::-;8412:13;;;;;-1:-1:-1;8412:13:2;-1:-1:-1;8412:13:2;:::o;14500:2336::-;;;;735:56436;;;;;;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;;;;;735:56436:2;;14724:27;:46;;;;14500:2336;14724:64;;;;14500:2336;14720:108;;14838:33;;735:56436;;-1:-1:-1;;;;;735:56436:2;14892:3;14923:19;;14838:33;15051:1779;14892:3;15083:13;;;15082:22;14892:3;;15325:28;15494:37;15325:28;15226:193;15325:28;15437:39;15325:28;;;;:::i;:::-;15375:26;;;;:::i;:::-;15226:193;;;;:::i;:::-;15437:39;;;;;:::i;:::-;15494:37;;:::i;:::-;15554:5;;15550:57;;16635:42;15078:1528;-1:-1:-1;;;;;15078:1528:2;16635:42;:::i;:::-;735:56436;;16695:14;;;16691:58;;16762:13;735:56436;;;16800:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;15051:1779;;;;;;;;16691:58;16729:5;;;;;;;;;14500:2336::o;15550:57::-;15583:5;;;;;;;;14500:2336::o;15078:1528::-;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;16800:5;735:56436;;15718:101;-1:-1:-1;;;;;735:56436:2;;;;;;;15718:101;:::i;:::-;735:56436;;;;16800:5;735:56436;;-1:-1:-1;;;;;15856:35:2;735:56436;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;40670:14;:24;;40721:11;40485:254;;15856:35;735:56436;-1:-1:-1;;;;;14892:3:2;15975:14;;735:56436;15974:28;15973:100;;;;15078:1528;15973:167;;;;15078:1528;15969:623;;;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;16252:14;:24;;16320:13;735:56436;;;16800:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;16408:8;;;15969:623;16493:30;;;-1:-1:-1;;;;;16493:30:2;;;16545:28;16493:30;16635:42;16493:30;;;;:::i;16545:28::-;15969:623;16635:42;:::i;15973:167::-;16099:26;;;;;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;;16098:41;15973:167;;:100;16029:28;;;;;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;;16028:44;15973:100;;14720:108;14804:13;;;;;;;;735:56436;14804:13;735:56436;14804:13;:::o;14724:64::-;735:56436;-1:-1:-1;;;;;735:56436:2;;14774:14;14724:64;;:46;735:56436;-1:-1:-1;;;;;735:56436:2;;14755:15;14724:46;;4074:1515;;;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;735:56436:2;4261:6;735:56436;;;-1:-1:-1;735:56436:2;;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;4296:21;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;4470:33;735:56436;;4595:55;-1:-1:-1;;;;;735:56436:2;;;4595:55;:::i;:::-;4565:85;4898:29;-1:-1:-1;;;;;;;;;;4736:69:2;:45;4565:85;;;735:56436;;;;;4736:45;;:::i;:::-;735:56436;;;4736:69;;:::i;:::-;735:56436;;;-1:-1:-1;735:56436:2;4261:6;735:56436;;-1:-1:-1;735:56436:2;;;;;;4898:29;:::i;:::-;-1:-1:-1;;;;;;735:56436:2;;4989:27;;;;4985:82;;5081:28;;5077:126;;5246:35;;;:::i;:::-;5296:8;;;;5292:63;;5378:68;;;;;;:::i;5292:63::-;5320:24;;;;;;;-1:-1:-1;5320:24:2;:::o;5077:126::-;;;;;:::i;4985:82::-;5032:24;-1:-1:-1;;;5032:24:2;-1:-1:-1;;;;;5032:24:2:o;735:56436::-;;;;-1:-1:-1;735:56436:2;;-1:-1:-1;735:56436:2;56498:671;56615:3;56605:13;;;56604:22;56600:456;;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;735:56436:2;57079:5;735:56436;;57133:29;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;735:56436:2;;;;;57133:29;:::i;:::-;57126:36;;56498:671::o;56600:456::-;735:56436;-1:-1:-1;;;;;;;;;;735:56436:2;;-1:-1:-1;735:56436:2;56615:3;735:56436;;;56921:73;735:56436;-1:-1:-1;735:56436:2;;56921:47;735:56436;56765:55;735:56436;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;;;;;56765:55;:::i;:::-;735:56436;;;;;;;56921:47;;:::i;:73::-;735:56436;57009:36;:::o;52422:549::-;;;-1:-1:-1;;;;;52422:549:2;735:56436;;;;;;52586:23;;52584:26;52667:11;;52702:10;;52698:54;;-1:-1:-1;;;;;735:56436:2;;;;;52794:15;52792:18;735:56436;-1:-1:-1;;;;;735:56436:2;;;;52907:5;-1:-1:-1;;;735:56436:2;;52607:1;735:56436;;52871:32;52870:42;;52941:14;;;;;52940:20;52932:32;52422:549;:::o;52698:54::-;-1:-1:-1;;;;;;52728:13:2:o;55017:145::-;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;735:56436:2;55144:5;735:56436;;;-1:-1:-1;735:56436:2;;55121:34;-1:-1:-1;;;;;53630:38:2;;735:56436;53696:3;735:56436;55017:145;:::o;20204:1323::-;;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;;20487:13;20510:1011;;-1:-1:-1;;;;;20543:27:2;;;;20542:36;;20541:45;20537:417;;20974:10;;21002;;;20998:397;;-1:-1:-1;;;735:56436:2;;21480:15;;21478:18;;20510:1011;;20998:397;-1:-1:-1;;;;;735:56436:2;;;;;;;;;20496:3;735:56436;21103:5;;:19;21304:23;;;21303:29;735:56436;21352:28;735:56436;21352:28;:::o;20537:417::-;-1:-1:-1;;20869:23:2;;;-1:-1:-1;;;;;20869:23:2;;;20680:5;;20496:3;735:56436;;;20680:19;20868:29;735:56436;;-1:-1:-1;20496:3:2;20917:22::o;735:56436::-;;;:::i;:::-;;;;;;;;;;;;;;;:::o;33009:628::-;;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;33118:19;33114:61;;-1:-1:-1;;;;;33184:16:2;735:56436;;:::i;:::-;33210:421;;735:56436;;;33244:5;735:56436;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;33276:21;;;;:47;;;;33210:421;33272:97;;33386:32;;;-1:-1:-1;;;;;42043:295:2;735:56436;;;;;;;42244:23;42242:26;42297:18;;42296:27;;42295:36;42043:295;;33386:32;735:56436;;;-1:-1:-1;;;;;33438:19:2;;33210:421;;33382:239;33482:33;;;;-1:-1:-1;;;;;42043:295:2;735:56436;;;;;;;42244:23;42242:26;42297:18;;42296:27;;42295:36;42043:295;;33482:33;735:56436;;;-1:-1:-1;;;;;33535:20:2;33210:421;;33478:143;33594:12;;;;735:56436;33594:12;:::o;33272:97::-;33343:11;;;;;33217:4;33343:11;:::o;33276:47::-;33301:22;;;;33276:47;;33114:61;33153:11;;;;33160:4;33153:11;:::o;54644:147::-;;;-1:-1:-1;;;;;;;;;;54644:147:2;735:56436;;;53293:3;735:56436;;;;53265:32;735:56436;;-1:-1:-1;735:56436:2;54738:5;735:56436;;;-1:-1:-1;735:56436:2;;54644:147::o;54178:219::-;54237:17;735:56436;;;-1:-1:-1;;;;;735:56436:2;;54237:24;;;;735:56436;;;;;53265:32;735:56436;54237:17;735:56436;54302:5;735:56436;;;54237:17;735:56436;;54237:17;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;54237:17;735:56436;54178:219::o;735:56436::-;;;;54237:17;735:56436;;54237:17;735:56436;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;;735:56436:2;;;;;;-1:-1:-1;;;735:56436:2;;;;;;;:::o;:::-;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;43180:2944::-;;;;;735:56436;;:::i;:::-;43348:13;43358:3;43348:13;;;43347:22;43343:139;;735:56436;43537:14;;-1:-1:-1;;;;;735:56436:2;;;43537:5;735:56436;;;;;;;43537:14;735:56436;:::i;:::-;43579:27;735:56436;43579:27;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;43660:34;;;:::i;:::-;735:56436;;;-1:-1:-1;;;;;43778:25:2;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;40670:14;:24;;40721:11;40485:254;;43778:25;735:56436;-1:-1:-1;;;;;43358:3:2;43867:14;;735:56436;43866:28;43865:67;;;;43180:2944;43861:2257;;;44022:10;;;43996:56;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;43996:56;;:::i;:::-;44066:59;43996:56;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;44066:59;;:::i;:::-;44144:34;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;;;;;735:56436:2;;;;;44144:41;735:56436;;44278:35;;44959:467;44278:35;;44959:467;44278:35;;;44959:467;44278:35;44376:74;44278:76;735:56436;44959:467;44278:35;;;43579:27;44278:35;735:56436;-1:-1:-1;;;;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;;44278:76;;:::i;:::-;44376:34;735:56436;44376:34;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;44413:37;44376:74;44022:10;44413:37;;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;44376:74;;;:::i;:::-;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;;;;44490:48;-1:-1:-1;;;;;735:56436:2;;;;;44490:48;44486:185;;44140:1596;735:56436;;;44959:467;45250:50;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;;;;45163:52;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;45163:52;;:::i;:::-;735:56436;;-1:-1:-1;;;;;735:56436:2;;;45250:50;735:56436;;45373:30;-1:-1:-1;;;;;735:56436:2;;;;;;;44751:14;:24;;45373:30;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;45373:34;735:56436;44959:467;735:56436;;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;;;44959:467;-1:-1:-1;;;;;735:56436:2;44022:10;44959:467;;735:56436;;44959:467;-1:-1:-1;;;;;735:56436:2;43579:27;44959:467;;735:56436;;44959:467;-1:-1:-1;;;;;735:56436:2;44376:34;44959:467;;735:56436;;44959:467;-1:-1:-1;;;;;735:56436:2;44144:34;44959:467;;735:56436;;44959:467;-1:-1:-1;;;;;735:56436:2;45373:30;44959:467;;735:56436;;44959:467;44140:1596;43180:2944::o;44486:185::-;735:56436;44562:47;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;44562:47;44631:14;;-1:-1:-1;;;;;735:56436:2;;;43537:5;735:56436;;;;;;;44631:14;735:56436;:::i;:::-;44486:185;;;;;44140:1596;735:56436;;;;;;;45484:55;735:56436;;;;;;-1:-1:-1;;;;;735:56436:2;;;;45484:55;;:::i;:::-;735:56436;44022:10;45649:72;45465:74;735:56436;45557:74;;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;45557:74;:::i;735:56436::-;45557:74;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;45557:74;45684:37;735:56436;-1:-1:-1;;;;;735:56436:2;;;;45649:72;44022:10;45649:31;;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;45649:72;-1:-1:-1;;;;;735:56436:2;;;;43861:2257;735:56436;;;;;45815:250;42719:3;735:56436;45815:250;735:56436;;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;;;45815:250;-1:-1:-1;;;;;735:56436:2;45815:250;;;735:56436;;45815:250;735:56436;43579:27;45815:250;;735:56436;;45815:250;;;735:56436;;45815:250;;;735:56436;;45815:250;;;735:56436;42719:3;;:::i;43865:67::-;735:56436;-1:-1:-1;;;;;735:56436:2;;-1:-1:-1;;;;;735:56436:2;;43900:31;43865:67;;43343:139;43422:49;;;;;:::i;53818:244::-;735:56436;;;;;53888:24;53884:91;;735:56436;;;;;;;;;;;54044:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;;53818:244::o;53884:91::-;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;53928:36;:::o;27578:2613::-;;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;735:56436:2;27759:5;735:56436;;;-1:-1:-1;735:56436:2;;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;27788:32;735:56436;;;;;;;27788:32;-1:-1:-1;;;;;42043:295:2;735:56436;;;;;;;42244:23;42242:26;42297:18;;42296:27;;42295:36;42043:295;;27788:32;27784:271;;28207:20;735:56436;;:::i;:::-;28287:16;;;:::i;:::-;735:56436;-1:-1:-1;;;;;735:56436:2;;28317:18;;;;;;735:56436;;;28445:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;28445:5;:::i;:::-;28482:37;-1:-1:-1;;;;;735:56436:2;;;28482:37;;;:::i;:::-;28537:20;;;;;;;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;:::i;:::-;;;;;28590:35;;735:56436;-1:-1:-1;;;;;735:56436:2;;;28590:35;;735:56436;28533:194;735:56436;28533:194;-1:-1:-1;;;;;28533:194:2;28892:19;735:56436;28533:194;;;28892:19;735:56436;28533:194;28869:21;28786:36;28533:194;;;;735:56436;;28786:36;:::i;:::-;28869:21;;:::i;28892:19::-;;;:::i;:::-;735:56436;;;;;28313:1797;-1:-1:-1;735:56436:2;27759:5;735:56436;;;;;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;-1:-1:-1;735:56436:2;27759:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;;;;;;;;;;;;:::i;28533:194::-;735:56436;;;:::i;:::-;;;;;28677:35;;735:56436;-1:-1:-1;;;;;735:56436:2;;;28677:35;;735:56436;28533:194;735:56436;28533:194;-1:-1:-1;;;;;28533:194:2;28892:19;735:56436;28533:194;;;28892:19;735:56436;28533:194;28869:21;28786:36;28533:194;;;;;28313:1797;735:56436;;;;;;;;29065:38;-1:-1:-1;;;;;735:56436:2;;;;29065:38;;;:::i;:::-;735:56436;-1:-1:-1;;;;;735:56436:2;;;;;;;29194:20;:36;;29383:21;;;;29379:680;29383:21;;;29465:5;;-1:-1:-1;;;;;29465:5:2;;735:56436;29465:5;;;;;;;;;;;735:56436;29465:5;;:::i;:::-;735:56436;;;;;;:::i;:::-;;;;;29502:36;;735:56436;;;29502:36;;735:56436;;-1:-1:-1;;;;;;;;735:56436:2;;;;;;;29556:29;735:56436;;;;-1:-1:-1;;;;;;;735:56436:2;;;-1:-1:-1;735:56436:2;29379:680;735:56436;;;;;28313:1797;;29379:680;-1:-1:-1;;;;;29725:27:2;;;;;;;;;;29959:17;735:56436;29725:27;29212:1;29725:27;-1:-1:-1;;;;;;;29725:27:2;735:56436;29725:27;;;;;:::i;:::-;735:56436;;;;;-1:-1:-1;735:56436:2;29787:32;;:38;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;735:56436:2;29959:17;;:::i;:::-;735:56436;;;;;;;:::i;:::-;;;;;30008:36;;735:56436;;;30008:36;;735:56436;29379:680;;;27784:271;27930:5;;;-1:-1:-1;;;;;27930:5:2;;;;;;;;;;;;;:::i;:::-;735:56436;;;;:::i;:::-;30932:457;;-1:-1:-1;;;;;735:56436:2;;-1:-1:-1;735:56436:2;27759:5;735:56436;;;-1:-1:-1;735:56436:2;;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;;;;31079:5;30959:21;;;31079:5;;:::i;:::-;735:56436;;31104:32;;;;-1:-1:-1;;;;;42043:295:2;735:56436;;;;;;;42244:23;42242:26;42297:18;;42296:27;;42295:36;42043:295;;31104:32;735:56436;;;31156:24;;;30932:457;;31100:242;735:56436;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;735:56436:2;;;42297:18;;;-1:-1:-1;;735:56436:2;;;;42244:23;;42242:26;42296:27;;735:56436;;31258:25;;30932:457;;31201:141;735:56436;31322:5;;;;;;;;735:56436;;:::i;:::-;31479:16;-1:-1:-1;;;;;31479:16:2;;:::i;:::-;735:56436;;;-1:-1:-1;;;;;735:56436:2;;31539:18;;;;;;735:56436;;;;;32582:19;;735:56436;31644:37;-1:-1:-1;;;;;735:56436:2;;;;;31644:37;;;:::i;:::-;31699:20;;;;;;;735:56436;;;;;;;:::i;:::-;;;;;31752:35;;735:56436;;;;;31752:35;;735:56436;31695:194;;32559:21;32476:40;735:56436;;;;;;;;;32476:40;:::i;32582:19::-;-1:-1:-1;735:56436:2;27759:5;735:56436;;;;;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;;;;;;;;;;;;:::i;31695:194::-;735:56436;;;:::i;:::-;;;;;31839:35;;735:56436;;;;;31839:35;;735:56436;31695:194;;;31535:877;32098:10;;735:56436;32098:10;;32582:19;-1:-1:-1;;;;;32098:10:2;32559:21;32476:40;32098:10;;32582:19;32098:10;735:56436;32071:38;32098:10;;735:56436;;;;;;32071:38;;;:::i;:::-;32127:21;;;;;;;735:56436;;;;;;;;:::i;:::-;;;;;32181:36;;735:56436;;;;;32181:36;;735:56436;32123:197;;735:56436;;;;;;;;;;32476:40;:::i;32123:197::-;735:56436;;;:::i;:::-;;;;;32269:36;;735:56436;;;;;32269:36;;735:56436;32123:197;;;50163:1987;;-1:-1:-1;;;;;;;;;;50163:1987:2;;;;735:56436;;-1:-1:-1;735:56436:2;50391:6;735:56436;;-1:-1:-1;;;;;735:56436:2;50615:71;735:56436;-1:-1:-1;735:56436:2;;50615:45;735:56436;50471:55;735:56436;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;50471:55;:::i;:::-;735:56436;;;;;;;50615:45;;:::i;:71::-;735:56436;;;-1:-1:-1;735:56436:2;;;-1:-1:-1;;;;;735:56436:2;;51148:23;;;51144:354;;50698:1446;-1:-1:-1;;;;;735:56436:2;;51516:25;;;;51512:254;;;;50698:1446;51780:251;;;;;;;;51866:39;;;;-1:-1:-1;51866:39:2;:::o;51780:251::-;51978:38;-1:-1:-1;51978:38:2;50391:6;;-1:-1:-1;51978:38:2:o;51512:254::-;51585:42;:65;:42;-1:-1:-1;;;;;51585:42:2;;:::i;:::-;:65;:::i;:::-;735:56436;51673:18;;;51669:83;;51512:254;;;;;;51669:83;51715:18;-1:-1:-1;51669:83:2;;;51144:354;51216:42;:64;:42;;-1:-1:-1;;;;;51216:42:2;;;:::i;:64::-;735:56436;-1:-1:-1;;;;;735:56436:2;;51401:20;;51397:87;;51144:354;;;;;;51397:87;;-1:-1:-1;51445:20:2;51397:87;;50698:1446;52113:20;;;;;-1:-1:-1;52113:20:2;-1:-1:-1;52113:20:2;-1:-1:-1;52113:20:2;:::o;33721:1745::-;33793:10;735:56436;-1:-1:-1;;;;;735:56436:2;;;;33861:3;33854:10;;33850:227;;-1:-1:-1;;;;;33861:3:2;735:56436;;;34224:10;;;735:56436;;34368:15;;;34366:18;735:56436;;;;;;34453:5;-1:-1:-1;;;735:56436:2;;33861:3;735:56436;;34417:32;34416:42;;34524:8;;;34561:23;;;;34560:29;735:56436;33793:10;735:56436;34618:5;735:56436;;-1:-1:-1;;;;;735:56436:2;33793:10;735:56436;42719:3;735:56436;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;42719:3;:::i;:::-;735:56436;;;;33861:3;735:56436;;:::i;:::-;24506:673;24513:22;33861:3;24514:13;;;24513:22;;;-1:-1:-1;;;;;735:56436:2;33861:3;735:56436;;33793:10;735:56436;34816:41;;;;735:56436;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;33793:10;735:56436;;34992:24;34988:61;;35421:38;735:56436;-1:-1:-1;;;;;33861:3:2;735:56436;;;;;34524:8;;;735:56436;;35277:15;;35275:18;735:56436;;;;35355:5;-1:-1:-1;;;735:56436:2;;33861:3;735:56436;;35319:32;35318:42;;35382:23;;;35381:29;735:56436;33793:10;735:56436;34618:5;735:56436;;;33793:10;735:56436;35421:38;:::i;34988:61::-;35032:7;;;:::o;24506:673::-;-1:-1:-1;;;;;735:56436:2;;33793:10;735:56436;34618:5;735:56436;;-1:-1:-1;;;;;735:56436:2;33793:10;735:56436;;24865:11;735:56436;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24770:40;;;;:::i;24865:11::-;-1:-1:-1;;735:56436:2;;;;24946:14;:24;;25118:12;24506:673;;33850:227;-1:-1:-1;;;;;;;735:56436:2;33793:10;735:56436;34060:7::o;35920:1735::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;36125:5;735:56436;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;36154:21;36150:963;;-1:-1:-1;;735:56436:2;;-1:-1:-1;;;;;735:56436:2;;;;42297:18;;;-1:-1:-1;;735:56436:2;;;;42244:23;;42242:26;42296:27;;37123:76;;37266:114;;;;;;:::i;:::-;37240:140;;;;37390:259;;35920:1735;;;;;;;;:::o;37390:259::-;37481:12;735:56436;-1:-1:-1;;;;;735:56436:2;;;37481:12;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;;;37513:27;;;37509:130;;37390:259;;;;;37509:130;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;36125:5;735:56436;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37509:130;;;;;;;37123:76;-1:-1:-1;735:56436:2;;-1:-1:-1;;;;;;;37176:12:2:o;36150:963::-;42719:3;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;735:56436:2;;;;;;;36365:14;:24;;735:56436;;;;;;;-1:-1:-1;;;;;;;735:56436:2;-1:-1:-1;;;;;735:56436:2;;36474:7;735:56436;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;-1:-1:-1;;;;;735:56436:2;;;;;36558:11;36556:14;36614:10;;-1:-1:-1;;;;;36614:10:2;;36643;;;36639:133;;-1:-1:-1;;;;;735:56436:2;;;37038:38;735:56436;;;;;;;;36818:10;:16;;;735:56436;;;;;;;;;;36894:11;;36892:14;37005;;37004:20;735:56436;;;36125:5;735:56436;;;;;37038:38;:::i;:::-;36377:1;37091:11;:::o;36639:133::-;36746:11;;;;36377:1;36746:11;:::o;46540:3062::-;;;-1:-1:-1;;;;;46951:73:2;46540:3062;735:56436;;:::i;:::-;;;;;-1:-1:-1;735:56436:2;46723:6;735:56436;;;-1:-1:-1;735:56436:2;;;;:::i;:::-;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;-1:-1:-1;;;;;;;;;;46803:55:2;735:56436;;;;;;;46803:55;:::i;:::-;735:56436;;;46951:47;735:56436;;;;;;;46951:47;;:::i;:73::-;735:56436;;;47040:24;;735:56436;;-1:-1:-1;;;;;735:56436:2;;;47175:34;;;735:56436;;;;;;;;;;:::i;:::-;;;;;47282:282;;735:56436;-1:-1:-1;735:56436:2;47282:282;;735:56436;-1:-1:-1;735:56436:2;47282:282;;735:56436;-1:-1:-1;47282:282:2;;;735:56436;-1:-1:-1;47282:282:2;;;735:56436;47171:1478;46540:3062::o;47171:1478::-;47890:71;48395:31;47890:71;;;735:56436;48461:29;47890:71;-1:-1:-1;;;;;;;;;;47890:71:2;;;;:96;:71;;;;;;;;;;;:::i;:96::-;735:56436;;;;;;;;;;;;;;-1:-1:-1;735:56436:2;46723:6;735:56436;;;;;-1:-1:-1;735:56436:2;;;;;;;;;;;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;;;735:56436:2;;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;;;;;;;;;;48395:31;:::i;:::-;48461:29;;:::i;:::-;735:56436;;;:::i;:::-;;;;;48237:353;;735:56436;;;48237:353;;735:56436;;;48237:353;;735:56436;48237:353;;;;735:56436;46723:6;48237:353;;;735:56436;;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;735:56436:2;;;-1:-1:-1;735:56436:2;6181:1568::o;47036:2028::-;735:56436;;;;;;;;;:::i;:::-;;-1:-1:-1;735:56436:2;;-1:-1:-1;735:56436:2;48750:263;;735:56436;;48750:263;;735:56436;;48750:263;;735:56436;48750:263;;;;735:56436;46723:6;48750:263;;;735:56436;;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;735:56436:2;;;-1:-1:-1;735:56436:2;46540:3062::o;56017:320::-;56242:23;-1:-1:-1;;;;;;;;;;56017:320:2;735:56436;;;-1:-1:-1;735:56436:2;56185:5;735:56436;;56207:25;735:56436;-1:-1:-1;735:56436:2;;56162:34;53630:38;;;735:56436;53696:3;735:56436;56207:25;;:::i;:::-;56242:23;;:::i;:::-;735:56436;;;53293:3;735:56436;;;;53265:32;735:56436;-1:-1:-1;735:56436:2;56185:5;735:56436;;;-1:-1:-1;735:56436:2;;56017:320::o;41035:714::-;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;;735:56436:2;-1:-1:-1;;735:56436:2;;;;40670:14;:24;;;;40721:11;41197:22;;40682:1;41197:22;41321:8;;;41320:17;41316:36;;41035:714;735:56436;41373:2;735:56436;41382:8;;;;;41381:17;41377:36;;41035:714;735:56436;;41434:1;735:56436;41442:8;;;;;41441:17;41437:36;;41035:714;735:56436;;41494:1;735:56436;41502:8;;;;;41501:17;41497:36;;41035:714;735:56436;;41554:1;735:56436;41562:8;;;;;41561:17;41557:36;;41035:714;735:56436;;;40682:1;735:56436;41622:8;;;;41621:17;41617:36;;41035:714;41690:5;;;735:56436;40682:1;735:56436;41676:19;41721:15;;;41720:21;735:56436;41035:714;:::o;41617:36::-;41642:8;;41617:36;;;41557;41582:8;-1:-1:-1;41557:36:2;;;41497;41522:8;-1:-1:-1;41497:36:2;;;41437;41462:8;-1:-1:-1;41437:36:2;;;41377;41402:8;-1:-1:-1;41377:36:2;;;41316;-1:-1:-1;;;;;735:56436:2;-1:-1:-1;41316:36:2;;21981:2012;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;;;;;735:56436:2;;;;;;;-1:-1:-1;;;;;735:56436:2;;;;;;22285:6;735:56436;;-1:-1:-1;;;;;22285:6:2;735:56436;22513:78;735:56436;;;;22513:52;735:56436;22370:55;735:56436;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;22370:55;:::i;:::-;735:56436;;;;;;;22513:52;;:::i;:78::-;735:56436;22603:10;;735:56436;;22628:32;;;22624:122;;23681:40;23593:16;23625:42;-1:-1:-1;;;;;22285:6:2;22756:12;;735:56436;22756:12;;;735:56436;;;;;22861:15;;22859:18;22897:1048;;735:56436;;22285:6;735:56436;22937:5;;:19;23036:8;;;23084:23;;;;23083:29;735:56436;;;;;23145:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;;;23252:34;;;;:::i;:::-;23424:39;;;;;;;:::i;:::-;23477:37;;;;:::i;23625:42::-;23681:40;;:::i;:::-;23740:23;;23736:67;;22897:1048;;;-1:-1:-1;;735:56436:2;;23904:15;;23902:18;;22897:1048;;23681:40;;23593:16;;23625:42;;-1:-1:-1;;;;;735:56436:2;22897:1048;;23736:67;23783:5;;-1:-1:-1;;;;;23783:5:2;;;;735:56436;21981:2012;:::o;22624:122::-;-1:-1:-1;22676:59:2;;-1:-1:-1;;;;;;;735:56436:2;;;;22676:59::o;55426:307::-;55640:21;-1:-1:-1;;;;;;;;;;55426:307:2;735:56436;;;-1:-1:-1;735:56436:2;55585:5;735:56436;;55607:23;735:56436;-1:-1:-1;735:56436:2;;55562:34;53630:38;;;735:56436;53696:3;735:56436;55607:23;;:::i;:::-;55640:21;;:::i;38180:1631::-;;;735:56436;38419:14;;-1:-1:-1;;;;;735:56436:2;;;43537:5;735:56436;;;;;;;;;-1:-1:-1;;;;;735:56436:2;;;-1:-1:-1;;;;;735:56436:2;;;;;;;;;38448:21;;;;38504:27;;;;;38560:10;38504:27;42719:3;735:56436;38504:27;735:56436;38504:27;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;42719:3;:::i;:::-;38560:10;735:56436;-1:-1:-1;;;;;735:56436:2;;;;38554:4;;38546:25::o;38444:282::-;38592:22;735:56436;38592:10;;;;;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;-1:-1:-1;;;;;735:56436:2;;;38592:22;;38588:138;;735:56436;38740:32;735:56436;;;-1:-1:-1;;;;;735:56436:2;;;;38740:32;-1:-1:-1;;;;;42043:295:2;735:56436;;;;;;;42244:23;42242:26;42297:18;;42296:27;;42295:36;42043:295;;38740:32;38762:9;;;735:56436;38814:78;735:56436;;;;;;-1:-1:-1;;;;;735:56436:2;;;;38814:78;:::i;:::-;38788:104;;38910:6;38906:64;;39006:27;39043:5;39006:27;735:56436;39006:27;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;39043:5;:::i;:::-;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;39068:27;39064:130;;38736:1069;39208:22;;39216:4;39208:22;;:::o;39064:130::-;39114:26;735:56436;39114:26;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;39114:26;39158:14;;-1:-1:-1;;;;;735:56436:2;;;43537:5;735:56436;;;;;;;;39064:130;;;;38906:64;38936:19;;;;;;-1:-1:-1;38936:19:2;-1:-1:-1;38936:19:2;:::o;38736:1069::-;39273:10;;;;735:56436;;;;-1:-1:-1;;;;;735:56436:2;;;;39251:33;;;-1:-1:-1;;;;;42043:295:2;735:56436;;;;;;;42244:23;42242:26;42297:18;;42296:27;;42295:36;42043:295;;39251:33;735:56436;;;39326:79;;;;;;:::i;:::-;39300:105;;39423:6;39419:64;;39519:27;39556:5;39519:27;735:56436;39519:27;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;39556:5;735:56436;;-1:-1:-1;;;;;735:56436:2;;;;;39581:27;39577:131;;39247:558;39722:22;;;39730:4;39722:22;;:::o;39577:131::-;735:56436;39627:27;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;;;39577:131;;;;;39419:64;39449:19;;;;;;;-1:-1:-1;39449:19:2;-1:-1:-1;39449:19:2;:::o;38588:138::-;38649:27;;;;735:56436;38649:27;;;42719:3;735:56436;38649:27;;;735:56436;-1:-1:-1;;;;;735:56436:2;;;42719:3;735:56436;-1:-1:-1;;;;;735:56436:2;;
Swarm Source
ipfs://8cfcacc5e1a529ebf0fcdf9254e84504f7511e5db7c567bdad1b03249b266717
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.