text:
package org.batfish.datamodel.answers;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.batfish.common.util.CollectionUtil.toImmutableMap;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.Streams;
import com.google.re2j.Pattern;
import com.google.re2j.PatternSyntaxException;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.similarity.LevenshteinDistance;
import org.batfish.common.CompletionMetadata;
import org.batfish.common.autocomplete.IpCompletionMetadata;
import org.batfish.common.autocomplete.IpCompletionRelevance;
import org.batfish.common.autocomplete.LocationCompletionMetadata;
import org.batfish.datamodel.InterfaceType;
import org.batfish.datamodel.Ip;
import org.batfish.datamodel.Prefix;
import org.batfish.datamodel.PrefixTrieMultiMap;
import org.batfish.datamodel.Protocol;
import org.batfish.datamodel.answers.AutocompleteSuggestion.SuggestionType;
import org.batfish.datamodel.collections.NodeInterfacePair;
import org.batfish.datamodel.questions.Variable;
import org.batfish.referencelibrary.ReferenceBook;
import org.batfish.referencelibrary.ReferenceLibrary;
import org.batfish.role.NodeRolesData;
import org.batfish.specifier.DispositionSpecifier;
import org.batfish.specifier.Grammar;
import org.batfish.specifier.ToSpecifierString;
import org.batfish.specifier.parboiled.ParboiledAutoComplete;

/** A utility class to generate auto complete suggestions for user input */
@ParametersAreNonnullByDefault
public final class AutoCompleteUtils {

  private static final int MAX_SUGGESTIONS_PER_TYPE = 5;

  /**
   * @param network name of network
   * @param snapshot name of snapshot
   * @param completionType completion type
   * @param query input query
   * @param maxSuggestions maximum number of suggestions returned
   * @param completionMetadata completion metadata
   * @param nodeRolesData node roles data
   * @param referenceLibrary reference library
   * @param fuzzyMatching if true will relax the input query to guarantee that suggestions are
   *     returned
   * @return a list of AutocompleteSuggestion
   */
  @Nonnull
  public static List<AutocompleteSuggestion> autoComplete(
      @Nullable String network,
      @Nullable String snapshot,
      Variable.Type completionType,
      String query,
      int maxSuggestions,
      @Nullable CompletionMetadata completionMetadata,
      @Nullable NodeRolesData nodeRolesData,
      @Nullable ReferenceLibrary referenceLibrary,
      boolean fuzzyMatching) {

    List<AutocompleteSuggestion> suggestions =
        getPotentialMatches(
            network,
            snapshot,
            completionType,
            query,
            maxSuggestions,
            completionMetadata,
            nodeRolesData,
            referenceLibrary);

    if (fuzzyMatching) {
      // If there are no suggestions, remove characters from the end of the query until there are
      // suggestions or the query is the empty string. This logic is done here to ensure that all
      // possible suggestions types have been considered before relaxing the query
      String relaxedQuery = query;
      while (relaxedQuery.length() > 0 && suggestions.isEmpty()) {
        relaxedQuery = relaxedQuery.substring(0, relaxedQuery.length() - 1);
        suggestions =
            getPotentialMatches(
                network,
                snapshot,
                completionType,
                relaxedQuery,
                maxSuggestions,
                completionMetadata,
                nodeRolesData,
                referenceLibrary);
      }
    }

    return limitSuggestionsByType(
        orderSuggestions(query, suggestions), maxSuggestions, MAX_SUGGESTIONS_PER_TYPE);
  }

  /** Basic ordering logic, by suggestion type, rank, and then by suggestion text */
  @VisibleForTesting
  static List<AutocompleteSuggestion> orderSuggestions(
      String query, List<AutocompleteSuggestion> suggestions) {
    final LevenshteinDistance distance = new LevenshteinDistance();
    return suggestions.stream()
        .sorted(
            // first order by suggestion type
            Comparator.comparing(AutocompleteSuggestion::getSuggestionType)
                // then rank within the same type
                .thenComparing(AutocompleteSuggestion::getRank)
                // then by (inverse of) common prefix length
                .thenComparing(
                    s ->
                        -1
                            * StringUtils.getCommonPrefix(
                                    query.toLowerCase(),
                                    (query.substring(0, s.getInsertionIndex()) + s.getText()))
                                .toLowerCase()
                                .length())
                // then by edit distance
                .thenComparing(
                    s ->
                        distance.apply(
                            query.toLowerCase(),
                            (query.substring(0, s.getInsertionIndex()) + s.getText())
                                .toLowerCase())))
        .collect(ImmutableList.toImmutableList());
  }

  /**
   * Limits the number of suggestions per type.
   *
   * @param orderedSuggestions original ordered list of suggestions
   * @param maxSuggestions the maximum number of suggestions
   * @param maxSuggestionsPerType the maximum number of suggestions for a given type
   */
  @VisibleForTesting
  static List<AutocompleteSuggestion> limitSuggestionsByType(
      List<AutocompleteSuggestion> orderedSuggestions,
      int maxSuggestions,
      int maxSuggestionsPerType) {
    if (orderedSuggestions.size() <= maxSuggestions) {
      return orderedSuggestions;
    }

    Map<SuggestionType, Integer> suggestionTypeCounts = new TreeMap<>();

    List<AutocompleteSuggestion> limitedSuggestions = new ArrayList<>();
    List<AutocompleteSuggestion> leftOverSuggestions = new ArrayList<>();

    for (AutocompleteSuggestion suggestion : orderedSuggestions) {
      if (limitedSuggestions.size() == maxSuggestions) {
        return limitedSuggestions;
      }

      Integer count = suggestionTypeCounts.getOrDefault(suggestion.getSuggestionType(), 0);

      if (count < maxSuggestionsPerType) {
        limitedSuggestions.add(suggestion);
        suggestionTypeCounts.put(suggestion.getSuggestionType(), count + 1);
      } else {
        leftOverSuggestions.add(suggestion);
      }
    }

    int suggestionsToAdd = maxSuggestions - limitedSuggestions.size();

    if (suggestionsToAdd > 0) {
      // add remaining suggestions from leftovers
      limitedSuggestions.addAll(
          leftOverSuggestions.subList(
              0, Integer.min(suggestionsToAdd, leftOverSuggestions.size())));
    }

    return limitedSuggestions;
  }

  @Nonnull
  private static List<AutocompleteSuggestion> getPotentialMatches(
      @Nullable String network,
      @Nullable String snapshot,
      Variable.Type completionType,
      String query,
      int maxSuggestions,
      @Nullable CompletionMetadata completionMetadata,
      @Nullable NodeRolesData nodeRolesData,
      @Nullable ReferenceLibrary referenceLibrary) {
    List<AutocompleteSuggestion> suggestions;

    try {
      switch (completionType) {
        case ADDRESS_GROUP_AND_BOOK:
          // deprecated -- left for now for backward compatibility
          suggestions = ImmutableList.of();
          break;
        case ADDRESS_GROUP_NAME:
          {
            checkReferenceLibrary(referenceLibrary, network);
            ImmutableSet<String> groups =
                referenceLibrary.getReferenceBooks().stream()
                    .map(
                        b ->
                            b.getAddressGroups().stream()
                                .map(ag -> ag.getName())
                                .collect(ImmutableSet.toImmutableSet()))
                    .flatMap(Collection::stream)
                    .collect(ImmutableSet.toImmutableSet());
            suggestions = stringAutoComplete(query, groups);
            break;
          }
        case APPLICATION_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.APPLICATION_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case BGP_PEER_PROPERTY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.BGP_PEER_PROPERTY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case BGP_PROCESS_PROPERTY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.BGP_PROCESS_PROPERTY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case BGP_ROUTE_STATUS_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.BGP_ROUTE_STATUS_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case BGP_SESSION_COMPAT_STATUS_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.BGP_SESSION_COMPAT_STATUS_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case BGP_SESSION_STATUS_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.BGP_SESSION_STATUS_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case BGP_SESSION_TYPE_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.BGP_SESSION_TYPE_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case DEPRECATED_FLOW_STATE:
          {
            suggestions = baseAutoComplete(query, ImmutableSet.of("NEW", "ESTABLISHED", "RELATED"));
            break;
          }
        case DISPOSITION_SPEC:
          {
            suggestions = DispositionSpecifier.autoComplete(query);
            break;
          }
        case FILTER_NAME:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = stringAutoComplete(query, completionMetadata.getFilterNames());
            break;
          }
        case FILTER:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = baseAutoComplete(query, completionMetadata.getFilterNames());
            break;
          }
        case FILTER_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.FILTER_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case INTERFACE:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions =
                baseAutoComplete(
                    query,
                    completionMetadata.getInterfaces().stream()
                        .map(NodeInterfacePair::toString)
                        .collect(ImmutableSet.toImmutableSet()));
            break;
          }
        case INTERFACE_GROUP_AND_BOOK:
          // deprecated -- left for now for backward compatibility
          suggestions = ImmutableList.of();
          break;
        case INTERFACE_GROUP_NAME:
          {
            checkReferenceLibrary(referenceLibrary, network);
            ImmutableSet<String> groups =
                referenceLibrary.getReferenceBooks().stream()
                    .flatMap(b -> b.getInterfaceGroups().stream().map(g -> g.getName()))
                    .collect(ImmutableSet.toImmutableSet());
            suggestions = stringAutoComplete(query, groups);
            break;
          }
        case INTERFACE_NAME:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions =
                stringAutoComplete(
                    query,
                    completionMetadata.getInterfaces().stream()
                        .map(NodeInterfacePair::getInterface)
                        .collect(Collectors.toSet()));
            break;
          }
        case INTERFACE_TYPE:
          {
            suggestions =
                stringAutoComplete(
                    query,
                    Arrays.stream(InterfaceType.values())
                        .map(type -> type.toString())
                        .collect(ImmutableSet.toImmutableSet()));
            break;
          }
        case INTERFACES_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.INTERFACE_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case INTERFACE_PROPERTY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.INTERFACE_PROPERTY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case IP:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = ipStringAutoComplete(query, completionMetadata.getIps());
            break;
          }
        case IP_PROTOCOL_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.IP_PROTOCOL_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case IP_SPACE_SPEC:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            // first, get the suggestions based on IP metadata
            List<AutocompleteSuggestion> metadataSuggestions =
                ipStringAutoComplete(query, completionMetadata.getIps());
            Set<String> metadataSuggestionTexts =
                metadataSuggestions.stream()
                    .map(s -> s.getText())
                    .collect(ImmutableSet.toImmutableSet());

            // then, get grammar-based suggestions
            List<AutocompleteSuggestion> grammarSuggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.IP_SPACE_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);

            // merge the suggestions
            suggestions =
                Streams.concat(
                        metadataSuggestions.stream(),
                        grammarSuggestions.stream()
                            .filter(s -> !metadataSuggestionTexts.contains(s.getText())))
                    .collect(ImmutableList.toImmutableList());
            break;
          }
        case IPSEC_SESSION_STATUS_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.IPSEC_SESSION_STATUS_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case LOCATION_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.LOCATION_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case MLAG_ID:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = stringAutoComplete(query, completionMetadata.getMlagIds());
            break;
          }
        case MLAG_ID_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.MLAG_ID_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case NAMED_STRUCTURE_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.NAMED_STRUCTURE_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case NODE_NAME:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            Map<String, Optional<String>> nodesWithDescriptions =
                toImmutableMap(
                    completionMetadata.getNodes(),
                    Entry::getKey,
                    entry -> Optional.ofNullable(entry.getValue().getHumanName()));
            suggestions = stringAutoComplete(query, nodesWithDescriptions);
            break;
          }
        case NODE_PROPERTY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.NODE_PROPERTY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case NODE_ROLE_AND_DIMENSION:
          // deprecated -- left for now for backward compatibility
          suggestions = ImmutableList.of();
          break;
        case NODE_ROLE_DIMENSION:
          // deprecated -- left for now for backward compatibility
          suggestions = ImmutableList.of();
          break;
        case NODE_ROLE_DIMENSION_NAME:
          {
            checkNodeRolesData(nodeRolesData, network);
            suggestions = stringAutoComplete(query, nodeRolesData.toNodeRoleDimensions().keySet());
            break;
          }
        case NODE_ROLE_NAME:
          {
            checkNodeRolesData(nodeRolesData, network);
            ImmutableSet<String> roles =
                nodeRolesData.toNodeRoleDimensions().values().stream()
                    .flatMap(d -> d.roleNamesFor(completionMetadata.getNodes().keySet()).stream())
                    .collect(ImmutableSet.toImmutableSet());
            suggestions = stringAutoComplete(query, roles);
            break;
          }
        case NODE_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.NODE_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case OSPF_INTERFACE_PROPERTY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.OSPF_INTERFACE_PROPERTY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case OSPF_PROCESS_PROPERTY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.OSPF_PROCESS_PROPERTY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case OSPF_SESSION_STATUS_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.OSPF_SESSION_STATUS_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case PREFIX:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = stringAutoComplete(query, completionMetadata.getPrefixes());
            break;
          }
        case PROTOCOL:
          {
            suggestions =
                baseAutoComplete(
                    query,
                    Stream.of(Protocol.values()).map(Protocol::name).collect(Collectors.toSet()));
            break;
          }
        case REFERENCE_BOOK_NAME:
          {
            checkReferenceLibrary(referenceLibrary, network);
            suggestions =
                stringAutoComplete(
                    query,
                    referenceLibrary.getReferenceBooks().stream()
                        .map(ReferenceBook::getName)
                        .collect(Collectors.toSet()));
            break;
          }
        case ROUTING_POLICY_NAME:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = stringAutoComplete(query, completionMetadata.getRoutingPolicyNames());
            break;
          }
        case ROUTING_POLICY_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.ROUTING_POLICY_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case ROUTING_PROTOCOL_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.ROUTING_PROTOCOL_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case SINGLE_APPLICATION_SPEC:
          {
            suggestions =
                ParboiledAutoComplete.autoComplete(
                    Grammar.SINGLE_APPLICATION_SPECIFIER,
                    network,
                    snapshot,
                    query,
                    maxSuggestions,
                    completionMetadata,
                    nodeRolesData,
                    referenceLibrary);
            break;
          }
        case SOURCE_LOCATION:
          {
            suggestions = autoCompleteSourceLocation(query, false, completionMetadata);
            break;
          }
        case STRUCTURE_NAME:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = baseAutoComplete(query, completionMetadata.getStructureNames());
            break;
          }
        case TRACEROUTE_SOURCE_LOCATION:
          {
            suggestions = autoCompleteSourceLocation(query, true, completionMetadata);
            break;
          }
        case VRF:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = baseAutoComplete(query, completionMetadata.getVrfs());
            break;
          }
        case ZONE:
          {
            checkCompletionMetadata(completionMetadata, network, snapshot);
            suggestions = baseAutoComplete(query, completionMetadata.getZones());
            break;
          }
        default:
          throw new IllegalArgumentException("Unsupported completion type: " + completionType);
      }
    } catch (Exception e) {
      // if any error occurs, just return an empty list
      return ImmutableList.of();
    }
    return suggestions;
  }

  /**
   * Returns a list of loactions that the match the query. The query can match on either the
   * location (node, interface) or the human name of the node. When tracerouteSource is false,
   * "natural" source locations (per location info) with IPs are considered. Otherwise, traceroute
   * sources are considered. In the latter mode, natural sources are ranked higher.
   */
  @Nonnull
  public static List<AutocompleteSuggestion> autoCompleteSourceLocation(
      String query, boolean tracerouteSource, @Nullable CompletionMetadata completionMetadata) {
    checkNotNull(
        completionMetadata, "Cannot autocomplete source locations without completion metadata");
    checkNotNull(
        completionMetadata.getLocations(),
        "cannot autocomplete source locations without location metadata");
    List<AutocompleteSuggestion> sourceSuggestions =
        stringAutoComplete(query, getLocationsWithHumanNames(false, completionMetadata), 1);
    if (!tracerouteSource) {
      return sourceSuggestions;
    }
    List<AutocompleteSuggestion> tracerouteSourceSuggestions =
        stringAutoComplete(query, getLocationsWithHumanNames(true, completionMetadata), 2);
    return Streams.concat(sourceSuggestions.stream(), tracerouteSourceSuggestions.stream())
        .collect(ImmutableList.toImmutableList());
  }

  /**
   * Returns a map from location to the (optional) human name of its node. When tracerouteSource is
   * false, "natural" source locations (per location info) with IPs are considered. Otherwise,
   * traceroute sources that are not source location with IPs are considered.
   */
  private static Map<String, Optional<String>> getLocationsWithHumanNames(
      boolean tracerouteSource, CompletionMetadata completionMetadata) {
    return (tracerouteSource
            ? completionMetadata.getLocations().stream()
                .filter(loc -> loc.isTracerouteSource() && !loc.isSourceWithIps())
            : completionMetadata.getLocations().stream()
                .filter(LocationCompletionMetadata::isSourceWithIps))
        .map(LocationCompletionMetadata::getLocation)
        .collect(
            ImmutableMap.toImmutableMap(
                ToSpecifierString::toSpecifierString,
                location ->
                    Optional.ofNullable(
                        completionMetadata.getNodes().get(location.getNodeName()).getHumanName())));
  }

  /**
   * Returns a list of suggestions based on the query. The current implementation treats the query
   * as a substring of the property string.
   *
   * <p>TODO: Get rid of this method in favor of methods below. Stop doing implicit regexes.
   */
  @Nonnull
  public static List<AutocompleteSuggestion> baseAutoComplete(
      @Nullable String query, Set<String> allProperties) {

    String finalQuery = firstNonNull(query, "").toLowerCase();
    ImmutableList.Builder<AutocompleteSuggestion> suggestions = new ImmutableList.Builder<>();
    String queryWithStars = ".*" + (finalQuery.isEmpty() ? "" : finalQuery + ".*");
    Pattern queryPattern = safeGetPattern(queryWithStars);

    /*
     * if queryWithStars is not a valid Pattern, finalQuery must be a funky string that will not
     * match anything as string.contains or regex.matches; so we skip formalities altogether
     */
    if (queryPattern != null) {
      suggestions.addAll(
          allProperties.stream()
              .filter(prop -> queryPattern.matcher(prop.toLowerCase()).matches())
              .map(prop -> new AutocompleteSuggestion(prop, false))
              .collect(Collectors.toList()));
    }
    return suggestions.build();
  }

  /**
   * Returns a list of suggestions based on query strings.
   *
   * <p>The search is case-insensitive and looks for a substring match.
   */
  @Nonnull
  public static List<AutocompleteSuggestion> stringAutoComplete(
      @Nullable String query, Set<String> strings) {

    String testQuery = query == null ? "" : query.toLowerCase();

    return strings.stream()
        .filter(s -> s.toLowerCase().contains(testQuery))
        .map(s -> new AutocompleteSuggestion(s, false))
        .collect(ImmutableList.toImmutableList());
  }

  /**
   * Returns a list of suggestions based on query strings.
   *
   * <p>The search is case-insensitive and looks for a substring match.
   */
  @VisibleForTesting
  @Nonnull
  static List<AutocompleteSuggestion> stringAutoComplete(
      @Nullable String query, Map<String, Optional<String>> stringsWithDescriptions) {
    return stringAutoComplete(query, stringsWithDescriptions, AutocompleteSuggestion.DEFAULT_RANK);
  }

  /**
   * Returns a list of suggestions based on query strings.
   *
   * <p>The search is case-insensitive and looks for a substring match.
   */
  @Nonnull
  private static List<AutocompleteSuggestion> stringAutoComplete(
      @Nullable String query, Map<String, Optional<String>> stringsWithDescriptions, int rank) {

    String testQuery = query == null ? "" : query.toLowerCase();

    return stringsWithDescriptions.entrySet().stream()
        .filter(
            s ->
                s.getKey().toLowerCase().contains(testQuery)
                    || s.getValue()
                        .map(hint -> hint.toLowerCase().contains(testQuery))
                        .orElse(false))
        .map(s -> new AutocompleteSuggestion(s.getKey(), false, s.getValue().orElse(null), rank))
        .collect(ImmutableList.toImmutableList());
  }

  /**
   * Returns a list of suggestions based on a query for Ips.
   *
   * <p>The query string may be an IP (e.g., "10.") or another string altogether (e.g., "nod"). The
   * method first matches on IPs (and includes all of its {@link IpCompletionMetadata} as hint and
   * then matches on {@link IpCompletionMetadata} (and includes only matching {@link
   * IpCompletionRelevance} in hints).
   */
  @Nonnull
  public static ImmutableList<AutocompleteSuggestion> ipStringAutoComplete(
      @Nullable String query, PrefixTrieMultiMap<IpCompletionMetadata> ips) {

    String testQuery = query == null ? "" : query.toLowerCase();

    // when the query has multiple words, each of those words should match
    String[] subQueries = testQuery.split("\\s+");

    RangeSet<Ip> allIps =
        ImmutableRangeSet.of(Range.closed(Prefix.ZERO.getStartIp(), Prefix.ZERO.getEndIp()));

    // find matching IP entries
    Map<Ip, IpCompletionMetadata> ipMatches =
        ips.getOverlappingEntries(allIps)
            .filter(e -> e.getKey().getPrefixLength() == Prefix.MAX_PREFIX_LENGTH)
            .filter(
                e -> {
                  String ipStr = e.getKey().getStartIp().toString();
                  return Arrays.stream(subQueries).allMatch(ipStr::contains);
                })
            .collect(
                ImmutableMap.toImmutableMap(
                    e -> e.getKey().getStartIp(),
                    // invariant: value set is non-empty. could have multiple elements, but this
                    // code will only use one.
                    e -> e.getValue().iterator().next()));

    // find relevance matches
    List<AutocompleteSuggestion> relevanceMatches =
        ips.getOverlappingEntries(allIps)
            .filter(
                e ->
                    e.getKey().getPrefixLength() == Prefix.MAX_PREFIX_LENGTH
                        && !ipMatches.containsKey(e.getKey().getStartIp()))
            .map(
                e -> {
                  Ip ip = e.getKey().getStartIp();
                  return new SimpleEntry<>(
                      ip,
                      e.getValue().stream()
                          .flatMap(metadata -> metadata.getRelevances().stream())
                          .filter(r -> r.matches(subQueries, ip))
                          .collect(ImmutableList.toImmutableList()));
                })
            .filter(e -> !e.getValue().isEmpty())
            .map(e -> toAutocompleteSuggestion(e.getKey(), e.getValue()))
            .collect(ImmutableList.toImmutableList());

    return new ImmutableList.Builder<AutocompleteSuggestion>()
        .addAll(
            ipMatches.entrySet().stream()
                .map(
                    entry ->
                        toAutocompleteSuggestion(entry.getKey(), entry.getValue().getRelevances()))
                .collect(ImmutableList.toImmutableList()))
        .addAll(relevanceMatches)
        .build();
  }

  public static AutocompleteSuggestion toAutocompleteSuggestion(
      Ip ip, List<IpCompletionRelevance> relevances) {
    return AutocompleteSuggestion.builder()
        .setText(ip.toString())
        .setDescription(toDescription(relevances))
        .setSuggestionType(SuggestionType.ADDRESS_LITERAL)
        .build();
  }

  @Nullable
  @VisibleForTesting
  static String toDescription(List<IpCompletionRelevance> relevances) {
    if (relevances.isEmpty()) {
      return null;
    }
    if (relevances.size() == 1) {
      return relevances.get(0).getDisplay();
    }
    return String.format("%s ... (%d more)", relevances.get(0).getDisplay(), relevances.size() - 1);
  }

  private static void checkCompletionMetadata(
      @Nullable CompletionMetadata completionMetadata,
      @Nullable String network,
      @Nullable String snapshot) {
    checkArgument(
        completionMetadata != null,
        "Cannot autocomplete because completion metadata not found for %s / %s",
        network,
        snapshot);
  }

  private static void checkNodeRolesData(
      @Nullable NodeRolesData nodeRolesData, @Nullable String network) {
    checkArgument(
        nodeRolesData != null,
        "Cannot autocomplete because node roles data not found for %s",
        network);
  }

  private static void checkReferenceLibrary(
      @Nullable ReferenceLibrary referenceLibrary, @Nullable String network) {
    checkArgument(
        referenceLibrary != null,
        "Cannot autocomplete because reference library not found for %s",
        network);
  }

  /** Returns the Pattern if {@code candidateRegex} is a valid regex, and null otherwise */
  @Nullable
  private static Pattern safeGetPattern(String candidateRegex) {
    try {
      return Pattern.compile(candidateRegex);
    } catch (PatternSyntaxException e) {
      return null;
    }
  }
}

redpajama_set_name: RedPajamaGithub


text:
Exonews TV
Tag: Michael Collins
Astronomer Has 'Little Doubt' We Are Not Alone in the Universe
ExoNews Editor
Listen to "E204 Astronomer Has 'Little Doubt' We Are Not Alone in the Universe" on Spreaker.
Article by Sebastian Kettley December 15, 2019 (express.co.uk)
• The discovery of extraterrestrial life is at the top of the priority list for NASA, the European Space Agency and the scientific community. In 2020, NASA will put another Mars rover on the Red Planet to look for evidence of past life. SETI continues listening to the night skies for signs of contact.
• Scientist Dr Maggie Aderin-Pocock recently told The Guardian that she had very "little doubt" humans are not the only intelligent life to call this cosmos home. "There are just too many planets, galaxies, solar systems, moons and stars to think there can't be more life," said Aderin-Pocock. But she also shed doubt on ever finding any extraterrestrial life saying, "Maybe they came in the age of the dinosaurs and left because they had no one to communicate with." "I think though that there's a great many variables that would need to happen to result in us making contact."
• Apollo 11 astronaut Michael Collins told the New York Daily News: "It seems to me the height of arrogance to say that our little stupid Sun off in one obscure corner of an odd galaxy called the Milky Way should be the only one in the whole universe capable of developing what we sometimes refer to as intelligent life."
• SpaceX founder and South African billionaire Elon Musk thinks aliens could be real, but we will likely never find them. He points out that the universe is 13.8 billion years old – plenty of time for alien civilizations to rise and fall without humans ever noticing.
• NASA has been focusing on the discovery of habitable exoplanets situated in a 'habitable zone' where life could evolve around stars far outside of our solar system. NASA's William Borucki said, "If we find lots of planets like ours, we'll know it's likely that we aren't alone, and that someday we might be able to join other intelligent life in the universe."
• NASA's now-retired Kepler space telescope uncovered thousands of distant exoplanets since 2009. Kepler scientist Padi Boyd stated, "I think it's a really exciting time to be a scientist." "Here we are in a position to actually answer the question, 'Are we alone?' and be able to get a scientific answer."
• [Editor's Note] Excuse me, but the discovery of extraterrestrial life is NOT at the top of the priority list for NASA, the European Space Agency or the scientific community. This is a load of "scientific" misdirection and double-talk. In spite of this article's optimistic title, it is nothing more than a parade of deep state puppets (with the exception of Michael Collins) spouting the deep state's agenda that while it may be possible that intelligent extraterrestrials exist somewhere, or may have existed in the past, our Earth civilization will never meet them. This is regarded as the "exciting" scientific point of view. They maintain this extraordinary lie so that the public won't pay attention to the "kooks on the fringe" who claim that extraterrestrial life exists throughout the galaxy, that many alien races have visited the Earth, and they continue to do so. For the past seventy years, the deep state shadow government has done everything within its considerable power to hide this reality. The public is absolutely brain-washed to believe that aliens do not exist anywhere near our solar system, despite the overwhelming evidence of UFOs and extraterrestrial visitation. But very soon the truth will be revealed. And when the truth is finally revealed, people will remember these deep state institutions and 'scientists' who made a long and lucrative career of lying to the world.
The question of 'are we alone in the universe' has fascinated the scientific community for decades. Aliens and other extraterrestrial organisms are the top of the priority list for bodies like NASA and the European Space Agency (ESA).
NASA scientist Padi Boyd
Deep State Stooge, Elon Musk
In 2020, NASA will launch a Mars rover to the Red Planet to trawl the alien world for evidence of past life.
And projects like SETI or the Search for Extraterrestrial Intelligence are continuously listening to the night skies for signs of contact.
Dr Maggie Aderin-Pocock is one of the scientists who have very "little doubt" humans are not the only intelligent life to call this cosmos home.
The space scientist told The Guardian the numbers are stacked in favour of a diverse universe.
Dr Aderin-Pocock said: "I sometimes wonder where the aliens are, but I have little doubt that they're out there. It's the numbers game.
naive astronomer who is just happy to be in the public limelight, Maggie Aderin-Pocock
NASA's William Borucki
"There are just too many planets, galaxies, solar systems, moons and stars to think there can't be more life.
"I think though that there's a great many variables that would need to happen to result in us making contact.
"Maybe they came in the age of the dinosaurs and left because they had no one to communicate with.
"I actually think that aliens arriving would be brilliant for us. Us putting aside our differences and getting our act together to face invading aliens might finally unite humanity."
FAIR USE NOTICE: This page contains copyrighted material the use of which has not been specifically authorized by the copyright owner. ExoNews.org distributes this material for the purpose of news reporting, educational research, comment and criticism, constituting Fair Use under 17 U.S.C § 107. Please contact the Editor at ExoNews with any copyright issue.
Apollo 11 Astronaut Michael Collins Confirms Belief in Extraterrestrials
Listen to "E90 9-9-19 Apollo 11 Astronaut Michael Collins Confirms Belief in Extraterrestrials" on Spreaker.
Article by Michael Moran August 28, 2019 (dailystar.co.uk)
• In the summer of 1969, Michael Collins was the pilot for the Apollo 11 Command Module. When Neil Armstrong and Buzz Aldrin took the Moon Lander to the surface of the Moon, Collins remained in the Command Module and orbited the Moon.
• On the third day of the Apollo 11 mission as the Command Module was traveling to the Moon, Commander Neil Armstrong spotted a nearby object moving roughly on a parallel course with them as they zoomed towards the Moon. The crew guessed that it was the third stage of the Saturn-V rocket that had launched them into space, called the S-IVB. Armstrong radioed Mission Control in Houston and asked "Do you have any idea where the S-IVB is with respect to us?" Mission Control replied. "The S-IVB is about 6,000 nautical miles from you now."
• Twitter conspiracy theorists went wild, convinced that what the three astronauts saw was an alien spacecraft shadowing them. Later on, Aldrin denied that the Apollo 11 crew had seen a UFO.
• Celebrating fifty years since the Apollo 11 Moon landing, Collins was a guest on an online Twitter chat recently. Collins was asked the typical questions, ie: what food did the astronauts eat, what music did they listen to, and technical questions about the Moon lander. But when one Twitter questioner asked Collins, "Do you believe in life outside Earth?" Collins immediately answered "Yes".
• [Editor's Note] Insiders such as William Tompkins who personally knew the engineers at NASA Mission Control have always known that the Apollo 11 crew encountered unambiguous alien spacecraft on and around the Moon. Several large and menacing spacecraft were parked along the rim of the crater in which the Moon lander had landed. Ham radio operators picked up Armstrong reporting to Mission Control on a private medical frequency that 'Santa Clause' was there – code for alien spacecraft. Later, Armstrong would reveal privately to close friends or family members that he had seen these alien craft watching them on the Moon. But of course, they were all sworn to secrecy under the penalty of harm to them or their families. These alien occupants of the Moon didn't particularly like these earth humans being there, and this is why after the scheduled Apollo missions were finished, NASA never ventured back to the Moon.
Michael Collins was the loneliest astronaut of all time when, in 1969, he orbited the Moon as Neil Armstrong and Buzz Aldrin took the first steps on the desolate satellite.
Armstrong, Collins and Aldrin
Alone in the Apollo 11 Command Module, he had plenty of time to think about life in outer space.
And the veteran astronaut has decided firmly in favour of extraterrestrials.
In an online chat this week, marking the 50th anniversary of the first Moon mission, Twitter users asked Michael about the food the astronauts ate, the music they listened to, and the technical side of flying the Moon lander.
But one curious questioner asked "Do you believe in life outside Earth?"
And Michael simply replied "Yes."
Buzz Aldrin: It's Time to Focus on the Great Migration of Humankind to Mars
by Buzz Aldrin May 1, 2019 (washingtonpost.com)
• In a Washington Post opinion piece, former NASA astronaut Buzz Aldrin says that America should take the lead in a global effort to go to the moon and to Mars. 'When Neil Armstrong, Michael Collins and I went to the moon 50 years ago this July, we did so with… America's can-do commitment to space exploration,' wrote Aldrin. 'More of that is needed now.' 'The United States should… offer itself as a willing team leader.' Aldrin added that 'Mars is waiting to be discovered… by living, breathing, walking, talking, caring and daring men and women.'
• '[M]embers of Congress, the Trump administration and the American public must… make human exploration missions to Mars a national priority. I do not mean spending billions of taxpayer dollars on a few hijinks or joy rides, allowing those who return to write books, tweet photos and talk of the novelty. ' 'It is time we get down to blueprints, architecture and implementation, and to take that next step — a sustainable international return to the moon, directly charting a pathway to Mars.' 'The United States… should focus on… the great migration of humankind to Mars.'
• 'The next step would build on our early lunar landings and establish permanent settlements on the moon. In the meantime, preparations for permanent migration to the red planet can be made. All of this is within reach for humans alive now. …The nation best poised to make it happen is the United States.'
• [P]otentially, the ultimate survival of our species demands humanity's continued outward reach into the universe. …Put simply: We explore, or we expire. That is why we must get on with it.
• '[T]he Trump administration and this Congress would be remembered decades forward for putting humans permanently on the moon and Americans on Mars — for making human footprints in red dust and subsequent migration possible.' 'I thank President Trump and the vice president for their commitment. But my eyes drift higher, to the red orb that, even now, awaits an American flag and plaque that reads: "We Come in Peace for All Mankind."
• [Editor's Note] What Buzz Aldrin is cleverly advocating here is transparency. There are already secret bases on the moon and colonies on Mars and elsewhere. President Trump's public foray into space will reveal that, over the past seventy years, governments and corporations have secretly built a vast breakaway civilization within our solar system. It is time the world learned the truth.
Last month, Vice President Pence announced that we are headed back to the moon. I am with him, in spirit and aspiration. Having been there, I can say it is high time we returned. When Neil Armstrong, Michael Collins and I went to the moon 50 years ago this July, we did so with a mission. Apollo 11 aimed to prove America's can-do commitment to space exploration, as well as its national security and technological superiority. We did all that. We also "Came in Peace for all Mankind." More of that is needed now.
Today, many nations have eyes for the moon, from China and Russia to friends in Europe and Middle East. That is all good. The United States should cooperate — and offer itself as a willing team leader — in exploring every aspect of the moon, from its geology and topography to its hydrology and cosmic history. In doing so, we can take "low-Earth orbit" cooperation to the moon, openly, eagerly and collegially.
Meanwhile, another looming orb — the red one — should become a serious focus of U.S. attention. Mars is waiting to be discovered, not by clever robots and rovers — though I support NASA's unmanned missions — but by living, breathing, walking, talking, caring and daring men and women.
To make that happen, members of Congress, the Trump administration and the American public must care enough to make human exploration missions to Mars a national priority. To be clear, I do not mean spending billions of taxpayer dollars on a few hijinks or joy rides, allowing those who return to write books, tweet photos and talk of the novelty. I mean something very different.
The United States' eyes — and our unified commitment — should focus on opening the door, in our time, to the great migration of humankind to Mars. Books aplenty have been written about how to do this, and they have inspired government and non-government leaders to make lofty plans. But plans without a detailed architecture, and without that "next step" into the future, are just fantasy.
Americans are good at writing fantasy, and incomparable at making the fantastic a reality. We did it with Mercury, Gemini, Apollo — and in thousands of other ways. It is time we get down to blueprints, architecture and implementation, and to take that next step — a sustainable international return to the moon, directly charting a pathway to Mars.
The Navy Has a Secret Classified Video of an Infamous UFO Incident January 22, 2020
Declassified UFO Report Documents 'Green Circular Object' Over Soviet Missile Range January 21, 2020
President Eisenhower and Extraterrestrials? Film Explores This Urban Legend January 20, 2020
George Adamski Got Famous Sharing UFO Photos and Alien 'Encounters' January 19, 2020
Planet Venus May Have Been Habitable For Billions of Years, NASA Says January 19, 2020
When an Air Force Jet Scrambled to Intercept a UFO and Disappeared January 18, 2020
First Chief of Space Force Sworn In January 18, 2020
Aliens Definitely Exist and They Could Be Living Among Us, Says Britain's First Astronaut January 17, 2020
Embark On the Search for Extraterrestrial Life in Documentary 'Wow Signal' January 16, 2020
How the CIA Tried to Quell a UFO Panic During the Cold War January 15, 2020
Copyright © 2019 Exopolitics Institute News Service. All Rights Reserved.

redpajama_set_name: RedPajamaCommonCrawl


text:
from model.base import db
from flask.ext.restful import fields

start_performance_marshaller = {
    'id': fields.Integer,
    'departure_loc': fields.Integer,
    'departure_time': fields.DateTime(dt_format='iso8601'),
    'distance': fields.Float
}

final_performance_marshaller = {
    'departure_loc': fields.Integer,
    'arrival_loc': fields.Integer,
    'departure_time': fields.DateTime(dt_format='iso8601'),
    'arrival_time': fields.DateTime(dt_format='iso8601'),
    'distance': fields.Float,
    'mean_speed': fields.Float
}

class Performance(db.Model):
    id = db.Column(db.Integer, primary_key=True)

    departure_loc = db.Column(db.Integer)
    arrival_loc = db.Column(db.Integer)
    departure_time = db.Column(db.DateTime)
    arrival_time = db.Column(db.DateTime)
    distance = db.Column(db.Float)
    mean_speed = db.Column(db.Float)

    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    def __init__(self, user, departure_loc, departure_time, distance):
        self.user = user
        self.departure_loc = departure_loc
        self.departure_time = departure_time
        self.distance = distance


text:
Advice Surgery & Community Support
Keeping everyone safe during Covid19 is very important. We are not able to provide face to face appointments but telephone advice and support can still be provided by one of our support workers. Our team can provide advice and information on carers rights, welfare benefits and accessing support services. We can also make referrals. All our advice and information is provided confidentially.
As soon as possible we will resume our face to face advice surgeries. In the mean time please contact us on 020 8514 6251.
Our community support team are still running monthly support groups on-line via Zoom. Join one of the following groups for peer support and to meet other carers.
First Friday of every month, 1:30pm till 3:30pm, contact Sylvia Williams 020 8418 9895.
Third Wednesday of every month, 10:00am till 12:00 noon, contact Jahan McCready 020 8590 1236.
Published: 21st November, 2019
Barkingside Support Group (1st Friday of every month)
Dementia Carers Support Group (2nd Thursday of the month)
Ilford Support group (3rd Wednesday of every month)
Older Carers Coffee Morning
Young Adult Carers Support Group
Refugee & Migrant Carers
The project is dedicated to newly arrived carers into the country and living in Redbridge. This project supports carers and their families from some of the most marginalised communities, including carers who are asylum seekers.
Older Carers Connect
The Older Carers Connect Project, aims to support and to empower carers aged 65 and over to make lasting friends and improve health and wellbeing.
Employment and training advice for unpaid carers aged 25 and over living in London.
Young Adult Carers Project
We offer general advice and individual support to young adult carers (YAC) aged 16-30. You will have an opportunity to meet other YACs at the monthly supp


text:
Q: AWS RDS disaster recovery using cross-account We are running AWS RDS PostgreSQL, with daily automatic snapshots, encrypted by AWS managed KMS key. My objective is to minimize risks and data loss, in case when main AWS account (running RDS) got compromised or RDS deleted/damaged in some way.
What we've implemented so far: RDS snapshots are shared with different (backup) account, periodically copied to backup account and re-encrypted with the KMS key from the backup account, to make copies local, and independent from the main AWS account.

I'm wondering if there are better ways to minimize recovery time objective and recovery point objective in case of a disaster event?

A: This AWS blog post seems to weigh the options well.

Automated backups are limited to a single AWS Region while manual snapshots and Read Replicas are supported across multiple Regions.

Having cross region Read replica would give you the best RPO and RTO as you can promote replica to be an independent instance which should improve your RPO / RTO
Alternatively, if you choose to use Amazon Aurora Backtrack it seems to offer a similar option to having a read replica but I do not have a personal experience with this feature so can't say how effective it is in improving RTO and RPO.

A: I wrote two scripts implementing flow at the diagram drawn above ^^^, the idea is to run them daily:
src_acc_take_share_rds_snapshot.py in src account:

*

*list available RDS snapshots according to provided regexp

*recrypt them with KMS key, shared from dst account

*share recrypted RDS snapshots with the dst account

*remove old decrypted snapshots

dst_acc_copy_shared_rds_snapshot_to_local.py in dst account

*

*list RDS snapshots, shared in src account with dst account

*copy RDS snapshots from src account to dst account

*remove old decrypted snapshots

*fire an SNS message if desired snapshot count != actual

and put them at GitHub https://github.com/mvasilenko/dr-rds-share-snapshot

redpajama_set_name: RedPajamaStackExchange


text:
Counter Terrorism Policing News Latest Home Office statistics reveal 7 late-stage plots foiled since March 2020
Latest Home Office statistics reveal 7 late-stage plots foiled since March 2020
Counter Terrorism Policing (CTP) and the UK Intelligence Services have stopped seven late-stage terror attacks since the start of the Covid-19 pandemic, leading senior police officers to warn the public not to let their guard slip during the festive period.
That takes the total number of foiled terrorism plots since March 2017 to 32 – with 18 related to Islamist extremism, 12 to Extreme Right Wing Terrorism (XRWT) and two to Left, Anarchist or Single Issue Terrorism (LASIT).
The warning comes as the Home Office's quarterly release of statistics relating to the police's use of powers under the Terrorism Act 2000 revealed there were a total of 188 arrests for terrorism-related activity in the year ending 30 September 2021.
The Senior National Coordinator for Counter Terrorism Policing, Deputy Assistant Commissioner Dean Haydon, said: "CTP and our colleagues in the security services have stopped seven terror plots in less than two years, assisted by our officers making 188 arrests in the 12 months to the end of September.
"The public will also be well aware of the fact that the UK has suffered two terror attacks in quick succession, with the national threat level raising to Severe – meaning an attack is highly likely.
"All of this combines to paint a picture of a sustained and high tempo threat, which our world-class police, security and intelligence services are doing everything in their power to combat.
"But it takes a whole society approach to effectively tackle terrorism, and co-operation between the police and the public is vital, so we need you to be vigilant, and we need you to be alert.
"As we approach the festive period, we need the public to help play their part in protecting the UK.
"That means trusting your instincts and contacting us if you see anything suspicious – we get 10,000 reports of suspected terrorist activity from the public every year and around 20% of those are useful intelligence which helps officers stop terrorists.
"I would urge everyone to remain vigilant and ACT by reporting it to us confidentially via gov.uk/ACT or by calling 0800 789 321. In an emergency, always dial 999."
CT experts have highlighted one other concerning element to the latest arrest statistics, and that is despite the overall total falling to one of its lowest levels in a decade – with 28 (13%) fewer arrests than the previous 12-month period – children continue to be disproportionally represented.
Despite the overall reduction in arrests, which is largely due to an overall reduction in crime since the beginning of the national lockdown in March last year, 25 children were arrested in relation to terrorism offending – the highest number ever recorded in a 12-month period.
"We are very concerned that children are becoming an increasing proportion of our arrests," added DAC Haydon.
"But it doesn't have to be this way. Ideally we would identify when a young person is being led down the path towards terrorism activity and use the Prevent programme to try and put them on a different path.
"Our research tells us that parents, family members and friends are the first to see the changes in behaviour which might indicate that a loved one is being radicalised. But currently just 3% of people we help through Prevent come to the programme because of concerns raised by those same people who know them best.
"We urge concerned parents to visit website – www.actearly.uk – designed specifically to offer advice and support for parents and family members who think their loved one might be following a dangerous path towards extremism.
"Asking for help is a difficult and emotional step, but we must see it for what it is – action which won't ruin their lives but may well save them."
If you are worried that someone you know is being radicalised, visit www.actearly.uk
For help and advice visit www.actearly.uk, or call the national Police Prevent Advice Line on 0800 011 3764, in confidence, and our specially trained Prevent officers will listen carefully to your concerns.