#!/usr/bin/env python
#
# Copyright 2007 John Wiseman <jjwiseman@yahoo.com>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import re
import sys
import StringIO
import getopt


class RegressiveImageryDictionary:
  """
  To use:
    1. Load a dictionary.
    2. Load an exclusion list (optional).
    3. Call analyze.
    4. Call display_results with the value returned by analyze.    
  """
  def __init__(self):
    self.category_tree = CategoryRoot()
    self.exclusion_patterns = []
    self.exclusion_pattern = None
    self.pattern_tree = DiscriminationTree('root', None)

  def load_dictionary_from_file(self, path):
    rid_in = open(path, "r")
    try:
      self.load_dictionary(rid_in)
    finally:
      rid_in.close()

  def load_dictionary_from_string(self, string):
    rid_in = StringIO.StringIO(string)
    self.load_dictionary(rid_in)
      
  def load_dictionary(self, stream):
    primary_category = None
    secondary_category = None
    tertiary_category = None

    for line in stream:
      num_tabs = count_leading_tabs(line)
      # The dictionary is in kind of a weird format.
      if num_tabs == 0:
        primary_category = line.strip()
        secondary_category = None
        tertiary_category = None
      elif num_tabs == 1:
        secondary_category = line.strip()
        tertiary_category = None
      elif num_tabs == 2 and not '(' in line:
        tertiary_category = line.strip()
      else:
        # We have a word pattern.
        pattern = line.strip().split(' ')[0].lower()
        category = self.ensure_category(primary_category, secondary_category, tertiary_category)
        category.add_word_pattern(pattern)
        self.pattern_tree.put(pattern, category)

  def load_exclusion_list_from_file(self, path):
    exc_in = open(path, "r")
    try:
      self.load_exclusion_list(exc_in)
    finally:
      exc_in.close()
      
  def load_exclusion_list_from_string(self, string):
    exc_in = StringIO.StringIO(string)
    self.load_exclusion_list(exc_in)

  def load_exclusion_list(self, stream):
    for line in stream:
      pattern = line.strip().lower()
      pattern = pattern.replace("*", ".*")
      self.exclusion_patterns.append(pattern)
    # One megapattern to exclude them all
    self.exclusion_pattern = re.compile('^(' + '|'.join(self.exclusion_patterns) + ')$')

  def token_is_excluded(self, token):
    return self.exclusion_pattern.match(token)

  def get_category(self, word):
    categories = self.pattern_tree.retrieve(word)
    if categories:
      return categories[0]
          
  def analyze(self, text):
    results = RIDResults()
    def increment_category(category, token):
      if not category in results.category_count:
        results.category_count[category] = 0
        results.category_words[category] = []
      results.category_count[category] += 1
      results.category_words[category].append(token)
    
    tokens = tokenize(text)
    results.word_count = len(tokens)
    for token in tokens:
      if not self.token_is_excluded(token):
        category = self.get_category(token)
        if category != None:
          increment_category(category, token)
    return results

  def display_results(self, results):
    # Detailed category breakout 
    total_count = 0
    for (category, count) in sorted(results.category_count.items(), key=lambda x: x[1], reverse=True):
      print "%-60s %5s" % (category.full_name(), count)
      print "  " + " ".join(results.category_words[category])
      total_count += count

    # Summary for each top-level category
    top_categories = self.category_tree.children.values()
    def get_top_category(cat):
      for top_cat in top_categories:
        if cat.isa(top_cat):
          return top_cat
      print "Category %s doesn't exist in %s" % (category, top_categories)
        
    top_category_counts = {}
    for top_category in top_categories:
      top_category_counts[top_category] = 0
    
    for category in results.category_count:
      top_category = get_top_category(category)
      if top_category:
        top_category_counts[top_category] += results.category_count[category]

    print ""

    def percent(x, y):
      if y == 0:
        return 0
      else:
        return (100.0 * x) / y
    for top_category in top_categories:
      count = top_category_counts[top_category]
      print "%-20s: %f %%" % (top_category.full_name(), percent(count, total_count))
        
    # Word count
    print "\n%d words total" % (results.word_count,)

  def display_results_html(self, results, title):
    # Detailed category breakout 
    total_count = 0
    print "<html><head>"

    print "<meta http-equiv='content-type' content='text/html; charset=UTF-8'>"
    print """
  <style type="text/css">
    .word-count { vertical-align: super; font-size: 50%; }
    .twisty { color: blue; font-family: monospace; }
    a.twisty { text-decoration: none; }
  </style>
"""
    print "<title>%s</title>" % (title,)
    print """
<script>

var TWISTY_EXPANDED = ' &#9662; ';
var TWISTY_COLLAPSED = ' &#9656; ';

function allWordNodes() {
  var nodes = document.getElementsByTagName("tr");
  var results = new Array();
  var numResults = 0;

  for (i = 0; i < nodes.length; i++) {
    var node = nodes.item(i);
    if (node.className == 'words') {
      results[numResults] = node;
      numResults++;
    }
  }
  return results;
}

function hideAll() {
  allNodes = allWordNodes();
  for (var i = 0; i < allNodes.length; i++) {
    hide(allNodes[i]);
  }
}

function showAll() {
  allNodes = allWordNodes();
  for (var i = 0; i < allNodes.length; i++) {
    show(allNodes[i]);
  }
}

function get_twisty_node(category) {
  var cell = document.getElementById(category + "-cat");
  return cell.childNodes[0];
}

function hide(element) {
  element.style.display = "none";
  var twisty = get_twisty_node(element.id);
  twisty.innerHTML = TWISTY_COLLAPSED;
}

function show(element) {
  element.style.display = "";
  var twisty = get_twisty_node(element.id);
  twisty.innerHTML = TWISTY_EXPANDED;
}

function toggle(cat) {
  var node = document.getElementById(cat)
  if (node.style.display == "none") {
    show(node);
  } else {
    hide(node);
  }
}

</script>
"""
    print "</head><body>"
    print "<h1>%s</h1>" % (title,)
    print "<p><a href='javascript:hideAll()'>- collapse all</a>  <a href='javascript:showAll()'>+ expand all</a></p>"
    print "<table width='100%'>"
    for (category, count) in sorted(results.category_count.items(), key=lambda x: x[1], reverse=True):
      sys.stdout.write("<tr>")
      sys.stdout.write("<td class='%s' id='%s'>" % ("category", category.full_name() + "-cat"))
      sys.stdout.write("""<a class='twisty' href="javascript:toggle('%s')"><span class='twisty'> &#9662; </span></a>""" % (category.full_name(),))
      sys.stdout.write("%s</td><td width='*' align='right'>%s</td></tr>""" % (category.full_name(), count))
      print "<tr class='%s' id='%s'>" % ("words", category.full_name())
      print "<td style='padding-left: 1cm;' colspan='2'>"
      words = uniq_c(results.category_words[category])
      for word in words:
        sys.stdout.write("%s<span class='word-count'>%s</span> " % (word))
      print "\n</td></tr>"
      total_count += count
    print "</table>"

    # Summary for each top-level category
    top_categories = self.category_tree.children.values()
    def get_top_category(cat):
      for top_cat in top_categories:
        if cat.isa(top_cat):
          return top_cat
      print "Category %s doesn't exist in %s" % (category, top_categories)
        
    top_category_counts = {}
    for top_category in top_categories:
      top_category_counts[top_category] = 0
    
    for category in results.category_count:
      top_category = get_top_category(category)
      if top_category:
        top_category_counts[top_category] += results.category_count[category]


    def percent(x, y):
      if y == 0:
        return 0
      else:
        return (100.0 * x) / y

    print "<table>"
    for top_category in top_categories:
      count = top_category_counts[top_category]
      print "<tr><td>%s:</td><td>%f %%</td></tr>" % (top_category.full_name(), percent(count, total_count))
    print "<table>"
        
    # Word count
    print "<p>%d words total</p>" % (results.word_count,)
    print "</body></html>"


  def ensure_category(self, *args):
    def ensure_cat_aux(category, category_path):
      if len(category_path) == 0 or category_path[0] == None:
        return category
      else:
        cat = category_path.pop(0)
        if not cat in category.children:
          category.children[cat] = Category(cat, category)
        return ensure_cat_aux(category.children[cat], category_path)
    return ensure_cat_aux(self.category_tree, list(args))


class RIDResults:
  def __init__(self):
    self.category_count = {}
    self.category_words = {}
    self.word_count = 0


WORD_REGEX = re.compile(r'[^a-zA-Z]+')
def tokenize(string):
  tokens = WORD_REGEX.split(string.lower())
  tokens = filter(lambda token: len(token) > 0, tokens)
  return tokens


def count_leading_tabs(string):
  for i, char in enumerate(string):
    if char != '\t':
      return i


class DiscriminationTree:
  """
  This is the discrimination tree we use for mapping words to
  categories.  The put method is used to insert category nodes in the
  tree, associated with some word pattern.  The retrieve method finds
  the category for a given word, if one exists.
  """
  def __init__(self, index, parent):
    self.index = index
    self.parent = parent
    self.leaves = []
    self.interiors = []
    self.is_wildcard = False

  def __str__(self):
    return "<DiscriminationTree %s>" % (self.index,)
 
  def child_matching_index(self, index):
    for child in self.interiors:
      if child.index == index:
        return child
    return None

  def retrieve(self, path):
    if len(path) == 0 or self.is_wildcard:
      return self.leaves
    else:
      next_index = path[0]
      next_disc_tree = self.child_matching_index(next_index)
      if next_disc_tree == None:
        return
      else:
        return next_disc_tree.retrieve(path[1:])

  def put(self, path, leaf):
    if len(path) == 0:
      if isinstance(leaf, DiscriminationTree):
        self.interiors.append(leaf)
      else:
        self.leaves.append(leaf)
      return True
    else:
      next_index = path[0]
      if next_index == '*':
        # Got a '*' so this is a wildcard node that will match
        # anything that reaches it.
        self.is_wildcard = True
        self.leaves.append(leaf)
      else:
        next_disc_tree = self.child_matching_index(next_index)
        if next_disc_tree == None:
          next_disc_tree = DiscriminationTree(next_index, self)
          self.interiors.append(next_disc_tree)
        next_disc_tree.put(path[1:], leaf)

  def dump(self, stream=sys.stdout, indent=0):
    stream.write("\n" + " "*indent + str(self))
    for child in self.leaves:
      stream.write("\n" + " "*(indent + 3) + str(child))
    for child in self.interiors:
      child.dump(stream=stream, indent=indent + 3)


class Category:
  def __init__(self, name, parent):
    self.name = name
    self.parent = parent
    self.children = {}
    self.leaves = []

  def __str__(self):
    return "<Category %s>" % (self.full_name(),)

  def add_word_pattern(self, pattern):
    self.leaves.append(pattern)

  def full_name(self):
    if self.parent == None or isinstance(self.parent, CategoryRoot):
      return self.name
    else:
      return self.parent.full_name() + ":" + self.name

  def isa(self, parent):
    return parent == self or (self.parent and self.parent.isa(parent))


class CategoryRoot(Category):
  def __init__(self):
    Category.__init__(self, 'root', None)

  def full_name(self):
    return ""


def uniq_c(words):
  words.sort()
  results = []
  last_word = words[0]
  last_word_count = 1
  for word in words[1:]:
    if word == last_word:
      last_word_count += 1
    else:
      results.append((last_word, last_word_count))
      last_word = word
      last_word_count = 1
  results = sorted(results, key=lambda x: x[1], reverse=True)
  return results
    


# This dictionary is the one from
# http://www.provalisresearch.com/Download/RID.ZIP with misspellings
# fixed.

DEFAULT_RID_DICTIONARY = """
PRIMARY
	NEED
		ORALITY
			ABSINTH* (1)
			ALE (1)
			ALES (1)
			ALIMENTARY (1)
			AMBROSIA* (1)
			AMBROSIAL* (1)
			APPETIT* (1)
			APPLE* (1)
			ARTICHOK* (1)
			ASPARAGU* (1)
			BACON* (1)
			BANANA* (1)
			BEAN* (1)
			BEEF* (1)
			BEER* (1)
			BELCH* (1)
			BELLIES (1)
			BELLY (1)
			BERRI* (1)
			BERRY* (1)
			BEVERAG* (1)
			BISCUIT* (1)
			BITE* (1)
			BITE (1)
			BITES (1)
			BITING (1)
			BITTEN* (1)
			BONBON* (1)
			BRANDY* (1)
			BREAD* (1)
			BREAKFAST* (1)
			BREAST* (1)
			BREW* (1)
			BROTH (1)
			BURP* (1)
			BUTTER* (1)
			BUTTERMILK* (1)
			CAFE (1)
			CAFES (1)
			CAKE (1)
			CAKES (1)
			CAFETARIA (1)
			CANDY* (1)
			CANNIBAL* (1)
			CAVIAR* (1)
			CHAMPAGN* (1)
			CHEES* (1)
			CHERRI* (1)
			CHERRY* (1)
			CHESTNUT* (1)
			CHEW* (1)
			CHOK* (1)
			CIDER* (1)
			CLARET* (1)
			COB (1)
			COBS (1)
			COCOA* (1)
			COCOANUT* (1)
			COCONUT* (1)
			COFFE* (1)
			CONSUM* (1)
			COOK* (1)
			CORN* (1)
			COUGH* (1)
			CRANBERRY* (1)
			CREAM* (1)
			DELICACI* (1)
			DELICACY* (1)
			DESSERT* (1)
			DEVOUR* (1)
			DIET* (1)
			DIGEST* (1)
			DINE (1)
			DINES (1)
			DINING (1)
			DINNER* (1)
			DISH (1)
			DISHES (1)
			DRANK* (1)
			DRINK* (1)
			DRUNK* (1)
			DRUNKEN* (1)
			EAT* (1)
			EATEN* (1)
			EGG* (1)
			ENTRAIL* (1)
			FAMIN* (1)
			FAMISH* (1)
			FAST (1)
			FASTS (1)
			FAT (1)
			FATTEN* (1)
			FEAST* (1)
			FED (1)
			FEED (1)
			FEEDS (1)
			FIG (1)
			FIGS (1)
			FLOUR* (1)
			FOOD* (1)
			FOODSTUFF* (1)
			FORK* (1)
			FRUIT* (1)
			GARLIC* (1)
			GIN (1)
			GINGER* (1)
			GINS (1)
			GLUTTON* (1)
			GLUTTONOU* (1)
			GNAW* (1)
			GOBBL* (1)
			GRAIN* (1)
			GRAP* (1)
			GROG* (1)
			GRUEL* (1)
			GULP* (1)
			GUM (1)
			GUMS (1)
			GUT (1)
			GUTS (1)
			HAM (1)
			HAMS (1)
			HERB* (1)
			HONEY* (1)
			HUNGER* (1)
			HUNGRY* (1)
			IMBIB* (1)
			INEDIBL* (1)
			INTESTIN* (1)
			JAW* (1)
			JUIC* (1)
			LAP (1)
			LAPS (1)
			LEMON* (1)
			LICK* (1)
			LIME (1)
			LIMES (1)
			LIP (1)
			LIPS (1)
			LIQUEUR* (1)
			LIQUOR* (1)
			LUNCH* (1)
			MAIZ* (1)
			MEAL* (1)
			MEAT* (1)
			MELON* (1)
			MENU* (1)
			MILK* (1)
			MINT* (1)
			MORSEL* (1)
			MOUTH* (1)
			MOUTHFUL* (1)
			MUSHROOM* (1)
			MUTTON* (1)
			NAUS* (1)
			NECTAR* (1)
			NIBBL* (1)
			NOURISH* (1)
			NOURISHMENT* (1)
			NURTUR* (1)
			NUT (1)
			NUTS (1)
			OLIV* (1)
			ORAL* (1)
			PALAT* (1)
			PARTAK* (1)
			PASTRI* (1)
			PASTRY* (1)
			PEA (1)
			PEANUT* (1)
			PEAR* (1)
			PEAS (1)
			PEPPER* (1)
			PHILTR* (1)
			PINEAPPL* (1)
			POISON* (1)
			PORK* (1)
			PORRIDG* (1)
			POT (1)
			POTATO* (1)
			POTBEL* (1)
			POTS (1)
			PUCKER* (1)
			PUMPKIN* (1)
			QUENCH* (1)
			RASPBERRY* (1)
			RAW (1)
			RAWLY (1)
			REPAST* (1)
			RESTAURANT* (1)
			RESTAURENT* (1)
			RICE (1)
			RICES (1)
			RIPENES* (1)
			ROAST* (1)
			RUM (1)
			RUMS (1)
			SALAD* (1)
			SALIVA* (1)
			SALIVAT* (1)
			SALT* (1)
			SAUC* (1)
			SAUERKRAUT* (1)
			SESAM* (1)
			SHERBERT* (1)
			SHERRY* (1)
			SOUP* (1)
			SPAT* (1)
			SPIT* (1)
			SPITTL* (1)
			SPOON* (1)
			STARV* (1)
			STARVAT* (1)
			STOMACH* (1)
			STRAWBERRI* (1)
			STRAWBERRY* (1)
			SUCK* (1)
			SUCKL* (1)
			SUGAR* (1)
			SUPPER* (1)
			SWALLOW* (1)
			TEA (1)
			TEAS (1)
			TEAT* (1)
			TEETH* (1)
			THIRST* (1)
			THIRSTY* (1)
			THROAT* (1)
			TIT (1)
			TITS (1)
			TOMATO* (1)
			TONGU* (1)
			TOOTH* (1)
			UNCOOK* (1)
			VEAL* (1)
			VEGETABL* (1)
			VENISON* (1)
			VODKA* (1)
			VOMIT* (1)
			WHEAT* (1)
			WHISKEY* (1)
			WHISKY* (1)
			YAM (1)
			YAMS* (1)
			YEAST* (1)
		ANALITY
			ANAL (1)
			ANUS (1)
			ANUSES (1)
			ARSE (1)
			ARSEHOL* (1)
			ASSES (1)
			ASS-HOL* (1)
			ASSHOL* (1)
			BESHAT* (1)
			BESHIT* (1)
			BESMEAR* (1)
			BILE* (1)
			BOWEL* (1)
			BUTTOCK* (1)
			CACK* (1)
			CESSPOOL* (1)
			CLOACA* (1)
			CLOT (1)
			CLOTS* (1)
			CONSTIPAT* (1)
			DANK* (1)
			DAUB* (1)
			DEFECAT* (1)
			DEFIL* (1)
			DELOUS* (1)
			DIARRHOEA* (1)
			DIRT* (1)
			DIRTY* (1)
			DISGUST* (1)
			DUNG* (1)
			DUNGHILL* (1)
			EFFLUVIA* (1)
			EFFLUVIUM* (1)
			ENEMA* (1)
			EXCRET* (1)
			FART (1)
			FARTS (1)
			FECAL* (1)
			FECES (1)
			FETID* (1)
			FETOR* (1)
			FILTH* (1)
			FILTHY* (1)
			IMPUR* (1)
			LATRIN* (1)
			LICE (1)
			LOATHSOM* (1)
			LOUS* (1)
			MAGGOT* (1)
			MAGGOTY* (1)
			MALODOROU* (1)
			MALODOUROU* (1)
			MANUR* (1)
			MESS (1)
			MESSES (1)
			MESSING (1)
			MIASMA* (1)
			MUD (1)
			MUDDY* (1)
			MUDS (1)
			OFFAL* (1)
			OOZ* (1)
			OOZY* (1)
			OUTHOUS* (1)
			PISS* (1)
			POLLUT* (1)
			PUTRESCENC* (1)
			PUTRESCENT* (1)
			PUTRID* (1)
			RANCID* (1)
			RECTUM* (1)
			REEK* (1)
			ROT (1)
			ROTS (1)
			ROTTEN* (1)
			ROTTING (1)
			RUMP* (1)
			SCUM* (1)
			SEWER* (1)
			SHAT* (1)
			SHIT* (1)
			SLIMY* (1)
			SMEAR* (1)
			SODOMIST* (1)
			SODOMY* (1)
			SOIL* (1)
			STAL* (1)
			STENCH* (1)
			STINK* (1)
			SWEAT* (1)
			UNCLEAN* (1)
			UNWASH* (1)
			URIN* (1)
		SEX
			VENEREAL* (1)
			ADULTERER* (1)
			ADULTERY* (1)
			ALLUR* (1)
			BAWD* (1)
			BAWDY* (1)
			BITCH* (1)
			BROTHEL* (1)
			CARESS* (1)
			CARNAL* (1)
			CIRCUMCIS* (1)
			CLITORI* (1)
			COHABIT* (1)
			COITU* (1)
			CONCUBIN* (1)
			COPULAT* (1)
			COQUETT* (1)
			COQUETTISH* (1)
			COURTESAN* (1)
			CUCKOLD* (1)
			CUNT* (1)
			CUPID* (1)
			DEBAUCH* (1)
			DEFLOWER* (1)
			EJACULAT* (1)
			EROTIC* (1)
			FONDL* (1)
			FORNICAT* (1)
			FUCK* (1)
			GENITAL* (1)
			GENITALIA* (1)
			GIRDL* (1)
			GROIN* (1)
			HAREM* (1)
			HARLOT* (1)
			HOMOSEXUAL* (1)
			HOMOSEXUALITY* (1)
			IMMODEST* (1)
			INCEST* (1)
			INCESTUOU* (1)
			INDECENT* (1)
			INDISCRET* (1)
			INFATUAT* (1)
			KISS* (1)
			LASCIVIOU* (1)
			LECHER* (1)
			LECHEROU* (1)
			LECHERY* (1)
			LEER (1)
			LEERS (1)
			LEWD* (1)
			LIBERTIN* (1)
			LICENTIOU* (1)
			LOVER* (1)
			LUST* (1)
			LUSTFUL* (1)
			LUSTY* (1)
			MASTURBAT* (1)
			MENSTRUAL* (1)
			MENSTRUAT* (1)
			MISTRES* (1)
			NAKED (1)
			NUDE (1)
			NUDES (1)
			OBSCEN* (1)
			OBSCENITY* (1)
			ORGASM* (1)
			ORGI* (1)
			ORGY* (1)
			PANDER* (1)
			PARAMOUR* (1)
			PENI* (1)
			PERVERS* (1)
			PERVERT* (1)
			PHALLIC* (1)
			PHALLU* (1)
			PREGNANCY* (1)
			PREGNANT* (1)
			PROCREAT* (1)
			PROSTITUT* (1)
			PRURIENT* (1)
			PUBERTY* (1)
			PUBI* (1)
			PUBIC* (1)
			RAPE* (1)
			RAPING* (1)
			RIBALD* (1)
			SATYR* (1)
			SEDUC* (1)
			SENSUAL* (1)
			SENSUOU* (1)
			SEX (1)
			SEXED (1)
			SEXES (1)
			SEX-LINKED (1)
			SEXUAL* (1)
			SEXY* (1)
			SHAMELES* (1)
			SLATTERN* (1)
			SLUT* (1)
			SLUTTY* (1)
			TESTI* (1)
			TESTICL* (1)
			THIGH* (1)
			TROLLOP* (1)
			UNBLUSH* (1)
			UNDRES* (1)
			VAGINA* (1)
			VENU* (1)
			VOLUPTUOU* (1)
			VULVA* (1)
			WAIST* (1)
			WANTON* (1)
			WHOR* (1)
			WOMB* (1)
			SENSATION (1)
	SENSATION
		TOUCH
			BRUSH* (1)
			COARS* (1)
			CONTACT* (1)
			CUDD* (1)
			CUDDL* (1)
			HANDL* (1)
			ITCH* (1)
			ITCHY* (1)
			MASSAG* (1)
			PRICKL* (1)
			ROUGH* (1)
			RUB (1)
			RUBB* (1)
			RUBS (1)
			SCALY (1)
			SCRATCH* (1)
			SHARP* (1)
			SLICK* (1)
			SLIPPERY* (1)
			SMOOTH* (1)
			SNUGGL* (1)
			STING (1)
			STINGS (1)
			STROK* (1)
			TEXTUR* (1)
			THICK* (1)
			TICKL* (1)
			TINGL* (1)
			TOUCH* (1)
			WAXY* (1)
		TASTE
			AFTERTAST* (1)
			BITTER* (1)
			DELECTABL* (1)
			DELICIOU* (1)
			FLAVOR* (1)
			GALL (1)
			HONI* (1)
			LUSCIOU* (1)
			PIQUANT* (1)
			SAVOR* (1)
			SAVORY* (1)
			SAVOUR* (1)
			SAVOURY* (1)
			SOUR* (1)
			SPIC* (1)
			SPICY* (1)
			SUGARY* (1)
			SWEET* (1)
			SWEETNES* (1)
			TANG* (1)
			TANGY* (1)
			TART* (1)
			TAST* (1)
			TASTY* (1)
			TOOTHSOM* (1)
			UNPALATABL* (1)
			UNSAVORY* (1)
			VINEGAR* (1)
			VINEGARY* (1)
		ODOR
			AROMA* (1)
			AROMATIC* (1)
			BREATH* (1)
			COLOGN* (1)
			FRAGRANC* (1)
			FRAGRANT* (1)
			FUME* (1)
			FUMING* (1)
			INCENS* (1)
			INHAL* (1)
			MUSK* (1)
			MUSKY* (1)
			MUSTY* (1)
			NOSE* (1)
			NOSTRIL* (1)
			ODOR* (1)
			ODOUR* (1)
			PERFUM* (1)
			PUNGENC* (1)
			PUNGENT* (1)
			SCENT* (1)
			SMEL* (1)
			SMELL* (1)
			SNIF* (1)
			SNIFF* (1)
		GENERAL-SENSATION
			APPERCEIVE (1)
			APPERCEPTIVE (1)
			ATTENT* (1)
			AWAR* (1)
			AWARENES* (1)
			BALMY* (1)
			BASK* (1)
			BEAUTIFUL* (1)
			BEAUTY* (1)
			CHARM* (1)
			COMFORT* (1)
			COMFORTABL* (1)
			CREAMY* (1)
			FAIR* (1)
			IMPRESS* (1)
			LOVELINES* (1)
			LUSH* (1)
			LUXURIOU* (1)
			LUXURY* (1)
			MILKY* (1)
			OVERSENSITIV* (1)
			PERCEIV* (1)
			PERCEPT* (1)
			PERCEPTUAL (1)
			PHYSICAL* (1)
			PLEASANT* (1)
			PRETTY* (1)
			REFRESH* (1)
			RELISH* (1)
			REVEL* (1)
			SENSAT* (1)
			SENSITIV* (1)
			STIMULAT* (1)
			SUMPTUOU* (1)
		SOUND
			AUDITORILLY (1)
			ALOUD* (1)
			AUDIBL* (1)
			AUDITION (1)
			AUDITORY* (1)
			AURAL (1)
			BANG* (1)
			BELL* (1)
			BINAURAL (1)
			BLAR* (1)
			BOOM* (1)
			BUZZ* (1)
			CHORD* (1)
			CHORU* (1)
			CLACK* (1)
			CLAMOR* (1)
			CLAMOUR* (1)
			CLANG* (1)
			CRACKL* (1)
			CROAK* (1)
			DEAF* (1)
			DRON* (1)
			DRUM* (1)
			EAR (1)
			EARS (1)
			ECHO* (1)
			HARK* (1)
			HEAR* (1)
			HEARD* (1)
			HISS* (1)
			HUM (1)
			HUMM* (1)
			HUMS (1)
			LISTEN* (1)
			LOUD* (1)
			LOUDER* (1)
			MELODI* (1)
			MELODIOU* (1)
			MELODY* (1)
			MUFFL* (1)
			MUSIC* (1)
			MUSICAL* (1)
			NOIS* (1)
			NOISY* (1)
			PEAL* (1)
			PURR* (1)
			RACKET* (1)
			RASP* (1)
			RATTL* (1)
			RAUCOU* (1)
			RESONANT* (1)
			RESOUND* (1)
			RHYTHM* (1)
			RING* (1)
			RUMBL* (1)
			RUSTL* (1)
			SERENAD* (1)
			SHRILL* (1)
			SNAP* (1)
			SONOROU* (1)
			SOUND* (1)
			STRIDANT* (1)
			STRIDENT* (1)
			SWISH* (1)
			SYMPHONY* (1)
			TEMPO* (1)
			THUD* (1)
			TIMBR* (1)
			TINKL* (1)
			TONAL (1)
			TONE (1)
			TONED (1)
			TONES (1)
			TRILL* (1)
			TUNE (1)
			TUNED (1)
			TUNES (1)
			TUNING* (1)
			UNHEARD* (1)
			VOCAL* (1)
			VOIC* (1)
			WHIR* (1)
			WHIRR* (1)
			WHISTL* (1)
			AFTER-IMAGE* (1)
		VISION
			BLINK* (1)
			ILLUMINANT (1)
			INVISIBILITY (1)
			MONOCULAR (1)
			AMBER* (1)
			APPEAR* (1)
			APPEARANC* (1)
			AURORA* (1)
			AZUR* (1)
			BEAM* (1)
			BEHOLD* (1)
			BINOCULAR (1)
			BLUE* (1)
			BLUISH* (1)
			BRIGHT* (1)
			BROWN* (1)
			BRUNETT* (1)
			CHROMATIC* (1)
			COLOR* (1)
			COLOUR* (1)
			COMPLEX* (1)
			CRIMSON* (1)
			DISCERN* (1)
			DYE* (1)
			EMERALD* (1)
			FILM* (1)
			FLASH* (1)
			FLICKER* (1)
			FLOURESCENT* (1)
			GAZE* (1)
			GAZING* (1)
			GLANC* (1)
			GLAR* (1)
			GLEAM* (1)
			GLIMPS* (1)
			GLINT* (1)
			GLISTEN* (1)
			GLITTER* (1)
			GLOSSY* (1)
			GLOW* (1)
			GRAY* (1)
			GREEN* (1)
			GREY* (1)
			HALO* (1)
			HUE* (1)
			ILLUMINAT* (1)
			IMAG* (1)
			INVISIBL* (1)
			LAMP* (1)
			LANTERN* (1)
			LAVENDER* (1)
			LIGHT* (1)
			LIGHTEN* (1)
			LIGHTN* (1)
			LIMPID* (1)
			LOOK* (1)
			LUCID* (1)
			LUMINANCE (1)
			LUMINOU* (1)
			LUSTER* (1)
			LUSTROU* (1)
			MOONBEAM* (1)
			MOONLIGHT* (1)
			NOTIC* (1)
			OBSERV* (1)
			OPAQU* (1)
			PAINT* (1)
			PEEK* (1)
			PEER* (1)
			PICTUR* (1)
			PINK* (1)
			RADIANC* (1)
			RADIANT* (1)
			RAY (1)
			RAYS (1)
			REGARD* (1)
			ROSY* (1)
			ROUG* (1)
			RUBY* (1)
			RUDDY* (1)
			SAPPHIR* (1)
			SAW (1)
			SCAN (1)
			SCANN* (1)
			SCANS (1)
			SCARLET* (1)
			SCEN* (1)
			SCENIC* (1)
			SEE (1)
			SEEING* (1)
			SEEN* (1)
			SEES (1)
			SHEEN* (1)
			SHIMMER* (1)
			SHIN* (1)
			SHON* (1)
			SIGHT* (1)
			SPARKL* (1)
			SPIED (1)
			SPIES (1)
			SPY (1)
			SPYING* (1)
			STAR (1)
			STARLIGHT* (1)
			STARS (1)
			SUNLIGHT* (1)
			SUNSHIN* (1)
			SURVEY* (1)
			TAN (1)
			TANNED (1)
			TANNING* (1)
			TANS (1)
			TINT* (1)
			TRANSLUCENT* (1)
			TRANSPARENT* (1)
			TWINKL* (1)
			UNSEEN* (1)
			VIEW* (1)
			VIOLET* (1)
			VISIBL* (1)
			VISION* (1)
			VISUAL* (1)
			WATCH* (1)
			WITNES* (1)
			YELLOW* (1)
		COLD
			ALASKA* (1)
			ARCTIC* (1)
			BENUMB* (1)
			CHIL* (1)
			CHILL* (1)
			COLD* (1)
			COLDER* (1)
			COOL* (1)
			FREEZ* (1)
			FRIGID* (1)
			FROST* (1)
			FROSTBIT* (1)
			FROZ* (1)
			FROZEN* (1)
			GLACIER* (1)
			HOAR* (1)
			ICE* (1)
			ICINES* (1)
			ICING* (1)
			ICY (1)
			NORTH* (1)
			NORTHERN* (1)
			NUMB (1)
			NUMBNESS* (1)
			POLAR* (1)
			SHIVER* (1)
			SIBERIA* (1)
			SLEET* (1)
			SNOW* (1)
			SNOWSTORM* (1)
			SNOWY* (1)
			THUL* (1)
			WINTER* (1)
			WINTRY* (1)
		HARD
			ALABASTER* (1)
			BRAS* (1)
			BRASSY* (1)
			BRAZEN* (1)
			BRITTL* (1)
			BRONZ* (1)
			COPPER* (1)
			CRISP* (1)
			CRISPY* (1)
			GLAS* (1)
			GLASSY* (1)
			GRANIT* (1)
			GRAVEL* (1)
			HARD* (1)
			IRON* (1)
			MARBL* (1)
			METAL* (1)
			METALLIC* (1)
			NAIL* (1)
			PEBB* (1)
			PORCELAIN* (1)
			RIGID* (1)
			ROCK* (1)
			SOLID* (1)
			SPLINTER* (1)
			STEEL* (1)
			STIFF* (1)
			STON* (1)
			STONY* (1)
			ZINC* (1)
		SOFT
			DAMASK* (1)
			DELICAT* (1)
			DOWNY* (1)
			FEATHER* (1)
			FLEEC* (1)
			FLEECY* (1)
			FLUFFY* (1)
			GENTL* (1)
			GENTLENES* (1)
			GOSSAMER* (1)
			LACE (1)
			LACES (1)
			LACING* (1)
			LACY* (1)
			MELLOW* (1)
			MILD* (1)
			MURMUR* (1)
			PLIANT* (1)
			POWDERY* (1)
			SATIN* (1)
			SATINY* (1)
			SILK* (1)
			SOFT* (1)
			TENDER* (1)
			TING* (1)
			VELVET* (1)
			VELVETY* (1)
			WHISPER* (1)
	DEFENSIVE SYMBOLIZATION
		PASSIVITY
			STAGNANT (1)
			APATHETIC* (1)
			APATHY* (1)
			BED (1)
			BEDD* (1)
			BEDS (1)
			BOREDOM* (1)
			CALM* (1)
			CONTENTED* (1)
			CONTENTMENT* (1)
			COUCH* (1)
			COZY* (1)
			DEAD* (1)
			DEATH* (1)
			DECAY* (1)
			DIE (1)
			DIED* (1)
			DIES (1)
			DORMANT* (1)
			DRIFT* (1)
			DYING* (1)
			EASE* (1)
			EASED (1)
			EASES (1)
			HUSH* (1)
			IDL* (1)
			IMMOBIL* (1)
			INACTIV* (1)
			INACTIVITY* (1)
			INDIFFERENC* (1)
			INDIFFERENT* (1)
			INDOLENT* (1)
			INERT* (1)
			INERTIA* (1)
			INNERT* (1)
			LAID* (1)
			LAIN* (1)
			LANGOROU* (1)
			LANGUID* (1)
			LANGUISH* (1)
			LANGUOR* (1)
			LASSITUD* (1)
			LAY (1)
			LAYING* (1)
			LAYS (1)
			LAZY* (1)
			LEADEN* (1)
			LEISUR* (1)
			LETHARGIC* (1)
			LETHARGY* (1)
			LIE (1)
			LIES (1)
			LINGER* (1)
			LISTLES* (1)
			LUL* (1)
			LULL* (1)
			MOTIONLES* (1)
			NESTL* (1)
			NONCHALANC* (1)
			NONCHALANT* (1)
			PASSIV* (1)
			PASSIVITY* (1)
			PEACEFUL* (1)
			PERISH* (1)
			PHLEGMATIC* (1)
			PLACID* (1)
			PROCRASTINAT* (1)
			QUIET* (1)
			RELAX* (1)
			RELAXAT* (1)
			REPOS* (1)
			REST* (1)
			RESTFUL* (1)
			RETIR* (1)
			SAFE (1)
			SAFELY (1)
			SAFETY* (1)
			SECUR* (1)
			SECURITY* (1)
			SEDENTARY* (1)
			SEREN* (1)
			SERENITY* (1)
			SILENC* (1)
			SILENT* (1)
			SLACK* (1)
			SLOTHFUL* (1)
			SLOW* (1)
			SLUGGISH* (1)
			SOLAC* (1)
			SOOTH* (1)
			STAGNAT* (1)
			STATIC* (1)
			STILLNES* (1)
			SUBMISS* (1)
			SUBMISSIV* (1)
			SUBMIT* (1)
			SUCCUMB* (1)
			TRANQ* (1)
			UNHURRI* (1)
			VAGRANT* (1)
			VELLEITY* (1)
			WEARISOM* (1)
			WEARY* (1)
			YIELD* (1)
		VOYAGE
			CARAVAN* (1)
			CHAS* (1)
			CRUIS* (1)
			DESERT* (1)
			DRIV* (1)
			EMBARK* (1)
			EMIGRAT* (1)
			EXPLOR* (1)
			IMMIGRAT* (1)
			IMMIGRANT* (1)
			JOURNEY* (1)
			MIGRAT* (1)
			NAVIGAT* (1)
			NOMAD* (1)
			NOMADIC* (1)
			OSCILLAT* (1)
			PILGRIM* (1)
			PILGRIMAG* (1)
			RIDE (1)
			RIDES (1)
			RIDING* (1)
			ROAM* (1)
			RODE (1)
			ROV* (1)
			SAIL* (1)
			SAILOR* (1)
			SEAFAR* (1)
			SEARCH* (1)
			SHIP* (1)
			STRAY* (1)
			TOUR* (1)
			TOURIST* (1)
			TRAVEL* (1)
			TREK* (1)
			TRIP* (1)
			VAGABOND* (1)
			VOYAG* (1)
			WANDER* (1)
			WANDERLUST* (1)
			WAYFARER* (1)
			WILDERNES* (1)
			YONDER* (1)
		RANDOM MOVEMENT
			ACTIVITI* (1)
			ACTIVITY* (1)
			AGITAT* (1)
			CHURN* (1)
			COMMOT* (1)
			CONVULS* (1)
			EXPAND* (1)
			EXPANS* (1)
			FIDGET* (1)
			FLOUNDER* (1)
			FLURRI* (1)
			FLURRY* (1)
			JERK* (1)
			LURCH* (1)
			ORBIT* (1)
			PITCH* (1)
			PIVOT* (1)
			PULS* (1)
			PULSAT* (1)
			QUAK* (1)
			QUIVER* (1)
			REEL* (1)
			REVOLV* (1)
			ROL* (1)
			ROLL* (1)
			ROTAT* (1)
			SEETH* (1)
			SHAK* (1)
			SHOOK* (1)
			SPASM* (1)
			SPIN* (1)
			SPREAD* (1)
			STAGGER* (1)
			STIR* (1)
			SWAY* (1)
			SWEL* (1)
			SWELL* (1)
			SWIVEL* (1)
			SWOLLEN* (1)
			THROB* (1)
			TOTTER* (1)
			TWICH* (1)
			TWIST* (1)
			TWITCH* (1)
			UNDULAT* (1)
			VIBRAT* (1)
			WAVE (1)
			WAVED (1)
			WAVES (1)
			WAVING* (1)
			WHIRL* (1)
			WOBBL* (1)
		DIFFUSION
			BLUR* (1)
			CLOUD* (1)
			CLOUDY* (1)
			CURTAIN* (1)
			DARKEN* (1)
			DIFFUS* (1)
			DIM (1)
			DIMM* (1)
			DIMS (1)
			EQUIVOCAL* (1)
			FADE (1)
			FADED (1)
			FADES* (1)
			FADING* (1)
			FOG (1)
			FOGG* (1)
			FOGS (1)
			HAZE* (1)
			HAZING* (1)
			HAZY* (1)
			INDEFINIT* (1)
			INDISTINCT* (1)
			MIST* (1)
			MISTY* (1)
			MURKINES* (1)
			MURKY* (1)
			NEBULA* (1)
			NEBULOU* (1)
			OBSCUR* (1)
			OVERCAST* (1)
			SCREEN* (1)
			SHAD* (1)
			SHADOW* (1)
			SHADOWY* (1)
			SHADY* (1)
			TWILIGHT* (1)
			UNCERTAIN* (1)
			UNCERTAINT* (1)
			UNCLEAR* (1)
			VAGU* (1)
			VAPOR* (1)
			VAPOUR* (1)
			VEIL* (1)
		CHAOS
			AIMLES* (1)
			AMBIGUIT* (1)
			AMBIGUOU* (1)
			ANARCHY* (1)
			CHANC* (1)
			CHAO* (1)
			CHAR (1)
			CHARS (1)
			CATASTROPHE (1)
			CONFUS* (1)
			CROWD* (1)
			DISCORD* (1)
			DISCORDANT* (1)
			DISHEVEL* (1)
			DISORDER* (1)
			ENTANGL* (1)
			GORDIAN* (1)
			HAPHAZARD* (1)
			IRREGULAR* (1)
			JUMBL* (1)
			JUNGL* (1)
			LABYRINTH* (1)
			LAWLES* (1)
			LITTER* (1)
			MOB (1)
			MOBB* (1)
			MOBS (1)
			OVERGROWN* (1)
			OVERRUN* (1)
			PERPLEX* (1)
			RANDOM* (1)
			RUIN* (1)
			UNRU* (1)
			WILD* (1)
	REGRESSIVE COGNITION
		UNKNOWN
			BIZZAR* (1)
			BODILES* (1)
			BOUNDLES* (1)
			CRYPTIC* (1)
			ENIGMA* (1)
			ESOTERIC* (1)
			EXOTIC* (1)
			FANTASTIC* (1)
			FORMLES* (1)
			IMMEASURABL* (1)
			INCONCEIVABL* (1)
			INCREDIBL* (1)
			INDESCRIBABL* (1)
			INEFFABL* (1)
			INFINITY* (1)
			INSCRUTABL* (1)
			LIMITLES* (1)
			MAGI* (1)
			MAGIC* (1)
			MAGU* (1)
			MARVEL* (1)
			MYST* (1)
			NAMELES* (1)
			NOTHINGNES* (1)
			NUMBERLES* (1)
			OCCULT* (1)
			ODD* (1)
			SECRECY* (1)
			SECRET* (1)
			SHAPELES* (1)
			SORCERER* (1)
			SORCERES* (1)
			STRANG* (1)
			TRANSCEND* (1)
			UNBELIEVABL* (1)
			UNBOUND* (1)
			UNIMAGINABL* (1)
			UNKNOWN* (1)
			UNLIMIT* (1)
			UNSPEAKABL* (1)
			UNTOLD* (1)
			VOID* (1)
		TIMELESSNESS
			AEON* (1)
			CEASELES* (1)
			CENTURI* (1)
			CENTURY* (1)
			CONTINUAL* (1)
			CONTINUOU* (1)
			ENDLES* (1)
			ENDUR* (1)
			EON* (1)
			ETERNAL* (1)
			ETERNITY* (1)
			EVERLAST* (1)
			FOREVER* (1)
			IMMORTAL* (1)
			INCESSANT* (1)
			LIFETIM* (1)
			OUTLIV* (1)
			PERMANENC* (1)
			PERMANENT* (1)
			PERPETUAL* (1)
			TIMELESSNES* (1)
			UNCEAS* (1)
			UNDY* (1)
			UNEND* (1)
			TEST5
		CONSCIOUSNESS ALTERATION
			AMUCK* (1)
			ASLEEP* (1)
			AWAK* (1)
			AWAKEN* (1)
			BEDLAM* (1)
			COMA* (1)
			CRAZ* (1)
			CRAZY* (1)
			DELIRIOU* (1)
			DELIRIUM* (1)
			DELPHIC* (1)
			DEMENT* (1)
			DOZE (1)
			DOZED (1)
			DOZES (1)
			DOZING (1)
			DREAM* (1)
			DREAMY* (1)
			DROWSY* (1)
			ECSTACY* (1)
			ECSTASY* (1)
			ECSTATIC* (1)
			ENCHANT* (1)
			EPILEPSY* (1)
			EPILEPTIC* (1)
			EXSTASY* (1)
			FAINT* (1)
			FANTASI* (1)
			FANTASY* (1)
			FEBRIL* (1)
			FEVER* (1)
			FEVERISH* (1)
			FRENZY* (1)
			HALLUCINAT* (1)
			HASHISH* (1)
			HIBERNAT* (1)
			HYPNO* (1)
			HYSTERIA* (1)
			HYSTERIC* (1)
			IMAGIN* (1)
			IMAGINAT* (1)
			INSAN* (1)
			INSANITY* (1)
			INTUIT* (1)
			IRRATIONAL* (1)
			LAUDANUM* (1)
			LUNACY* (1)
			LUNATIC* (1)
			MAD (1)
			MADLY (1)
			MADMAN* (1)
			MADMEN* (1)
			MADNES* (1)
			MADWOMAN* (1)
			MADWOMEN* (1)
			MANIA* (1)
			MANIAC* (1)
			MEDITAT* (1)
			MESMERIZ* (1)
			MONOMANIA* (1)
			NAP (1)
			NAPP* (1)
			NAPS (1)
			NEUROSI* (1)
			NEUROTIC* (1)
			NIGHTMAR* (1)
			NIGHTMARISH* (1)
			OPIUM* (1)
			OPIATES (1)
			ORACL* (1)
			PARANO* (1)
			PREMONIT* (1)
			PSYCHIC* (1)
			PSYCHOSI* (1)
			PSYCHOTIC* (1)
			RAPTUR* (1)
			RAPTUROU* (1)
			REVERI* (1)
			REVERY* (1)
			REVIV* (1)
			SEER* (1)
			SLEEP* (1)
			SLEEPY* (1)
			SLUMBER* (1)
			STUPOR* (1)
			SWOON* (1)
			TELEPATHY* (1)
			TRANC* (1)
			UNREASON* (1)
			VERTIGO* (1)
			VISIONARY* (1)
			WAK* (1)
			WOKE (1)
		BRINK-PASSAGE
			ACCES* (1)
			AISL* (1)
			AQUEDUCT* (1)
			ARTERI* (1)
			ARTERY* (1)
			AVENU* (1)
			BARRIER* (1)
			BORDER* (1)
			BOUNDARI* (1)
			BOUNDARY* (1)
			BRIDG* (1)
			BRIM* (1)
			BRINK* (1)
			CANAL* (1)
			CHANNEL* (1)
			COAST* (1)
			CONDUIT* (1)
			CORRIDOR* (1)
			CURB* (1)
			DOOR* (1)
			DOORSTEP* (1)
			DOORWAY* (1)
			EDG* (1)
			ENTRANC* (1)
			ENTRY* (1)
			FENC* (1)
			FERRI* (1)
			FERRY* (1)
			FLOOR* (1)
			FOOTPATH* (1)
			FOYER* (1)
			FRAM* (1)
			FRING* (1)
			FRONTIER* (1)
			GATE* (1)
			GATING* (1)
			HALL* (1)
			HALLWAY* (1)
			HIGHWAY* (1)
			HORIZON* (1)
			LANE (1)
			LANES (1)
			LEDG* (1)
			LINE (1)
			LINED (1)
			LINES (1)
			LINING* (1)
			MARGIN* (1)
			PASSAG* (1)
			PASSAGEWAY* (1)
			PATH* (1)
			PERIMET* (1)
			PERIPHER* (1)
			PORT* (1)
			RAILROAD* (1)
			RAILWAY* (1)
			RIM (1)
			RIMM* (1)
			RIMS (1)
			ROAD* (1)
			ROUT* (1)
			SIDEWALK* (1)
			SKYLIN* (1)
			STAIR* (1)
			STEP* (1)
			STREET* (1)
			THRESHOLD* (1)
			TRAIL* (1)
			VERG* (1)
			VIADUCT* (1)
			VISTA* (1)
			WALL* (1)
			WINDOW* (1)
		NARCISSISM
			ARM (1)
			ARMS (1)
			BEARD* (1)
			BLOOD* (1)
			BODI* (1)
			BODY* (1)
			BONE (1)
			BONES (1)
			BRAIN* (1)
			BROW (1)
			BROWS (1)
			CHEEK* (1)
			CHEST* (1)
			CHIN* (1)
			CORPS* (1)
			EYE* (1)
			FACE (1)
			FACES (1)
			FACIES (1)
			FEET* (1)
			FLESH* (1)
			FOOT* (1)
			FOREHEAD* (1)
			HAIR* (1)
			HAND* (1)
			HEAD* (1)
			HEART* (1)
			HEEL* (1)
			HIP (1)
			HIPS (1)
			KIDNEY* (1)
			KNEE (1)
			KNEES (1)
			LEG (1)
			LEGS (1)
			LIMB* (1)
			LIVER* (1)
			MUSCL* (1)
			NAVEL* (1)
			NECK* (1)
			ORGAN* (1)
			PALM* (1)
			RIB (1)
			RIBS (1)
			SHOULDER* (1)
			SKIN* (1)
			SKULL* (1)
			THUMB* (1)
			TOE (1)
			TOES (1)
			VEIN* (1)
			WRIST* (1)
		CONCRETENESS
			ACROS* (1)
			AFAR* (1)
			AFIELD* (1)
			AHEAD* (1)
			ALONG* (1)
			AMONG* (1)
			APART* (1)
			ASID* (1)
			AT (1)
			AWAY* (1)
			BACK* (1)
			BEHIND* (1)
			BESID* (1)
			BETWEEN* (1)
			CENTER* (1)
			CENTR* (1)
			CIRCL* (1)
			CLOS* (1)
			CLOSER* (1)
			CORNER* (1)
			CURV* (1)
			DISTANC* (1)
			DISTANT* (1)
			EAST* (1)
			EASTERN* (1)
			EVERYWHER* (1)
			EXTEND* (1)
			EXTENSIV* (1)
			EXTENT* (1)
			FAR (1)
			FARTHER* (1)
			FLAT* (1)
			FORWARD* (1)
			FRONT* (1)
			FURTHER* (1)
			HERE (1)
			HITHER* (1)
			INSID* (1)
			INTERIOR* (1)
			LAYER* (1)
			LENGTH* (1)
			LEVEL* (1)
			LONG* (1)
			MIDDL* (1)
			MIDST* (1)
			NARROW* (1)
			NEAR* (1)
			NEARBY* (1)
			NEARER* (1)
			NEAREST* (1)
			OFF (1)
			OPEN* (1)
			OUT (1)
			OUTING* (1)
			OUTS (1)
			OUTSID* (1)
			OUTWARD* (1)
			OVER* (1)
			PLAC* (1)
			POINT* (1)
			POSIT* (1)
			REAR* (1)
			REGION* (1)
			ROUND* (1)
			SEPARAT* (1)
			SIDE (1)
			SIDED (1)
			SIDES (1)
			SIDING* (1)
			SITUAT* (1)
			SOMEWHER* (1)
			SOUTH* (1)
			SPAC* (1)
			SPACIOU* (1)
			SPATIAL (1)
			SQUAR* (1)
			STRAIGHT* (1)
			SURFAC* (1)
			SURROUND* (1)
			THENC* (1)
			THITHER* (1)
			TIP (1)
			TIPP* (1)
			TIPS (1)
			TOWARD* (1)
			WEST* (1)
			WESTERN* (1)
			WHER* (1)
			WHEREVER* (1)
			WIDE* (1)
			WIDTH* (1)
			WITHIN* (1)
	ICARIAN IMAGERY
		ASCENT
			ALOFT* (1)
			ARIS* (1)
			ARISEN* (1)
			AROS* (1)
			ASCEND* (1)
			ASCENS* (1)
			BOUNC* (1)
			CLIMB* (1)
			DANGL* (1)
			DAWN* (1)
			FLAP* (1)
			FLED (1)
			FLEW* (1)
			FLIER* (1)
			FLIGHT* (1)
			FLING* (1)
			FLOAT* (1)
			FLOWN* (1)
			FLUNG* (1)
			FLUTTER* (1)
			FLY* (1)
			HANG* (1)
			HOVER* (1)
			HURL* (1)
			ICARIAN* (1)
			ICARU* (1)
			JUMP* (1)
			LEAP* (1)
			LEPT* (1)
			LIFT* (1)
			MOUNT* (1)
			MOUNTAINSID* (1)
			RISE (1)
			RISEN* (1)
			RISES (1)
			RISING* (1)
			SOAR* (1)
			SPRANG* (1)
			SPRING* (1)
			SPRUNG* (1)
			SUNRIS* (1)
			SWING* (1)
			THREW* (1)
			THROW* (1)
			THROWN* (1)
			TOSS* (1)
			UPHILL* (1)
			UPWARD* (1)
			WING* (1)
		HEIGHT
			ABOV* (1)
			AERIAL* (1)
			AIRPLAN* (1)
			ARCH (1)
			ATMOSPHER* (1)
			BALCONY* (1)
			BATTLEMENT* (1)
			BIRD* (1)
			BRANCH* (1)
			CEIL* (1)
			CLIFF* (1)
			CRAG* (1)
			CRAGGY* (1)
			DOME (1)
			DOMES (1)
			DOMING (1)
			ELEVAT* (1)
			ERECT* (1)
			GREW* (1)
			GROW* (1)
			GROWN* (1)
			HEAP* (1)
			HEAVEN* (1)
			HEIGHT* (1)
			HIGH* (1)
			HIGHER* (1)
			HILL* (1)
			HILLSID* (1)
			HILLTOP* (1)
			HUNG* (1)
			LADDER* (1)
			LOFT* (1)
			LOFTY* (1)
			MOUND* (1)
			MOUNTAIN* (1)
			OBELISK* (1)
			OVERHEAD* (1)
			PEAK* (1)
			PILE* (1)
			PILING* (1)
			PLANET* (1)
			PRECIPIC* (1)
			PYRAMID* (1)
			RAFTER* (1)
			RAINBOW* (1)
			RAMPART* (1)
			RIDG* (1)
			ROOF* (1)
			SKY (1)
			SLOP* (1)
			SPIR* (1)
			STEEP* (1)
			SUMMIT* (1)
			TALL* (1)
			TALLER* (1)
			TALLEST* (1)
			TOP (1)
			TOPP* (1)
			TOPS (1)
			TOWER* (1)
			TREE* (1)
			TRELLI* (1)
			UPPER* (1)
			UPPERMOST* (1)
			ZENITH* (1)
		DESCENT
			BASE (1)
			BASES (1)
			BURI* (1)
			BURROW* (1)
			BURY* (1)
			DESCEND* (1)
			DESCENT* (1)
			DIG (1)
			DIGG* (1)
			DIGS (1)
			DIP (1)
			DIPP* (1)
			DIPS (1)
			DIVE* (1)
			DOWNHILL* (1)
			DOWNSTREAM* (1)
			DROOP* (1)
			DROP (1)
			DROPS (1)
			DUG (1)
			FALL* (1)
			FALLEN* (1)
			FELL* (1)
			HEADLONG* (1)
			LEAN* (1)
			PLUNG* (1)
			RECED* (1)
			RECLIN* (1)
			SANK* (1)
			SINK* (1)
			SLID* (1)
			SLIP* (1)
			STOOP* (1)
			SUNDOWN* (1)
			SUNK* (1)
			SUNKEN* (1)
			SUNSET* (1)
			SWOOP* (1)
			TOPPL* (1)
			TUMBL* (1)
		DEPTH
			BELOW* (1)
			BENEATH* (1)
			BOTTOM* (1)
			CANYON* (1)
			CAVE* (1)
			CAVING* (1)
			CELLAR* (1)
			CHASM* (1)
			CREVAS* (1)
			DEEP* (1)
			DEEPER* (1)
			DEPTH* (1)
			DITCH* (1)
			DOWNWARD* (1)
			GUTTER* (1)
			HOLE (1)
			HOLES (1)
			LOW* (1)
			PIT (1)
			PITS (1)
			PITT* (1)
			PRECIPITOU* (1)
			RAVIN* (1)
			ROOT* (1)
			SUBMARIN* (1)
			TRENCH* (1)
			TUNNEL* (1)
			UNDER (1)
			UNDERGROUND* (1)
			UNDERNEATH* (1)
			UNDERWORLD* (1)
			VALLEY* (1)
		FIRE
			SOLAR (1)
			ABLAZ* (1)
			AFIR* (1)
			ASH (1)
			ASHES (1)
			BLAST* (1)
			BLAZ* (1)
			BOIL* (1)
			BROIL* (1)
			BURN* (1)
			BURNT* (1)
			CANDL* (1)
			CHARCOAL* (1)
			COAL* (1)
			COMBUST* (1)
			EMBER* (1)
			FIERY* (1)
			FIRE* (1)
			FLAM* (1)
			HEARTH* (1)
			HEAT* (1)
			HOT (1)
			IGNIT* (1)
			INFERNO* (1)
			INFLAM* (1)
			KINDL* (1)
			LIT (1)
			MELT* (1)
			SCORCH* (1)
			SEAR* (1)
			SIZZL* (1)
			SMOK* (1)
			SMOLDER* (1)
			SMOULDER* (1)
			SPARK* (1)
			SULTRY* (1)
			SUN (1)
			SUNN* (1)
			SUNS (1)
			SUNSTROK* (1)
			TROPIC* (1)
			TROPICAL* (1)
			WARM* (1)
			WARMTH* (1)
		WATER
			BATH* (1)
			BEACH* (1)
			BROOK* (1)
			BUBBL* (1)
			BUCKET* (1)
			CREEK* (1)
			DAM (1)
			DAMM* (1)
			DAMP* (1)
			DAMS (1)
			DEW (1)
			DEWS (1)
			DEWY (1)
			DIKE* (1)
			DOWNPOUR* (1)
			DRENCH* (1)
			SHORING (1)
			SURF (1)
			SURFING (1)
			DRIP* (1)
			FEN (1)
			FLOOD* (1)
			FLUID* (1)
			FOAM* (1)
			FOUNTAIN* (1)
			GURGL* (1)
			HUMID* (1)
			LAKE (1)
			LAKES (1)
			LIQUID* (1)
			MOAT* (1)
			MOIST* (1)
			MOISTUR* (1)
			MOSS (1)
			MOSSES (1)
			OCEAN* (1)
			OVERFLOW* (1)
			PERSPIR* (1)
			PERSPIRAT* (1)
			POND* (1)
			POOL* (1)
			POUR* (1)
			RAIN* (1)
			RAINFALL* (1)
			RIVER* (1)
			SATURAT* (1)
			SEA (1)
			SEAS (1)
			SHORE (1)
			SHORES (1)
			SHOWER* (1)
			SOAK* (1)
			SPLASH* (1)
			SPRINKL* (1)
			STEAM* (1)
			STEAMY* (1)
			STREAM* (1)
			SWAM* (1)
			SWAMP* (1)
			SWAMPY* (1)
			SWIM* (1)
			SWUM* (1)
			TIDE (1)
			TIDES (1)
			TIDING (1)
			TRICKL* (1)
			WADE* (1)
			WADING (1)
			WASH* (1)
			WATER* (1)
			WATERFALL* (1)
			WET* (1)
SECONDARY
	ABSTRACTION
		DIVERSE (1)
		DIVERSIFICATION (1)
		DIVERSIFIED (1)
		DIVERSITY (1)
		EVIDENT (1)
		EVIDENTIAL (1)
		GUESS* (1)
		LOGISTIC (1)
		ABSTRACT* (1)
		ALMOST* (1)
		ALTERNATIV* (1)
		ANALY* (1)
		ATTRIBUT* (1)
		AXIOM* (1)
		BASIC* (1)
		BELIEF* (1)
		BELIEV* (1)
		CALCULAT* (1)
		CAUS* (1)
		CERTAIN* (1)
		CHARACTERIZ* (1)
		CHOIC* (1)
		CHOOS* (1)
		CHOS* (1)
		CIRCUMSTANC* (1)
		COMPREHEND* (1)
		COMPAR* (1)
		COMPREHENS* (1)
		CONDITIONAL* (1)
		CONCENTRAT* (1)
		CONCEPT* (1)
		CONCLUD* (1)
		CONJECTUR* (1)
		CONSEQUENC* (1)
		CONSEQUENT* (1)
		CONSIDER* (1)
		CONTRIV* (1)
		CRITER* (1)
		CRITERIA* (1)
		DECID* (1)
		DEEM* (1)
		DEFIN* (1)
		DELIBERAT* (1)
		DETERMIN* (1)
		DIFFERENC* (1)
		DIFFERENT* (1)
		DISTINCT* (1)
		DISTINGUISH* (1)
		DOCTRIN* (1)
		EFFECT* (1)
		ESTABLISH* (1)
		ESTIMAT* (1)
		EVALUAT* (1)
		EVIDENC* (1)
		EXAMIN* (1)
		EXAMPL* (1)
		EXCEPT* (1)
		FACT (1)
		FACTS (1)
		FEATUR* (1)
		FIGUR* (1)
		FORETHOUGHT* (1)
		FORMULAT* (1)
		GUES* (1)
		HISTORY* (1)
		IDEA* (1)
		IMPORTANC* (1)
		IMPORTANT* (1)
		INFORMAT* (1)
		INTERPRET* (1)
		INTERPRETAT* (1)
		JUDG* (1)
		JUDGMENT* (1)
		KNEW* (1)
		KNOW* (1)
		LEARN* (1)
		LOGIC* (1)
		MAY (1)
		MEANT* (1)
		MISTAK* (1)
		MISTAKEN* (1)
		MISTOOK* (1)
		MODEL* (1)
		OPIN* (1)
		OTHERWIS* (1)
		PERHAP* (1)
		PLAN* (1)
		POSSI* (1)
		PREDICAT* (1)
		PREDICT* (1)
		PROBAB* (1)
		PROBABL* (1)
		PROBLEM* (1)
		PROOF* (1)
		PROV* (1)
		PURPOS* (1)
		QUALI* (1)
		QUANT* (1)
		RE-ANALY* (1)
		RE-EXAMIN* (1)
		RATIONAL* (1)
		REAL (1)
		REALITY* (1)
		REASON* (1)
		REASONABL* (1)
		RECONSIDER* (1)
		REEXAMIN* (1)
		REFORMULAT* (1)
		REINTERPRETAT* (1)
		RELEARN* (1)
		RELEVANC* (1)
		RELEVANT* (1)
		RESEARCH* (1)
		RESOLV* (1)
		SCHEM* (1)
		SCIENC* (1)
		SCIENTIFIC* (1)
		SELECT* (1)
		SIGNIFICANC* (1)
		SOLUT* (1)
		SOMETH* (1)
		SOMEWHAT* (1)
		SOURC* (1)
		SUBJECT* (1)
		SUPPOS* (1)
		SURE (1)
		SURELY (1)
		TEND* (1)
		THEM* (1)
		THEOR* (1)
		THINK* (1)
		THINKER* (1)
		THOUGHT* (1)
		TOPIC* (1)
		TRUE (1)
		TRULY (1)
		TRUTH* (1)
		TTT1 (1)
		UNDERSTAND* (1)
		UNDERSTOOD* (1)
		WEIGH (1)
		WEIGHED* (1)
		WEIGHING* (1)
		WEIGHS (1)
		WHY (1)
	SOCIAL BEHAVIOR
		GUEST* (1)
		QUOTA (1)
		QUOTA-* (1)
		QUOTAS (1)
		ACQUIESCENCE (1)
		APPROBATION (1)
		CONSENSUS* (1)
		CONSULT (1)
		PROSOCIAL (1)
		SOCIABLE (1)
		ABLE* (1)
		ACCEPT* (1)
		ACCEPTANC* (1)
		ADDRES* (1)
		ADMIT* (1)
		ADVIC* (1)
		ADVIS* (1)
		AGRE* (1)
		AID* (1)
		ALLOW* (1)
		ANNOUNC* (1)
		ANSWER* (1)
		APOLOGIS* (1)
		APOLOGIZ* (1)
		APPEAL* (1)
		APPROV* (1)
		APPROVAL* (1)
		ASK (1)
		ASKED (1)
		ASKING (1)
		ASKS (1)
		ASSIST* (1)
		ASSUR* (1)
		BARGAIN* (1)
		BECKON* (1)
		BESEECH* (1)
		BORROW* (1)
		CALL* (1)
		COMMENT* (1)
		COMMIT* (1)
		COMMUNICAT* (1)
		CONDUCT* (1)
		CONFER* (1)
		CONFES* (1)
		CONFID* (1)
		CONFIRM* (1)
		CONGRATULAT* (1)
		CONSENT* (1)
		CONSOL* (1)
		CONSOLAT* (1)
		CONVERS* (1)
		CONVERSAT* (1)
		CONVINC* (1)
		COOPERAT* (1)
		COUNSEL* (1)
		DECLAR* (1)
		DEPEND* (1)
		DEPENDENT* (1)
		DESCRIB* (1)
		DIALOGU* (1)
		DISCOURS* (1)
		DISCUS* (1)
		DISCUSS* (1)
		DONAT* (1)
		EDUCAT* (1)
		ELECT* (1)
		ENCOURAG* (1)
		ENCOURAGEMENT* (1)
		ENGAG* (1)
		ESCORT* (1)
		EXCUS* (1)
		EXPLAIN* (1)
		FOLLOW* (1)
		FORGAV* (1)
		FORGIV* (1)
		FORGIVEN* (1)
		GENEROSITY* (1)
		GENEROU* (1)
		GIFT* (1)
		GRANT* (1)
		GREET* (1)
		GUID* (1)
		GUIDANC* (1)
		HELP* (1)
		IMITAT* (1)
		IMPLOR* (1)
		INFLUENC* (1)
		INFORM* (1)
		INQUIR* (1)
		INSTRUCT* (1)
		INTERVIEW* (1)
		INTRODUC* (1)
		INVIT* (1)
		KNEEL* (1)
		LEND* (1)
		LENT* (1)
		MEET* (1)
		MENT* (1)
		MESSAG* (1)
		MET* (1)
		MUTUAL* (1)
		OFFER* (1)
		PARDON* (1)
		PARTICIPAT* (1)
		PERSUAD* (1)
		PERSUA* (1)
		PLEAD* (1)
		PLEAS* (1)
		PREACH* (1)
		PROCLAIM* (1)
		PROMIS* (1)
		PROPOS* (1)
		PROTECT* (1)
		PROVID* (1)
		QUOT* (1)
		RECIT* (1)
		REEDUCATION (1)
		REMARK* (1)
		REMIND* (1)
		REPLI* (1)
		REPLY (1)
		REPRESENT* (1)
		REQUEST* (1)
		RESCU* (1)
		RESPOND* (1)
		RESPONS* (1)
		SAID* (1)
		SALE (1)
		SALES (1)
		SAY* (1)
		SERVIC* (1)
		SHAR* (1)
		SHELTER* (1)
		SIGNAL* (1)
		SOCIAL* (1)
		SOLICIT* (1)
		SPEAK* (1)
		SPEAKER* (1)
		SPEECH* (1)
		SPOK* (1)
		SPOKEN* (1)
		SUGGEST* (1)
		SWORN* (1)
		TALK* (1)
		TAUGHT* (1)
		TEACH* (1)
		TELL* (1)
		THANK* (1)
		TOLD* (1)
		TREAT* (1)
		UTTER* (1)
		VISIT* (1)
	INSTRUMENTAL BEHAVIOR
		AVAIL (1)
		CAVEAT* (1)
		DIVESTMENT* (1)
		DIVIDEND* (1)
		FOUNDR* (1)
		LABORATOR* (1)
		SPIN-OFF* (1)
		AVAILABILITY (1)
		COMPONENT* (1)
		INGREDIENT (1)
		LOGISTICS (1)
		MERCHANDISE (1)
		PROVISION* (1)
		ACHIEV* (1)
		ACHIEVEMENT* (1)
		ACQUIR* (1)
		ACQUISIT* (1)
		AFFORD* (1)
		AIM* (1)
		APPLIC* (1)
		APPLIE* (1)
		APPLY (1)
		ARCHITECT* (1)
		ASSEMBL* (1)
		ATTAIN* (1)
		ATTEMPT* (1)
		AVAILABL* (1)
		BELONG* (1)
		BID* (1)
		BOUGHT* (1)
		BUILD* (1)
		BUILT* (1)
		BURDEN* (1)
		BUSINES* (1)
		BUY* (1)
		CAPABL* (1)
		CARRI* (1)
		CARRY* (1)
		CLAIM* (1)
		COLLECT* (1)
		CONSTRUCT* (1)
		COPI* (1)
		COPY* (1)
		COST* (1)
		COUNT* (1)
		CRAFT* (1)
		CRAFTSMAN* (1)
		CULTIVAT* (1)
		CURE* (1)
		CURING* (1)
		DELIVER* (1)
		EARN* (1)
		EFFORT* (1)
		EMPLOY* (1)
		ENDEAVOR* (1)
		FACTORI* (1)
		FACTORY* (1)
		FEAT (1)
		FEATS (1)
		FIND* (1)
		FINISH* (1)
		FORGE (1)
		FORGES (1)
		FOUND* (1)
		GAIN* (1)
		GOAL* (1)
		GRASP* (1)
		HARVEST* (1)
		HIRE (1)
		HIRED (1)
		HIRES (1)
		HIRING* (1)
		IMPROV* (1)
		INDUSTRI* (1)
		INDUSTRY* (1)
		JOB (1)
		JOBS (1)
		LABOR* (1)
		LABORIOU* (1)
		LABOUR* (1)
		LABOURIOU* (1)
		LESSON* (1)
		MACHIN* (1)
		MACHINERY* (1)
		MAK* (1)
		MANIPULAT* (1)
		MANUFACTUR* (1)
		MARKET* (1)
		MEND* (1)
		MERCHANT* (1)
		MONEY* (1)
		OBTAIN* (1)
		OCCUPAT* (1)
		OCCUPY* (1)
		OWNERSHIP* (1)
		PAID* (1)
		PAY (1)
		PAYING* (1)
		PAYS (1)
		PERFORM* (1)
		PICK* (1)
		PLOUGH* (1)
		PLOW* (1)
		POSSES* (1)
		POSSESS* (1)
		PRACTIC* (1)
		PREPAR* (1)
		PRIC* (1)
		PRIVATION* (1)
		PRODUC* (1)
		PROFIT* (1)
		PROFITABL* (1)
		PROPERTY* (1)
		PURCHAS* (1)
		PURSU* (1)
		REACH* (1)
		RECONSTRUCT (1)
		RECORD* (1)
		RECOVER* (1)
		REPAIR* (1)
		REPRODUCE (1)
		RESTOR* (1)
		RESULT* (1)
		RISK* (1)
		SEL* (1)
		SELL* (1)
		SKIL* (1)
		SKILL* (1)
		SKILLFUL* (1)
		SOLD* (1)
		SOW* (1)
		SPEND* (1)
		SPENT* (1)
		STUDENT* (1)
		STUDI* (1)
		STUDIOU* (1)
		STUDY* (1)
		SUCCE* (1)
		SWEEP* (1)
		SWEPT* (1)
		TASK* (1)
		TEST* (1)
		TOIL (1)
		TOILED (1)
		TOILS* (1)
		TRAD* (1)
		TRIED (1)
		TRY (1)
		TRYING* (1)
		TRYS (1)
		USE (1)
		USED (1)
		USES (1)
		USING (1)
		WIN (1)
		WINNING* (1)
		WINS (1)
		WON (1)
		WORK* (1)
	RESTRAINT
		COMPTROLLER* (1)
		DISCIPLINE (1)
		MAGIST* (1)
		PENALIZ* (1)
		PENITENTIARY (1)
		ARREST* (1)
		ASSIGN* (1)
		AUTHORIZ* (1)
		BAR (1)
		BARRED (1)
		BARRING (1)
		BARS (1)
		BIND* (1)
		BLOCK* (1)
		BLOCKAD* (1)
		BOUND* (1)
		CAG* (1)
		CAPTIV* (1)
		CAPTIVITY* (1)
		CAPTUR* (1)
		CATCH* (1)
		CAUGHT* (1)
		CENSUR* (1)
		CHASTIS* (1)
		CHASTIZ* (1)
		COERC* (1)
		COMPEL* (1)
		CONFIN* (1)
		CONFORM* (1)
		CONFORMITY* (1)
		CONSTRAIN* (1)
		CONSTRAINT* (1)
		CONSTRICT* (1)
		CONTROL* (1)
		DECREE* (1)
		DETAIN* (1)
		DETER* (1)
		DUNGEON* (1)
		ENCLOS* (1)
		FORBAD* (1)
		FORBID* (1)
		FORBIDDEN* (1)
		GUARD* (1)
		GUARDIAN* (1)
		HALT* (1)
		HAMPER* (1)
		HINDER* (1)
		HINDRANC* (1)
		IMPERATIV* (1)
		IMPRISON* (1)
		INHIBIT* (1)
		INSIST* (1)
		INTERFER* (1)
		INTERRUPT* (1)
		JAIL* (1)
		LEASH* (1)
		LIMIT* (1)
		LOCK* (1)
		MANAG* (1)
		MUST* (1)
		NECESSARY* (1)
		NECESSITY* (1)
		OBEDIENC* (1)
		OBEY* (1)
		OBLIG* (1)
		OBLIGAT* (1)
		OBSTACL* (1)
		OBSTRUCT* (1)
		PENALTI* (1)
		PENALTY* (1)
		PERMISS* (1)
		PERMIT* (1)
		POLIC* (1)
		POLICEMAN* (1)
		POLICEMEN* (1)
		PRESCRIB* (1)
		PREVAIL* (1)
		PREVENT* (1)
		PRISON* (1)
		PROHIBIT* (1)
		PUNISH* (1)
		PUNISHMENT* (1)
		REFUS* (1)
		REGULAT* (1)
		REIGN* (1)
		REQUIR* (1)
		REQUIREMENT* (1)
		RESIST* (1)
		RESTRAIN* (1)
		RESTRAINT* (1)
		RESTRICT* (1)
		SCOLD* (1)
		SHUT* (1)
		STOP* (1)
		STRICT* (1)
		SUMMON* (1)
		SUPPRES* (1)
		TABOO* (1)
		TAX* (1)
		THWART* (1)
	ORDER
		ORDINAL (1)
		ACCURAT* (1)
		ARRANG* (1)
		ARRAY* (1)
		BALANC* (1)
		CATALOG* (1)
		CLASS* (1)
		CONSISTENC* (1)
		CONSISTENT* (1)
		CONSTANC* (1)
		CONSTANT* (1)
		DIVID* (1)
		FORM* (1)
		FORMULA* (1)
		GRAD* (1)
		INDEX* (1)
		LIST* (1)
		MEASUR* (1)
		METHOD* (1)
		MODERAT* (1)
		NEAT* (1)
		NORM* (1)
		NORMAL* (1)
		ORGANI* (1)
		ORDER (1)
		PATTERN* (1)
		PRECIS* (1)
		RANK* (1)
		REGULAR* (1)
		REORGANIZ* (1)
		ROUTIN* (1)
		SERIAL (1)
		SERIES* (1)
		SIMPL* (1)
		SIMPLICITY* (1)
		STABILITY* (1)
		STANDARD* (1)
		SYMMETR* (1)
		SYSTEM* (1)
		UNIFORM* (1)
		UNIVERSAL* (1)
	TEMPORAL REFERENCES
		FULL-TIME (1)
		LONG-TERM (1)
		LONGEVIT* (1)
		PART-TIME (1)
		SHORT-TERM (1)
		ABRUPT* (1)
		AGAIN (1)
		AGO (1)
		ALREADY* (1)
		ANCIENT (1)
		BREVITY* (1)
		BRIEF* (1)
		CLOCK* (1)
		DAILY* (1)
		DATE (1)
		DATED (1)
		DATES (1)
		DATING (1)
		DECAD* (1)
		DUR* (1)
		DURAT* (1)
		EARLIER* (1)
		EARLY* (1)
		EPHEMERAL* (1)
		EVER* (1)
		FORMER* (1)
		FREQUENT* (1)
		HAST* (1)
		HENCEFORTH* (1)
		HOUR* (1)
		IMMEDIAT* (1)
		IMMEDIATE* (1)
		INSTANT* (1)
		INTERLUD* (1)
		MEANTIM* (1)
		MEANWHIL* (1)
		MINUT* (1)
		MOMENT* (1)
		MOMENTARY* (1)
		MONTH* (1)
		NOW (1)
		OCCAS* (1)
		OCCASIONAL* (1)
		OFTEN* (1)
		OLD (1)
		OLDER* (1)
		ONCE (1)
		PAST* (1)
		PREMATUR* (1)
		PRESENT* (1)
		PREVIOU* (1)
		PRIOR* (1)
		QUICK* (1)
		SEASON* (1)
		SELDOM* (1)
		SOMETIM* (1)
		SOON* (1)
		SOONER* (1)
		SUDDEN* (1)
		TEMPORARY* (1)
		THEN* (1)
		TILL* (1)
		TIME* (1)
		TIMING* (1)
		TODAY* (1)
		TONIGHT* (1)
		WEEK* (1)
		WHEN* (1)
		WHENEVER* (1)
		WHIL* (1)
		YEAR* (1)
		YESTERDAY* (1)
	MORAL IMPERATIVE
		LEGITIMACY (1)
		RESPECT (1)
		BIRTHRIGHT* (1)
		COMMANDMENT* (1)
		CONSCIENC* (1)
		CONSCIENTIOU* (1)
		CORRECT* (1)
		CUSTOM (1)
		CUSTOMER* (1)
		CUSTOMIZ* (1)
		DUTI* (1)
		DUTY* (1)
		ETHIC* (1)
		HONEST* (1)
		HONESTY* (1)
		HONOR* (1)
		HONORABL* (1)
		HONOUR* (1)
		HONOURABL* (1)
		JUSTIC* (1)
		LAW (1)
		LAWFUL* (1)
		LAWS (1)
		LEGAL* (1)
		LEGITIMAT* (1)
		MORAL* (1)
		MORALITY* (1)
		OUGHT* (1)
		PREROGATIV* (1)
		PRINCIPL* (1)
		PRIVILEG* (1)
		PROPER* (1)
		RECTITUD* (1)
		RESPECTFUL* (1)
		RESPONSIBILITY* (1)
		RESPONSIBL* (1)
		RIGHT* (1)
		RIGHTEOU* (1)
		RIGHTFUL* (1)
		SANCT* (1)
		SHOULD* (1)
		TRUSTWORTHY* (1)
		UNJUST* (1)
		UPRIGHT* (1)
		VIRTU* (1)
EMOTIONS
	POSITIVE AFFECT
		AMUS* (1)
		AMUSEMENT* (1)
		BLITH* (1)
		CAREFRE* (1)
		CELEBRAT* (1)
		CHEER* (1)
		CHEERFUL* (1)
		CHEERY* (1)
		CHUCKL* (1)
		DELIGHT* (1)
		DELIGHTFUL* (1)
		ELAT* (1)
		ENJOY* (1)
		ENJOYABL* (1)
		ENJOYMENT* (1)
		ENTERTAIN* (1)
		ENTERTAINMENT* (1)
		ENTHUSIASM* (1)
		ENTHUSIASTIC* (1)
		EXCIT* (1)
		EXHILERAT* (1)
		EXULT* (1)
		EXULTANT* (1)
		FUN (1)
		FUNNY* (1)
		GAIETY* (1)
		GAY* (1)
		GLAD* (1)
		GLADNES* (1)
		GLEE (1)
		GLEEFUL* (1)
		GLEELY (1)
		GRATIFI* (1)
		GRATIFY* (1)
		GRIN* (1)
		HAPPINES* (1)
		HAPPY* (1)
		HILARIOU* (1)
		HUMOR* (1)
		HUMOROU* (1)
		HUMOUR* (1)
		HUMOUROU* (1)
		JOCUND* (1)
		JOK* (1)
		JOLLY (1)
		JOVIAL* (1)
		JOY* (1)
		JOYFUL* (1)
		JOYOU* (1)
		LAUGH* (1)
		LAUGHTER* (1)
		MERRIMENT* (1)
		MERRY* (1)
		MIRTH* (1)
		MIRTHFUL* (1)
		OVERJOY* (1)
		PLAYFUL* (1)
		PLEASANTRY* (1)
		PLEASUR* (1)
		PLEASURABL* (1)
		REJOIC* (1)
		RELIEF* (1)
		RELIEV* (1)
		ROLLICK* (1)
		SATISF* (1)
		SMIL* (1)
		THRIL* (1)
		THRILL* (1)
		VIVACIOU* (1)
		VIVACITY* (1)
	ANXIETY
		TREMOR (1)
		AFRAID* (1)
		AGHAST* (1)
		ALARM* (1)
		ANGUISH* (1)
		ANXI* (1)
		AVOID* (1)
		BLUSH* (1)
		CARES (1)
		COWARD* (1)
		COWER* (1)
		CRISI* (1)
		DANGEROU* (1)
		DESPERAT* (1)
		DISTRES* (1)
		DREAD* (1)
		DREADFUL* (1)
		FEAR* (1)
		FEARFUL* (1)
		FRANTIC* (1)
		FRET* (1)
		FRIGHT* (1)
		HORRIFI* (1)
		HORRIFY* (1)
		HORROR* (1)
		NERVOU* (1)
		NERVOUSNES* (1)
		PANIC* (1)
		PHOBIA* (1)
		PHOBIC* (1)
		SCARE (1)
		SCARED (1)
		SCARES (1)
		SCARY (1)
		SHRIEK* (1)
		SHUDDER* (1)
		SHY* (1)
		TERRIFI* (1)
		TERRIFY* (1)
		TERROR* (1)
		TIMID* (1)
		TRAUMA* (1)
		TREMBL* (1)
		TREMULOU* (1)
		TROUBL* (1)
		UNEASINES* (1)
		UNEASY* (1)
		WORRI* (1)
		WORRY* (1)
	SADNESS
		AGGRIEVED (1)
		ALAS (1)
		DEJECT* (1)
		DEPRES* (1)
		DEPRESS* (1)
		DESPAIR* (1)
		DESPONDANT* (1)
		DESPONDENT* (1)
		DIRG* (1)
		DISAPPOINT* (1)
		DISAPPOINTMENT* (1)
		DISCONSOLAT* (1)
		DISCOURAG* (1)
		DISHEARTEN* (1)
		DISMAL* (1)
		DISSATISFI* (1)
		DISSATISFY* (1)
		DISTRAUGHT* (1)
		DOLDRUM* (1)
		DOWNCAST* (1)
		DREARY* (1)
		ELEGY* (1)
		FORLORN* (1)
		FROWN* (1)
		FUNEREAL* (1)
		GRIE* (1)
		GROAN* (1)
		HOPELES* (1)
		HUMILIAT* (1)
		LAMENT* (1)
		LAMENTAT* (1)
		LONE* (1)
		LONELINES* (1)
		MELANC* (1)
		MISERABL* (1)
		MISERI* (1)
		MISERY* (1)
		MOAN* (1)
		MOURN* (1)
		MOURNFUL* (1)
		ORPHAN* (1)
		PAIN* (1)
		PITIFUL* (1)
		PLAINT* (1)
		REGRET* (1)
		REGRETFUL* (1)
		REMORS* (1)
		REPENT* (1)
		REPENTANC* (1)
		REPENTENC* (1)
		RUE (1)
		SAD (1)
		SADDEN* (1)
		SADLY (1)
		SADNES* (1)
		SOB (1)
		SOBB* (1)
		SOBS (1)
		SOMBER* (1)
		SOMBR* (1)
		SORROW* (1)
		SORROWFUL* (1)
		SORRY* (1)
		SUFFER* (1)
		TEARFUL* (1)
		TRAGEDY* (1)
		TRAGIC* (1)
		UNHAPPINES* (1)
		UNHAPPY* (1)
		WAIL* (1)
		WEEP* (1)
		WEPT* (1)
		WHIN* (1)
		WOE (1)
		WOES (1)
	AFFECTION
		AFFECT* (1)
		AFFECTIONAT* (1)
		AMOROU* (1)
		AMOUROU* (1)
		APPRECIAT* (1)
		ATTRACTIV* (1)
		BEFRIEND* (1)
		BELOV* (1)
		BOSOM* (1)
		BRIDAL* (1)
		BRIDE* (1)
		CHERISH* (1)
		CONGENIAL* (1)
		CORDIAL* (1)
		COURTSHIP* (1)
		DARL* (1)
		DEAR* (1)
		DEVOT* (1)
		EMBRAC* (1)
		ENAMOR* (1)
		ENAMOUR* (1)
		ENDEAR* (1)
		FAMILIAR* (1)
		FONDER (1)
		FAREWELL* (1)
		FAVOR* (1)
		FAVOUR* (1)
		FIANC* (1)
		FLIRT* (1)
		FOND (1)
		FONDNES* (1)
		FRATERNITY* (1)
		FRIEND* (1)
		FRIENDSHIP* (1)
		GOODBY* (1)
		GRATEFUL* (1)
		INTIMACY* (1)
		INTIMAT* (1)
		KIND* (1)
		KINDNES* (1)
		LIKE* (1)
		LIKING* (1)
		LOV* (1)
		MARRI* (1)
		MARRIAG* (1)
		MARRY* (1)
		MATE (1)
		MATED (1)
		MATES (1)
		MATING* (1)
		MERCY* (1)
		PAT (1)
		PATS (1)
		PATT* (1)
		PITI* (1)
		PITY* (1)
		ROMANC* (1)
		SWEETHEART* (1)
		SYMPAT* (1)
		UNSELFISH* (1)
		WARMHEART* (1)
		WELCOM* (1)
		WOOED* (1)
		WOOING* (1)
		WOOS (1)
	AGGRESSION
		ABHOR* (1)
		ABUS* (1)
		ABUSIV* (1)
		ACCUS* (1)
		AFFLICT* (1)
		AGGRESS* (1)
		AGGRESSIV* (1)
		AMBUSH* (1)
		ANGER* (1)
		ANGRI* (1)
		ANGRIER* (1)
		ANGRY* (1)
		ANNIHILAT* (1)
		ANNOY* (1)
		ANNOYANC* (1)
		ANTAGONIZ* (1)
		ARGU* (1)
		ARGUMENT* (1)
		ARMY* (1)
		ARROW* (1)
		ASSAULT* (1)
		ATTACK* (1)
		AVENG* (1)
		AX (1)
		AXE (1)
		AXES (1)
		BATTL* (1)
		BEAK* (1)
		BEAT* (1)
		BEATEN* (1)
		BETRAY* (1)
		BLADE* (1)
		BLAM* (1)
		BLOODY* (1)
		BOTHER* (1)
		BRAWL* (1)
		BREAK* (1)
		BROK* (1)
		BROKEN* (1)
		BRUTAL* (1)
		CANNON* (1)
		CHID* (1)
		COMBAT* (1)
		COMPLAIN* (1)
		CONFLICT* (1)
		CONDEMN* (1)
		CONTROVERSY* (1)
		CRITIC* (1)
		CRUEL* (1)
		CRUSH* (1)
		CUT (1)
		CUTS (1)
		CUTT* (1)
		DAMAG* (1)
		DECEI* (1)
		DEFEAT* (1)
		DEGRAD* (1)
		DEMOLISH* (1)
		DEPRIV* (1)
		DERID* (1)
		DESPIS* (1)
		DESTROY* (1)
		DESTRUCT* (1)
		DESTRUCTIV* (1)
		DETEST* (1)
		DISAGRE* (1)
		DISAGREEMENT* (1)
		DISAPPROV* (1)
		DISCONTENT* (1)
		DISLIK* (1)
		DISPUT* (1)
		DISTURB* (1)
		DOUBT* (1)
		ENEMI* (1)
		ENEMY* (1)
		ENRAG* (1)
		EXASPERAT* (1)
		CONTROVERSIAL* (1)
		CRITIQUE (1)
		DISPARAG* (1)
		IRRITABLE (1)
		EXPLOIT* (1)
		EXTERMINAT* (1)
		FEUD* (1)
		FIERC* (1)
		FIGHT* (1)
		FOUGHT* (1)
		FURIOU* (1)
		FURY* (1)
		GASH* (1)
		GRAPPL* (1)
		GROWL* (1)
		GRUDG* (1)
		GUN (1)
		GUNN* (1)
		GUNS (1)
		HARM* (1)
		HARSH* (1)
		HATE* (1)
		HATR* (1)
		HIT (1)
		HITS (1)
		HITT* (1)
		HOMICID* (1)
		HOSTIL* (1)
		HURT* (1)
		INGRAT* (1)
		INJUR* (1)
		INJURY* (1)
		INSULT* (1)
		INVAD* (1)
		INVAS* (1)
		IRAT* (1)
		IRK* (1)
		IRRITAT* (1)
		JEALOU* (1)
		JEALOUSY* (1)
		JEER* (1)
		KICK* (1)
		KIL* (1)
		KILL* (1)
		KNIF* (1)
		KNIV* (1)
		LOATH* (1)
		MAIM* (1)
		MISTREAT* (1)
		MOCK* (1)
		MURDER* (1)
		OBLITERAT* (1)
		OFFEND* (1)
		OPPOS* (1)
		PREDATORY* (1)
		PROTEST* (1)
		QUARREL* (1)
		RAGE (1)
		RAGES (1)
		RAGING (1)
		RAPIN* (1)
		REBEL* (1)
		REBELL* (1)
		REBUK* (1)
		RELENTLES* (1)
		REPROACH* (1)
		RESENT* (1)
		RESENTMENT* (1)
		RETRIBUT* (1)
		REVENG* (1)
		REVOLT* (1)
		RIDICUL* (1)
		RIP (1)
		RIPP* (1)
		RIPS (1)
		ROB (1)
		ROBB* (1)
		ROBS (1)
		SARCASM* (1)
		SARCASTIC* (1)
		SCALP* (1)
		SCOF* (1)
		SCOFF* (1)
		SCOURG* (1)
		SEIZ* (1)
		SEVER* (1)
		SEVERITY* (1)
		SHATTER* (1)
		SHOOT* (1)
		SHOT* (1)
		SHOV* (1)
		SLAIN* (1)
		SLANDER* (1)
		SLAP* (1)
		SLAUGHTER* (1)
		SLAY* (1)
		SLEW* (1)
		SMASH* (1)
		SNARL* (1)
		SNEER* (1)
		SPEAR* (1)
		SPITEFUL* (1)
		SPURN* (1)
		STAB* (1)
		STEAL* (1)
		STOL* (1)
		STOLEN* (1)
		STRANGL* (1)
		STRIF* (1)
		STRIK* (1)
		STRUCK* (1)
		STRUGGL* (1)
		STUBBORN* (1)
		SWORD* (1)
		TAUNT* (1)
		TEMPER* (1)
		THREAT* (1)
		THREATEN* (1)
		TORE (1)
		TORMENT* (1)
		TORN* (1)
		TORTUR* (1)
		TRAITOR* (1)
		TRAMPL* (1)
		TREACHEROU* (1)
		TREACHERY* (1)
		TYRANT* (1)
		UNKIND* (1)
		VENGEANC* (1)
		VENGEFUL* (1)
		VEX (1)
		VEXING (1)
		VIOLAT* (1)
		VIOLENC* (1)
		VIOLENT* (1)
		WAR (1)
		WARRING (1)
		WARRIOR* (1)
		WARS (1)
		WEAPON* (1)
		WHIP* (1)
		WOUND* (1)
		WRATH* (1)
		FOOTBALL* (1)
		WRECK* (1)
	EXPRESSIVE BEHAVIOR
		ART (1)
		ARTS* (1)
		BARD* (1)
		BARK* (1)
		BAWL* (1)
		BELLOW* (1)
		BLEAT* (1)
		CAROL* (1)
		CHANT* (1)
		CLOWN* (1)
		CRIE* (1)
		CRIING (1)
		CRY (1)
		DANC* (1)
		EXCLAIM* (1)
		EXPRESSIV* (1)
		FRISK* (1)
		FROLIC* (1)
		GAME* (1)
		GUITAR* (1)
		HARP* (1)
		HORN* (1)
		HURRAH* (1)
		HURRAY* (1)
		LULLABY* (1)
		LUTE (1)
		LUTES (1)
		LYRE (1)
		MINSTREL* (1)
		NEIGH (1)
		NEIGHS (1)
		PAINTER* (1)
		PLAY* (1)
		POEM* (1)
		POET* (1)
		POETIC* (1)
		POETRY* (1)
		ROAR* (1)
		SANG* (1)
		SCREAM* (1)
		SHOUT* (1)
		SIGH* (1)
		SING (1)
		SINGS* (1)
		SPORT* (1)
		SUNG* (1)
		TROUBADOR* (1)
		TROUBADOUR* (1)
		VIOLIN* (1)
		WARBL* (1)
		YEL* (1)
		YELL* (1)
	GLORY
		ADMIR* (1)
		ADMIRABL* (1)
		ADVENTUR* (1)
		APPLAUD* (1)
		APPLAUS* (1)
		ARROGANC* (1)
		ARROGANT* (1)
		AUDACITY* (1)
		AWE* (1)
		BOAST* (1)
		BOASTFUL* (1)
		BRILLIANC* (1)
		BRILLIANT* (1)
		CAESAR* (1)
		CASTL* (1)
		CONQUE* (1)
		CROWN* (1)
		DAZZL* (1)
		EAGL* (1)
		ELIT* (1)
		EMPEROR* (1)
		EMPIR* (1)
		EXALT* (1)
		EXHIBIT* (1)
		EXQUISIT* (1)
		EXTRAORDINARY* (1)
		EXTREM* (1)
		FAME (1)
		FAMED (1)
		FAMOU* (1)
		FOREMOST* (1)
		GENIU* (1)
		GLOR* (1)
		GOLD* (1)
		GOLDEN* (1)
		GRANDEUR* (1)
		GREAT* (1)
		HAUGHTY* (1)
		HERO* (1)
		HOMAG* (1)
		ILLUSTRIOU* (1)
		KINGDOM* (1)
		MAGESTIC* (1)
		MAGNIFICENT* (1)
		MAJESTIC* (1)
		MAJESTY* (1)
		NOBL* (1)
		OUTSTAND* (1)
		PALAC* (1)
		POMP* (1)
		PRESTIG* (1)
		PRID* (1)
		PRINC* (1)
		PROUD* (1)
		RENOWN* (1)
		RESPLENDENT* (1)
		RICH* (1)
		ROYAL* (1)
		ROYALTY* (1)
		SCEPTR* (1)
		SCORN* (1)
		SPLENDID* (1)
		SPLENDOR* (1)
		STRUT* (1)
		SUBLIM* (1)
		SUPERIOR* (1)
		SUPERIORITY* (1)
		SUPREM* (1)
		THRON* (1)
		TRIUMP* (1)
		VICTOR* (1)
		VICTORIOU* (1)
		VICTORY* (1)
		WEALTH* (1)
		WONDER* (1)
		WONDERFUL* (1)
"""

DEFAULT_RID_EXCLUSION_LIST = """
PROVINC*
MIDDLE-*
DIVERSION*
DIETHYL*
COUNTY*
SHARK*
PRICK*
PASTE*
HANDICAP*
HANDBOOK*
GRAPH*
FACTORIAL*
BUTTERFL*
BLANKET*
FASTI*
ENERGUMEN*
RELIGHT
REVERSE
DISPOSSESS*
NEEDL*
EXTREMITY
EXTREMENESS
EMPIRI*
TEMPERAT*
TEMPERAN*
TEMPERAMENT
SEVERAL
HARMO*
PATTERN
DECADENT
TAXO*
TAXI*
DETERS*
DETERR*
DETERIO*
DETERG*
TRADU*
TRADI*
TESTAM*
SOWBUG*
SELF*
FACTORIAL
COUNTE*
COUNTR*
TREATMENT*
TELLU*
QUOTI*
QUOTH*
PROVIDE*
PROMISC*
METTL*
METR*
METO*
METI*
METH*
METE*
META*
MENTO*
MENTH*
MENTA*
INFORMAL
ELECTR*
CONSOLIDAT*
SOLUTE
PROVER*
MAY-1
POOLED-1
POOL-1
HEATH*
COALESC*
COALI*
UNDERGRADUAT*
UNDERC*
FALLAC*
DIVERGEN*
ARIST*
REGU*
REGR*
REGIS*
REGE*
POSITIV*
PLACEN*
PLACEB*
OVERV*
OVERL*
LIMBIC*
CHINE*
PORTU*
PORTR*
PORTM*
PORTL*
PORTI*
PORTF*
PORTE*
PORTA*
PATHO*
PATHE*
SECRETI*
SECRETO*
SECRETA*
ROLE
QUAKER
TRIPT*
TRIPLE
TRIPE
RESTR*
RESTO*
RESTI*
RESTA*
REPOSSESS*
CONTENTS*
CONTENT-*
HOARY
HOARS
HOARD*
BASKET
AWARD*
TESTIN*
TESTIF*
TESTIMON*
STALK
SPATI*
GRAPHIC*
BREADTH
"""

class RIDApp:
  def usage(self, args):
    print "usage: %s [-h [-t TITLE] | -d FILE | -e FILE | --add-dict=FILE | --add-exc=FILE]" % (args[0],)
    print "%s reads from standard input and writes to standard output." % (args[0],)
    print "options:"
    print "    -h                Generate HTML output."
    print "    -t TITLE          Use TITLE as the report heading."
    print "    -d FILE           Replaces the built-in dictionary with FILE."
    print "    -e FILE           Replaces the built-in exclusion list with FILE."
    print "    --add-dict=FILE   Processes FILE as a category dictionary."
    print "    --add-exc=FILE    Processes FILE as an exlusion list."
    
  def run(self, args):
    rid = RegressiveImageryDictionary()
    load_default_dict = True
    load_default_exc = True
    html_output = False
    title = "RID Analysis"

    try:
      optlist, args = getopt.getopt(sys.argv[1:], 'd:e:ht:',
                                    ['add-dict=', 'add-exc='])
      for (o, v) in optlist:
        if o == '-d':
          rid.load_dictionary_from_file(v)
          load_default_dict = False
        elif o == '-e':
          rid.load_exclusion_list_from_file(v)
          load_default_exc = False
        elif o == '--add-dict':
          rid.load_dictionary_from_file(v)
        elif o == '--add-exc':
          rid.load_exclusion_list_from_file(v)
        elif o == '-h':
          html_output = True
        elif o == '-t':
          title = v
        else:
          sys.stderr.write("%s: illegal option '%s'\n" % (args[0], o))
          self.usage(args)
    except getopt.GetoptError, e:
      sys.stderr.write("%s: %s\n" % (args[0], e.msg))
      self.usage(args)
      sys.exit(1)
                       
    if load_default_dict:
      rid.load_dictionary_from_string(DEFAULT_RID_DICTIONARY)
    if load_default_exc:
      rid.load_exclusion_list_from_string(DEFAULT_RID_EXCLUSION_LIST)
      
    results = rid.analyze(sys.stdin.read())
    if html_output:
      rid.display_results_html(results, title)
    else:
      rid.display_results(results)
      
if __name__ == '__main__':
  app = RIDApp()
  app.run(sys.argv)

