  #############################################################################
     
    // START_DEFINITION
    /*
    The fingerprint identifies sessions visiting the Tor Project website from
    non-fvey countries.
    */
    fingerprint('anonymizer/tor/torpoject_visit')=http_host('www.torproject.org')
    and not(xff_cc('US' OR 'GB' OR 'CA' OR 'AU' OR 'NZ'));
    // END_DEFINITION
     
     
    // START_DEFINITION
    /*
    These variables define terms and websites relating to the TAILs (The Amnesic
    Incognito Live System) software program, a comsec mechanism advocated by
    extremists on extremist forums.
    */
     
    $TAILS_terms=word('tails' or 'Amnesiac Incognito Live System') and word('linux'
    or ' USB ' or ' CD ' or 'secure desktop' or ' IRC ' or 'truecrypt' or ' tor ');
    $TAILS_websites=('tails.boum.org/') or ('linuxjournal.com/content/linux*');
    // END_DEFINITION
     
    // START_DEFINITION
    /*
    This fingerprint identifies users searching for the TAILs (The Amnesic
    Incognito Live System) software program, viewing documents relating to TAILs,
    or viewing websites that detail TAILs.
    */
    fingerprint('ct_mo/TAILS')=
    fingerprint('documents/comsec/tails_doc') or web_search($TAILS_terms) or
    url($TAILS_websites) or html_title($TAILS_websites);
    // END_DEFINITION
     
     
    // START_DEFINITION
    requires grammar version 5
    /**
     * Aggregate Tor hidden service addresses seen in raw traffic.
     */
    mapreduce::plugin('anonymizer/tor/plugin/onion') =
      immediate_keyword(/(?:([a-z]+):\/\/){0,1}([a-z2-7]{16})\.onion(?::(\d+)){0,1}/c : c++
        includes: {{
          #include <boost/lexical_cast.hpp>
        }}
        proto: {{
          message onion_t {
            required string address = 1;
            optional string scheme = 2;
            optional string port = 3;
          }
        }}
        mapper<onion_t>: {{
          static const std::string prefix = "anonymizer/tor/hiddenservice/address/";
     
          onion_t onion;
          size_t matches = cur_args()->matches.size();
          for (size_t pos=0; pos < matches; ++pos) {
            const std::string &value = match(pos);
            if (value.size() == 16)
              onion.set_address(value);
            else if(!onion.has_scheme())
              onion.set_scheme(value);
            else
              onion.set_port(value);
          }
     
          if (!onion.has_address())
            return false;
     
          MAPPER.map(onion.address(), onion);
          xks::fire_fingerprint(prefix + onion.address());
          return true;
        }}
        reducer<onion_t>: {{
          for (values_t::const_iterator iter = VALUES.begin();
              iter != VALUES.end();
              ++iter) {
            DB["tor_onion_survey"]["onion_address"] = iter->address() + ".onion";
            if (iter->has_scheme())
              DB["tor_onion_survey"]["onion_scheme"] = iter->scheme();
            if (iter->has_port())
              DB["tor_onion_survey"]["onion_port"] = iter->port();
            DB["tor_onion_survey"]["onion_count"] = boost::lexical_cast<std::string>(TOTAL_VALUE_COUNT);
            DB.apply();
            DB.clear();
          }
          return true;
        }});
     
    /**
     * Placeholder fingerprint for Tor hidden service addresses.
     * Real fingerpritns will be fired by the plugins
     *   'anonymizer/tor/plugin/onion/*'
     */
    fingerprint('anonymizer/tor/hiddenservice/address') = nil;
    // END_DEFINITION
     
     
    // START_DEFINITION
    appid('anonymizer/mailer/mixminion', 3.0, viewer=$ascii_viewer) =
            http_host('mixminion') or
            ip('128.31.0.34');
    // END_DEFINITION
     