Contract 0xb9310bc42ff1f0ff4cc4ba60bbdf50d5371bb9be

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x4ed2702ffd18f19c8a1f175132dee4752dd1a0b0fb945650d6ca740f5bbdd2c00x60806040280112672022-01-15 6:49:5611 days 13 hrs ago0x481140f916a4e64559694db4d56d692cadc0326c IN  Create: Allowlist0 FTM0.745892344093
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x4ed2702ffd18f19c8a1f175132dee4752dd1a0b0fb945650d6ca740f5bbdd2c0280112672022-01-15 6:49:5611 days 13 hrs ago 0x481140f916a4e64559694db4d56d692cadc0326c  Contract Creation0 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Allowlist

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 1 of 9: Allowlist.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "./Ownable.sol";
import "./Strings.sol";
import "./Introspection.sol";
import "./JsonWriter.sol";
import "./CalldataValidation.sol";

/*******************************************************
 *                   Main Contract Logic
 *******************************************************/
contract Allowlist is IAllowlist, Ownable {
  using JsonWriter for JsonWriter.Json; // Initialize JSON writer
  string[] public conditionsIds; // Array of condition IDs
  mapping(string => Condition) public conditionById; // Condition ID to condition mapping
  string public name; // Domain name of protocol (ie. "yearn.finance")
  address public allowlistFactoryAddress; // Address of root allowlist (parent/factory)
  mapping(string => address) public implementationById; // Implementation ID to implementation address mapping
  string[] public implementationsIds; // Array of implementation IDs

  /**
   * @notice Initialize the contract (this will only be called by proxy)
   * @param _name The allowlist name (for the protocols this is domain name: ie. "yearn.finance")
   */
  function initialize(string memory _name, address _ownerAddress) public {
    require(
      allowlistFactoryAddress == address(0),
      "Contract is already initialized"
    );
    allowlistFactoryAddress = msg.sender;
    name = _name;
    ownerAddress = _ownerAddress;
  }

  /*******************************************************
   *                   Implementation Logic
   *******************************************************/

  struct Implementation {
    string id;
    address addr;
  }

  /**
   * @notice Set implementation address for an ID (ie. "VAULT_VALIDATIONS" => 0x...)
   * @param implementationId The unique of the implementation
   * @param implementationAddress The address of the new implementation
   */
  function setImplementation(
    string memory implementationId,
    address implementationAddress
  ) public onlyOwner {
    // Add implementation ID to the implementationsIds list if it doesn't exist
    bool implementationExists = implementationById[implementationId] !=
      address(0);
    if (!implementationExists) {
      implementationsIds.push(implementationId);
    }

    // Set implementation
    implementationById[implementationId] = implementationAddress;

    // Validate implementation against existing conditions
    validateConditions();
  }

  /**
   * @notice Set multiple implementations
   * @param implementations An array of implementation tuples
   */
  function setImplementations(Implementation[] memory implementations)
    public
    onlyOwner
  {
    for (
      uint256 implementationIdx;
      implementationIdx < implementations.length;
      implementationIdx++
    ) {
      Implementation memory implementation = implementations[implementationIdx];
      setImplementation(implementation.id, implementation.addr);
    }
  }

  function implementationsIdsList() public view returns (string[] memory) {
    return implementationsIds;
  }

  function implementationsList() public view returns (Implementation[] memory) {
    string[] memory _implementationsIdsList = implementationsIdsList();
    Implementation[] memory implementations = new Implementation[](
      _implementationsIdsList.length
    );
    for (
      uint256 implementationIdx;
      implementationIdx < _implementationsIdsList.length;
      implementationIdx++
    ) {
      string memory implementationId = _implementationsIdsList[
        implementationIdx
      ];
      address implementationAddress = implementationById[implementationId];
      implementations[implementationIdx] = Implementation({
        id: implementationId,
        addr: implementationAddress
      });
    }
    return implementations;
  }

  /*******************************************************
   *                   Condition CRUD Logic
   *******************************************************/

  /**
   * @dev Internal method for adding a condition
   * @dev Condition ID validation happens here (IDs must be unqiue and not have spaces)
   * @dev Actual condition validation does not happen here (it happens in "validateCondition(condition)")
   */
  function _addCondition(Condition memory condition) internal {
    // Condition ID must be unique
    bool conditionExists = !Strings.stringsEqual(
      conditionById[condition.id].id,
      ""
    );
    require(conditionExists == false, "Condition with this ID already exists");

    // Condition ID cannot have spaces
    bool idHasSpaces = Strings.indexOfStringInString(" ", condition.id) != -1;
    require(idHasSpaces == false, "Condition IDs cannot have spaces");

    // Add condition
    conditionById[condition.id] = condition;
    conditionsIds.push(condition.id);
  }

  /**
   * @notice Add a condition with validation
   * @param condition The condition to add
   */
  function addCondition(Condition memory condition) public onlyOwner {
    validateCondition(condition);
    _addCondition(condition);
  }

  /**
   * @notice Add multiple conditions with validation
   * @param _conditions The conditions to add
   */
  function addConditions(Condition[] memory _conditions) public onlyOwner {
    for (
      uint256 conditionIdx;
      conditionIdx < _conditions.length;
      conditionIdx++
    ) {
      Condition memory condition = _conditions[conditionIdx];
      addCondition(condition);
    }
  }

  /**
   * @notice Add a condition without validation
   * @param condition The condition to add
   */
  function addConditionWithoutValidation(Condition memory condition)
    public
    onlyOwner
  {
    _addCondition(condition);
  }

  /**
   * @notice Add multiple conditions without validation
   * @param _conditions The conditions to add
   */
  function addConditionsWithoutValidation(Condition[] memory _conditions)
    public
    onlyOwner
  {
    for (
      uint256 conditionIdx;
      conditionIdx < _conditions.length;
      conditionIdx++
    ) {
      Condition memory condition = _conditions[conditionIdx];
      addConditionWithoutValidation(condition);
    }
  }

  /**
   * @notice Delete a condition given an ID
   * @param conditionId The ID of the condition to delete
   */
  function deleteCondition(string memory conditionId) public onlyOwner {
    string memory lastConditionId = conditionsIds[conditionsIds.length - 1];
    for (
      uint256 conditionIdx;
      conditionIdx < conditionsIds.length;
      conditionIdx++
    ) {
      string memory currentConditionId = conditionsIds[conditionIdx];
      if (Strings.stringsEqual(currentConditionId, conditionId)) {
        conditionsIds[conditionIdx] = lastConditionId;
        conditionsIds.pop();
        delete conditionById[conditionId];
        return;
      }
    }
    revert("Cannot find condition with that ID");
  }

  /**
   * @notice Delete multiple conditions given a list of IDs
   * @param _conditionsIds A list of condition IDs to delete
   */
  function deleteConditions(string[] memory _conditionsIds) public onlyOwner {
    for (
      uint256 conditionIdx;
      conditionIdx < _conditionsIds.length;
      conditionIdx++
    ) {
      string memory conditionId = _conditionsIds[conditionIdx];
      deleteCondition(conditionId);
    }
  }

  /**
   * @notice Delete every condition
   */
  function deleteAllConditions() public onlyOwner {
    uint256 _conditionsLength = conditionsIds.length;
    for (
      uint256 conditionIdx;
      conditionIdx < _conditionsLength;
      conditionIdx++
    ) {
      string memory conditionId = conditionsIds[0];
      deleteCondition(conditionId);
    }
  }

  /**
   * @notice Update an existing condition
   * @dev Reads condition.id to determine which condition to update
   * @param condition The new condition
   */
  function updateCondition(Condition memory condition) public onlyOwner {
    bool conditionExists = !Strings.stringsEqual(
      conditionById[condition.id].id,
      ""
    );
    require(conditionExists, "Condition with this ID does not exist");
    deleteCondition(condition.id);
    addCondition(condition);
  }

  /**
   * @notice Fetch a list of conditions
   * @return Returns all conditions
   */
  function conditionsList() public view returns (Condition[] memory) {
    Condition[] memory _conditions = new Condition[](conditionsIds.length);
    for (
      uint256 conditionIdx;
      conditionIdx < conditionsIds.length;
      conditionIdx++
    ) {
      _conditions[conditionIdx] = conditionById[conditionsIds[conditionIdx]];
    }
    return _conditions;
  }

  /**
   * @notice Fetch current conditions list as JSON
   * @return Returns JSON representation of conditions list
   */
  function conditionsJson() public view returns (string memory) {
    Condition[] memory conditions = conditionsList();

    // Start array
    JsonWriter.Json memory writer;
    writer = writer.writeStartArray();
    for (
      uint256 conditionIdx;
      conditionIdx < conditions.length;
      conditionIdx++
    ) {
      // Load condition
      Condition memory condition = conditions[conditionIdx];

      // Start object
      writer = writer.writeStartObject();

      // ID
      writer = writer.writeStringProperty("id", condition.id);

      // Implementation ID
      writer = writer.writeStringProperty(
        "implementationId",
        condition.implementationId
      );

      // Method name
      writer = writer.writeStringProperty("methodName", condition.methodName);

      // Param types
      writer = writer.writeStartArray("paramTypes");
      for (
        uint256 paramTypeIdx;
        paramTypeIdx < condition.paramTypes.length;
        paramTypeIdx++
      ) {
        writer = writer.writeStringValue(condition.paramTypes[paramTypeIdx]);
      }
      writer = writer.writeEndArray();

      // Requirements
      writer = writer.writeStartArray("requirements");
      for (
        uint256 requirementIdx;
        requirementIdx < condition.requirements.length;
        requirementIdx++
      ) {
        string[] memory requirement = condition.requirements[requirementIdx];
        writer = writer.writeStartArray();
        for (
          uint256 requirementItemIdx;
          requirementItemIdx < requirement.length;
          requirementItemIdx++
        ) {
          writer = writer.writeStringValue(requirement[requirementItemIdx]);
        }
        writer = writer.writeEndArray();
      }
      writer = writer.writeEndArray();

      // End object
      writer = writer.writeEndObject();
    }
    // End array
    writer = writer.writeEndArray();
    return writer.value;
  }

  /**
   * @notice Fetch a list of all condition IDs
   * @return An array of condition IDs
   */
  function conditionsIdsList() public view returns (string[] memory) {
    return conditionsIds;
  }

  /**
   * @notice Fetch the total number of conditions in this contract
   * @return Returns length of conditionIds
   */
  function conditionsLength() public view returns (uint256) {
    return conditionsIds.length;
  }

  /*******************************************************
   *                Condition Validation Logic
   *******************************************************/
  /**
   * @notice Validate the integrity of a condition
   * @dev For example: are the arguments of the condition valid, and do they point to a valid implementation?
   * @param condition The condition to validate
   */
  function validateCondition(Condition memory condition) public view {
    string[][] memory requirements = condition.requirements;

    for (
      uint256 requirementIdx;
      requirementIdx < requirements.length;
      requirementIdx++
    ) {
      string[] memory requirement = requirements[requirementIdx];
      string memory requirementType = requirement[0];
      string memory requirementValidationMethod = requirement[1];
      string memory methodSignature;
      string memory paramType;
      bool requirementTypeIsTarget = Strings.stringsEqual(
        requirementType,
        "target"
      );
      bool requirementTypeIsParam = Strings.stringsEqual(
        requirementType,
        "param"
      );
      if (requirementTypeIsTarget) {
        require(
          requirement.length == 2,
          "Requirement length must be equal to 2"
        );
        methodSignature = string(
          abi.encodePacked(requirementValidationMethod, "(address)")
        );
      } else if (requirementTypeIsParam) {
        require(
          requirement.length == 3,
          "Requirement length must be equal to 3"
        );
        uint256 paramIdx = Strings.atoi(requirement[2], 10);
        require(
          paramIdx <= condition.paramTypes.length - 1,
          "Requirement parameter index is out of range"
        );
        paramType = condition.paramTypes[paramIdx];
        methodSignature = string(
          abi.encodePacked(requirementValidationMethod, "(", paramType, ")")
        );
      } else {
        revert("Unsupported requirement type");
      }

      address implementationAddress = implementationById[
        condition.implementationId
      ];
      require(
        implementationAddress != address(0),
        "Implementation address is not set"
      );

      bool implementsInterface = Introspection.implementsMethodSignature(
        implementationAddress,
        methodSignature
      );
      require(
        implementsInterface == true,
        "Implementation does not implement method selector"
      );
    }
  }

  /**
   * @notice Validate all conditions
   * @dev Reverts if some conditions are invalid
   */
  function validateConditions() public view {
    for (
      uint256 conditionIdx;
      conditionIdx < conditionsIds.length;
      conditionIdx++
    ) {
      string memory conditionId = conditionsIds[conditionIdx];
      Condition memory condition = conditionById[conditionId];
      validateCondition(condition);
    }
  }

  /**
   * @notice Determine whether or not all conditions are valid
   * @return Return true if all conditions are valid, false if not
   */
  function conditionsValid() public view returns (bool) {
    (bool success, ) = address(this).staticcall(
      abi.encodeWithSignature("validateConditions()")
    );
    return success;
  }

  /**
   * @notice Determine whether or not a given target and calldata is valid
   * @dev In order to be valid, target and calldata must pass the allowlist conditions tests
   * @param targetAddress The target address of the method call
   * @param data The raw calldata of the call
   * @return isValid True if valid, false if not
   */
  function validateCalldata(address targetAddress, bytes calldata data)
    public
    view
    returns (bool isValid)
  {
    isValid = CalldataValidation.validateCalldataByAllowlist(
      address(this),
      targetAddress,
      data
    );
  }
}

File 2 of 9: AbiDecoder.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "./Strings.sol";

/**
 * @title Decode raw calldata and params
 * @author yearn.finance
 */

library AbiDecoder {
  /**
   * @notice Extract all params from calldata given a list of param types and raw calldata bytes
   * @param paramTypes An array of param types (ie. ["address", "bytes[]", "uint256"])
   * @param data Raw calldata (including 4byte method selector)
   * @return Returns an array of input param data
   */
  function getParamsFromCalldata(
    string[] memory paramTypes,
    bytes calldata data
  ) public pure returns (bytes[] memory) {
    uint256 numberOfParams = paramTypes.length;
    bytes[] memory results = new bytes[](numberOfParams);
    for (uint256 paramIdx = 0; paramIdx < numberOfParams; paramIdx++) {
      string memory paramType = paramTypes[paramIdx];
      bytes memory param = getParamFromCalldata(data, paramType, paramIdx);
      results[paramIdx] = param;
    }
    return results;
  }

  /**
   * @notice Extract param bytes given calldata, param type and param index
   * @param data Raw calldata (including 4byte method selector)
   * @param paramIdx The position of the param data to fetch (0 will fetch the first param)
   * @return Returns the raw data of the param at paramIdx index
   * @dev If the type is "bytes", "bytes[]", "string" or "string[]" the offset byte
   *      will be set to 0x20. The param is isolated in such a way that it can be passed as an
   *      input to another method selector using call or staticcall.
   */
  function getParamFromCalldata(
    bytes calldata data,
    string memory paramType,
    uint256 paramIdx
  ) public pure returns (bytes memory) {
    uint256 paramsStartIdx = 0x04; // Start after method selector
    uint256 paramOffset = 0x20 * paramIdx;
    bytes memory paramDescriptorValue = bytes(
      data[paramsStartIdx + paramOffset:paramsStartIdx + paramOffset + 0x20]
    );

    bool paramTypeIsStringOrBytes = Strings.stringsEqual(paramType, "bytes") ||
      Strings.stringsEqual(paramType, "string");
    bool paramTypeIsStringArrayOrBytesArray = Strings.stringsEqual(
      paramType,
      "bytes[]"
    ) || Strings.stringsEqual(paramType, "string[]");
    bool _paramTypeIsArray = paramTypeIsArray(paramType);

    uint256 paramStartIdx = uint256(bytes32(paramDescriptorValue)) + 0x04;
    if (paramTypeIsStringOrBytes) {
      return extractParamForBytesType(data, paramStartIdx);
    } else if (paramTypeIsStringArrayOrBytesArray) {
      return extractParamForBytesArrayType(data, paramStartIdx);
    } else if (_paramTypeIsArray) {
      return extractParamForSimpleArray(data, paramStartIdx);
    } else {
      return paramDescriptorValue;
    }
  }

  /**
   * @notice Extract param for "bytes" and "string" types given calldata and a param start index
   * @param data Raw calldata (including 4byte method selector)
   * @param paramStartIdx The offset the param starts at
   * @return Returns the raw data of the param at paramIdx index
   */
  function extractParamForBytesType(bytes calldata data, uint256 paramStartIdx)
    public
    pure
    returns (bytes memory)
  {
    uint256 paramEndIdx = paramStartIdx + 0x20;
    bytes32 bytesLengthBytes = bytes32(data[paramStartIdx:paramEndIdx]);
    uint256 bytesLength = uint256(bytesLengthBytes);
    bytes memory dataToAdd = abi.encodePacked(
      uint256(0x20),
      bytes32(bytesLengthBytes)
    );
    uint256 numberOfRowsOfBytes = (bytesLength / 32) + 1;
    for (uint256 rowIdx; rowIdx < numberOfRowsOfBytes; rowIdx++) {
      uint256 rowStartIdx = paramEndIdx + (0x20 * rowIdx);
      dataToAdd = abi.encodePacked(
        dataToAdd,
        data[rowStartIdx:rowStartIdx + 0x20]
      );
    }
    return dataToAdd;
  }

  /**
   * @notice Extract param for "bytes[]" and "string[]" types given calldata and a param start index
   * @param data Raw calldata (including 4byte method selector)
   * @param paramStartIdx The offset the param starts at
   * @return Returns the raw data of the param at paramIdx index
   */
  function extractParamForBytesArrayType(
    bytes calldata data,
    uint256 paramStartIdx
  ) public pure returns (bytes memory) {
    uint256 paramEndIdx = paramStartIdx + 0x20;
    bytes32 arrayLengthBytes = bytes32(data[paramStartIdx:paramEndIdx]);
    uint256 arrayLength = uint256(arrayLengthBytes);
    bytes memory dataToAdd = abi.encodePacked(
      uint256(0x20),
      bytes32(arrayLengthBytes)
    );
    uint256 lastOffsetStartIdx = paramEndIdx + (0x20 * arrayLength) - 0x20;
    uint256 lastOffset = uint256(
      bytes32(data[lastOffsetStartIdx:lastOffsetStartIdx + 0x20])
    );
    bytes32 lastElementBytesLengthBytes = bytes32(
      data[paramEndIdx + lastOffset:paramEndIdx + lastOffset + 0x20]
    );
    uint256 lastElementBytesLength = uint256(lastElementBytesLengthBytes);
    uint256 numberOfRowsOfBytesForLastElement = (lastElementBytesLength / 32) +
      1;
    uint256 dataEndIdx = paramEndIdx +
      lastOffset +
      0x20 +
      (0x20 * numberOfRowsOfBytesForLastElement);
    dataToAdd = abi.encodePacked(dataToAdd, data[paramEndIdx:dataEndIdx]);
    return dataToAdd;
  }

  /**
   * @notice Extract param for "*[]" types given calldata and a param start index, assuming each element is 32 bytes
   * @param data Raw calldata (including 4byte method selector)
   * @param paramStartIdx The offset the param starts at
   * @return Returns the raw data of the param at paramIdx index
   */
  function extractParamForSimpleArray(
    bytes calldata data,
    uint256 paramStartIdx
  ) public pure returns (bytes memory) {
    uint256 paramEndIdx = paramStartIdx + 0x20;
    bytes32 arrayLengthBytes = bytes32(data[paramStartIdx:paramEndIdx]);
    uint256 arrayLength = uint256(arrayLengthBytes);
    bytes memory dataToAdd = abi.encodePacked(
      uint256(0x20),
      bytes32(arrayLengthBytes)
    );
    for (uint256 rowIdx; rowIdx < arrayLength; rowIdx++) {
      uint256 rowStartIdx = paramEndIdx + (0x20 * rowIdx);
      dataToAdd = abi.encodePacked(
        dataToAdd,
        data[rowStartIdx:rowStartIdx + 0x20]
      );
    }
    return dataToAdd;
  }

  /**
   * @notice Check to see if the last two characters of a string are "[]"
   * @param paramType Param type as a string (ie. "uint256", "uint256[]")
   * @return Returns true if the paramType ends with "[]", false if not
   */
  function paramTypeIsArray(string memory paramType)
    internal
    pure
    returns (bool)
  {
    bytes32 lastTwoCharacters;
    assembly {
      let len := mload(paramType)
      lastTwoCharacters := mload(add(add(paramType, 0x20), sub(len, 2)))
    }
    return lastTwoCharacters == bytes32(bytes("[]"));
  }
}

File 3 of 9: CalldataValidation.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "./Strings.sol";
import "./AbiDecoder.sol";
import "./IAllowlist.sol";

/**
 * @title Validate raw calldata against an allowlist
 * @author yearn.finance
 */

/*******************************************************
 *                   Main Contract Logic
 *******************************************************/
library CalldataValidation {
  /**
   * @notice Calculate a method signature given a condition
   * @param condition The condition from which to generate the signature
   * @return signature The method signature in string format (ie. "approve(address,uint256)")
   */
  function methodSignatureByCondition(IAllowlist.Condition memory condition)
    public
    pure
    returns (string memory signature)
  {
    bytes memory signatureBytes = abi.encodePacked(condition.methodName, "(");
    for (uint256 paramIdx; paramIdx < condition.paramTypes.length; paramIdx++) {
      signatureBytes = abi.encodePacked(
        signatureBytes,
        condition.paramTypes[paramIdx]
      );
      if (paramIdx + 1 < condition.paramTypes.length) {
        signatureBytes = abi.encodePacked(signatureBytes, ",");
      }
    }
    signatureBytes = abi.encodePacked(signatureBytes, ")");
    signature = string(signatureBytes);
  }

  /**
   * @notice Check target validity
   * @param implementationAddress The address the validation method will be executed against
   * @param targetAddress The target address to validate
   * @param requirementValidationMethod The method to execute
   * @return targetValid Returns true if the target is valid and false otherwise
   * @dev If "requirementValidationMethod" is "isValidVaultToken" and target address is usdc
   *      the validation check will look like this: usdc.isValidVaultToken(targetAddress),
   *      where the result of the validation method is expected to return a bool
   */
  function checkTarget(
    address implementationAddress,
    address targetAddress,
    string memory requirementValidationMethod
  ) public view returns (bool targetValid) {
    string memory methodSignature = string(
      abi.encodePacked(requirementValidationMethod, "(address)")
    );
    (, bytes memory data) = address(implementationAddress).staticcall(
      abi.encodeWithSignature(methodSignature, targetAddress)
    );
    targetValid = abi.decode(data, (bool));
  }

  /**
   * @notice Check method selector validity
   * @param data Raw input calldata (we will extract the 4-byte selector
   *             from the beginning of the calldata)
   * @param condition The condition struct to check (we generate the complete
   *        method selector using condition.methodName and condition.paramTypes)
   * @return methodSelectorValid Returns true if the method selector is valid and false otherwise
   */
  function checkMethodSelector(
    bytes calldata data,
    IAllowlist.Condition memory condition
  ) public pure returns (bool methodSelectorValid) {
    string memory methodSignature = methodSignatureByCondition(condition);
    bytes4 methodSelectorBySignature = bytes4(
      keccak256(bytes(methodSignature))
    );
    bytes4 methodSelectorByCalldata = bytes4(data[0:4]);
    methodSelectorValid = methodSelectorBySignature == methodSelectorByCalldata;
  }

  /**
   * @notice Check an individual method param's validity
   * @param implementationAddress The address the validation method will be executed against
   * @param requirement The specific requirement (of type "param") to check (ie. ["param", "isVault", "0"])
   * @dev A condition may have multiple requirements, all of which must be true
   * @dev The middle element of a requirement is the requirement validation method
   * @dev The last element of a requirement is the parameter index to validate against
   * @param condition The entire condition struct to check the param against
   * @param data Raw input calldata for the original method call
   * @return Returns true if the param is valid, false if not
   */
  function checkParam(
    address implementationAddress,
    string[] memory requirement,
    IAllowlist.Condition memory condition,
    bytes calldata data
  ) public view returns (bool) {
    uint256 paramIdx = Strings.atoi(requirement[2], 10);
    string memory paramType = condition.paramTypes[paramIdx];
    bytes memory paramCalldata = AbiDecoder.getParamFromCalldata(
      data,
      paramType,
      paramIdx
    );
    string memory methodSignature = string(
      abi.encodePacked(requirement[1], "(", paramType, ")")
    );
    bytes memory encodedCalldata = abi.encodePacked(
      bytes4(keccak256(bytes(methodSignature))),
      paramCalldata
    );
    bool success;
    bytes memory resultData;
    (success, resultData) = address(implementationAddress).staticcall(
      encodedCalldata
    );
    if (success) {
      return abi.decode(resultData, (bool));
    }
    return false;
  }

  /**
   * @notice Test a target address and calldata against a specific condition and implementation
   * @param condition The condition to test
   * @param targetAddress Target address of the original method call
   * @param data Calldata of the original methodcall
   * @return Returns true if the condition passes and false if not
   * @dev The condition check is comprised of 3 parts:
          - Method selector check (to make sure the calldata method selector matches the condition method selector)
          - Target check (to make sure the target is valid)
          - Param check (to make sure the specified param is valid)
   */
  function testCondition(
    address allowlistAddress,
    IAllowlist.Condition memory condition,
    address targetAddress,
    bytes calldata data
  ) public view returns (bool) {
    string[][] memory requirements = condition.requirements;
    address implementationAddress = IAllowlist(allowlistAddress)
      .implementationById(condition.implementationId);
    for (
      uint256 requirementIdx;
      requirementIdx < requirements.length;
      requirementIdx++
    ) {
      string[] memory requirement = requirements[requirementIdx];
      string memory requirementType = requirement[0];
      string memory requirementValidationMethod = requirement[1];
      if (!checkMethodSelector(data, condition)) {
        return false;
      }
      if (Strings.stringsEqual(requirementType, "target")) {
        bool targetValid = checkTarget(
          implementationAddress,
          targetAddress,
          requirementValidationMethod
        );
        if (!targetValid) {
          return false;
        }
      } else if (Strings.stringsEqual(requirementType, "param")) {
        bool paramValid = checkParam(
          implementationAddress,
          requirement,
          condition,
          data
        );
        if (!paramValid) {
          return false;
        }
      }
    }
    return true;
  }

  /**
   * @notice Test target address and calldata against all stored protocol conditions
   * @dev This is done to determine whether or not the target address and calldata are valid and whitelisted
   * @dev This is the primary method that should be called by integrators
   * @param allowlistAddress The address of the allowlist to check calldata against
   * @param targetAddress The target address of the call
   * @param data The raw calldata to test
   * @return Returns true if the calldata/target test is successful and false if not
   */
  function validateCalldataByAllowlist(
    address allowlistAddress,
    address targetAddress,
    bytes calldata data
  ) public view returns (bool) {
    IAllowlist.Condition[] memory _conditions = IAllowlist(allowlistAddress)
      .conditionsList();
    for (
      uint256 conditionIdx;
      conditionIdx < _conditions.length;
      conditionIdx++
    ) {
      IAllowlist.Condition memory condition = _conditions[conditionIdx];
      bool conditionPassed = testCondition(
        allowlistAddress,
        condition,
        targetAddress,
        data
      );
      if (conditionPassed) {
        return true;
      }
    }
    return false;
  }
}

File 4 of 9: IAllowlist.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "./IOwnable.sol";

interface IAllowlist is IOwnable {
  struct Condition {
    string id;
    string implementationId;
    string methodName;
    string[] paramTypes;
    string[][] requirements;
  }

  function conditionsList() external view returns (Condition[] memory);

  function addConditions(Condition[] memory) external;

  function implementationById(string memory) external view returns (address);
}

File 5 of 9: Introspection.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;

/**
 * @title Detect whether or not a contract implements a specific method signature
 * @dev Works by scanning bytecode for PUSH4 operations
 * @author yearn.finance
 */

library Introspection {
  function implementsMethodSignature(address _address, string memory _signature)
    public
    view
    returns (bool)
  {
    bytes4 _selector = bytes4(keccak256(bytes(_signature)));
    uint256 contractSize;
    assembly {
      contractSize := extcodesize(_address)
    }
    bytes memory code = new bytes(contractSize);
    assembly {
      extcodecopy(_address, add(code, 0x20), 0, contractSize)
    }
    uint256 ptr = 0;
    while (ptr < contractSize) {
      // PUSH4 0x000000 (selector)
      if (code[ptr] == 0x63) {
        bytes memory selectorBytes = new bytes(64);
        selectorBytes[0] = code[ptr + 1];
        selectorBytes[1] = code[ptr + 2];
        selectorBytes[2] = code[ptr + 3];
        selectorBytes[3] = code[ptr + 4];
        bytes4 selector = abi.decode(selectorBytes, (bytes4));
        if (selector == _selector) {
          return true;
        }
      }
      ptr++;
    }
    return false;
  }

  function implementsInterface(address _address, string[] memory _interface)
    public
    view
    returns (bool)
  {
    for (uint256 methodIdx = 0; methodIdx < _interface.length; methodIdx++) {
      string memory method = _interface[methodIdx];
      bool methodIsImplemented = implementsMethodSignature(_address, method);
      if (!methodIsImplemented) {
        return false;
      }
    }
    return true;
  }
}

File 6 of 9: IOwnable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;

interface IOwnable {
  function setOwnerAddress(address _ownerAddress) external;
}

File 7 of 9: JsonWriter.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.11;

/**
 * @title Write nested JSON using solidity
 * @author Ben Meredith
 * @dev https://github.com/bmeredith/solidity-json-writer
 */

library JsonWriter {
  using JsonWriter for string;

  struct Json {
    int256 depthBitTracker;
    string value;
  }

  bytes1 constant BACKSLASH = bytes1(uint8(92));
  bytes1 constant BACKSPACE = bytes1(uint8(8));
  bytes1 constant CARRIAGE_RETURN = bytes1(uint8(13));
  bytes1 constant DOUBLE_QUOTE = bytes1(uint8(34));
  bytes1 constant FORM_FEED = bytes1(uint8(12));
  bytes1 constant FRONTSLASH = bytes1(uint8(47));
  bytes1 constant HORIZONTAL_TAB = bytes1(uint8(9));
  bytes1 constant NEWLINE = bytes1(uint8(10));

  string constant TRUE = "true";
  string constant FALSE = "false";
  bytes1 constant OPEN_BRACE = "{";
  bytes1 constant CLOSED_BRACE = "}";
  bytes1 constant OPEN_BRACKET = "[";
  bytes1 constant CLOSED_BRACKET = "]";
  bytes1 constant LIST_SEPARATOR = ",";

  int256 constant MAX_INT256 = type(int256).max;

  /**
   * @dev Writes the beginning of a JSON array.
   */
  function writeStartArray(Json memory json) public pure returns (Json memory) {
    return writeStart(json, OPEN_BRACKET);
  }

  /**
   * @dev Writes the beginning of a JSON array with a property name as the key.
   */
  function writeStartArray(Json memory json, string memory propertyName)
    public
    pure
    returns (Json memory)
  {
    return writeStart(json, propertyName, OPEN_BRACKET);
  }

  /**
   * @dev Writes the beginning of a JSON object.
   */
  function writeStartObject(Json memory json)
    public
    pure
    returns (Json memory)
  {
    return writeStart(json, OPEN_BRACE);
  }

  /**
   * @dev Writes the beginning of a JSON object with a property name as the key.
   */
  function writeStartObject(Json memory json, string memory propertyName)
    public
    pure
    returns (Json memory)
  {
    return writeStart(json, propertyName, OPEN_BRACE);
  }

  /**
   * @dev Writes the end of a JSON array.
   */
  function writeEndArray(Json memory json) public pure returns (Json memory) {
    return writeEnd(json, CLOSED_BRACKET);
  }

  /**
   * @dev Writes the end of a JSON object.
   */
  function writeEndObject(Json memory json) public pure returns (Json memory) {
    return writeEnd(json, CLOSED_BRACE);
  }

  /**
   * @dev Writes the property name and address value (as a JSON string) as part of a name/value pair of a JSON object.
   */
  function writeAddressProperty(
    Json memory json,
    string memory propertyName,
    address value
  ) public pure returns (Json memory) {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": "',
          addressToString(value),
          '"'
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(
          json.value,
          '"',
          propertyName,
          '": "',
          addressToString(value),
          '"'
        )
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the address value (as a JSON string) as an element of a JSON array.
   */
  function writeAddressValue(Json memory json, address value)
    public
    pure
    returns (Json memory)
  {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          addressToString(value),
          '"'
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(json.value, '"', addressToString(value), '"')
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the property name and boolean value (as a JSON literal "true" or "false") as part of a name/value pair of a JSON object.
   */
  function writeBooleanProperty(
    Json memory json,
    string memory propertyName,
    bool value
  ) public pure returns (Json memory) {
    string memory strValue;
    if (value) {
      strValue = TRUE;
    } else {
      strValue = FALSE;
    }

    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": ',
          strValue
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(json.value, '"', propertyName, '": ', strValue)
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the boolean value (as a JSON literal "true" or "false") as an element of a JSON array.
   */
  function writeBooleanValue(Json memory json, bool value)
    public
    pure
    returns (Json memory)
  {
    string memory strValue;
    if (value) {
      strValue = TRUE;
    } else {
      strValue = FALSE;
    }

    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(json.value, LIST_SEPARATOR, strValue)
      );
    } else {
      json.value = string(abi.encodePacked(json.value, strValue));
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the property name and int value (as a JSON number) as part of a name/value pair of a JSON object.
   */
  function writeIntProperty(
    Json memory json,
    string memory propertyName,
    int256 value
  ) public pure returns (Json memory) {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": ',
          intToString(value)
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(
          json.value,
          '"',
          propertyName,
          '": ',
          intToString(value)
        )
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the int value (as a JSON number) as an element of a JSON array.
   */
  function writeIntValue(Json memory json, int256 value)
    public
    pure
    returns (Json memory)
  {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(json.value, LIST_SEPARATOR, intToString(value))
      );
    } else {
      json.value = string(abi.encodePacked(json.value, intToString(value)));
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the property name and value of null as part of a name/value pair of a JSON object.
   */
  function writeNullProperty(Json memory json, string memory propertyName)
    public
    pure
    returns (Json memory)
  {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": null'
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(json.value, '"', propertyName, '": null')
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the value of null as an element of a JSON array.
   */
  function writeNullValue(Json memory json) public pure returns (Json memory) {
    if (json.depthBitTracker < 0) {
      json.value = string(abi.encodePacked(json.value, LIST_SEPARATOR, "null"));
    } else {
      json.value = string(abi.encodePacked(json.value, "null"));
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the string text value (as a JSON string) as an element of a JSON array.
   */
  function writeStringProperty(
    Json memory json,
    string memory propertyName,
    string memory value
  ) public pure returns (Json memory) {
    string memory jsonEscapedString = escapeJsonString(value);
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": "',
          jsonEscapedString,
          '"'
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(
          json.value,
          '"',
          propertyName,
          '": "',
          jsonEscapedString,
          '"'
        )
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the property name and string text value (as a JSON string) as part of a name/value pair of a JSON object.
   */
  function writeStringValue(Json memory json, string memory value)
    public
    pure
    returns (Json memory)
  {
    string memory jsonEscapedString = escapeJsonString(value);
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          jsonEscapedString,
          '"'
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(json.value, '"', jsonEscapedString, '"')
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the property name and uint value (as a JSON number) as part of a name/value pair of a JSON object.
   */
  function writeUintProperty(
    Json memory json,
    string memory propertyName,
    uint256 value
  ) public pure returns (Json memory) {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": ',
          uintToString(value)
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(
          json.value,
          '"',
          propertyName,
          '": ',
          uintToString(value)
        )
      );
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the uint value (as a JSON number) as an element of a JSON array.
   */
  function writeUintValue(Json memory json, uint256 value)
    public
    pure
    returns (Json memory)
  {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(json.value, LIST_SEPARATOR, uintToString(value))
      );
    } else {
      json.value = string(abi.encodePacked(json.value, uintToString(value)));
    }

    json.depthBitTracker = setListSeparatorFlag(json);

    return json;
  }

  /**
   * @dev Writes the beginning of a JSON array or object based on the token parameter.
   */
  function writeStart(Json memory json, bytes1 token)
    public
    pure
    returns (Json memory)
  {
    if (json.depthBitTracker < 0) {
      json.value = string(abi.encodePacked(json.value, LIST_SEPARATOR, token));
    } else {
      json.value = string(abi.encodePacked(json.value, token));
    }

    json.depthBitTracker &= MAX_INT256;
    json.depthBitTracker++;

    return json;
  }

  /**
   * @dev Writes the beginning of a JSON array or object based on the token parameter with a property name as the key.
   */
  function writeStart(
    Json memory json,
    string memory propertyName,
    bytes1 token
  ) public pure returns (Json memory) {
    if (json.depthBitTracker < 0) {
      json.value = string(
        abi.encodePacked(
          json.value,
          LIST_SEPARATOR,
          '"',
          propertyName,
          '": ',
          token
        )
      );
    } else {
      json.value = string(
        abi.encodePacked(json.value, '"', propertyName, '": ', token)
      );
    }

    json.depthBitTracker &= MAX_INT256;
    json.depthBitTracker++;

    return json;
  }

  /**
   * @dev Writes the end of a JSON array or object based on the token parameter.
   */
  function writeEnd(Json memory json, bytes1 token)
    public
    pure
    returns (Json memory)
  {
    json.value = string(abi.encodePacked(json.value, token));
    json.depthBitTracker = setListSeparatorFlag(json);

    if (getCurrentDepth(json) != 0) {
      json.depthBitTracker--;
    }

    return json;
  }

  /**
   * @dev Escapes any characters that required by JSON to be escaped.
   */
  function escapeJsonString(string memory value)
    public
    pure
    returns (string memory str)
  {
    bytes memory b = bytes(value);
    bool foundEscapeChars;

    for (uint256 i; i < b.length; i++) {
      if (b[i] == BACKSLASH) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == DOUBLE_QUOTE) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == FRONTSLASH) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == HORIZONTAL_TAB) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == FORM_FEED) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == NEWLINE) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == CARRIAGE_RETURN) {
        foundEscapeChars = true;
        break;
      } else if (b[i] == BACKSPACE) {
        foundEscapeChars = true;
        break;
      }
    }

    if (!foundEscapeChars) {
      return value;
    }

    for (uint256 i; i < b.length; i++) {
      if (b[i] == BACKSLASH) {
        str = string(abi.encodePacked(str, "\\\\"));
      } else if (b[i] == DOUBLE_QUOTE) {
        str = string(abi.encodePacked(str, '\\"'));
      } else if (b[i] == FRONTSLASH) {
        str = string(abi.encodePacked(str, "\\/"));
      } else if (b[i] == HORIZONTAL_TAB) {
        str = string(abi.encodePacked(str, "\\t"));
      } else if (b[i] == FORM_FEED) {
        str = string(abi.encodePacked(str, "\\f"));
      } else if (b[i] == NEWLINE) {
        str = string(abi.encodePacked(str, "\\n"));
      } else if (b[i] == CARRIAGE_RETURN) {
        str = string(abi.encodePacked(str, "\\r"));
      } else if (b[i] == BACKSPACE) {
        str = string(abi.encodePacked(str, "\\b"));
      } else {
        str = string(abi.encodePacked(str, b[i]));
      }
    }

    return str;
  }

  /**
   * @dev Tracks the recursive depth of the nested objects / arrays within the JSON text
   * written so far. This provides the depth of the current token.
   */
  function getCurrentDepth(Json memory json) public pure returns (int256) {
    return json.depthBitTracker & MAX_INT256;
  }

  /**
   * @dev The highest order bit of json.depthBitTracker is used to discern whether we are writing the first item in a list or not.
   * if (json.depthBitTracker >> 255) == 1, add a list separator before writing the item
   * else, no list separator is needed since we are writing the first item.
   */
  function setListSeparatorFlag(Json memory json)
    private
    pure
    returns (int256)
  {
    return json.depthBitTracker | (int256(1) << 255);
  }

  /**
   * @dev Converts an address to a string.
   */
  function addressToString(address _address)
    internal
    pure
    returns (string memory)
  {
    bytes32 value = bytes32(uint256(uint160(_address)));
    bytes16 alphabet = "0123456789abcdef";

    bytes memory str = new bytes(42);
    str[0] = "0";
    str[1] = "x";
    for (uint256 i; i < 20; i++) {
      str[2 + i * 2] = alphabet[uint8(value[i + 12] >> 4)];
      str[3 + i * 2] = alphabet[uint8(value[i + 12] & 0x0f)];
    }

    return string(str);
  }

  /**
   * @dev Converts an int to a string.
   */
  function intToString(int256 i) internal pure returns (string memory) {
    if (i == 0) {
      return "0";
    }

    if (i == type(int256).min) {
      // hard-coded since int256 min value can't be converted to unsigned
      return
        "-57896044618658097711785492504343953926634992332820282019728792003956564819968";
    }

    bool negative = i < 0;
    uint256 len;
    uint256 j;
    if (!negative) {
      j = uint256(i);
    } else {
      j = uint256(-i);
      ++len; // make room for '-' sign
    }

    uint256 l = j;
    while (j != 0) {
      len++;
      j /= 10;
    }

    bytes memory bstr = new bytes(len);
    uint256 k = len;
    while (l != 0) {
      bstr[--k] = bytes1((48 + uint8(l - (l / 10) * 10)));
      l /= 10;
    }

    if (negative) {
      bstr[0] = "-"; // prepend '-'
    }

    return string(bstr);
  }

  /**
   * @dev Converts a uint to a string.
   */
  function uintToString(uint256 _i) internal pure returns (string memory) {
    if (_i == 0) {
      return "0";
    }

    uint256 j = _i;
    uint256 len;
    while (j != 0) {
      len++;
      j /= 10;
    }

    bytes memory bstr = new bytes(len);
    uint256 k = len;
    while (_i != 0) {
      bstr[--k] = bytes1((48 + uint8(_i - (_i / 10) * 10)));
      _i /= 10;
    }

    return string(bstr);
  }
}

File 8 of 9: Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
import "./IOwnable.sol";

contract Ownable is IOwnable {
  address public ownerAddress;

  constructor() {
    ownerAddress = msg.sender;
  }

  modifier onlyOwner() {
    require(msg.sender == ownerAddress, "Ownable: caller is not the owner");
    _;
  }

  function setOwnerAddress(address _ownerAddress) public onlyOwner {
    ownerAddress = _ownerAddress;
  }
}

File 9 of 9: Strings.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;

/**
 * @title Small library for working with strings
 * @author yearn.finance
 */

library Strings {
  /**
   * @notice Search for a needle in a haystack
   * @param haystack The string to search
   * @param needle The string to search for
   */
  function stringStartsWith(string memory haystack, string memory needle)
    public
    pure
    returns (bool)
  {
    return indexOfStringInString(needle, haystack) == 0;
  }

  /**
   * @notice Find the index of a string in another string
   * @param needle The string to search for
   * @param haystack The string to search
   * @return Returns -1 if no match is found, otherwise returns the index of the match
   */
  function indexOfStringInString(string memory needle, string memory haystack)
    public
    pure
    returns (int256)
  {
    bytes memory _needle = bytes(needle);
    bytes memory _haystack = bytes(haystack);
    if (_haystack.length < _needle.length) {
      return -1;
    }
    bool _match;
    for (uint256 haystackIdx; haystackIdx < _haystack.length; haystackIdx++) {
      for (uint256 needleIdx; needleIdx < _needle.length; needleIdx++) {
        uint8 needleChar = uint8(_needle[needleIdx]);
        if (haystackIdx + needleIdx >= _haystack.length) {
          return -1;
        }
        uint8 haystackChar = uint8(_haystack[haystackIdx + needleIdx]);
        if (needleChar == haystackChar) {
          _match = true;
          if (needleIdx == _needle.length - 1) {
            return int256(haystackIdx);
          }
        } else {
          _match = false;
          break;
        }
      }
    }
    return -1;
  }

  /**
   * @notice Check to see if two strings are exactly equal
   * @dev Supports strings of arbitrary length
   * @param input0 First string to compare
   * @param input1 Second string to compare
   * @return Returns true if strings are exactly equal, false if not
   */
  function stringsEqual(string memory input0, string memory input1)
    public
    pure
    returns (bool)
  {
    uint256 input0Length = bytes(input0).length;
    uint256 input1Length = bytes(input1).length;
    uint256 maxLength;
    if (input0Length > input1Length) {
      maxLength = input0Length;
    } else {
      maxLength = input1Length;
    }
    uint256 numberOfRowsToCompare = (maxLength / 32) + 1;
    bytes32 input0Bytes32;
    bytes32 input1Bytes32;
    for (uint256 rowIdx; rowIdx < numberOfRowsToCompare; rowIdx++) {
      uint256 offset = 0x20 * (rowIdx + 1);
      assembly {
        input0Bytes32 := mload(add(input0, offset))
        input1Bytes32 := mload(add(input1, offset))
      }
      if (input0Bytes32 != input1Bytes32) {
        return false;
      }
    }
    return true;
  }

  /**
   * @notice Convert ASCII to integer
   * @param input Integer as a string (ie. "345")
   * @param base Base to use for the conversion (10 for decimal)
   * @return output Returns uint256 representation of input string
   * @dev Based on GemERC721 utility but includes a fix
   */
  function atoi(string memory input, uint8 base)
    public
    pure
    returns (uint256 output)
  {
    require(base == 2 || base == 8 || base == 10 || base == 16);
    bytes memory buf = bytes(input);
    for (uint256 idx = 0; idx < buf.length; idx++) {
      uint8 digit = uint8(buf[idx]) - 0x30;
      if (digit > 10) {
        digit -= 7;
      }
      require(digit < base);
      output *= base;
      output += digit;
    }
    return output;
  }

  /**
   * @notice Convert integer to ASCII
   * @param input Integer as a string (ie. "345")
   * @param base Base to use for the conversion (10 for decimal)
   * @return output Returns string representation of input integer
   * @dev Based on GemERC721 utility but includes a fix
   */
  function itoa(uint256 input, uint8 base)
    public
    pure
    returns (string memory output)
  {
    require(base == 2 || base == 8 || base == 10 || base == 16);
    if (input == 0) {
      return "0";
    }
    bytes memory buf = new bytes(256);
    uint256 idx = 0;
    while (input > 0) {
      uint8 digit = uint8(input % base);
      uint8 ascii = digit + 0x30;
      if (digit > 9) {
        ascii += 7;
      }
      buf[idx++] = bytes1(ascii);
      input /= base;
    }
    uint256 length = idx;
    for (idx = 0; idx < length / 2; idx++) {
      buf[idx] ^= buf[length - 1 - idx];
      buf[length - 1 - idx] ^= buf[idx];
      buf[idx] ^= buf[length - 1 - idx];
    }
    output = string(buf);
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition","name":"condition","type":"tuple"}],"name":"addCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition","name":"condition","type":"tuple"}],"name":"addConditionWithoutValidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition[]","name":"_conditions","type":"tuple[]"}],"name":"addConditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition[]","name":"_conditions","type":"tuple[]"}],"name":"addConditionsWithoutValidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowlistFactoryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"conditionById","outputs":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"conditionsIds","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionsIdsList","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionsJson","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionsList","outputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"conditionsValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deleteAllConditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"conditionId","type":"string"}],"name":"deleteCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"_conditionsIds","type":"string[]"}],"name":"deleteConditions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"implementationById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"implementationsIds","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementationsIdsList","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementationsList","outputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct Allowlist.Implementation[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_ownerAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"address","name":"implementationAddress","type":"address"}],"name":"setImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct Allowlist.Implementation[]","name":"implementations","type":"tuple[]"}],"name":"setImplementations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ownerAddress","type":"address"}],"name":"setOwnerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition","name":"condition","type":"tuple"}],"name":"updateCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"validateCalldata","outputs":[{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"id","type":"string"},{"internalType":"string","name":"implementationId","type":"string"},{"internalType":"string","name":"methodName","type":"string"},{"internalType":"string[]","name":"paramTypes","type":"string[]"},{"internalType":"string[][]","name":"requirements","type":"string[][]"}],"internalType":"struct IAllowlist.Condition","name":"condition","type":"tuple"}],"name":"validateCondition","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validateConditions","outputs":[],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550615ee280620000616000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806361bb77d011610104578063b5bd099d116100a2578063dd2c907811610071578063dd2c9078146104aa578063e4449b10146104da578063ed1f39fd1461050a578063f63da20214610526576101cf565b8063b5bd099d1461044c578063b727602e14610456578063c1854a5714610472578063cb6484861461048e576101cf565b80638f84aa09116100de5780638f84aa09146103d657806390f534ec146103f4578063a83dcb1314610410578063b2b8768f1461042e576101cf565b806361bb77d01461036a5780637ab4339d1461039c57806382b8cf12146103b8576101cf565b80631a73be221161017157806339cf274e1161014b57806339cf274e1461030a5780633a2ab9c01461031457806345d840e91461033057806360ff5dee1461034c576101cf565b80631a73be22146102a257806331a93cd5146102be578063331a6bf5146102ee576101cf565b80631032a3d9116101ad5780631032a3d91461022a578063113da2f21461024857806314e872f2146102665780631717412f14610284576101cf565b806304f70083146101d457806306419fe5146101f057806306fdde031461020c575b600080fd5b6101ee60048036038101906101e99190613b4c565b610556565b005b61020a60048036038101906102059190613bf3565b610907565b005b610214610ab3565b6040516102219190613cd7565b60405180910390f35b610232610b41565b60405161023f9190613e05565b60405180910390f35b610250610c1a565b60405161025d9190613f35565b60405180910390f35b61026e610d56565b60405161027b91906141f3565b60405180910390f35b61028c6111f3565b6040516102999190614224565b60405180910390f35b6102bc60048036038101906102b79190614528565b611219565b005b6102d860048036038101906102d39190613b4c565b6112bc565b6040516102e59190614224565b60405180910390f35b61030860048036038101906103039190614571565b611305565b005b6103126113d6565b005b61032e60048036038101906103299190614528565b61188e565b005b61034a6004803603810190610345919061459e565b611a17565b005b610354611af1565b6040516103619190614600565b60405180910390f35b610384600480360381019061037f9190613b4c565b611afe565b6040516103939392919061461b565b60405180910390f35b6103b660048036038101906103b19190613bf3565b611cd6565b005b6103c0611e03565b6040516103cd9190613e05565b60405180910390f35b6103de611edc565b6040516103eb9190614224565b60405180910390f35b61040e60048036038101906104099190614748565b611f00565b005b610418611fda565b6040516104259190613cd7565b60405180910390f35b6104366128a5565b60405161044391906147ac565b60405180910390f35b61045461299a565b005b610470600480360381019061046b9190614528565b612b0a565b005b61048c60048036038101906104879190614748565b613046565b005b6104a860048036038101906104a39190614528565b613120565b005b6104c460048036038101906104bf9190614822565b6131ba565b6040516104d191906147ac565b60405180910390f35b6104f460048036038101906104ef91906148ae565b613243565b6040516105019190613cd7565b60405180910390f35b610524600480360381019061051f9190614a28565b6132ef565b005b610540600480360381019061053b91906148ae565b6133d2565b60405161054d9190613cd7565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105db90614abd565b60405180910390fd5b600060018080805490506105f89190614b0c565b8154811061060957610608614b40565b5b90600052602060002001805461061e90614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461064a90614b9e565b80156106975780601f1061066c57610100808354040283529160200191610697565b820191906000526020600020905b81548152906001019060200180831161067a57829003601f168201915b5050505050905060005b6001805490508110156108c8576000600182815481106106c4576106c3614b40565b5b9060005260206000200180546106d990614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461070590614b9e565b80156107525780601f1061072757610100808354040283529160200191610752565b820191906000526020600020905b81548152906001019060200180831161073557829003601f168201915b50505050509050738b87bf02ab74a3e091a8c6d940678192f23d43476313d1995082866040518363ffffffff1660e01b8152600401610792929190614c1a565b602060405180830381865af41580156107af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d39190614c7d565b156108b45782600183815481106107ed576107ec614b40565b5b90600052602060002001908051906020019061080a92919061374c565b50600180548061081d5761081c614caa565b5b60019003818190600052602060002001600061083991906137d2565b905560028460405161084b9190614d15565b90815260200160405180910390206000808201600061086a91906137d2565b60018201600061087a91906137d2565b60028201600061088a91906137d2565b60038201600061089a9190613812565b6004820160006108aa9190613833565b5050505050610904565b5080806108c090614d2c565b9150506106a1565b506040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108fb90614de7565b60405180910390fd5b50565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610995576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098c90614abd565b60405180910390fd5b60008073ffffffffffffffffffffffffffffffffffffffff166005846040516109be9190614d15565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415905080610a4957600683908060018154018082558091505060019003906000526020600020016000909190919091509080519060200190610a4792919061374c565b505b81600584604051610a5a9190614d15565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610aae6113d6565b505050565b60038054610ac090614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054610aec90614b9e565b8015610b395780601f10610b0e57610100808354040283529160200191610b39565b820191906000526020600020905b815481529060010190602001808311610b1c57829003601f168201915b505050505081565b60606006805480602002602001604051908101604052809291908181526020016000905b82821015610c11578382906000526020600020018054610b8490614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb090614b9e565b8015610bfd5780601f10610bd257610100808354040283529160200191610bfd565b820191906000526020600020905b815481529060010190602001808311610be057829003601f168201915b505050505081526020019060010190610b65565b50505050905090565b60606000610c26610b41565b90506000815167ffffffffffffffff811115610c4557610c44613a21565b5b604051908082528060200260200182016040528015610c7e57816020015b610c6b613854565b815260200190600190039081610c635790505b50905060005b8251811015610d4d576000838281518110610ca257610ca1614b40565b5b602002602001015190506000600582604051610cbe9190614d15565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060405180604001604052808381526020018273ffffffffffffffffffffffffffffffffffffffff16815250848481518110610d2d57610d2c614b40565b5b602002602001018190525050508080610d4590614d2c565b915050610c84565b50809250505090565b6060600060018054905067ffffffffffffffff811115610d7957610d78613a21565b5b604051908082528060200260200182016040528015610db257816020015b610d9f613884565b815260200190600190039081610d975790505b50905060005b6001805490508110156111eb57600260018281548110610ddb57610dda614b40565b5b90600052602060002001604051610df29190614e9b565b90815260200160405180910390206040518060a0016040529081600082018054610e1b90614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054610e4790614b9e565b8015610e945780601f10610e6957610100808354040283529160200191610e94565b820191906000526020600020905b815481529060010190602001808311610e7757829003601f168201915b50505050508152602001600182018054610ead90614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed990614b9e565b8015610f265780601f10610efb57610100808354040283529160200191610f26565b820191906000526020600020905b815481529060010190602001808311610f0957829003601f168201915b50505050508152602001600282018054610f3f90614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6b90614b9e565b8015610fb85780601f10610f8d57610100808354040283529160200191610fb8565b820191906000526020600020905b815481529060010190602001808311610f9b57829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b8282101561109257838290600052602060002001805461100590614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461103190614b9e565b801561107e5780601f106110535761010080835404028352916020019161107e565b820191906000526020600020905b81548152906001019060200180831161106157829003601f168201915b505050505081526020019060010190610fe6565b50505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b828210156111b257838290600052602060002001805480602002602001604051908101604052809291908181526020016000905b8282101561119f57838290600052602060002001805461111290614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461113e90614b9e565b801561118b5780601f106111605761010080835404028352916020019161118b565b820191906000526020600020905b81548152906001019060200180831161116e57829003601f168201915b5050505050815260200190600101906110f3565b50505050815260200190600101906110bf565b50505050815250508282815181106111cd576111cc614b40565b5b602002602001018190525080806111e390614d2c565b915050610db8565b508091505090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161129e90614abd565b60405180910390fd5b6112b081612b0a565b6112b98161347e565b50565b6005818051602081018201805184825260208301602085012081835280955050505050506000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611393576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161138a90614abd565b60405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60005b60018054905081101561188b576000600182815481106113fc576113fb614b40565b5b90600052602060002001805461141190614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461143d90614b9e565b801561148a5780601f1061145f5761010080835404028352916020019161148a565b820191906000526020600020905b81548152906001019060200180831161146d57829003601f168201915b5050505050905060006002826040516114a39190614d15565b90815260200160405180910390206040518060a00160405290816000820180546114cc90614b9e565b80601f01602080910402602001604051908101604052809291908181526020018280546114f890614b9e565b80156115455780601f1061151a57610100808354040283529160200191611545565b820191906000526020600020905b81548152906001019060200180831161152857829003601f168201915b5050505050815260200160018201805461155e90614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461158a90614b9e565b80156115d75780601f106115ac576101008083540402835291602001916115d7565b820191906000526020600020905b8154815290600101906020018083116115ba57829003601f168201915b505050505081526020016002820180546115f090614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461161c90614b9e565b80156116695780601f1061163e57610100808354040283529160200191611669565b820191906000526020600020905b81548152906001019060200180831161164c57829003601f168201915b5050505050815260200160038201805480602002602001604051908101604052809291908181526020016000905b828210156117435783829060005260206000200180546116b690614b9e565b80601f01602080910402602001604051908101604052809291908181526020018280546116e290614b9e565b801561172f5780601f106117045761010080835404028352916020019161172f565b820191906000526020600020905b81548152906001019060200180831161171257829003601f168201915b505050505081526020019060010190611697565b50505050815260200160048201805480602002602001604051908101604052809291908181526020016000905b8282101561186357838290600052602060002001805480602002602001604051908101604052809291908181526020016000905b828210156118505783829060005260206000200180546117c390614b9e565b80601f01602080910402602001604051908101604052809291908181526020018280546117ef90614b9e565b801561183c5780601f106118115761010080835404028352916020019161183c565b820191906000526020600020905b81548152906001019060200180831161181f57829003601f168201915b5050505050815260200190600101906117a4565b5050505081526020019060010190611770565b5050505081525050905061187681612b0a565b5050808061188390614d2c565b9150506113d9565b50565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461191c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191390614abd565b60405180910390fd5b6000738b87bf02ab74a3e091a8c6d940678192f23d43476313d199506002846000015160405161194c9190614d15565b90815260200160405180910390206000016040518263ffffffff1660e01b81526004016119799190614f58565b602060405180830381865af4158015611996573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ba9190614c7d565b159050806119fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f490614fff565b60405180910390fd5b611a0a8260000151610556565b611a1382611219565b5050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611aa5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9c90614abd565b60405180910390fd5b60005b8151811015611aed576000828281518110611ac657611ac5614b40565b5b60200260200101519050611ad981610556565b508080611ae590614d2c565b915050611aa8565b5050565b6000600180549050905090565b600281805160208101820180518482526020830160208501208183528095505050505050600091509050806000018054611b3790614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054611b6390614b9e565b8015611bb05780601f10611b8557610100808354040283529160200191611bb0565b820191906000526020600020905b815481529060010190602001808311611b9357829003601f168201915b505050505090806001018054611bc590614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054611bf190614b9e565b8015611c3e5780601f10611c1357610100808354040283529160200191611c3e565b820191906000526020600020905b815481529060010190602001808311611c2157829003601f168201915b505050505090806002018054611c5390614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054611c7f90614b9e565b8015611ccc5780601f10611ca157610100808354040283529160200191611ccc565b820191906000526020600020905b815481529060010190602001808311611caf57829003601f168201915b5050505050905083565b600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611d67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5e9061506b565b60405180910390fd5b33600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160039080519060200190611dbe92919061374c565b50806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015611ed3578382906000526020600020018054611e4690614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054611e7290614b9e565b8015611ebf5780601f10611e9457610100808354040283529160200191611ebf565b820191906000526020600020905b815481529060010190602001808311611ea257829003601f168201915b505050505081526020019060010190611e27565b50505050905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611f8e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f8590614abd565b60405180910390fd5b60005b8151811015611fd6576000828281518110611faf57611fae614b40565b5b60200260200101519050611fc281613120565b508080611fce90614d2c565b915050611f91565b5050565b60606000611fe6610d56565b9050611ff06138b3565b80738db15c98a9ae5a41951655f138693caf5e5ca4d863615a94a690916040518263ffffffff1660e01b8152600401612029919061512b565b600060405180830381865af4158015612046573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061206f9190615255565b905060005b825181101561281757600083828151811061209257612091614b40565b5b6020026020010151905082738db15c98a9ae5a41951655f138693caf5e5ca4d8637c5cb88390916040518263ffffffff1660e01b81526004016120d5919061512b565b600060405180830381865af41580156120f2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061211b9190615255565b925082738db15c98a9ae5a41951655f138693caf5e5ca4d8638283c7f8909183600001516040518363ffffffff1660e01b815260040161215c9291906152ea565b600060405180830381865af4158015612179573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906121a29190615255565b925082738db15c98a9ae5a41951655f138693caf5e5ca4d8638283c7f8909183602001516040518363ffffffff1660e01b81526004016121e3929190615380565b600060405180830381865af4158015612200573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122299190615255565b925082738db15c98a9ae5a41951655f138693caf5e5ca4d8638283c7f8909183604001516040518363ffffffff1660e01b815260040161226a929190615416565b600060405180830381865af4158015612287573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122b09190615255565b925082738db15c98a9ae5a41951655f138693caf5e5ca4d8639c1b9fe690916040518263ffffffff1660e01b81526004016122eb91906154ac565b600060405180830381865af4158015612308573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906123319190615255565b925060005b8160600151518110156123f75783738db15c98a9ae5a41951655f138693caf5e5ca4d8636e87909090918460600151848151811061237757612376614b40565b5b60200260200101516040518363ffffffff1660e01b815260040161239c9291906154e1565b600060405180830381865af41580156123b9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906123e29190615255565b935080806123ef90614d2c565b915050612336565b5082738db15c98a9ae5a41951655f138693caf5e5ca4d863d49a381190916040518263ffffffff1660e01b8152600401612431919061512b565b600060405180830381865af415801561244e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906124779190615255565b925082738db15c98a9ae5a41951655f138693caf5e5ca4d8639c1b9fe690916040518263ffffffff1660e01b81526004016124b29190615564565b600060405180830381865af41580156124cf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906124f89190615255565b925060005b8160800151518110156127005760008260800151828151811061252357612522614b40565b5b6020026020010151905084738db15c98a9ae5a41951655f138693caf5e5ca4d863615a94a690916040518263ffffffff1660e01b8152600401612566919061512b565b600060405180830381865af4158015612583573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906125ac9190615255565b945060005b815181101561266a5785738db15c98a9ae5a41951655f138693caf5e5ca4d8636e87909090918484815181106125ea576125e9614b40565b5b60200260200101516040518363ffffffff1660e01b815260040161260f9291906154e1565b600060405180830381865af415801561262c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906126559190615255565b9550808061266290614d2c565b9150506125b1565b5084738db15c98a9ae5a41951655f138693caf5e5ca4d863d49a381190916040518263ffffffff1660e01b81526004016126a4919061512b565b600060405180830381865af41580156126c1573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906126ea9190615255565b94505080806126f890614d2c565b9150506124fd565b5082738db15c98a9ae5a41951655f138693caf5e5ca4d863d49a381190916040518263ffffffff1660e01b815260040161273a919061512b565b600060405180830381865af4158015612757573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906127809190615255565b925082738db15c98a9ae5a41951655f138693caf5e5ca4d86339f824f890916040518263ffffffff1660e01b81526004016127bb919061512b565b600060405180830381865af41580156127d8573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906128019190615255565b925050808061280f90614d2c565b915050612074565b5080738db15c98a9ae5a41951655f138693caf5e5ca4d863d49a381190916040518263ffffffff1660e01b8152600401612851919061512b565b600060405180830381865af415801561286e573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906128979190615255565b905080602001519250505090565b6000803073ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f39cf274e000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161294f91906155e0565b600060405180830381855afa9150503d806000811461298a576040519150601f19603f3d011682016040523d82523d6000602084013e61298f565b606091505b505090508091505090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a28576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a1f90614abd565b60405180910390fd5b6000600180549050905060005b81811015612b065760006001600081548110612a5457612a53614b40565b5b906000526020600020018054612a6990614b9e565b80601f0160208091040260200160405190810160405280929190818152602001828054612a9590614b9e565b8015612ae25780601f10612ab757610100808354040283529160200191612ae2565b820191906000526020600020905b815481529060010190602001808311612ac557829003601f168201915b50505050509050612af281610556565b508080612afe90614d2c565b915050612a35565b5050565b60008160800151905060005b8151811015613041576000828281518110612b3457612b33614b40565b5b60200260200101519050600081600081518110612b5457612b53614b40565b5b60200260200101519050600082600181518110612b7457612b73614b40565b5b602002602001015190506060806000738b87bf02ab74a3e091a8c6d940678192f23d43476313d19950866040518263ffffffff1660e01b8152600401612bba9190615643565b602060405180830381865af4158015612bd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bfb9190614c7d565b90506000738b87bf02ab74a3e091a8c6d940678192f23d43476313d19950876040518263ffffffff1660e01b8152600401612c3691906156c4565b602060405180830381865af4158015612c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c779190614c7d565b90508115612cea576002875114612cc3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cba9061576b565b60405180910390fd5b84604051602001612cd491906157d7565b6040516020818303038152906040529350612ea9565b8015612e6d576003875114612d34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d2b9061586b565b60405180910390fd5b6000738b87bf02ab74a3e091a8c6d940678192f23d43476329c34b6a89600281518110612d6457612d63614b40565b5b6020026020010151600a6040518363ffffffff1660e01b8152600401612d8b9291906158dd565b602060405180830381865af4158015612da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dcc9190615922565b905060018b6060015151612de09190614b0c565b811115612e22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e19906159c1565b60405180910390fd5b8a606001518181518110612e3957612e38614b40565b5b602002602001015193508584604051602001612e56929190615a79565b604051602081830303815290604052945050612ea8565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9f90615aff565b60405180910390fd5b5b600060058b60200151604051612ebf9190614d15565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612f60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5790615b91565b60405180910390fd5b600073ae2b0841755df78a072775ccc328ffc62eb89fc7639a9ec0ca83886040518363ffffffff1660e01b8152600401612f9b929190615bc0565b602060405180830381865af4158015612fb8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fdc9190614c7d565b90506001151581151514613025576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161301c90615c62565b60405180910390fd5b505050505050505050808061303990614d2c565b915050612b16565b505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146130d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cb90614abd565b60405180910390fd5b60005b815181101561311c5760008282815181106130f5576130f4614b40565b5b6020026020010151905061310881611219565b50808061311490614d2c565b9150506130d7565b5050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146131ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131a590614abd565b60405180910390fd5b6131b78161347e565b50565b600073c4fa9d2440482b4fead00748d33186f7b0539098630d16ed6f308686866040518563ffffffff1660e01b81526004016131f99493929190615cc0565b602060405180830381865af4158015613216573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323a9190614c7d565b90509392505050565b6006818154811061325357600080fd5b90600052602060002001600091509050805461326e90614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461329a90614b9e565b80156132e75780601f106132bc576101008083540402835291602001916132e7565b820191906000526020600020905b8154815290600101906020018083116132ca57829003601f168201915b505050505081565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461337d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161337490614abd565b60405180910390fd5b60005b81518110156133ce57600082828151811061339e5761339d614b40565b5b602002602001015190506133ba81600001518260200151610907565b5080806133c690614d2c565b915050613380565b5050565b600181815481106133e257600080fd5b9060005260206000200160009150905080546133fd90614b9e565b80601f016020809104026020016040519081016040528092919081815260200182805461342990614b9e565b80156134765780601f1061344b57610100808354040283529160200191613476565b820191906000526020600020905b81548152906001019060200180831161345957829003601f168201915b505050505081565b6000738b87bf02ab74a3e091a8c6d940678192f23d43476313d19950600284600001516040516134ae9190614d15565b90815260200160405180910390206000016040518263ffffffff1660e01b81526004016134db9190614f58565b602060405180830381865af41580156134f8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351c9190614c7d565b1590506000151581151514613566576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161355d90615d72565b60405180910390fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff738b87bf02ab74a3e091a8c6d940678192f23d4347631465a32d85600001516040518263ffffffff1660e01b81526004016135c49190615dde565b602060405180830381865af41580156135e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136059190615e13565b141590506000151581151514613650576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161364790615e8c565b60405180910390fd5b82600284600001516040516136659190614d15565b9081526020016040518091039020600082015181600001908051906020019061368f92919061374c565b5060208201518160010190805190602001906136ac92919061374c565b5060408201518160020190805190602001906136c992919061374c565b5060608201518160030190805190602001906136e69291906138cd565b50608082015181600401908051906020019061370392919061392d565b509050506001836000015190806001815401808255809150506001900390600052602060002001600090919091909150908051906020019061374692919061374c565b50505050565b82805461375890614b9e565b90600052602060002090601f01602090048101928261377a57600085556137c1565b82601f1061379357805160ff19168380011785556137c1565b828001600101855582156137c1579182015b828111156137c05782518255916020019190600101906137a5565b5b5090506137ce919061398d565b5090565b5080546137de90614b9e565b6000825580601f106137f0575061380f565b601f01602090049060005260206000209081019061380e919061398d565b5b50565b508054600082559060005260206000209081019061383091906139aa565b50565b508054600082559060005260206000209081019061385191906139ce565b50565b604051806040016040528060608152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060a0016040528060608152602001606081526020016060815260200160608152602001606081525090565b604051806040016040528060008152602001606081525090565b82805482825590600052602060002090810192821561391c579160200282015b8281111561391b57825182908051906020019061390b92919061374c565b50916020019190600101906138ed565b5b50905061392991906139aa565b5090565b82805482825590600052602060002090810192821561397c579160200282015b8281111561397b57825182908051906020019061396b9291906138cd565b509160200191906001019061394d565b5b50905061398991906139ce565b5090565b5b808211156139a657600081600090555060010161398e565b5090565b5b808211156139ca57600081816139c191906137d2565b506001016139ab565b5090565b5b808211156139ee57600081816139e59190613812565b506001016139cf565b5090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613a5982613a10565b810181811067ffffffffffffffff82111715613a7857613a77613a21565b5b80604052505050565b6000613a8b6139f2565b9050613a978282613a50565b919050565b600067ffffffffffffffff821115613ab757613ab6613a21565b5b613ac082613a10565b9050602081019050919050565b82818337600083830152505050565b6000613aef613aea84613a9c565b613a81565b905082815260208101848484011115613b0b57613b0a613a0b565b5b613b16848285613acd565b509392505050565b600082601f830112613b3357613b32613a06565b5b8135613b43848260208601613adc565b91505092915050565b600060208284031215613b6257613b616139fc565b5b600082013567ffffffffffffffff811115613b8057613b7f613a01565b5b613b8c84828501613b1e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613bc082613b95565b9050919050565b613bd081613bb5565b8114613bdb57600080fd5b50565b600081359050613bed81613bc7565b92915050565b60008060408385031215613c0a57613c096139fc565b5b600083013567ffffffffffffffff811115613c2857613c27613a01565b5b613c3485828601613b1e565b9250506020613c4585828601613bde565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015613c89578082015181840152602081019050613c6e565b83811115613c98576000848401525b50505050565b6000613ca982613c4f565b613cb38185613c5a565b9350613cc3818560208601613c6b565b613ccc81613a10565b840191505092915050565b60006020820190508181036000830152613cf18184613c9e565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b6000613d4182613c4f565b613d4b8185613d25565b9350613d5b818560208601613c6b565b613d6481613a10565b840191505092915050565b6000613d7b8383613d36565b905092915050565b6000602082019050919050565b6000613d9b82613cf9565b613da58185613d04565b935083602082028501613db785613d15565b8060005b85811015613df35784840389528151613dd48582613d6f565b9450613ddf83613d83565b925060208a01995050600181019050613dbb565b50829750879550505050505092915050565b60006020820190508181036000830152613e1f8184613d90565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613e5c81613bb5565b82525050565b60006040830160008301518482036000860152613e7f8282613d36565b9150506020830151613e946020860182613e53565b508091505092915050565b6000613eab8383613e62565b905092915050565b6000602082019050919050565b6000613ecb82613e27565b613ed58185613e32565b935083602082028501613ee785613e43565b8060005b85811015613f235784840389528151613f048582613e9f565b9450613f0f83613eb3565b925060208a01995050600181019050613eeb565b50829750879550505050505092915050565b60006020820190508181036000830152613f4f8184613ec0565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b6000613f9f82613cf9565b613fa98185613f83565b935083602082028501613fbb85613d15565b8060005b85811015613ff75784840389528151613fd88582613d6f565b9450613fe383613d83565b925060208a01995050600181019050613fbf565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006140418383613f94565b905092915050565b6000602082019050919050565b600061406182614009565b61406b8185614014565b93508360208202850161407d85614025565b8060005b858110156140b9578484038952815161409a8582614035565b94506140a583614049565b925060208a01995050600181019050614081565b50829750879550505050505092915050565b600060a08301600083015184820360008601526140e88282613d36565b915050602083015184820360208601526141028282613d36565b9150506040830151848203604086015261411c8282613d36565b915050606083015184820360608601526141368282613f94565b915050608083015184820360808601526141508282614056565b9150508091505092915050565b600061416983836140cb565b905092915050565b6000602082019050919050565b600061418982613f57565b6141938185613f62565b9350836020820285016141a585613f73565b8060005b858110156141e157848403895281516141c2858261415d565b94506141cd83614171565b925060208a019950506001810190506141a9565b50829750879550505050505092915050565b6000602082019050818103600083015261420d818461417e565b905092915050565b61421e81613bb5565b82525050565b60006020820190506142396000830184614215565b92915050565b600080fd5b600080fd5b600067ffffffffffffffff82111561426457614263613a21565b5b602082029050602081019050919050565b600080fd5b600061428d61428884614249565b613a81565b905080838252602082019050602084028301858111156142b0576142af614275565b5b835b818110156142f757803567ffffffffffffffff8111156142d5576142d4613a06565b5b8086016142e28982613b1e565b855260208501945050506020810190506142b2565b5050509392505050565b600082601f83011261431657614315613a06565b5b813561432684826020860161427a565b91505092915050565b600067ffffffffffffffff82111561434a57614349613a21565b5b602082029050602081019050919050565b600061436e6143698461432f565b613a81565b9050808382526020820190506020840283018581111561439157614390614275565b5b835b818110156143d857803567ffffffffffffffff8111156143b6576143b5613a06565b5b8086016143c38982614301565b85526020850194505050602081019050614393565b5050509392505050565b600082601f8301126143f7576143f6613a06565b5b813561440784826020860161435b565b91505092915050565b600060a082840312156144265761442561423f565b5b61443060a0613a81565b9050600082013567ffffffffffffffff8111156144505761444f614244565b5b61445c84828501613b1e565b600083015250602082013567ffffffffffffffff8111156144805761447f614244565b5b61448c84828501613b1e565b602083015250604082013567ffffffffffffffff8111156144b0576144af614244565b5b6144bc84828501613b1e565b604083015250606082013567ffffffffffffffff8111156144e0576144df614244565b5b6144ec84828501614301565b606083015250608082013567ffffffffffffffff8111156145105761450f614244565b5b61451c848285016143e2565b60808301525092915050565b60006020828403121561453e5761453d6139fc565b5b600082013567ffffffffffffffff81111561455c5761455b613a01565b5b61456884828501614410565b91505092915050565b600060208284031215614587576145866139fc565b5b600061459584828501613bde565b91505092915050565b6000602082840312156145b4576145b36139fc565b5b600082013567ffffffffffffffff8111156145d2576145d1613a01565b5b6145de84828501614301565b91505092915050565b6000819050919050565b6145fa816145e7565b82525050565b600060208201905061461560008301846145f1565b92915050565b600060608201905081810360008301526146358186613c9e565b905081810360208301526146498185613c9e565b9050818103604083015261465d8184613c9e565b9050949350505050565b600067ffffffffffffffff82111561468257614681613a21565b5b602082029050602081019050919050565b60006146a66146a184614667565b613a81565b905080838252602082019050602084028301858111156146c9576146c8614275565b5b835b8181101561471057803567ffffffffffffffff8111156146ee576146ed613a06565b5b8086016146fb8982614410565b855260208501945050506020810190506146cb565b5050509392505050565b600082601f83011261472f5761472e613a06565b5b813561473f848260208601614693565b91505092915050565b60006020828403121561475e5761475d6139fc565b5b600082013567ffffffffffffffff81111561477c5761477b613a01565b5b6147888482850161471a565b91505092915050565b60008115159050919050565b6147a681614791565b82525050565b60006020820190506147c1600083018461479d565b92915050565b600080fd5b60008083601f8401126147e2576147e1613a06565b5b8235905067ffffffffffffffff8111156147ff576147fe6147c7565b5b60208301915083600182028301111561481b5761481a614275565b5b9250929050565b60008060006040848603121561483b5761483a6139fc565b5b600061484986828701613bde565b935050602084013567ffffffffffffffff81111561486a57614869613a01565b5b614876868287016147cc565b92509250509250925092565b61488b816145e7565b811461489657600080fd5b50565b6000813590506148a881614882565b92915050565b6000602082840312156148c4576148c36139fc565b5b60006148d284828501614899565b91505092915050565b600067ffffffffffffffff8211156148f6576148f5613a21565b5b602082029050602081019050919050565b60006040828403121561491d5761491c61423f565b5b6149276040613a81565b9050600082013567ffffffffffffffff81111561494757614946614244565b5b61495384828501613b1e565b600083015250602061496784828501613bde565b60208301525092915050565b6000614986614981846148db565b613a81565b905080838252602082019050602084028301858111156149a9576149a8614275565b5b835b818110156149f057803567ffffffffffffffff8111156149ce576149cd613a06565b5b8086016149db8982614907565b855260208501945050506020810190506149ab565b5050509392505050565b600082601f830112614a0f57614a0e613a06565b5b8135614a1f848260208601614973565b91505092915050565b600060208284031215614a3e57614a3d6139fc565b5b600082013567ffffffffffffffff811115614a5c57614a5b613a01565b5b614a68848285016149fa565b91505092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000614aa7602083613c5a565b9150614ab282614a71565b602082019050919050565b60006020820190508181036000830152614ad681614a9a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614b17826145e7565b9150614b22836145e7565b925082821015614b3557614b34614add565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614bb657607f821691505b60208210811415614bca57614bc9614b6f565b5b50919050565b600082825260208201905092915050565b6000614bec82613c4f565b614bf68185614bd0565b9350614c06818560208601613c6b565b614c0f81613a10565b840191505092915050565b60006040820190508181036000830152614c348185614be1565b90508181036020830152614c488184614be1565b90509392505050565b614c5a81614791565b8114614c6557600080fd5b50565b600081519050614c7781614c51565b92915050565b600060208284031215614c9357614c926139fc565b5b6000614ca184828501614c68565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b600081905092915050565b6000614cef82613c4f565b614cf98185614cd9565b9350614d09818560208601613c6b565b80840191505092915050565b6000614d218284614ce4565b915081905092915050565b6000614d37826145e7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614d6a57614d69614add565b5b600182019050919050565b7f43616e6e6f742066696e6420636f6e646974696f6e207769746820746861742060008201527f4944000000000000000000000000000000000000000000000000000000000000602082015250565b6000614dd1602283613c5a565b9150614ddc82614d75565b604082019050919050565b60006020820190508181036000830152614e0081614dc4565b9050919050565b60008190508160005260206000209050919050565b60008154614e2981614b9e565b614e338186614cd9565b94506001821660008114614e4e5760018114614e5f57614e92565b60ff19831686528186019350614e92565b614e6885614e07565b60005b83811015614e8a57815481890152600182019150602081019050614e6b565b838801955050505b50505092915050565b6000614ea78284614e1c565b915081905092915050565b60008154614ebf81614b9e565b614ec98186614bd0565b94506001821660008114614ee45760018114614ef657614f29565b60ff1983168652602086019350614f29565b614eff85614e07565b60005b83811015614f2157815481890152600182019150602081019050614f02565b808801955050505b50505092915050565b50565b6000614f42600083614bd0565b9150614f4d82614f32565b600082019050919050565b60006040820190508181036000830152614f728184614eb2565b90508181036020830152614f8581614f35565b905092915050565b7f436f6e646974696f6e2077697468207468697320494420646f6573206e6f742060008201527f6578697374000000000000000000000000000000000000000000000000000000602082015250565b6000614fe9602583613c5a565b9150614ff482614f8d565b604082019050919050565b6000602082019050818103600083015261501881614fdc565b9050919050565b7f436f6e747261637420697320616c726561647920696e697469616c697a656400600082015250565b6000615055601f83613c5a565b91506150608261501f565b602082019050919050565b6000602082019050818103600083015261508481615048565b9050919050565b6000819050919050565b61509e8161508b565b82525050565b600082825260208201905092915050565b60006150c082613c4f565b6150ca81856150a4565b93506150da818560208601613c6b565b6150e381613a10565b840191505092915050565b60006040830160008301516151066000860182615095565b506020830151848203602086015261511e82826150b5565b9150508091505092915050565b6000602082019050818103600083015261514581846150ee565b905092915050565b6151568161508b565b811461516157600080fd5b50565b6000815190506151738161514d565b92915050565b600061518c61518784613a9c565b613a81565b9050828152602081018484840111156151a8576151a7613a0b565b5b6151b3848285613c6b565b509392505050565b600082601f8301126151d0576151cf613a06565b5b81516151e0848260208601615179565b91505092915050565b6000604082840312156151ff576151fe61423f565b5b6152096040613a81565b9050600061521984828501615164565b600083015250602082015167ffffffffffffffff81111561523d5761523c614244565b5b615249848285016151bb565b60208301525092915050565b60006020828403121561526b5761526a6139fc565b5b600082015167ffffffffffffffff81111561528957615288613a01565b5b615295848285016151e9565b91505092915050565b7f6964000000000000000000000000000000000000000000000000000000000000600082015250565b60006152d4600283614bd0565b91506152df8261529e565b602082019050919050565b6000606082019050818103600083015261530481856150ee565b90508181036020830152615317816152c7565b9050818103604083015261532b8184614be1565b90509392505050565b7f696d706c656d656e746174696f6e496400000000000000000000000000000000600082015250565b600061536a601083614bd0565b915061537582615334565b602082019050919050565b6000606082019050818103600083015261539a81856150ee565b905081810360208301526153ad8161535d565b905081810360408301526153c18184614be1565b90509392505050565b7f6d6574686f644e616d6500000000000000000000000000000000000000000000600082015250565b6000615400600a83614bd0565b915061540b826153ca565b602082019050919050565b6000606082019050818103600083015261543081856150ee565b90508181036020830152615443816153f3565b905081810360408301526154578184614be1565b90509392505050565b7f706172616d547970657300000000000000000000000000000000000000000000600082015250565b6000615496600a83614bd0565b91506154a182615460565b602082019050919050565b600060408201905081810360008301526154c681846150ee565b905081810360208301526154d981615489565b905092915050565b600060408201905081810360008301526154fb81856150ee565b9050818103602083015261550f8184614be1565b90509392505050565b7f726571756972656d656e74730000000000000000000000000000000000000000600082015250565b600061554e600c83614bd0565b915061555982615518565b602082019050919050565b6000604082019050818103600083015261557e81846150ee565b9050818103602083015261559181615541565b905092915050565b600081519050919050565b600081905092915050565b60006155ba82615599565b6155c481856155a4565b93506155d4818560208601613c6b565b80840191505092915050565b60006155ec82846155af565b915081905092915050565b7f7461726765740000000000000000000000000000000000000000000000000000600082015250565b600061562d600683614bd0565b9150615638826155f7565b602082019050919050565b6000604082019050818103600083015261565d8184614be1565b9050818103602083015261567081615620565b905092915050565b7f706172616d000000000000000000000000000000000000000000000000000000600082015250565b60006156ae600583614bd0565b91506156b982615678565b602082019050919050565b600060408201905081810360008301526156de8184614be1565b905081810360208301526156f1816156a1565b905092915050565b7f526571756972656d656e74206c656e677468206d75737420626520657175616c60008201527f20746f2032000000000000000000000000000000000000000000000000000000602082015250565b6000615755602583613c5a565b9150615760826156f9565b604082019050919050565b6000602082019050818103600083015261578481615748565b9050919050565b7f2861646472657373290000000000000000000000000000000000000000000000600082015250565b60006157c1600983614cd9565b91506157cc8261578b565b600982019050919050565b60006157e38284614ce4565b91506157ee826157b4565b915081905092915050565b7f526571756972656d656e74206c656e677468206d75737420626520657175616c60008201527f20746f2033000000000000000000000000000000000000000000000000000000602082015250565b6000615855602583613c5a565b9150615860826157f9565b604082019050919050565b6000602082019050818103600083015261588481615848565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b60006158c76158c26158bd8461588b565b6158a2565b615895565b9050919050565b6158d7816158ac565b82525050565b600060408201905081810360008301526158f78185614be1565b905061590660208301846158ce565b9392505050565b60008151905061591c81614882565b92915050565b600060208284031215615938576159376139fc565b5b60006159468482850161590d565b91505092915050565b7f526571756972656d656e7420706172616d6574657220696e646578206973206f60008201527f7574206f662072616e6765000000000000000000000000000000000000000000602082015250565b60006159ab602b83613c5a565b91506159b68261594f565b604082019050919050565b600060208201905081810360008301526159da8161599e565b9050919050565b7f2800000000000000000000000000000000000000000000000000000000000000600082015250565b6000615a17600183614cd9565b9150615a22826159e1565b600182019050919050565b7f2900000000000000000000000000000000000000000000000000000000000000600082015250565b6000615a63600183614cd9565b9150615a6e82615a2d565b600182019050919050565b6000615a858285614ce4565b9150615a9082615a0a565b9150615a9c8284614ce4565b9150615aa782615a56565b91508190509392505050565b7f556e737570706f7274656420726571756972656d656e74207479706500000000600082015250565b6000615ae9601c83613c5a565b9150615af482615ab3565b602082019050919050565b60006020820190508181036000830152615b1881615adc565b9050919050565b7f496d706c656d656e746174696f6e2061646472657373206973206e6f7420736560008201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b6000615b7b602183613c5a565b9150615b8682615b1f565b604082019050919050565b60006020820190508181036000830152615baa81615b6e565b9050919050565b615bba81613bb5565b82525050565b6000604082019050615bd56000830185615bb1565b8181036020830152615be78184614be1565b90509392505050565b7f496d706c656d656e746174696f6e20646f6573206e6f7420696d706c656d656e60008201527f74206d6574686f642073656c6563746f72000000000000000000000000000000602082015250565b6000615c4c603183613c5a565b9150615c5782615bf0565b604082019050919050565b60006020820190508181036000830152615c7b81615c3f565b9050919050565b600082825260208201905092915050565b6000615c9f8385615c82565b9350615cac838584613acd565b615cb583613a10565b840190509392505050565b6000606082019050615cd56000830187615bb1565b615ce26020830186615bb1565b8181036040830152615cf5818486615c93565b905095945050505050565b7f436f6e646974696f6e2077697468207468697320494420616c7265616479206560008201527f7869737473000000000000000000000000000000000000000000000000000000602082015250565b6000615d5c602583613c5a565b9150615d6782615d00565b604082019050919050565b60006020820190508181036000830152615d8b81615d4f565b9050919050565b7f2000000000000000000000000000000000000000000000000000000000000000600082015250565b6000615dc8600183614bd0565b9150615dd382615d92565b602082019050919050565b60006040820190508181036000830152615df781615dbb565b90508181036020830152615e0b8184614be1565b905092915050565b600060208284031215615e2957615e286139fc565b5b6000615e3784828501615164565b91505092915050565b7f436f6e646974696f6e204944732063616e6e6f74206861766520737061636573600082015250565b6000615e76602083613c5a565b9150615e8182615e40565b602082019050919050565b60006020820190508181036000830152615ea581615e69565b905091905056fea2646970667358221220ee0e3eda07dc8cba8e97ae5842e125f542f2faff30a5254c26d6076d6da6942f64736f6c634300080b0033

Deployed ByteCode Sourcemap

353:14505:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6239:605;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1875:561;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;614:18;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2940:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;3052:746;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8210:366;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;685:38;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4904:136;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;773:52;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;315:104:7;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;13607:325:1;;;:::i;:::-;;7804:314;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6981:297;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10950:96;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;524:49;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;1137:275;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;10725:98;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;115:27:7;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5793:328:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;8703:1920;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14078:189;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7330:308;;;:::i;:::-;;11437:2068;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5155:284;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5546:129;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14610:246;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;884:34;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2556:380;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;465:29;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6239:605;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;6314:29:1::1;6346:13;6383:1:::0;6360:13;:20:::1;;;;:24;;;;:::i;:::-;6346:39;;;;;;;;:::i;:::-;;;;;;;;;6314:71;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6403:20;6391:399;6446:13;:20;;;;6431:12;:35;6391:399;;;6503:32;6538:13;6552:12;6538:27;;;;;;;;:::i;:::-;;;;;;;;;6503:62;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6577:7;:20;6598:18;6618:11;6577:53;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6573:211;;;6672:15;6642:13;6656:12;6642:27;;;;;;;;:::i;:::-;;;;;;;;;:45;;;;;;;;;;;;:::i;:::-;;6697:13;:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;:::i;:::-;;;6733:13;6747:11;6733:26;;;;;;:::i;:::-;;;;;;;;;;;;;;6726:33:::0;::::1;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;6769:7;;;;;6573:211;6495:295;6474:14;;;;;:::i;:::-;;;;6391:399;;;;6795:44;;;;;;;;;;:::i;:::-;;;;;;;;305:1:7;6239:605:1::0;:::o;1875:561::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;2080:25:1::1;2162:1:::0;2108:56:::1;;:18;2127:16;2108:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;:56;;;;2080:84;;2175:20;2170:83;;2205:18;2229:16;2205:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;2170:83;2324:21;2285:18;2304:16;2285:36;;;;;;:::i;:::-;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;2411:20;:18;:20::i;:::-;1994:442;1875:561:::0;;:::o;614:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2940:108::-;2995:15;3025:18;3018:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2940:108;:::o;3052:746::-;3104:23;3135:39;3177:24;:22;:24::i;:::-;3135:66;;3207:39;3277:23;:30;3249:64;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;3207:106;;3331:25;3319:447;3384:23;:30;3364:17;:50;3319:447;;;3456:30;3489:23;3522:17;3489:58;;;;;;;;:::i;:::-;;;;;;;;3456:91;;3555:29;3587:18;3606:16;3587:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;3555:68;;3668:91;;;;;;;;3697:16;3668:91;;;;3729:21;3668:91;;;;;3631:15;3647:17;3631:34;;;;;;;;:::i;:::-;;;;;;;:128;;;;3448:318;;3422:19;;;;;:::i;:::-;;;;3319:447;;;;3778:15;3771:22;;;;3052:746;:::o;8210:366::-;8257:18;8283:30;8332:13;:20;;;;8316:37;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;8283:70;;8371:20;8359:189;8414:13;:20;;;;8399:12;:35;8359:189;;;8499:13;8513;8527:12;8513:27;;;;;;;;:::i;:::-;;;;;;;;;8499:42;;;;;;:::i;:::-;;;;;;;;;;;;;8471:70;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:11;8483:12;8471:25;;;;;;;;:::i;:::-;;;;;;;:70;;;;8442:14;;;;;:::i;:::-;;;;8359:189;;;;8560:11;8553:18;;;8210:366;:::o;685:38::-;;;;;;;;;;;;;:::o;4904:136::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;4977:28:1::1;4995:9;4977:17;:28::i;:::-;5011:24;5025:9;5011:13;:24::i;:::-;4904:136:::0;:::o;773:52::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;315:104:7:-;250:12;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;401:13:::1;386:12;::::0;:28:::1;;;;;;;;;;;;;;;;;;315:104:::0;:::o;13607:325:1:-;13667:20;13655:273;13710:13;:20;;;;13695:12;:35;13655:273;;;13767:25;13795:13;13809:12;13795:27;;;;;;;;:::i;:::-;;;;;;;;;13767:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13830:26;13859:13;13873:11;13859:26;;;;;;:::i;:::-;;;;;;;;;;;;;13830:55;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13893:28;13911:9;13893:17;:28::i;:::-;13759:169;;13738:14;;;;;:::i;:::-;;;;13655:273;;;;13607:325::o;7804:314::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;7880:20:1::1;7904:7;:20;7932:13;7946:9;:12;;;7932:27;;;;;;:::i;:::-;;;;;;;;;;;;;:30;;7904:74;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7903:75;7880:98;;7992:15;7984:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;8055:29;8071:9;:12;;;8055:15;:29::i;:::-;8090:23;8103:9;8090:12;:23::i;:::-;7874:244;7804:314:::0;:::o;6981:297::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;7074:20:1::1;7062:212;7117:14;:21;7102:12;:36;7062:212;;;7175:25;7203:14;7218:12;7203:28;;;;;;;;:::i;:::-;;;;;;;;7175:56;;7239:28;7255:11;7239:15;:28::i;:::-;7167:107;7146:14;;;;;:::i;:::-;;;;7062:212;;;;6981:297:::0;:::o;10950:96::-;10999:7;11021:13;:20;;;;11014:27;;10950:96;:::o;524:49::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1137:275::-;1264:1;1229:37;;:23;;;;;;;;;;;:37;;;1214:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;1345:10;1319:23;;:36;;;;;;;;;;;;;;;;;;1368:5;1361:4;:12;;;;;;;;;;;;:::i;:::-;;1394:13;1379:12;;:28;;;;;;;;;;;;;;;;;;1137:275;;:::o;10725:98::-;10775:15;10805:13;10798:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10725:98;:::o;115:27:7:-;;;;;;;;;;;;:::o;5793:328:1:-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;5910:20:1::1;5898:219;5953:11;:18;5938:12;:33;5898:219;;;6008:26;6037:11;6049:12;6037:25;;;;;;;;:::i;:::-;;;;;;;;6008:54;;6070:40;6100:9;6070:29;:40::i;:::-;6000:117;5979:14;;;;;:::i;:::-;;;;5898:219;;;;5793:328:::0;:::o;8703:1920::-;8750:13;8771:29;8803:16;:14;:16::i;:::-;8771:48;;8845:29;;:::i;:::-;8889:6;:22;;;;:24;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8880:33;;8931:20;8919:1621;8974:10;:17;8959:12;:32;8919:1621;;;9052:26;9081:10;9092:12;9081:24;;;;;;;;:::i;:::-;;;;;;;;9052:53;;9145:6;:23;;;;:25;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9136:34;;9200:6;:26;;;;9233:9;:12;;;9200:46;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9191:55;;9291:6;:26;;;;9355:9;:26;;;9291:98;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9282:107;;9428:6;:26;;;;9469:9;:20;;;9428:62;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9419:71;;9529:6;:22;;;;:36;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9520:45;;9587:20;9573:206;9632:9;:20;;;:27;9617:12;:42;9573:206;;;9711:6;:23;;;;9735:9;:20;;;9756:12;9735:34;;;;;;;;:::i;:::-;;;;;;;;9711:59;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9702:68;;9669:14;;;;;:::i;:::-;;;;9573:206;;;;9795:6;:20;;;;:22;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9786:31;;9857:6;:22;;;;:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9848:47;;9917:22;9903:531;9966:9;:22;;;:29;9949:14;:46;9903:531;;;10040:27;10070:9;:22;;;10093:14;10070:38;;;;;;;;:::i;:::-;;;;;;;;10040:68;;10127:6;:22;;;;:24;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10118:33;;10177:26;10161:224;10236:11;:18;10215;:39;10161:224;;;10318:6;:23;;;;10342:11;10354:18;10342:31;;;;;;;;:::i;:::-;;;;;;;;10318:56;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10309:65;;10266:20;;;;;:::i;:::-;;;;10161:224;;;;10403:6;:20;;;;:22;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10394:31;;10030:404;10005:16;;;;;:::i;:::-;;;;9903:531;;;;10450:6;:20;;;;:22;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10441:31;;10510:6;:21;;;;:23;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10501:32;;9020:1520;8999:14;;;;;:::i;:::-;;;;8919:1621;;;;10571:6;:20;;;;:22;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;10562:31;;10606:6;:12;;;10599:19;;;;8703:1920;:::o;14078:189::-;14126:4;14139:12;14165:4;14157:24;;14189:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14157:85;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14138:104;;;14255:7;14248:14;;;14078:189;:::o;7330:308::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;7384:25:1::1;7412:13;:20;;;;7384:48;;7450:20;7438:196;7493:17;7478:12;:32;7438:196;;;7547:25;7575:13;7589:1;7575:16;;;;;;;;:::i;:::-;;;;;;;;;7547:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7599:28;7615:11;7599:15;:28::i;:::-;7539:95;7518:14;;;;;:::i;:::-;;;;7438:196;;;;7378:260;7330:308::o:0;11437:2068::-;11510:30;11543:9;:22;;;11510:55;;11584:22;11572:1929;11631:12;:19;11614:14;:36;11572:1929;;;11689:27;11719:12;11732:14;11719:28;;;;;;;;:::i;:::-;;;;;;;;11689:58;;11755:29;11787:11;11799:1;11787:14;;;;;;;;:::i;:::-;;;;;;;;11755:46;;11809:41;11853:11;11865:1;11853:14;;;;;;;;:::i;:::-;;;;;;;;11809:58;;11875:29;11912:23;11943:28;11974:7;:20;12004:15;11974:71;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11943:102;;12053:27;12083:7;:20;12113:15;12083:70;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12053:100;;12165:23;12161:858;;;12241:1;12219:11;:18;:23;12200:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;12366:27;12349:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;12313:104;;12161:858;;;12436:22;12432:587;;;12511:1;12489:11;:18;:23;12470:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;12583:16;12602:7;:12;12615:11;12627:1;12615:14;;;;;;;;:::i;:::-;;;;;;;;12631:2;12602:32;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12583:51;;12705:1;12675:9;:20;;;:27;:31;;;;:::i;:::-;12663:8;:43;;12644:129;;;;;;;;;;;;:::i;:::-;;;;;;;;;12795:9;:20;;;12816:8;12795:30;;;;;;;;:::i;:::-;;;;;;;;12783:42;;12888:27;12922:9;12871:66;;;;;;;;;:::i;:::-;;;;;;;;;;;;;12835:112;;12460:496;12432:587;;;12972:38;;;;;;;;;;:::i;:::-;;;;;;;;12432:587;12161:858;13027:29;13059:18;13087:9;:26;;;13059:62;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;13027:94;;13179:1;13146:35;;:21;:35;;;;13129:105;;;;;;;;;;;;:::i;:::-;;;;;;;;;13243:24;13270:13;:39;13319:21;13350:15;13270:103;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13243:130;;13421:4;13398:27;;:19;:27;;;13381:113;;;;;;;;;;;;:::i;:::-;;;;;;;;;11681:1820;;;;;;;;;11658:16;;;;;:::i;:::-;;;;11572:1929;;;;11504:2001;11437:2068;:::o;5155:284::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;5245:20:1::1;5233:202;5288:11;:18;5273:12;:33;5233:202;;;5343:26;5372:11;5384:12;5372:25;;;;;;;;:::i;:::-;;;;;;;;5343:54;;5405:23;5418:9;5405:12;:23::i;:::-;5335:100;5314:14;;;;;:::i;:::-;;;;5233:202;;;;5155:284:::0;:::o;5546:129::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;5646:24:1::1;5660:9;5646:13;:24::i;:::-;5546:129:::0;:::o;14610:246::-;14713:12;14745:18;:46;14807:4;14820:13;14841:4;;14745:106;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14735:116;;14610:246;;;;;:::o;884:34::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2556:380::-;250:12:7;;;;;;;;;;236:26;;:10;:26;;;228:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;2670:25:1::1;2658:274;2723:15;:22;2703:17;:42;2658:274;;;2787:36;2826:15;2842:17;2826:34;;;;;;;;:::i;:::-;;;;;;;;2787:73;;2868:57;2886:14;:17;;;2905:14;:19;;;2868:17;:57::i;:::-;2779:153;2753:19;;;;;:::i;:::-;;;;2658:274;;;;2556:380:::0;:::o;465:29::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;4221:579::-;4322:20;4346:7;:20;4374:13;4388:9;:12;;;4374:27;;;;;;:::i;:::-;;;;;;;;;;;;;:30;;4346:74;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4345:75;4322:98;;4453:5;4434:24;;:15;:24;;;4426:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;4546:16;4617:2;4565:7;:29;4600:9;:12;;;4565:48;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;4546:73;;4648:5;4633:20;;:11;:20;;;4625:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;4748:9;4718:13;4732:9;:12;;;4718:27;;;;;;:::i;:::-;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;4763:13;4782:9;:12;;;4763:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;4281:519;;4221:579;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::o;7:75:9:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:117;443:1;440;433:12;457:117;566:1;563;556:12;580:102;621:6;672:2;668:7;663:2;656:5;652:14;648:28;638:38;;580:102;;;:::o;688:180::-;736:77;733:1;726:88;833:4;830:1;823:15;857:4;854:1;847:15;874:281;957:27;979:4;957:27;:::i;:::-;949:6;945:40;1087:6;1075:10;1072:22;1051:18;1039:10;1036:34;1033:62;1030:88;;;1098:18;;:::i;:::-;1030:88;1138:10;1134:2;1127:22;917:238;874:281;;:::o;1161:129::-;1195:6;1222:20;;:::i;:::-;1212:30;;1251:33;1279:4;1271:6;1251:33;:::i;:::-;1161:129;;;:::o;1296:308::-;1358:4;1448:18;1440:6;1437:30;1434:56;;;1470:18;;:::i;:::-;1434:56;1508:29;1530:6;1508:29;:::i;:::-;1500:37;;1592:4;1586;1582:15;1574:23;;1296:308;;;:::o;1610:154::-;1694:6;1689:3;1684;1671:30;1756:1;1747:6;1742:3;1738:16;1731:27;1610:154;;;:::o;1770:412::-;1848:5;1873:66;1889:49;1931:6;1889:49;:::i;:::-;1873:66;:::i;:::-;1864:75;;1962:6;1955:5;1948:21;2000:4;1993:5;1989:16;2038:3;2029:6;2024:3;2020:16;2017:25;2014:112;;;2045:79;;:::i;:::-;2014:112;2135:41;2169:6;2164:3;2159;2135:41;:::i;:::-;1854:328;1770:412;;;;;:::o;2202:340::-;2258:5;2307:3;2300:4;2292:6;2288:17;2284:27;2274:122;;2315:79;;:::i;:::-;2274:122;2432:6;2419:20;2457:79;2532:3;2524:6;2517:4;2509:6;2505:17;2457:79;:::i;:::-;2448:88;;2264:278;2202:340;;;;:::o;2548:509::-;2617:6;2666:2;2654:9;2645:7;2641:23;2637:32;2634:119;;;2672:79;;:::i;:::-;2634:119;2820:1;2809:9;2805:17;2792:31;2850:18;2842:6;2839:30;2836:117;;;2872:79;;:::i;:::-;2836:117;2977:63;3032:7;3023:6;3012:9;3008:22;2977:63;:::i;:::-;2967:73;;2763:287;2548:509;;;;:::o;3063:126::-;3100:7;3140:42;3133:5;3129:54;3118:65;;3063:126;;;:::o;3195:96::-;3232:7;3261:24;3279:5;3261:24;:::i;:::-;3250:35;;3195:96;;;:::o;3297:122::-;3370:24;3388:5;3370:24;:::i;:::-;3363:5;3360:35;3350:63;;3409:1;3406;3399:12;3350:63;3297:122;:::o;3425:139::-;3471:5;3509:6;3496:20;3487:29;;3525:33;3552:5;3525:33;:::i;:::-;3425:139;;;;:::o;3570:654::-;3648:6;3656;3705:2;3693:9;3684:7;3680:23;3676:32;3673:119;;;3711:79;;:::i;:::-;3673:119;3859:1;3848:9;3844:17;3831:31;3889:18;3881:6;3878:30;3875:117;;;3911:79;;:::i;:::-;3875:117;4016:63;4071:7;4062:6;4051:9;4047:22;4016:63;:::i;:::-;4006:73;;3802:287;4128:2;4154:53;4199:7;4190:6;4179:9;4175:22;4154:53;:::i;:::-;4144:63;;4099:118;3570:654;;;;;:::o;4230:99::-;4282:6;4316:5;4310:12;4300:22;;4230:99;;;:::o;4335:169::-;4419:11;4453:6;4448:3;4441:19;4493:4;4488:3;4484:14;4469:29;;4335:169;;;;:::o;4510:307::-;4578:1;4588:113;4602:6;4599:1;4596:13;4588:113;;;4687:1;4682:3;4678:11;4672:18;4668:1;4663:3;4659:11;4652:39;4624:2;4621:1;4617:10;4612:15;;4588:113;;;4719:6;4716:1;4713:13;4710:101;;;4799:1;4790:6;4785:3;4781:16;4774:27;4710:101;4559:258;4510:307;;;:::o;4823:364::-;4911:3;4939:39;4972:5;4939:39;:::i;:::-;4994:71;5058:6;5053:3;4994:71;:::i;:::-;4987:78;;5074:52;5119:6;5114:3;5107:4;5100:5;5096:16;5074:52;:::i;:::-;5151:29;5173:6;5151:29;:::i;:::-;5146:3;5142:39;5135:46;;4915:272;4823:364;;;;:::o;5193:313::-;5306:4;5344:2;5333:9;5329:18;5321:26;;5393:9;5387:4;5383:20;5379:1;5368:9;5364:17;5357:47;5421:78;5494:4;5485:6;5421:78;:::i;:::-;5413:86;;5193:313;;;;:::o;5512:124::-;5589:6;5623:5;5617:12;5607:22;;5512:124;;;:::o;5642:194::-;5751:11;5785:6;5780:3;5773:19;5825:4;5820:3;5816:14;5801:29;;5642:194;;;;:::o;5842:142::-;5919:4;5942:3;5934:11;;5972:4;5967:3;5963:14;5955:22;;5842:142;;;:::o;5990:159::-;6064:11;6098:6;6093:3;6086:19;6138:4;6133:3;6129:14;6114:29;;5990:159;;;;:::o;6155:344::-;6233:3;6261:39;6294:5;6261:39;:::i;:::-;6316:61;6370:6;6365:3;6316:61;:::i;:::-;6309:68;;6386:52;6431:6;6426:3;6419:4;6412:5;6408:16;6386:52;:::i;:::-;6463:29;6485:6;6463:29;:::i;:::-;6458:3;6454:39;6447:46;;6237:262;6155:344;;;;:::o;6505:196::-;6594:10;6629:66;6691:3;6683:6;6629:66;:::i;:::-;6615:80;;6505:196;;;;:::o;6707:123::-;6787:4;6819;6814:3;6810:14;6802:22;;6707:123;;;:::o;6864:991::-;7003:3;7032:64;7090:5;7032:64;:::i;:::-;7112:96;7201:6;7196:3;7112:96;:::i;:::-;7105:103;;7234:3;7279:4;7271:6;7267:17;7262:3;7258:27;7309:66;7369:5;7309:66;:::i;:::-;7398:7;7429:1;7414:396;7439:6;7436:1;7433:13;7414:396;;;7510:9;7504:4;7500:20;7495:3;7488:33;7561:6;7555:13;7589:84;7668:4;7653:13;7589:84;:::i;:::-;7581:92;;7696:70;7759:6;7696:70;:::i;:::-;7686:80;;7795:4;7790:3;7786:14;7779:21;;7474:336;7461:1;7458;7454:9;7449:14;;7414:396;;;7418:14;7826:4;7819:11;;7846:3;7839:10;;7008:847;;;;;6864:991;;;;:::o;7861:413::-;8024:4;8062:2;8051:9;8047:18;8039:26;;8111:9;8105:4;8101:20;8097:1;8086:9;8082:17;8075:47;8139:128;8262:4;8253:6;8139:128;:::i;:::-;8131:136;;7861:413;;;;:::o;8280:145::-;8378:6;8412:5;8406:12;8396:22;;8280:145;;;:::o;8431:215::-;8561:11;8595:6;8590:3;8583:19;8635:4;8630:3;8626:14;8611:29;;8431:215;;;;:::o;8652:163::-;8750:4;8773:3;8765:11;;8803:4;8798:3;8794:14;8786:22;;8652:163;;;:::o;8821:108::-;8898:24;8916:5;8898:24;:::i;:::-;8893:3;8886:37;8821:108;;:::o;9009:606::-;9130:3;9166:4;9161:3;9157:14;9251:4;9244:5;9240:16;9234:23;9304:3;9298:4;9294:14;9287:4;9282:3;9278:14;9271:38;9330:73;9398:4;9384:12;9330:73;:::i;:::-;9322:81;;9181:233;9496:4;9489:5;9485:16;9479:23;9515:63;9572:4;9567:3;9563:14;9549:12;9515:63;:::i;:::-;9424:164;9605:4;9598:11;;9135:480;9009:606;;;;:::o;9621:280::-;9752:10;9787:108;9891:3;9883:6;9787:108;:::i;:::-;9773:122;;9621:280;;;;:::o;9907:144::-;10008:4;10040;10035:3;10031:14;10023:22;;9907:144;;;:::o;10135:1159::-;10316:3;10345:85;10424:5;10345:85;:::i;:::-;10446:117;10556:6;10551:3;10446:117;:::i;:::-;10439:124;;10589:3;10634:4;10626:6;10622:17;10617:3;10613:27;10664:87;10745:5;10664:87;:::i;:::-;10774:7;10805:1;10790:459;10815:6;10812:1;10809:13;10790:459;;;10886:9;10880:4;10876:20;10871:3;10864:33;10937:6;10931:13;10965:126;11086:4;11071:13;10965:126;:::i;:::-;10957:134;;11114:91;11198:6;11114:91;:::i;:::-;11104:101;;11234:4;11229:3;11225:14;11218:21;;10850:399;10837:1;10834;10830:9;10825:14;;10790:459;;;10794:14;11265:4;11258:11;;11285:3;11278:10;;10321:973;;;;;10135:1159;;;;:::o;11300:497::-;11505:4;11543:2;11532:9;11528:18;11520:26;;11592:9;11586:4;11582:20;11578:1;11567:9;11563:17;11556:47;11620:170;11785:4;11776:6;11620:170;:::i;:::-;11612:178;;11300:497;;;;:::o;11803:141::-;11897:6;11931:5;11925:12;11915:22;;11803:141;;;:::o;11950:211::-;12076:11;12110:6;12105:3;12098:19;12150:4;12145:3;12141:14;12126:29;;11950:211;;;;:::o;12167:159::-;12261:4;12284:3;12276:11;;12314:4;12309:3;12305:14;12297:22;;12167:159;;;:::o;12332:184::-;12431:11;12465:6;12460:3;12453:19;12505:4;12500:3;12496:14;12481:29;;12332:184;;;;:::o;12550:971::-;12679:3;12708:64;12766:5;12708:64;:::i;:::-;12788:86;12867:6;12862:3;12788:86;:::i;:::-;12781:93;;12900:3;12945:4;12937:6;12933:17;12928:3;12924:27;12975:66;13035:5;12975:66;:::i;:::-;13064:7;13095:1;13080:396;13105:6;13102:1;13099:13;13080:396;;;13176:9;13170:4;13166:20;13161:3;13154:33;13227:6;13221:13;13255:84;13334:4;13319:13;13255:84;:::i;:::-;13247:92;;13362:70;13425:6;13362:70;:::i;:::-;13352:80;;13461:4;13456:3;13452:14;13445:21;;13140:336;13127:1;13124;13120:9;13115:14;;13080:396;;;13084:14;13492:4;13485:11;;13512:3;13505:10;;12684:837;;;;;12550:971;;;;:::o;13527:149::-;13629:6;13663:5;13657:12;13647:22;;13527:149;;;:::o;13682:209::-;13806:11;13840:6;13835:3;13828:19;13880:4;13875:3;13871:14;13856:29;;13682:209;;;;:::o;13897:167::-;13999:4;14022:3;14014:11;;14052:4;14047:3;14043:14;14035:22;;13897:167;;;:::o;14070:296::-;14209:10;14244:116;14356:3;14348:6;14244:116;:::i;:::-;14230:130;;14070:296;;;;:::o;14372:148::-;14477:4;14509;14504:3;14500:14;14492:22;;14372:148;;;:::o;14558:1171::-;14737:3;14766:89;14849:5;14766:89;:::i;:::-;14871:111;14975:6;14970:3;14871:111;:::i;:::-;14864:118;;15008:3;15053:4;15045:6;15041:17;15036:3;15032:27;15083:91;15168:5;15083:91;:::i;:::-;15197:7;15228:1;15213:471;15238:6;15235:1;15232:13;15213:471;;;15309:9;15303:4;15299:20;15294:3;15287:33;15360:6;15354:13;15388:134;15517:4;15502:13;15388:134;:::i;:::-;15380:142;;15545:95;15633:6;15545:95;:::i;:::-;15535:105;;15669:4;15664:3;15660:14;15653:21;;15273:411;15260:1;15257;15253:9;15248:14;;15213:471;;;15217:14;15700:4;15693:11;;15720:3;15713:10;;14742:987;;;;;14558:1171;;;;:::o;15801:1586::-;15914:3;15950:4;15945:3;15941:14;16035:4;16028:5;16024:16;16018:23;16088:3;16082:4;16078:14;16071:4;16066:3;16062:14;16055:38;16114:73;16182:4;16168:12;16114:73;:::i;:::-;16106:81;;15965:233;16292:4;16285:5;16281:16;16275:23;16345:3;16339:4;16335:14;16328:4;16323:3;16319:14;16312:38;16371:73;16439:4;16425:12;16371:73;:::i;:::-;16363:81;;16208:247;16543:4;16536:5;16532:16;16526:23;16596:3;16590:4;16586:14;16579:4;16574:3;16570:14;16563:38;16622:73;16690:4;16676:12;16622:73;:::i;:::-;16614:81;;16465:241;16794:4;16787:5;16783:16;16777:23;16847:3;16841:4;16837:14;16830:4;16825:3;16821:14;16814:38;16873:123;16991:4;16977:12;16873:123;:::i;:::-;16865:131;;16716:291;17097:4;17090:5;17086:16;17080:23;17150:3;17144:4;17140:14;17133:4;17128:3;17124:14;17117:38;17176:173;17344:4;17330:12;17176:173;:::i;:::-;17168:181;;17017:343;17377:4;17370:11;;15919:1468;15801:1586;;;;:::o;17393:264::-;17516:10;17551:100;17647:3;17639:6;17551:100;:::i;:::-;17537:114;;17393:264;;;;:::o;17663:140::-;17760:4;17792;17787:3;17783:14;17775:22;;17663:140;;;:::o;17879:1127::-;18052:3;18081:81;18156:5;18081:81;:::i;:::-;18178:113;18284:6;18279:3;18178:113;:::i;:::-;18171:120;;18317:3;18362:4;18354:6;18350:17;18345:3;18341:27;18392:83;18469:5;18392:83;:::i;:::-;18498:7;18529:1;18514:447;18539:6;18536:1;18533:13;18514:447;;;18610:9;18604:4;18600:20;18595:3;18588:33;18661:6;18655:13;18689:118;18802:4;18787:13;18689:118;:::i;:::-;18681:126;;18830:87;18910:6;18830:87;:::i;:::-;18820:97;;18946:4;18941:3;18937:14;18930:21;;18574:387;18561:1;18558;18554:9;18549:14;;18514:447;;;18518:14;18977:4;18970:11;;18997:3;18990:10;;18057:949;;;;;17879:1127;;;;:::o;19012:481::-;19209:4;19247:2;19236:9;19232:18;19224:26;;19296:9;19290:4;19286:20;19282:1;19271:9;19267:17;19260:47;19324:162;19481:4;19472:6;19324:162;:::i;:::-;19316:170;;19012:481;;;;:::o;19499:118::-;19586:24;19604:5;19586:24;:::i;:::-;19581:3;19574:37;19499:118;;:::o;19623:222::-;19716:4;19754:2;19743:9;19739:18;19731:26;;19767:71;19835:1;19824:9;19820:17;19811:6;19767:71;:::i;:::-;19623:222;;;;:::o;19851:117::-;19960:1;19957;19950:12;19974:117;20083:1;20080;20073:12;20097:321;20184:4;20274:18;20266:6;20263:30;20260:56;;;20296:18;;:::i;:::-;20260:56;20346:4;20338:6;20334:17;20326:25;;20406:4;20400;20396:15;20388:23;;20097:321;;;:::o;20424:117::-;20533:1;20530;20523:12;20563:945;20669:5;20694:91;20710:74;20777:6;20710:74;:::i;:::-;20694:91;:::i;:::-;20685:100;;20805:5;20834:6;20827:5;20820:21;20868:4;20861:5;20857:16;20850:23;;20921:4;20913:6;20909:17;20901:6;20897:30;20950:3;20942:6;20939:15;20936:122;;;20969:79;;:::i;:::-;20936:122;21084:6;21067:435;21101:6;21096:3;21093:15;21067:435;;;21190:3;21177:17;21226:18;21213:11;21210:35;21207:122;;;21248:79;;:::i;:::-;21207:122;21372:11;21364:6;21360:24;21410:47;21453:3;21441:10;21410:47;:::i;:::-;21405:3;21398:60;21487:4;21482:3;21478:14;21471:21;;21143:359;;21127:4;21122:3;21118:14;21111:21;;21067:435;;;21071:21;20675:833;;20563:945;;;;;:::o;21530:390::-;21611:5;21660:3;21653:4;21645:6;21641:17;21637:27;21627:122;;21668:79;;:::i;:::-;21627:122;21785:6;21772:20;21810:104;21910:3;21902:6;21895:4;21887:6;21883:17;21810:104;:::i;:::-;21801:113;;21617:303;21530:390;;;;:::o;21926:346::-;22038:4;22128:18;22120:6;22117:30;22114:56;;;22150:18;;:::i;:::-;22114:56;22200:4;22192:6;22188:17;22180:25;;22260:4;22254;22250:15;22242:23;;21926:346;;;:::o;22296:1020::-;22427:5;22452:116;22468:99;22560:6;22468:99;:::i;:::-;22452:116;:::i;:::-;22443:125;;22588:5;22617:6;22610:5;22603:21;22651:4;22644:5;22640:16;22633:23;;22704:4;22696:6;22692:17;22684:6;22680:30;22733:3;22725:6;22722:15;22719:122;;;22752:79;;:::i;:::-;22719:122;22867:6;22850:460;22884:6;22879:3;22876:15;22850:460;;;22973:3;22960:17;23009:18;22996:11;22993:35;22990:122;;;23031:79;;:::i;:::-;22990:122;23155:11;23147:6;23143:24;23193:72;23261:3;23249:10;23193:72;:::i;:::-;23188:3;23181:85;23295:4;23290:3;23286:14;23279:21;;22926:384;;22910:4;22905:3;22901:14;22894:21;;22850:460;;;22854:21;22433:883;;22296:1020;;;;;:::o;23340:440::-;23446:5;23495:3;23488:4;23480:6;23476:17;23472:27;23462:122;;23503:79;;:::i;:::-;23462:122;23620:6;23607:20;23645:129;23770:3;23762:6;23755:4;23747:6;23743:17;23645:129;:::i;:::-;23636:138;;23452:328;23340:440;;;;:::o;23821:2015::-;23897:5;23941:4;23929:9;23924:3;23920:19;23916:30;23913:117;;;23949:79;;:::i;:::-;23913:117;24048:21;24064:4;24048:21;:::i;:::-;24039:30;;24154:1;24143:9;24139:17;24126:31;24184:18;24176:6;24173:30;24170:117;;;24206:79;;:::i;:::-;24170:117;24326:59;24381:3;24372:6;24361:9;24357:22;24326:59;:::i;:::-;24319:4;24312:5;24308:16;24301:85;24079:318;24496:2;24485:9;24481:18;24468:32;24527:18;24519:6;24516:30;24513:117;;;24549:79;;:::i;:::-;24513:117;24669:59;24724:3;24715:6;24704:9;24700:22;24669:59;:::i;:::-;24662:4;24655:5;24651:16;24644:85;24407:333;24833:2;24822:9;24818:18;24805:32;24864:18;24856:6;24853:30;24850:117;;;24886:79;;:::i;:::-;24850:117;25006:59;25061:3;25052:6;25041:9;25037:22;25006:59;:::i;:::-;24999:4;24992:5;24988:16;24981:85;24750:327;25170:2;25159:9;25155:18;25142:32;25201:18;25193:6;25190:30;25187:117;;;25223:79;;:::i;:::-;25187:117;25343:84;25423:3;25414:6;25403:9;25399:22;25343:84;:::i;:::-;25336:4;25329:5;25325:16;25318:110;25087:352;25534:3;25523:9;25519:19;25506:33;25566:18;25558:6;25555:30;25552:117;;;25588:79;;:::i;:::-;25552:117;25708:109;25813:3;25804:6;25793:9;25789:22;25708:109;:::i;:::-;25701:4;25694:5;25690:16;25683:135;25449:380;23821:2015;;;;:::o;25842:543::-;25928:6;25977:2;25965:9;25956:7;25952:23;25948:32;25945:119;;;25983:79;;:::i;:::-;25945:119;26131:1;26120:9;26116:17;26103:31;26161:18;26153:6;26150:30;26147:117;;;26183:79;;:::i;:::-;26147:117;26288:80;26360:7;26351:6;26340:9;26336:22;26288:80;:::i;:::-;26278:90;;26074:304;25842:543;;;;:::o;26391:329::-;26450:6;26499:2;26487:9;26478:7;26474:23;26470:32;26467:119;;;26505:79;;:::i;:::-;26467:119;26625:1;26650:53;26695:7;26686:6;26675:9;26671:22;26650:53;:::i;:::-;26640:63;;26596:117;26391:329;;;;:::o;26726:559::-;26820:6;26869:2;26857:9;26848:7;26844:23;26840:32;26837:119;;;26875:79;;:::i;:::-;26837:119;27023:1;27012:9;27008:17;26995:31;27053:18;27045:6;27042:30;27039:117;;;27075:79;;:::i;:::-;27039:117;27180:88;27260:7;27251:6;27240:9;27236:22;27180:88;:::i;:::-;27170:98;;26966:312;26726:559;;;;:::o;27291:77::-;27328:7;27357:5;27346:16;;27291:77;;;:::o;27374:118::-;27461:24;27479:5;27461:24;:::i;:::-;27456:3;27449:37;27374:118;;:::o;27498:222::-;27591:4;27629:2;27618:9;27614:18;27606:26;;27642:71;27710:1;27699:9;27695:17;27686:6;27642:71;:::i;:::-;27498:222;;;;:::o;27726:715::-;27935:4;27973:2;27962:9;27958:18;27950:26;;28022:9;28016:4;28012:20;28008:1;27997:9;27993:17;27986:47;28050:78;28123:4;28114:6;28050:78;:::i;:::-;28042:86;;28175:9;28169:4;28165:20;28160:2;28149:9;28145:18;28138:48;28203:78;28276:4;28267:6;28203:78;:::i;:::-;28195:86;;28328:9;28322:4;28318:20;28313:2;28302:9;28298:18;28291:48;28356:78;28429:4;28420:6;28356:78;:::i;:::-;28348:86;;27726:715;;;;;;:::o;28447:338::-;28551:4;28641:18;28633:6;28630:30;28627:56;;;28663:18;;:::i;:::-;28627:56;28713:4;28705:6;28701:17;28693:25;;28773:4;28767;28763:15;28755:23;;28447:338;;;:::o;28828:996::-;28951:5;28976:108;28992:91;29076:6;28992:91;:::i;:::-;28976:108;:::i;:::-;28967:117;;29104:5;29133:6;29126:5;29119:21;29167:4;29160:5;29156:16;29149:23;;29220:4;29212:6;29208:17;29200:6;29196:30;29249:3;29241:6;29238:15;29235:122;;;29268:79;;:::i;:::-;29235:122;29383:6;29366:452;29400:6;29395:3;29392:15;29366:452;;;29489:3;29476:17;29525:18;29512:11;29509:35;29506:122;;;29547:79;;:::i;:::-;29506:122;29671:11;29663:6;29659:24;29709:64;29769:3;29757:10;29709:64;:::i;:::-;29704:3;29697:77;29803:4;29798:3;29794:14;29787:21;;29442:376;;29426:4;29421:3;29417:14;29410:21;;29366:452;;;29370:21;28957:867;;28828:996;;;;;:::o;29867:424::-;29965:5;30014:3;30007:4;29999:6;29995:17;29991:27;29981:122;;30022:79;;:::i;:::-;29981:122;30139:6;30126:20;30164:121;30281:3;30273:6;30266:4;30258:6;30254:17;30164:121;:::i;:::-;30155:130;;29971:320;29867:424;;;;:::o;30297:593::-;30408:6;30457:2;30445:9;30436:7;30432:23;30428:32;30425:119;;;30463:79;;:::i;:::-;30425:119;30611:1;30600:9;30596:17;30583:31;30641:18;30633:6;30630:30;30627:117;;;30663:79;;:::i;:::-;30627:117;30768:105;30865:7;30856:6;30845:9;30841:22;30768:105;:::i;:::-;30758:115;;30554:329;30297:593;;;;:::o;30896:90::-;30930:7;30973:5;30966:13;30959:21;30948:32;;30896:90;;;:::o;30992:109::-;31073:21;31088:5;31073:21;:::i;:::-;31068:3;31061:34;30992:109;;:::o;31107:210::-;31194:4;31232:2;31221:9;31217:18;31209:26;;31245:65;31307:1;31296:9;31292:17;31283:6;31245:65;:::i;:::-;31107:210;;;;:::o;31323:117::-;31432:1;31429;31422:12;31459:552;31516:8;31526:6;31576:3;31569:4;31561:6;31557:17;31553:27;31543:122;;31584:79;;:::i;:::-;31543:122;31697:6;31684:20;31674:30;;31727:18;31719:6;31716:30;31713:117;;;31749:79;;:::i;:::-;31713:117;31863:4;31855:6;31851:17;31839:29;;31917:3;31909:4;31901:6;31897:17;31887:8;31883:32;31880:41;31877:128;;;31924:79;;:::i;:::-;31877:128;31459:552;;;;;:::o;32017:672::-;32096:6;32104;32112;32161:2;32149:9;32140:7;32136:23;32132:32;32129:119;;;32167:79;;:::i;:::-;32129:119;32287:1;32312:53;32357:7;32348:6;32337:9;32333:22;32312:53;:::i;:::-;32302:63;;32258:117;32442:2;32431:9;32427:18;32414:32;32473:18;32465:6;32462:30;32459:117;;;32495:79;;:::i;:::-;32459:117;32608:64;32664:7;32655:6;32644:9;32640:22;32608:64;:::i;:::-;32590:82;;;;32385:297;32017:672;;;;;:::o;32695:122::-;32768:24;32786:5;32768:24;:::i;:::-;32761:5;32758:35;32748:63;;32807:1;32804;32797:12;32748:63;32695:122;:::o;32823:139::-;32869:5;32907:6;32894:20;32885:29;;32923:33;32950:5;32923:33;:::i;:::-;32823:139;;;;:::o;32968:329::-;33027:6;33076:2;33064:9;33055:7;33051:23;33047:32;33044:119;;;33082:79;;:::i;:::-;33044:119;33202:1;33227:53;33272:7;33263:6;33252:9;33248:22;33227:53;:::i;:::-;33217:63;;33173:117;32968:329;;;;:::o;33303:342::-;33411:4;33501:18;33493:6;33490:30;33487:56;;;33523:18;;:::i;:::-;33487:56;33573:4;33565:6;33561:17;33553:25;;33633:4;33627;33623:15;33615:23;;33303:342;;;:::o;33690:748::-;33770:5;33814:4;33802:9;33797:3;33793:19;33789:30;33786:117;;;33822:79;;:::i;:::-;33786:117;33921:21;33937:4;33921:21;:::i;:::-;33912:30;;34027:1;34016:9;34012:17;33999:31;34057:18;34049:6;34046:30;34043:117;;;34079:79;;:::i;:::-;34043:117;34199:59;34254:3;34245:6;34234:9;34230:22;34199:59;:::i;:::-;34192:4;34185:5;34181:16;34174:85;33952:318;34329:2;34370:49;34415:3;34406:6;34395:9;34391:22;34370:49;:::i;:::-;34363:4;34356:5;34352:16;34345:75;34280:151;33690:748;;;;:::o;34485:1008::-;34612:5;34637:112;34653:95;34741:6;34653:95;:::i;:::-;34637:112;:::i;:::-;34628:121;;34769:5;34798:6;34791:5;34784:21;34832:4;34825:5;34821:16;34814:23;;34885:4;34877:6;34873:17;34865:6;34861:30;34914:3;34906:6;34903:15;34900:122;;;34933:79;;:::i;:::-;34900:122;35048:6;35031:456;35065:6;35060:3;35057:15;35031:456;;;35154:3;35141:17;35190:18;35177:11;35174:35;35171:122;;;35212:79;;:::i;:::-;35171:122;35336:11;35328:6;35324:24;35374:68;35438:3;35426:10;35374:68;:::i;:::-;35369:3;35362:81;35472:4;35467:3;35463:14;35456:21;;35107:380;;35091:4;35086:3;35082:14;35075:21;;35031:456;;;35035:21;34618:875;;34485:1008;;;;;:::o;35540:432::-;35642:5;35691:3;35684:4;35676:6;35672:17;35668:27;35658:122;;35699:79;;:::i;:::-;35658:122;35816:6;35803:20;35841:125;35962:3;35954:6;35947:4;35939:6;35935:17;35841:125;:::i;:::-;35832:134;;35648:324;35540:432;;;;:::o;35978:601::-;36093:6;36142:2;36130:9;36121:7;36117:23;36113:32;36110:119;;;36148:79;;:::i;:::-;36110:119;36296:1;36285:9;36281:17;36268:31;36326:18;36318:6;36315:30;36312:117;;;36348:79;;:::i;:::-;36312:117;36453:109;36554:7;36545:6;36534:9;36530:22;36453:109;:::i;:::-;36443:119;;36239:333;35978:601;;;;:::o;36585:182::-;36725:34;36721:1;36713:6;36709:14;36702:58;36585:182;:::o;36773:366::-;36915:3;36936:67;37000:2;36995:3;36936:67;:::i;:::-;36929:74;;37012:93;37101:3;37012:93;:::i;:::-;37130:2;37125:3;37121:12;37114:19;;36773:366;;;:::o;37145:419::-;37311:4;37349:2;37338:9;37334:18;37326:26;;37398:9;37392:4;37388:20;37384:1;37373:9;37369:17;37362:47;37426:131;37552:4;37426:131;:::i;:::-;37418:139;;37145:419;;;:::o;37570:180::-;37618:77;37615:1;37608:88;37715:4;37712:1;37705:15;37739:4;37736:1;37729:15;37756:191;37796:4;37816:20;37834:1;37816:20;:::i;:::-;37811:25;;37850:20;37868:1;37850:20;:::i;:::-;37845:25;;37889:1;37886;37883:8;37880:34;;;37894:18;;:::i;:::-;37880:34;37939:1;37936;37932:9;37924:17;;37756:191;;;;:::o;37953:180::-;38001:77;37998:1;37991:88;38098:4;38095:1;38088:15;38122:4;38119:1;38112:15;38139:180;38187:77;38184:1;38177:88;38284:4;38281:1;38274:15;38308:4;38305:1;38298:15;38325:320;38369:6;38406:1;38400:4;38396:12;38386:22;;38453:1;38447:4;38443:12;38474:18;38464:81;;38530:4;38522:6;38518:17;38508:27;;38464:81;38592:2;38584:6;38581:14;38561:18;38558:38;38555:84;;;38611:18;;:::i;:::-;38555:84;38376:269;38325:320;;;:::o;38651:177::-;38743:11;38777:6;38772:3;38765:19;38817:4;38812:3;38808:14;38793:29;;38651:177;;;;:::o;38834:380::-;38930:3;38958:39;38991:5;38958:39;:::i;:::-;39013:79;39085:6;39080:3;39013:79;:::i;:::-;39006:86;;39101:52;39146:6;39141:3;39134:4;39127:5;39123:16;39101:52;:::i;:::-;39178:29;39200:6;39178:29;:::i;:::-;39173:3;39169:39;39162:46;;38934:280;38834:380;;;;:::o;39220:538::-;39389:4;39427:2;39416:9;39412:18;39404:26;;39476:9;39470:4;39466:20;39462:1;39451:9;39447:17;39440:47;39504:86;39585:4;39576:6;39504:86;:::i;:::-;39496:94;;39637:9;39631:4;39627:20;39622:2;39611:9;39607:18;39600:48;39665:86;39746:4;39737:6;39665:86;:::i;:::-;39657:94;;39220:538;;;;;:::o;39764:116::-;39834:21;39849:5;39834:21;:::i;:::-;39827:5;39824:32;39814:60;;39870:1;39867;39860:12;39814:60;39764:116;:::o;39886:137::-;39940:5;39971:6;39965:13;39956:22;;39987:30;40011:5;39987:30;:::i;:::-;39886:137;;;;:::o;40029:345::-;40096:6;40145:2;40133:9;40124:7;40120:23;40116:32;40113:119;;;40151:79;;:::i;:::-;40113:119;40271:1;40296:61;40349:7;40340:6;40329:9;40325:22;40296:61;:::i;:::-;40286:71;;40242:125;40029:345;;;;:::o;40380:180::-;40428:77;40425:1;40418:88;40525:4;40522:1;40515:15;40549:4;40546:1;40539:15;40566:148;40668:11;40705:3;40690:18;;40566:148;;;;:::o;40720:377::-;40826:3;40854:39;40887:5;40854:39;:::i;:::-;40909:89;40991:6;40986:3;40909:89;:::i;:::-;40902:96;;41007:52;41052:6;41047:3;41040:4;41033:5;41029:16;41007:52;:::i;:::-;41084:6;41079:3;41075:16;41068:23;;40830:267;40720:377;;;;:::o;41103:275::-;41235:3;41257:95;41348:3;41339:6;41257:95;:::i;:::-;41250:102;;41369:3;41362:10;;41103:275;;;;:::o;41384:233::-;41423:3;41446:24;41464:5;41446:24;:::i;:::-;41437:33;;41492:66;41485:5;41482:77;41479:103;;;41562:18;;:::i;:::-;41479:103;41609:1;41602:5;41598:13;41591:20;;41384:233;;;:::o;41623:221::-;41763:34;41759:1;41751:6;41747:14;41740:58;41832:4;41827:2;41819:6;41815:15;41808:29;41623:221;:::o;41850:366::-;41992:3;42013:67;42077:2;42072:3;42013:67;:::i;:::-;42006:74;;42089:93;42178:3;42089:93;:::i;:::-;42207:2;42202:3;42198:12;42191:19;;41850:366;;;:::o;42222:419::-;42388:4;42426:2;42415:9;42411:18;42403:26;;42475:9;42469:4;42465:20;42461:1;42450:9;42446:17;42439:47;42503:131;42629:4;42503:131;:::i;:::-;42495:139;;42222:419;;;:::o;42647:141::-;42696:4;42719:3;42711:11;;42742:3;42739:1;42732:14;42776:4;42773:1;42763:18;42755:26;;42647:141;;;:::o;42818:845::-;42921:3;42958:5;42952:12;42987:36;43013:9;42987:36;:::i;:::-;43039:89;43121:6;43116:3;43039:89;:::i;:::-;43032:96;;43159:1;43148:9;43144:17;43175:1;43170:137;;;;43321:1;43316:341;;;;43137:520;;43170:137;43254:4;43250:9;43239;43235:25;43230:3;43223:38;43290:6;43285:3;43281:16;43274:23;;43170:137;;43316:341;43383:38;43415:5;43383:38;:::i;:::-;43443:1;43457:154;43471:6;43468:1;43465:13;43457:154;;;43545:7;43539:14;43535:1;43530:3;43526:11;43519:35;43595:1;43586:7;43582:15;43571:26;;43493:4;43490:1;43486:12;43481:17;;43457:154;;;43640:6;43635:3;43631:16;43624:23;;43323:334;;43137:520;;42925:738;;42818:845;;;;:::o;43669:269::-;43798:3;43820:92;43908:3;43899:6;43820:92;:::i;:::-;43813:99;;43929:3;43922:10;;43669:269;;;;:::o;43968:818::-;44061:3;44098:5;44092:12;44127:36;44153:9;44127:36;:::i;:::-;44179:79;44251:6;44246:3;44179:79;:::i;:::-;44172:86;;44289:1;44278:9;44274:17;44305:1;44300:135;;;;44449:1;44444:336;;;;44267:513;;44300:135;44384:4;44380:9;44369;44365:25;44360:3;44353:38;44420:4;44415:3;44411:14;44404:21;;44300:135;;44444:336;44511:38;44543:5;44511:38;:::i;:::-;44571:1;44585:154;44599:6;44596:1;44593:13;44585:154;;;44673:7;44667:14;44663:1;44658:3;44654:11;44647:35;44723:1;44714:7;44710:15;44699:26;;44621:4;44618:1;44614:12;44609:17;;44585:154;;;44768:1;44763:3;44759:11;44752:18;;44451:329;;44267:513;;44065:721;;43968:818;;;;:::o;44792:114::-;;:::o;44912:380::-;45062:3;45083:74;45155:1;45150:3;45083:74;:::i;:::-;45076:81;;45166:93;45255:3;45166:93;:::i;:::-;45284:1;45279:3;45275:11;45268:18;;44912:380;;;:::o;45298:638::-;45517:4;45555:2;45544:9;45540:18;45532:26;;45604:9;45598:4;45594:20;45590:1;45579:9;45575:17;45568:47;45632:83;45710:4;45701:6;45632:83;:::i;:::-;45624:91;;45762:9;45756:4;45752:20;45747:2;45736:9;45732:18;45725:48;45790:139;45924:4;45790:139;:::i;:::-;45782:147;;45298:638;;;;:::o;45942:224::-;46082:34;46078:1;46070:6;46066:14;46059:58;46151:7;46146:2;46138:6;46134:15;46127:32;45942:224;:::o;46172:366::-;46314:3;46335:67;46399:2;46394:3;46335:67;:::i;:::-;46328:74;;46411:93;46500:3;46411:93;:::i;:::-;46529:2;46524:3;46520:12;46513:19;;46172:366;;;:::o;46544:419::-;46710:4;46748:2;46737:9;46733:18;46725:26;;46797:9;46791:4;46787:20;46783:1;46772:9;46768:17;46761:47;46825:131;46951:4;46825:131;:::i;:::-;46817:139;;46544:419;;;:::o;46969:181::-;47109:33;47105:1;47097:6;47093:14;47086:57;46969:181;:::o;47156:366::-;47298:3;47319:67;47383:2;47378:3;47319:67;:::i;:::-;47312:74;;47395:93;47484:3;47395:93;:::i;:::-;47513:2;47508:3;47504:12;47497:19;;47156:366;;;:::o;47528:419::-;47694:4;47732:2;47721:9;47717:18;47709:26;;47781:9;47775:4;47771:20;47767:1;47756:9;47752:17;47745:47;47809:131;47935:4;47809:131;:::i;:::-;47801:139;;47528:419;;;:::o;47953:76::-;47989:7;48018:5;48007:16;;47953:76;;;:::o;48035:113::-;48118:23;48135:5;48118:23;:::i;:::-;48113:3;48106:36;48035:113;;:::o;48154:167::-;48236:11;48270:6;48265:3;48258:19;48310:4;48305:3;48301:14;48286:29;;48154:167;;;;:::o;48327:360::-;48413:3;48441:39;48474:5;48441:39;:::i;:::-;48496:69;48558:6;48553:3;48496:69;:::i;:::-;48489:76;;48574:52;48619:6;48614:3;48607:4;48600:5;48596:16;48574:52;:::i;:::-;48651:29;48673:6;48651:29;:::i;:::-;48646:3;48642:39;48635:46;;48417:270;48327:360;;;;:::o;48749:634::-;48870:3;48906:4;48901:3;48897:14;49004:4;48997:5;48993:16;48987:23;49023:69;49086:4;49081:3;49077:14;49063:12;49023:69;:::i;:::-;48921:181;49185:4;49178:5;49174:16;49168:23;49238:3;49232:4;49228:14;49221:4;49216:3;49212:14;49205:38;49264:81;49340:4;49326:12;49264:81;:::i;:::-;49256:89;;49112:244;49373:4;49366:11;;48875:508;48749:634;;;;:::o;49389:377::-;49534:4;49572:2;49561:9;49557:18;49549:26;;49621:9;49615:4;49611:20;49607:1;49596:9;49592:17;49585:47;49649:110;49754:4;49745:6;49649:110;:::i;:::-;49641:118;;49389:377;;;;:::o;49772:120::-;49844:23;49861:5;49844:23;:::i;:::-;49837:5;49834:34;49824:62;;49882:1;49879;49872:12;49824:62;49772:120;:::o;49898:141::-;49954:5;49985:6;49979:13;49970:22;;50001:32;50027:5;50001:32;:::i;:::-;49898:141;;;;:::o;50045:421::-;50134:5;50159:66;50175:49;50217:6;50175:49;:::i;:::-;50159:66;:::i;:::-;50150:75;;50248:6;50241:5;50234:21;50286:4;50279:5;50275:16;50324:3;50315:6;50310:3;50306:16;50303:25;50300:112;;;50331:79;;:::i;:::-;50300:112;50421:39;50453:6;50448:3;50443;50421:39;:::i;:::-;50140:326;50045:421;;;;;:::o;50486:355::-;50553:5;50602:3;50595:4;50587:6;50583:17;50579:27;50569:122;;50610:79;;:::i;:::-;50569:122;50720:6;50714:13;50745:90;50831:3;50823:6;50816:4;50808:6;50804:17;50745:90;:::i;:::-;50736:99;;50559:282;50486:355;;;;:::o;50877:778::-;50959:5;51003:4;50991:9;50986:3;50982:19;50978:30;50975:117;;;51011:79;;:::i;:::-;50975:117;51110:21;51126:4;51110:21;:::i;:::-;51101:30;;51201:1;51241:59;51296:3;51287:6;51276:9;51272:22;51241:59;:::i;:::-;51234:4;51227:5;51223:16;51216:85;51141:171;51393:2;51382:9;51378:18;51372:25;51424:18;51416:6;51413:30;51410:117;;;51446:79;;:::i;:::-;51410:117;51566:70;51632:3;51623:6;51612:9;51608:22;51566:70;:::i;:::-;51559:4;51552:5;51548:16;51541:96;51322:326;50877:778;;;;:::o;51661:548::-;51753:6;51802:2;51790:9;51781:7;51777:23;51773:32;51770:119;;;51808:79;;:::i;:::-;51770:119;51949:1;51938:9;51934:17;51928:24;51979:18;51971:6;51968:30;51965:117;;;52001:79;;:::i;:::-;51965:117;52106:86;52184:7;52175:6;52164:9;52160:22;52106:86;:::i;:::-;52096:96;;51899:303;51661:548;;;;:::o;52215:152::-;52355:4;52351:1;52343:6;52339:14;52332:28;52215:152;:::o;52373:381::-;52523:3;52544:74;52616:1;52611:3;52544:74;:::i;:::-;52537:81;;52627:93;52716:3;52627:93;:::i;:::-;52745:2;52740:3;52736:12;52729:19;;52373:381;;;:::o;52760:901::-;53054:4;53092:2;53081:9;53077:18;53069:26;;53141:9;53135:4;53131:20;53127:1;53116:9;53112:17;53105:47;53169:110;53274:4;53265:6;53169:110;:::i;:::-;53161:118;;53326:9;53320:4;53316:20;53311:2;53300:9;53296:18;53289:48;53354:139;53488:4;53354:139;:::i;:::-;53346:147;;53540:9;53534:4;53530:20;53525:2;53514:9;53510:18;53503:48;53568:86;53649:4;53640:6;53568:86;:::i;:::-;53560:94;;52760:901;;;;;:::o;53667:166::-;53807:18;53803:1;53795:6;53791:14;53784:42;53667:166;:::o;53839:382::-;53989:3;54010:75;54082:2;54077:3;54010:75;:::i;:::-;54003:82;;54094:93;54183:3;54094:93;:::i;:::-;54212:2;54207:3;54203:12;54196:19;;53839:382;;;:::o;54227:901::-;54521:4;54559:2;54548:9;54544:18;54536:26;;54608:9;54602:4;54598:20;54594:1;54583:9;54579:17;54572:47;54636:110;54741:4;54732:6;54636:110;:::i;:::-;54628:118;;54793:9;54787:4;54783:20;54778:2;54767:9;54763:18;54756:48;54821:139;54955:4;54821:139;:::i;:::-;54813:147;;55007:9;55001:4;54997:20;54992:2;54981:9;54977:18;54970:48;55035:86;55116:4;55107:6;55035:86;:::i;:::-;55027:94;;54227:901;;;;;:::o;55134:160::-;55274:12;55270:1;55262:6;55258:14;55251:36;55134:160;:::o;55300:382::-;55450:3;55471:75;55543:2;55538:3;55471:75;:::i;:::-;55464:82;;55555:93;55644:3;55555:93;:::i;:::-;55673:2;55668:3;55664:12;55657:19;;55300:382;;;:::o;55688:901::-;55982:4;56020:2;56009:9;56005:18;55997:26;;56069:9;56063:4;56059:20;56055:1;56044:9;56040:17;56033:47;56097:110;56202:4;56193:6;56097:110;:::i;:::-;56089:118;;56254:9;56248:4;56244:20;56239:2;56228:9;56224:18;56217:48;56282:139;56416:4;56282:139;:::i;:::-;56274:147;;56468:9;56462:4;56458:20;56453:2;56442:9;56438:18;56431:48;56496:86;56577:4;56568:6;56496:86;:::i;:::-;56488:94;;55688:901;;;;;:::o;56595:160::-;56735:12;56731:1;56723:6;56719:14;56712:36;56595:160;:::o;56761:382::-;56911:3;56932:75;57004:2;56999:3;56932:75;:::i;:::-;56925:82;;57016:93;57105:3;57016:93;:::i;:::-;57134:2;57129:3;57125:12;57118:19;;56761:382;;;:::o;57149:692::-;57395:4;57433:2;57422:9;57418:18;57410:26;;57482:9;57476:4;57472:20;57468:1;57457:9;57453:17;57446:47;57510:110;57615:4;57606:6;57510:110;:::i;:::-;57502:118;;57667:9;57661:4;57657:20;57652:2;57641:9;57637:18;57630:48;57695:139;57829:4;57695:139;:::i;:::-;57687:147;;57149:692;;;;:::o;57847:586::-;58040:4;58078:2;58067:9;58063:18;58055:26;;58127:9;58121:4;58117:20;58113:1;58102:9;58098:17;58091:47;58155:110;58260:4;58251:6;58155:110;:::i;:::-;58147:118;;58312:9;58306:4;58302:20;58297:2;58286:9;58282:18;58275:48;58340:86;58421:4;58412:6;58340:86;:::i;:::-;58332:94;;57847:586;;;;;:::o;58439:162::-;58579:14;58575:1;58567:6;58563:14;58556:38;58439:162;:::o;58607:382::-;58757:3;58778:75;58850:2;58845:3;58778:75;:::i;:::-;58771:82;;58862:93;58951:3;58862:93;:::i;:::-;58980:2;58975:3;58971:12;58964:19;;58607:382;;;:::o;58995:692::-;59241:4;59279:2;59268:9;59264:18;59256:26;;59328:9;59322:4;59318:20;59314:1;59303:9;59299:17;59292:47;59356:110;59461:4;59452:6;59356:110;:::i;:::-;59348:118;;59513:9;59507:4;59503:20;59498:2;59487:9;59483:18;59476:48;59541:139;59675:4;59541:139;:::i;:::-;59533:147;;58995:692;;;;:::o;59693:98::-;59744:6;59778:5;59772:12;59762:22;;59693:98;;;:::o;59797:147::-;59898:11;59935:3;59920:18;;59797:147;;;;:::o;59950:373::-;60054:3;60082:38;60114:5;60082:38;:::i;:::-;60136:88;60217:6;60212:3;60136:88;:::i;:::-;60129:95;;60233:52;60278:6;60273:3;60266:4;60259:5;60255:16;60233:52;:::i;:::-;60310:6;60305:3;60301:16;60294:23;;60058:265;59950:373;;;;:::o;60329:271::-;60459:3;60481:93;60570:3;60561:6;60481:93;:::i;:::-;60474:100;;60591:3;60584:10;;60329:271;;;;:::o;60606:156::-;60746:8;60742:1;60734:6;60730:14;60723:32;60606:156;:::o;60768:381::-;60918:3;60939:74;61011:1;61006:3;60939:74;:::i;:::-;60932:81;;61022:93;61111:3;61022:93;:::i;:::-;61140:2;61135:3;61131:12;61124:19;;60768:381;;;:::o;61155:644::-;61377:4;61415:2;61404:9;61400:18;61392:26;;61464:9;61458:4;61454:20;61450:1;61439:9;61435:17;61428:47;61492:86;61573:4;61564:6;61492:86;:::i;:::-;61484:94;;61625:9;61619:4;61615:20;61610:2;61599:9;61595:18;61588:48;61653:139;61787:4;61653:139;:::i;:::-;61645:147;;61155:644;;;;:::o;61805:155::-;61945:7;61941:1;61933:6;61929:14;61922:31;61805:155;:::o;61966:381::-;62116:3;62137:74;62209:1;62204:3;62137:74;:::i;:::-;62130:81;;62220:93;62309:3;62220:93;:::i;:::-;62338:2;62333:3;62329:12;62322:19;;61966:381;;;:::o;62353:644::-;62575:4;62613:2;62602:9;62598:18;62590:26;;62662:9;62656:4;62652:20;62648:1;62637:9;62633:17;62626:47;62690:86;62771:4;62762:6;62690:86;:::i;:::-;62682:94;;62823:9;62817:4;62813:20;62808:2;62797:9;62793:18;62786:48;62851:139;62985:4;62851:139;:::i;:::-;62843:147;;62353:644;;;;:::o;63003:224::-;63143:34;63139:1;63131:6;63127:14;63120:58;63212:7;63207:2;63199:6;63195:15;63188:32;63003:224;:::o;63233:366::-;63375:3;63396:67;63460:2;63455:3;63396:67;:::i;:::-;63389:74;;63472:93;63561:3;63472:93;:::i;:::-;63590:2;63585:3;63581:12;63574:19;;63233:366;;;:::o;63605:419::-;63771:4;63809:2;63798:9;63794:18;63786:26;;63858:9;63852:4;63848:20;63844:1;63833:9;63829:17;63822:47;63886:131;64012:4;63886:131;:::i;:::-;63878:139;;63605:419;;;:::o;64030:159::-;64170:11;64166:1;64158:6;64154:14;64147:35;64030:159;:::o;64195:400::-;64355:3;64376:84;64458:1;64453:3;64376:84;:::i;:::-;64369:91;;64469:93;64558:3;64469:93;:::i;:::-;64587:1;64582:3;64578:11;64571:18;;64195:400;;;:::o;64601:541::-;64834:3;64856:95;64947:3;64938:6;64856:95;:::i;:::-;64849:102;;64968:148;65112:3;64968:148;:::i;:::-;64961:155;;65133:3;65126:10;;64601:541;;;;:::o;65148:224::-;65288:34;65284:1;65276:6;65272:14;65265:58;65357:7;65352:2;65344:6;65340:15;65333:32;65148:224;:::o;65378:366::-;65520:3;65541:67;65605:2;65600:3;65541:67;:::i;:::-;65534:74;;65617:93;65706:3;65617:93;:::i;:::-;65735:2;65730:3;65726:12;65719:19;;65378:366;;;:::o;65750:419::-;65916:4;65954:2;65943:9;65939:18;65931:26;;66003:9;65997:4;65993:20;65989:1;65978:9;65974:17;65967:47;66031:131;66157:4;66031:131;:::i;:::-;66023:139;;65750:419;;;:::o;66175:86::-;66221:7;66250:5;66239:16;;66175:86;;;:::o;66267:::-;66302:7;66342:4;66335:5;66331:16;66320:27;;66267:86;;;:::o;66359:60::-;66387:3;66408:5;66401:12;;66359:60;;;:::o;66425:156::-;66482:9;66515:60;66531:43;66540:33;66567:5;66540:33;:::i;:::-;66531:43;:::i;:::-;66515:60;:::i;:::-;66502:73;;66425:156;;;:::o;66587:153::-;66689:44;66727:5;66689:44;:::i;:::-;66684:3;66677:57;66587:153;;:::o;66746:461::-;66902:4;66940:2;66929:9;66925:18;66917:26;;66989:9;66983:4;66979:20;66975:1;66964:9;66960:17;66953:47;67017:86;67098:4;67089:6;67017:86;:::i;:::-;67009:94;;67113:87;67196:2;67185:9;67181:18;67172:6;67113:87;:::i;:::-;66746:461;;;;;:::o;67213:143::-;67270:5;67301:6;67295:13;67286:22;;67317:33;67344:5;67317:33;:::i;:::-;67213:143;;;;:::o;67362:351::-;67432:6;67481:2;67469:9;67460:7;67456:23;67452:32;67449:119;;;67487:79;;:::i;:::-;67449:119;67607:1;67632:64;67688:7;67679:6;67668:9;67664:22;67632:64;:::i;:::-;67622:74;;67578:128;67362:351;;;;:::o;67719:230::-;67859:34;67855:1;67847:6;67843:14;67836:58;67928:13;67923:2;67915:6;67911:15;67904:38;67719:230;:::o;67955:366::-;68097:3;68118:67;68182:2;68177:3;68118:67;:::i;:::-;68111:74;;68194:93;68283:3;68194:93;:::i;:::-;68312:2;68307:3;68303:12;68296:19;;67955:366;;;:::o;68327:419::-;68493:4;68531:2;68520:9;68516:18;68508:26;;68580:9;68574:4;68570:20;68566:1;68555:9;68551:17;68544:47;68608:131;68734:4;68608:131;:::i;:::-;68600:139;;68327:419;;;:::o;68752:155::-;68892:3;68888:1;68880:6;68876:14;68869:27;68752:155;:::o;68917:416::-;69077:3;69102:84;69184:1;69179:3;69102:84;:::i;:::-;69095:91;;69199:93;69288:3;69199:93;:::i;:::-;69321:1;69316:3;69312:11;69305:18;;68917:416;;;:::o;69343:151::-;69483:3;69479:1;69471:6;69467:14;69460:27;69343:151;:::o;69500:400::-;69660:3;69681:84;69763:1;69758:3;69681:84;:::i;:::-;69674:91;;69774:93;69863:3;69774:93;:::i;:::-;69892:1;69887:3;69883:11;69876:18;;69500:400;;;:::o;69906:967::-;70288:3;70310:95;70401:3;70392:6;70310:95;:::i;:::-;70303:102;;70422:148;70566:3;70422:148;:::i;:::-;70415:155;;70587:95;70678:3;70669:6;70587:95;:::i;:::-;70580:102;;70699:148;70843:3;70699:148;:::i;:::-;70692:155;;70864:3;70857:10;;69906:967;;;;;:::o;70879:178::-;71019:30;71015:1;71007:6;71003:14;70996:54;70879:178;:::o;71063:366::-;71205:3;71226:67;71290:2;71285:3;71226:67;:::i;:::-;71219:74;;71302:93;71391:3;71302:93;:::i;:::-;71420:2;71415:3;71411:12;71404:19;;71063:366;;;:::o;71435:419::-;71601:4;71639:2;71628:9;71624:18;71616:26;;71688:9;71682:4;71678:20;71674:1;71663:9;71659:17;71652:47;71716:131;71842:4;71716:131;:::i;:::-;71708:139;;71435:419;;;:::o;71860:220::-;72000:34;71996:1;71988:6;71984:14;71977:58;72069:3;72064:2;72056:6;72052:15;72045:28;71860:220;:::o;72086:366::-;72228:3;72249:67;72313:2;72308:3;72249:67;:::i;:::-;72242:74;;72325:93;72414:3;72325:93;:::i;:::-;72443:2;72438:3;72434:12;72427:19;;72086:366;;;:::o;72458:419::-;72624:4;72662:2;72651:9;72647:18;72639:26;;72711:9;72705:4;72701:20;72697:1;72686:9;72682:17;72675:47;72739:131;72865:4;72739:131;:::i;:::-;72731:139;;72458:419;;;:::o;72883:126::-;72978:24;72996:5;72978:24;:::i;:::-;72973:3;72966:37;72883:126;;:::o;73015:447::-;73164:4;73202:2;73191:9;73187:18;73179:26;;73215:79;73291:1;73280:9;73276:17;73267:6;73215:79;:::i;:::-;73341:9;73335:4;73331:20;73326:2;73315:9;73311:18;73304:48;73369:86;73450:4;73441:6;73369:86;:::i;:::-;73361:94;;73015:447;;;;;:::o;73468:236::-;73608:34;73604:1;73596:6;73592:14;73585:58;73677:19;73672:2;73664:6;73660:15;73653:44;73468:236;:::o;73710:366::-;73852:3;73873:67;73937:2;73932:3;73873:67;:::i;:::-;73866:74;;73949:93;74038:3;73949:93;:::i;:::-;74067:2;74062:3;74058:12;74051:19;;73710:366;;;:::o;74082:419::-;74248:4;74286:2;74275:9;74271:18;74263:26;;74335:9;74329:4;74325:20;74321:1;74310:9;74306:17;74299:47;74363:131;74489:4;74363:131;:::i;:::-;74355:139;;74082:419;;;:::o;74507:176::-;74598:11;74632:6;74627:3;74620:19;74672:4;74667:3;74663:14;74648:29;;74507:176;;;;:::o;74711:317::-;74815:3;74836:78;74907:6;74902:3;74836:78;:::i;:::-;74829:85;;74924:43;74960:6;74955:3;74948:5;74924:43;:::i;:::-;74992:29;75014:6;74992:29;:::i;:::-;74987:3;74983:39;74976:46;;74711:317;;;;;:::o;75034:581::-;75219:4;75257:2;75246:9;75242:18;75234:26;;75270:79;75346:1;75335:9;75331:17;75322:6;75270:79;:::i;:::-;75359:80;75435:2;75424:9;75420:18;75411:6;75359:80;:::i;:::-;75486:9;75480:4;75476:20;75471:2;75460:9;75456:18;75449:48;75514:94;75603:4;75594:6;75586;75514:94;:::i;:::-;75506:102;;75034:581;;;;;;;:::o;75621:224::-;75761:34;75757:1;75749:6;75745:14;75738:58;75830:7;75825:2;75817:6;75813:15;75806:32;75621:224;:::o;75851:366::-;75993:3;76014:67;76078:2;76073:3;76014:67;:::i;:::-;76007:74;;76090:93;76179:3;76090:93;:::i;:::-;76208:2;76203:3;76199:12;76192:19;;75851:366;;;:::o;76223:419::-;76389:4;76427:2;76416:9;76412:18;76404:26;;76476:9;76470:4;76466:20;76462:1;76451:9;76447:17;76440:47;76504:131;76630:4;76504:131;:::i;:::-;76496:139;;76223:419;;;:::o;76648:151::-;76788:3;76784:1;76776:6;76772:14;76765:27;76648:151;:::o;76805:381::-;76955:3;76976:74;77048:1;77043:3;76976:74;:::i;:::-;76969:81;;77059:93;77148:3;77059:93;:::i;:::-;77177:2;77172:3;77168:12;77161:19;;76805:381;;;:::o;77192:644::-;77414:4;77452:2;77441:9;77437:18;77429:26;;77501:9;77495:4;77491:20;77487:1;77476:9;77472:17;77465:47;77529:139;77663:4;77529:139;:::i;:::-;77521:147;;77715:9;77709:4;77705:20;77700:2;77689:9;77685:18;77678:48;77743:86;77824:4;77815:6;77743:86;:::i;:::-;77735:94;;77192:644;;;;:::o;77842:349::-;77911:6;77960:2;77948:9;77939:7;77935:23;77931:32;77928:119;;;77966:79;;:::i;:::-;77928:119;78086:1;78111:63;78166:7;78157:6;78146:9;78142:22;78111:63;:::i;:::-;78101:73;;78057:127;77842:349;;;;:::o;78197:182::-;78337:34;78333:1;78325:6;78321:14;78314:58;78197:182;:::o;78385:366::-;78527:3;78548:67;78612:2;78607:3;78548:67;:::i;:::-;78541:74;;78624:93;78713:3;78624:93;:::i;:::-;78742:2;78737:3;78733:12;78726:19;;78385:366;;;:::o;78757:419::-;78923:4;78961:2;78950:9;78946:18;78938:26;;79010:9;79004:4;79000:20;78996:1;78985:9;78981:17;78974:47;79038:131;79164:4;79038:131;:::i;:::-;79030:139;;78757:419;;;:::o

Swarm Source

ipfs://ee0e3eda07dc8cba8e97ae5842e125f542f2faff30a5254c26d6076d6da6942f
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.