commit 87986d4b2ab201fa95d054bd0b28074e545301ec Author: Brandon Rozek Date: Fri Jan 5 22:30:58 2024 -0500 Initial draft diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4d9d14f --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +state.pickle +results.db +__pycache__ diff --git a/client.py b/client.py new file mode 100644 index 0000000..c435789 --- /dev/null +++ b/client.py @@ -0,0 +1,83 @@ +""" +Author: Brandon Rozek + +TODO: Argparse +""" +from datetime import datetime + +from pubnix import ( + run_simple_client, + send_message, + receive_message +) +from wordguess import WordGuess + +WIN_TEXT = lambda score: f""" +Congratulations! You solved the word of the day. +Come back tomorrow! Your score: {score} +""" + +GUESSES_REMAINING = lambda gr: f"You have {gr} guesses remaining." + +LOSE_TEXT = """ +You ran out of guesses for the day. Come back tomorrow! +""" + + +class WordGuessClient: + def __init__(self): + pass + + + def start_game(self, client, _): + message = receive_message(client, WordGuess.GameStartMessage) + guesses_remaining = message.guesses_remaining + is_winner = message.is_winner + today = datetime.today().date() + print(f""" +Welcome to WordGuess! + +The goal is to guess the word of the day. +This word is {message.num_characters} characters long. + +A * character means a letter was guessed correctly, +but in the incorrect position. + +Today is {today}. +""") + if is_winner: + print(WIN_TEXT(guesses_remaining)) + elif guesses_remaining > 0: + print(f"You have {guesses_remaining} guesses remaining") + print("\nTo quit, press CTRL-C.") + + try: + while not is_winner and guesses_remaining > 0: + guess = input("Guess: ") + send_message(client, WordGuess.GuessMessage(guess)) + + message = receive_message(client, WordGuess.GuessResponseMessage) + if not message.valid: + print("Not a valid guess, try again.") + continue + + guesses_remaining = message.guesses_remaining + is_winner = message.winner + print(message.hint) + print(GUESSES_REMAINING(guesses_remaining)) + print("Letters Guessed:", sorted(message.letters_guessed)) + + if is_winner: + print(WIN_TEXT(guesses_remaining)) + + if not is_winner: + print(LOSE_TEXT) + + except KeyboardInterrupt: + pass + + + +if __name__ == "__main__": + w = WordGuessClient() + run_simple_client(WordGuess.ADDRESS, w.start_game) diff --git a/game.py b/game.py new file mode 100644 index 0000000..2b06a41 --- /dev/null +++ b/game.py @@ -0,0 +1,97 @@ +from collections import defaultdict +from datetime import datetime +from typing import List + +SEED = 838232 + +WORDS = [] + +GAME_WORDS = "gamewords.txt" +GUESS_WORDS = "guesswords.txt" +WORD_LENGTH = 5 + +with open("words.txt", "r") as file: + lines = file.read().splitlines() + WORDS.extend([l for l in lines if len(l) == WORD_LENGTH]) + +NUMBER_OF_GUESSES = 6 + +TODAY = datetime.today() +WORD_OF_THE_DAY = WORDS[(TODAY.year * TODAY.month * TODAY.day * SEED) % len(WORDS) ] + +def valid_guess(guess: str): + if len(guess) != len(WORD_OF_THE_DAY): + return False + + # Guess needs to be part of our + # dictionary + if guess not in WORDS: + return False + + return True + +def char_positions(word: str): + """ + Return a dictionary with positions + of each character within a word. + Ex: "hello" -> {"h": [0], "e": [1], "l": [2, 3], "o": [4]} + """ + result = defaultdict(list) + for i, char in enumerate(word): + result[char].append(i) + return result + + +CHAR_POSITIONS = char_positions(WORD_OF_THE_DAY) + +def compare(expected: str, guess: str) -> List[str]: + output = ["_"] * len(expected) + counted_pos = set() + + + # (1) Check for letters in correct positions + for i, (e_char, g_char) in enumerate(zip(expected, guess)): + if e_char == g_char: + output[i] = e_char + + + for i, g_char in enumerate(guess): + if g_char in expected and output[i] in ["_", "-"]: + for pos in CHAR_POSITIONS[g_char]: + if pos not in counted_pos: + output[i] = "-" + counted_pos.add(pos) + break + pass + + return output + +if __name__ == "__main__": + num_guesses = 0 + print(""" +Guess words one at a time to guess the game word. + +A - character means a letter was guessed correctly, +but in the incorrect position. + +To quit, press CTRL-C. +""") + # start of the user name interaction + print("_ " * WORD_LENGTH) + while True: + guess = input("Guess: ").lower() + if not valid_guess(guess): + print("Not a valid guesss") + continue + num_guesses += 1 + + result = compare(WORD_OF_THE_DAY, guess) + print(" ".join(result)) + + if guess == WORD_OF_THE_DAY: + print("You won") + break + + if num_guesses >= NUMBER_OF_GUESSES: + print("You lost") + break \ No newline at end of file diff --git a/leaderboard.py b/leaderboard.py new file mode 100644 index 0000000..6b8191c --- /dev/null +++ b/leaderboard.py @@ -0,0 +1,24 @@ +""" +Author: Brandon Rozek + +View leaderboard information for a particular date + +# TODO: argparse +""" + +from wordguess import WordGuess +import sqlite3 +from datetime import datetime + + +DATE = str(datetime.today().date()) + +if __name__ == "__main__": + con = sqlite3.connect(WordGuess.RESULTS_LOCATION) + try: + cur = con.cursor() + res = cur.execute(f"SELECT user, score FROM scores WHERE date = '{DATE}' ORDER BY score DESC") + for username, score in res.fetchall(): + print(username, score) + finally: + con.close() diff --git a/pubnix.py b/pubnix.py new file mode 100644 index 0000000..285a954 --- /dev/null +++ b/pubnix.py @@ -0,0 +1,250 @@ +""" +Author: Brandon Rozek + +TODO: Handle a user trying to connect multiple +times at the same time. + +This might be handled automatically if only one +user can play at a time... +""" + +import json +import pwd +import os +import sys +import socket +import binascii +from pathlib import Path +from typing import Union +from contextlib import contextmanager +from dataclasses import dataclass + +# __all__ = ['send_message', 'MESSAGE_BUFFER_LEN', 'ChallengeMessage'] + +MESSAGE_BUFFER_LEN = 1024 +TOKEN_LENGTH = 50 +TIMEOUT = 5 * 60 # 5 minutes + + + +@contextmanager +def start_client(address): + # Create the Unix socket client + client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + + # Connect to the server + try: + client.connect(address) + except FileNotFoundError: + print("Game server is not running at location", address) + sys.exit(1) + + try: + yield client + finally: + client.close() + + + +def run_simple_client(address, fn, force_auth=True): + with start_client(address) as client: + if force_auth: + user = login(client) + send_message(client, StartMessage()) + fn(client, user) + +@contextmanager +def client_connection(sock): + connection, _ = sock.accept() + try: + yield connection + except ( + ProtocolException, + BrokenPipeError, + TimeoutError, + ConnectionResetError) as e: + # Ignore as client can reconnect + pass + finally: # clean up the connection + connection.close() + + +def run_simple_server(address, fn, force_auth=True): + with start_server(address) as sock: + print("Started server at", address) + try: + while True: + with client_connection(sock) as connection: + user = None + if force_auth: + user = authenticate(connection) + receive_message(connection, StartMessage) + fn(connection, user) + except KeyboardInterrupt: + print("Stopping server...") + + +def generate_token(length): + # From https://stackoverflow.com/a/41354711 + return binascii.hexlify(os.urandom(length // 2)).decode() + +def find_owner(path: Union[str, Path]) -> str: + return Path(path).owner() + +def generate_challenge(user): + return ChallengeMessage( + username=user, + token=generate_token(TOKEN_LENGTH), + location=f"/home/{user}/.pubnix_challenge" + ) + +def authenticate(connection): + # First message should be an authentication message + message = receive_message(connection, AuthenticateMessage) + user = message.username + + # Send challenge message + challenge = generate_challenge(user) + send_message(connection, challenge) + + # Second message should be validation message + message = receive_message(connection, ValidationMessage) + + # Check that challenge file exists + if not os.path.exists(challenge.location): + close_with_error(connection, "Challange file doesn't exist") + + # Check if user owns the file + if find_owner(challenge.location) != user: + close_with_error(connection, "Challange file not owned by user") + + # Make sure we can read the file + if not os.access(challenge.location, os.R_OK): + close_with_error(connection, "Challange file cannot be read by server") + + # Check contents of challenge file + with open(challenge.location, "r") as file: + contents = file.read() + if contents != challenge.token: + close_with_error(connection, "Token within challange file is incorrect") + + # Send authentication successful message + send_message(connection, AuthSuccessMessage()) + return user + +MESSAGE_BUFFER_LEN = 1024 + +def login(connection): + # Send authentication message + user = pwd.getpwuid(os.geteuid()).pw_name + message = AuthenticateMessage(username=user) + send_message(connection, message) + + # Receive challenge message + challenge = receive_message(connection, ChallengeMessage) + + # Write to challenge file + with open(challenge.location, "w") as file: + file.write(challenge.token) + + # Tell server to check the challenge file + send_message(connection, ValidationMessage()) + + try: + message = receive_message(connection, AuthSuccessMessage) + finally: + # Delete challenge file + os.unlink(challenge.location) + + return user + + +class MessageEncoder(json.JSONEncoder): + def default(self, o): + return o.__dict__ + +def send_message(connection, message): + contents = json.dumps(message, cls=MessageEncoder).encode() + connection.sendall(contents) + +def receive_message(connection, cls=None): + message = connection.recv(MESSAGE_BUFFER_LEN).decode() + try: + message = json.loads(message) + except Exception: + print("Received:", message, flush=True) + close_with_error(connection, "Invalid Message Received") + + if cls is not None: + try: + message = cls(**message) + except (TypeError, AssertionError): + close_with_error(connection, "Expected message of type") + + return message + +@contextmanager +def start_server(address): + if os.path.exists(address): + print("game.sock exists -- game server already running") + sys.exit(1) + + # Create a unix domain socket + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.settimeout(TIMEOUT) + sock.bind(address) + sock.listen() + + try: + yield sock + finally: + # Delete game.sock when finished + os.unlink(address) + + +class ProtocolException(Exception): + pass + +def close_with_error(connection, content: str): + message = dict(type="error", message=content) + connection.sendall(json.dumps(message).encode()) + raise ProtocolException() + + +@dataclass +class ChallengeMessage: + username: str + token: str + location: str + action: str = "challenge" + + def __post_init__(self): + assert self.action == "challenge" + +@dataclass +class AuthenticateMessage: + username: str + action: str = "authenticate" + + def __post_init__(self): + assert self.action == "authenticate" + assert len(self.username) > 0 + +@dataclass +class ValidationMessage: + action: str = "validate" + def __post_init__(self): + assert self.action == "validate" + +@dataclass +class AuthSuccessMessage: + type: str = "authentication_success" + def __post_init__(self): + assert self.type == "authentication_success" + + +@dataclass +class StartMessage: + action: str = "start" + def __post_init__(self): + assert self.action == "start" diff --git a/server.py b/server.py new file mode 100644 index 0000000..9ce47ef --- /dev/null +++ b/server.py @@ -0,0 +1,210 @@ +""" +Author: Brandon Rozek + +WordGuess game server + +TODO: argparse + +TODO: Multiple users trying to access it at same time? + +TODO: Fix timeout issue + +""" +from datetime import datetime +from functools import lru_cache +from pubnix import ( + run_simple_server, + receive_message, + send_message +) +from collections import defaultdict +from wordguess import WordGuess +from typing import List +import os +import pickle +from pathlib import Path +import sqlite3 + +SEED = 838211 +SAVE_LOCATION = "state.pickle" + +@lru_cache +def char_positions(word: str): + """ + Return a dictionary with positions + of each character within a word. + Ex: "hello" -> {"h": [0], "e": [1], "l": [2, 3], "o": [4]} + """ + result = defaultdict(list) + for i, char in enumerate(word): + result[char].append(i) + return result + +def make_zero(): + return 0 + +def make_false(): + return False + +def make_default_dict_zero(): + return defaultdict(make_zero) + +def make_default_dict_false(): + return defaultdict(make_false) + +def make_default_dict_set(): + return defaultdict(set) + +class WordGuessServer: + def __init__(self, seed, word_length = 5, guesses_allowed = 6): + self.seed = seed + self.word_length = word_length + self.guesses_allowed = guesses_allowed + # date -> user str -> int + self.guesses_made = defaultdict(make_default_dict_zero) + # date -> user str -> bool + self.is_winner = defaultdict(make_default_dict_false) + # date -> user str -> set[char] + self.letters_guessed = defaultdict(make_default_dict_set) + + def fix_permissions(self): + # 33152 = '-rw-------.' + # 33188 = '-rw-r--r--.' + os.chmod(__file__, 33152) + os.chmod("pubnix.py", 33188) + os.chmod("wordguess.py", 33188) + os.chmod("words.txt", 33188) + os.chmod("client.py", 33188) + Path(WordGuess.RESULTS_LOCATION).touch(33188) + Path(SAVE_LOCATION).touch(33152) + + @staticmethod + def save_record(date, username, score): + con = sqlite3.connect(WordGuess.RESULTS_LOCATION) + try: + cur = con.cursor() + cur.execute( + "CREATE TABLE IF NOT EXISTS scores(user TEXT NOT NULL, score INT NOT NULL, date TIMESTAMP NOT NULL, PRIMARY KEY (user, date))" + ) + cur.execute("INSERT INTO scores VALUES (?, ?, ?)", (username, score, date)) + con.commit() + except sqlite3.IntegrityError: + print("Cannot write record:", (date, username, score)) + finally: + con.close() + + @lru_cache + def get_words(self): + words = [] + game_words = "words.txt" + # guess_words = "words.txt" + with open(game_words, "r") as file: + lines = file.read().splitlines() + words.extend([l for l in lines if len(l) == self.word_length]) + return words + + def get_wotd(self, day): + words = self.get_words() + index = (day.year * day.month * day.day * self.seed) % len(words) + return words[index] + + def valid_guess(self, guess: str): + if len(guess) != self.word_length: + return False + + # Guess needs to be part of our + # dictionary + if guess not in self.get_words(): + return False + + return True + + @staticmethod + def compare(expected: str, guess: str) -> List[str]: + output = ["_"] * len(expected) + counted_pos = set() + + # (1) Check for letters in correct positions + for i, (e_char, g_char) in enumerate(zip(expected, guess)): + if e_char == g_char: + output[i] = e_char + + gchar_pos = char_positions(expected) + + for i, g_char in enumerate(guess): + if g_char in expected and output[i] in ["_", "*"]: + for pos in gchar_pos[g_char]: + if pos not in counted_pos: + output[i] = "*" + counted_pos.add(pos) + break + + return output + + def game(self, connection, user): + # As long as the connection is alive, + # treat the time the same + # NOTE: Timeout does exist in pubnix.py + today = datetime.today().date() + wotd = self.get_wotd(today) + + gr = self.guesses_allowed - self.guesses_made[today][user] + is_winner = self.is_winner[today][user] + send_message(connection, WordGuess.GameStartMessage(is_winner, self.word_length, gr, list(self.letters_guessed[today][user]))) + + if self.is_winner[today][user]: + return + + while not self.is_winner[today][user] and self.guesses_made[today][user] < self.guesses_allowed: + message = receive_message(connection, WordGuess.GuessMessage) + message.word = message.word.lower() + + if not self.valid_guess(message.word): + send_message(connection, WordGuess.GuessResponseMessage(gr)) + continue + + self.is_winner[today][user] = message.word == wotd + if not self.is_winner[today][user]: + self.guesses_made[today][user] += 1 + gr = self.guesses_allowed - self.guesses_made[today][user] + result = WordGuessServer.compare(wotd, message.word) + + # Populate letters guessed + for c in message.word: + self.letters_guessed[today][user].add(c) + + send_message( + connection, + WordGuess.GuessResponseMessage( + gr, + True, + self.is_winner[today][user], + result, + list(self.letters_guessed[today][user]) + ) + ) + + if self.is_winner[today][user]: + WordGuessServer.save_record(today, user, gr) + +if __name__ == "__main__": + w = WordGuessServer(SEED) + + # Load data structure if existent + if os.path.exists(SAVE_LOCATION): + with open(SAVE_LOCATION, "rb") as file: + w = pickle.load(file) + print("Successfully loaded game state") + + # Make sure permissions are correct + # to prevent cheating... + w.fix_permissions() + + try: + run_simple_server(WordGuess.ADDRESS, w.game) + finally: + # Save game data structure + print("Saving game state... ", end="") + with open(SAVE_LOCATION, "wb") as file: + pickle.dump(w, file) + print("Done.") diff --git a/wordguess.py b/wordguess.py new file mode 100644 index 0000000..c4062c8 --- /dev/null +++ b/wordguess.py @@ -0,0 +1,33 @@ +""" +Author: Brandon Rozek + +Contains common data structures +between WordGuess client and server +""" +from dataclasses import dataclass + +class WordGuess: + RESULTS_LOCATION = "/home/rozek/repo/wordGuess/results.db" + ADDRESS = "/home/rozek/wordGuess/game.sock" + + @dataclass + class GuessMessage: + word: str + action: str = "guess" + def __post_init__(self): + assert self.action == "guess" + + @dataclass + class GuessResponseMessage: + guesses_remaining: int + valid: bool = False + winner: bool = False + hint: str = "" + letters_guessed: str = "" + + @dataclass + class GameStartMessage: + is_winner: bool + num_characters: int + guesses_remaining: int + letters_guessed: str diff --git a/words.txt b/words.txt new file mode 100644 index 0000000..bf594ea --- /dev/null +++ b/words.txt @@ -0,0 +1,5757 @@ +which +there +their +about +would +these +other +words +could +write +first +water +after +where +right +think +three +years +place +sound +great +again +still +every +small +found +those +never +under +might +while +house +world +below +asked +going +large +until +along +shall +being +often +earth +began +since +study +night +light +above +paper +parts +young +story +point +times +heard +whole +white +given +means +music +miles +thing +today +later +using +money +lines +order +group +among +learn +known +space +table +early +trees +short +hands +state +black +shown +stood +front +voice +kinds +makes +comes +close +power +lived +vowel +taken +built +heart +ready +quite +class +bring +round +horse +shows +piece +green +stand +birds +start +river +tried +least +field +whose +girls +leave +added +color +third +hours +moved +plant +doing +names +forms +heavy +ideas +cried +check +floor +begin +woman +alone +plane +spell +watch +carry +wrote +clear +named +books +child +glass +human +takes +party +build +seems +blood +sides +seven +mouth +solve +north +value +death +maybe +happy +tells +gives +looks +shape +lives +steps +areas +sense +speak +force +ocean +speed +women +metal +south +grass +scale +cells +lower +sleep +wrong +pages +ships +needs +rocks +eight +major +level +total +ahead +reach +stars +store +sight +terms +catch +works +board +cover +songs +equal +stone +waves +guess +dance +spoke +break +cause +radio +weeks +lands +basic +liked +trade +fresh +final +fight +meant +drive +spent +local +waxes +knows +train +bread +homes +teeth +coast +thick +brown +clean +quiet +sugar +facts +steel +forth +rules +notes +units +peace +month +verbs +seeds +helps +sharp +visit +woods +chief +walls +cross +wings +grown +cases +foods +crops +fruit +stick +wants +stage +sheep +nouns +plain +drink +bones +apart +turns +moves +touch +angle +based +range +marks +tired +older +farms +spend +shoes +goods +chair +twice +cents +empty +alike +style +broke +pairs +count +enjoy +score +shore +roots +paint +heads +shook +serve +angry +crowd +wheel +quick +dress +share +alive +noise +solid +cloth +signs +hills +types +drawn +worth +truck +piano +upper +loved +usual +faces +drove +cabin +boats +towns +proud +court +model +prime +fifty +plans +yards +prove +tools +price +sheet +smell +boxes +raise +match +truth +roads +threw +enemy +lunch +chart +scene +graph +doubt +guide +winds +block +grain +smoke +mixed +games +wagon +sweet +topic +extra +plate +title +knife +fence +falls +cloud +wheat +plays +enter +broad +steam +atoms +press +lying +basis +clock +taste +grows +thank +storm +agree +brain +track +smile +funny +beach +stock +hurry +saved +sorry +giant +trail +offer +ought +rough +daily +avoid +keeps +throw +allow +cream +laugh +edges +teach +frame +bells +dream +magic +occur +ended +chord +false +skill +holes +dozen +brave +apple +climb +outer +pitch +ruler +holds +fixed +costs +calls +blank +staff +labor +eaten +youth +tones +honor +globe +gases +doors +poles +loose +apply +tears +exact +brush +chest +layer +whale +minor +faith +tests +judge +items +worry +waste +hoped +strip +begun +aside +lakes +bound +depth +candy +event +worse +aware +shell +rooms +ranch +image +snake +aloud +dried +likes +motor +pound +knees +refer +fully +chain +shirt +flour +drops +spite +orbit +banks +shoot +curve +tribe +tight +blind +slept +shade +claim +flies +theme +queen +fifth +union +hence +straw +entry +issue +birth +feels +anger +brief +rhyme +glory +guard +flows +flesh +owned +trick +yours +sizes +noted +width +burst +route +lungs +uncle +bears +royal +kings +forty +trial +cards +brass +opera +chose +owner +vapor +beats +mouse +tough +wires +meter +tower +finds +inner +stuck +arrow +poems +label +swing +solar +truly +tense +beans +split +rises +weigh +hotel +stems +pride +swung +grade +digit +badly +boots +pilot +sales +swept +lucky +prize +stove +tubes +acres +wound +steep +slide +trunk +error +porch +slave +exist +faced +mines +marry +juice +raced +waved +goose +trust +fewer +favor +mills +views +joint +eager +spots +blend +rings +adult +index +nails +horns +balls +flame +rates +drill +trace +skins +waxed +seats +stuff +ratio +minds +dirty +silly +coins +hello +trips +leads +rifle +hopes +bases +shine +bench +moral +fires +meals +shake +shops +cycle +movie +slope +canoe +teams +folks +fired +bands +thumb +shout +canal +habit +reply +ruled +fever +crust +shelf +walks +midst +crack +print +tales +coach +stiff +flood +verse +awake +rocky +march +fault +swift +faint +civil +ghost +feast +blade +limit +germs +reads +ducks +dairy +worst +gifts +lists +stops +rapid +brick +claws +beads +beast +skirt +cakes +lions +frogs +tries +nerve +grand +armed +treat +honey +moist +legal +penny +crown +shock +taxes +sixty +altar +pulls +sport +drums +talks +dying +dates +drank +blows +lever +wages +proof +drugs +tanks +sings +tails +pause +herds +arose +hated +clues +novel +shame +burnt +races +flash +weary +heels +token +coats +spare +shiny +alarm +dimes +sixth +clerk +mercy +sunny +guest +float +shone +pipes +worms +bills +sweat +suits +smart +upset +rains +sandy +rainy +parks +sadly +fancy +rider +unity +bunch +rolls +crash +craft +newly +gates +hatch +paths +funds +wider +grace +grave +tides +admit +shift +sails +pupil +tiger +angel +cruel +agent +drama +urged +patch +nests +vital +sword +blame +weeds +screw +vocal +bacon +chalk +cargo +crazy +acted +goats +arise +witch +loves +queer +dwell +backs +ropes +shots +merry +phone +cheek +peaks +ideal +beard +eagle +creek +cries +ashes +stall +yield +mayor +opens +input +fleet +tooth +cubic +wives +burns +poets +apron +spear +organ +cliff +stamp +paste +rural +baked +chase +slice +slant +knock +noisy +sorts +stays +wiped +blown +piled +clubs +cheer +widow +twist +tenth +hides +comma +sweep +spoon +stern +crept +maple +deeds +rides +muddy +crime +jelly +ridge +drift +dusty +devil +tempo +humor +sends +steal +tents +waist +roses +reign +noble +cheap +dense +linen +geese +woven +posts +hired +wrath +salad +bowed +tires +shark +belts +grasp +blast +polar +fungi +tends +pearl +loads +jokes +veins +frost +hears +loses +hosts +diver +phase +toads +alert +tasks +seams +coral +focus +naked +puppy +jumps +spoil +quart +macro +fears +flung +spark +vivid +brook +steer +spray +decay +ports +socks +urban +goals +grant +minus +films +tunes +shaft +firms +skies +bride +wreck +flock +stare +hobby +bonds +dared +faded +thief +crude +pants +flute +votes +tonal +radar +wells +skull +hairs +argue +wears +dolls +voted +caves +cared +broom +scent +panel +fairy +olive +bends +prism +lamps +cable +peach +ruins +rally +schwa +lambs +sells +cools +draft +charm +limbs +brake +gazed +cubes +delay +beams +fetch +ranks +array +harsh +camel +vines +picks +naval +purse +rigid +crawl +toast +soils +sauce +basin +ponds +twins +wrist +fluid +pools +brand +stalk +robot +reeds +hoofs +buses +sheer +grief +bloom +dwelt +melts +risen +flags +knelt +fiber +roofs +freed +armor +piles +aimed +algae +twigs +lemon +ditch +drunk +rests +chill +slain +panic +cords +tuned +crisp +ledge +dived +swamp +clung +stole +molds +yarns +liver +gauge +breed +stool +gulls +awoke +gross +diary +rails +belly +trend +flask +stake +fried +draws +actor +handy +bowls +haste +scope +deals +knots +moons +essay +thump +hangs +bliss +dealt +gains +bombs +clown +palms +cones +roast +tidal +bored +chant +acids +dough +camps +swore +lover +hooks +males +cocoa +punch +award +reins +ninth +noses +links +drain +fills +nylon +lunar +pulse +flown +elbow +fatal +sites +moths +meats +foxes +mined +attic +fiery +mount +usage +swear +snowy +rusty +scare +traps +relax +react +valid +robin +cease +gills +prior +safer +polio +loyal +swell +salty +marsh +vague +weave +mound +seals +mules +virus +scout +acute +windy +stout +folds +seize +hilly +joins +pluck +stack +lords +dunes +burro +hawks +trout +feeds +scarf +halls +coals +towel +souls +elect +buggy +pumps +loans +spins +files +oxide +pains +photo +rival +flats +syrup +rodeo +sands +moose +pints +curly +comic +cloak +onion +clams +scrap +didst +couch +codes +fails +ounce +lodge +greet +gypsy +utter +paved +zones +fours +alley +tiles +bless +crest +elder +kills +yeast +erect +bugle +medal +roles +hound +snail +alter +ankle +relay +loops +zeros +bites +modes +debts +realm +glove +rayon +swims +poked +stray +lifts +maker +lumps +graze +dread +barns +docks +masts +pours +wharf +curse +plump +robes +seeks +cedar +curls +jolly +myths +cages +gloom +locks +pedal +beets +crows +anode +slash +creep +rowed +chips +fists +wines +cares +valve +newer +motel +ivory +necks +clamp +barge +blues +alien +frown +strap +crews +shack +gonna +saves +stump +ferry +idols +cooks +juicy +glare +carts +alloy +bulbs +lawns +lasts +fuels +oddly +crane +filed +weird +shawl +slips +troop +bolts +suite +sleek +quilt +tramp +blaze +atlas +odors +scrub +crabs +probe +logic +adobe +exile +rebel +grind +sting +spine +cling +desks +grove +leaps +prose +lofty +agony +snare +tusks +bulls +moods +humid +finer +dimly +plank +china +pines +guilt +sacks +brace +quote +lathe +gaily +fonts +scalp +adopt +foggy +ferns +grams +clump +perch +tumor +teens +crank +fable +hedge +genes +sober +boast +tract +cigar +unite +owing +thigh +haiku +swish +dikes +wedge +booth +eased +frail +cough +tombs +darts +forts +choir +pouch +pinch +hairy +buyer +torch +vigor +waltz +heats +herbs +users +flint +click +madam +bleak +blunt +aided +lacks +masks +waded +risks +nurse +chaos +sewed +cured +ample +lease +steak +sinks +merit +bluff +bathe +gleam +bonus +colts +shear +gland +silky +skate +birch +anvil +sleds +groan +maids +meets +speck +hymns +hints +drown +bosom +slick +quest +coils +spied +snows +stead +snack +plows +blond +tamed +thorn +waits +glued +banjo +tease +arena +bulky +carve +stunt +warms +shady +razor +folly +leafy +notch +fools +otter +pears +flush +genus +ached +fives +flaps +spout +smote +fumes +adapt +cuffs +tasty +stoop +clips +disks +sniff +lanes +brisk +imply +demon +super +furry +raged +growl +texts +hardy +stung +typed +hates +wiser +timid +serum +beaks +rotor +casts +baths +glide +plots +trait +resin +slums +lyric +puffs +decks +brood +mourn +aloft +abuse +whirl +edged +ovary +quack +heaps +slang +await +civic +saint +bevel +sonar +aunts +packs +froze +tonic +corps +swarm +frank +repay +gaunt +wired +niece +cello +needy +chuck +stony +media +surge +hurts +repel +husky +dated +hunts +mists +exert +dries +mates +sworn +baker +spice +oasis +boils +spurs +doves +sneak +paces +colon +siege +strum +drier +cacao +humus +bales +piped +nasty +rinse +boxer +shrub +amuse +tacks +cited +slung +delta +laden +larva +rents +yells +spool +spill +crush +jewel +snaps +stain +kicks +tying +slits +rated +eerie +smash +plums +zebra +earns +bushy +scary +squad +tutor +silks +slabs +bumps +evils +fangs +snout +peril +pivot +yacht +lobby +jeans +grins +viola +liner +comet +scars +chops +raids +eater +slate +skips +soles +misty +urine +knobs +sleet +holly +pests +forks +grill +trays +pails +borne +tenor +wares +carol +woody +canon +wakes +kitty +miner +polls +shaky +nasal +scorn +chess +taxis +crate +shyly +tulip +forge +nymph +budge +lowly +abide +depot +oases +asses +sheds +fudge +pills +rivet +thine +groom +lanky +boost +broth +heave +gravy +beech +timed +quail +inert +gears +chick +hinge +trash +clash +sighs +renew +bough +dwarf +slows +quill +shave +spore +sixes +chunk +madly +paced +braid +fuzzy +motto +spies +slack +mucus +magma +awful +discs +erase +posed +asset +cider +taper +theft +churn +satin +slots +taxed +bully +sloth +shale +tread +raked +curds +manor +aisle +bulge +loins +stair +tapes +leans +bunks +squat +towed +lance +panes +sakes +heirs +caste +dummy +pores +fauna +crook +poise +epoch +risky +warns +fling +berry +grape +flank +drags +squid +pelts +icing +irony +irons +barks +whoop +choke +diets +whips +tally +dozed +twine +kites +bikes +ticks +riots +roars +vault +looms +scold +blink +dandy +pupae +sieve +spike +ducts +lends +pizza +brink +widen +plumb +pagan +feats +bison +soggy +scoop +argon +nudge +skiff +amber +sexes +rouse +salts +hitch +exalt +leash +dined +chute +snort +gusts +melon +cheat +reefs +llama +lasso +debut +quota +oaths +prone +mixes +rafts +dives +stale +inlet +flick +pinto +brows +untie +batch +greed +chore +stirs +blush +onset +barbs +volts +beige +swoop +paddy +laced +shove +jerky +poppy +leaks +fares +dodge +godly +squaw +affix +brute +nicer +undue +snarl +merge +doses +showy +daddy +roost +vases +swirl +petty +colds +curry +cobra +genie +flare +messy +cores +soaks +ripen +whine +amino +plaid +spiny +mowed +baton +peers +vowed +pious +swans +exits +afoot +plugs +idiom +chili +rites +serfs +cleft +berth +grubs +annex +dizzy +hasty +latch +wasps +mirth +baron +plead +aloof +aging +pixel +bared +mummy +hotly +auger +buddy +chaps +badge +stark +fairs +gully +mumps +emery +filly +ovens +drone +gauze +idiot +fussy +annoy +shank +gouge +bleed +elves +roped +unfit +baggy +mower +scant +grabs +fleas +lousy +album +sawed +cooky +murky +infer +burly +waged +dingy +brine +kneel +creak +vanes +smoky +spurt +combs +easel +laces +humps +rumor +aroma +horde +swiss +leapt +opium +slime +afire +pansy +mares +soaps +husks +snips +hazel +lined +cafes +naive +wraps +sized +piers +beset +agile +tongs +steed +fraud +booty +valor +downy +witty +mossy +psalm +scuba +tours +polka +milky +gaudy +shrug +tufts +wilds +laser +truss +hares +creed +lilac +siren +tarry +bribe +swine +muted +flips +cures +sinew +boxed +hoops +gasps +hoods +niche +yucca +glows +sewer +whack +fuses +gowns +droop +bucks +pangs +mails +whisk +haven +clasp +sling +stint +urges +champ +piety +chirp +pleat +posse +sunup +menus +howls +quake +knack +plaza +fiend +caked +bangs +erupt +poker +olden +cramp +voter +poses +manly +slump +fined +grips +gaped +purge +hiked +maize +fluff +strut +sloop +prowl +roach +cocks +bland +dials +plume +slaps +soups +dully +wills +foams +solos +skier +eaves +totem +fused +latex +veils +mused +mains +myrrh +racks +galls +gnats +bouts +sisal +shuts +hoses +dryly +hover +gloss +seeps +denim +putty +guppy +leaky +dusky +filth +oboes +spans +fowls +adorn +glaze +haunt +dares +obeys +bakes +abyss +smelt +gangs +aches +trawl +claps +undid +spicy +hoist +fades +vicar +acorn +pussy +gruff +musty +tarts +snuff +hunch +truce +tweed +dryer +loser +sheaf +moles +lapse +tawny +vexed +autos +wager +domes +sheen +clang +spade +sowed +broil +slyly +studs +grunt +donor +slugs +aspen +homer +croak +tithe +halts +avert +havoc +hogan +glint +ruddy +jeeps +flaky +ladle +taunt +snore +fines +props +prune +pesos +radii +pokes +tiled +daisy +heron +villa +farce +binds +cites +fixes +jerks +livid +waked +inked +booms +chews +licks +hyena +scoff +lusty +sonic +smith +usher +tucks +vigil +molts +sects +spars +dumps +scaly +wisps +sores +mince +panda +flier +axles +plied +booby +patio +rabbi +petal +polyp +tints +grate +troll +tolls +relic +phony +bleat +flaws +flake +snags +aptly +drawl +ulcer +soapy +bossy +monks +crags +caged +twang +diner +taped +cadet +grids +spawn +guile +noose +mores +girth +slimy +aides +spasm +burrs +alibi +lymph +saucy +muggy +liter +joked +goofy +exams +enact +stork +lured +toxic +omens +nears +covet +wrung +forum +venom +moody +alder +sassy +flair +guild +prays +wrens +hauls +stave +tilts +pecks +stomp +gales +tempt +capes +mesas +omits +tepee +harry +wring +evoke +limes +cluck +lunge +highs +canes +giddy +lithe +verge +khaki +queue +loath +foyer +outdo +fared +deter +crumb +astir +spire +jumpy +extol +buoys +stubs +lucid +thong +afore +whiff +maxim +hulls +clogs +slats +jiffy +arbor +cinch +igloo +goody +gazes +dowel +calms +bitch +scowl +gulps +coded +waver +mason +lobes +ebony +flail +isles +clods +dazed +adept +oozed +sedan +clays +warts +ketch +skunk +manes +adore +sneer +mango +fiord +flora +roomy +minks +thaws +watts +freer +exult +plush +paled +twain +clink +scamp +pawed +grope +bravo +gable +stink +sever +waned +rarer +regal +wards +fawns +babes +unify +amend +oaken +glade +visor +hefty +nines +throb +pecan +butts +pence +sills +jails +flyer +saber +nomad +miter +beeps +domed +gulfs +curbs +heath +moors +aorta +larks +tangy +wryly +cheep +rages +evade +lures +freak +vogue +tunic +slams +knits +dumpy +mania +spits +firth +hikes +trots +nosed +clank +dogma +bloat +balsa +graft +middy +stile +keyed +finch +sperm +chaff +wiles +amigo +copra +amiss +eying +twirl +lurch +popes +chins +smock +tines +guise +grits +junks +shoal +cache +tapir +atoll +deity +toils +spree +mocks +scans +shorn +revel +raven +hoary +reels +scuff +mimic +weedy +corny +truer +rouge +ember +floes +torso +wipes +edict +sulky +recur +groin +baste +kinks +surer +piggy +moldy +franc +liars +inept +gusty +facet +jetty +equip +leper +slink +soars +cater +dowry +sided +yearn +decoy +taboo +ovals +heals +pleas +beret +spilt +gayly +rover +endow +pygmy +carat +abbey +vents +waken +chimp +fumed +sodas +vinyl +clout +wades +mites +smirk +bores +bunny +surly +frock +foray +purer +milks +query +mired +blare +froth +gruel +navel +paler +puffy +casks +grime +derby +mamma +gavel +teddy +vomit +moans +allot +defer +wield +viper +louse +erred +hewed +abhor +wrest +waxen +adage +ardor +stabs +pored +rondo +loped +fishy +bible +hires +foals +feuds +jambs +thuds +jeers +knead +quirk +rugby +expel +greys +rigor +ester +lyres +aback +glues +lotus +lurid +rungs +hutch +thyme +valet +tommy +yokes +epics +trill +pikes +ozone +caper +chime +frees +famed +leech +smite +neigh +erode +robed +hoard +salve +conic +gawky +craze +jacks +gloat +mushy +rumps +fetus +wince +pinks +shalt +toots +glens +cooed +rusts +stews +shred +parka +chugs +winks +clots +shrew +booed +filmy +juror +dents +gummy +grays +hooky +butte +dogie +poled +reams +fifes +spank +gayer +tepid +spook +taint +flirt +rogue +spiky +opals +miser +cocky +coyly +balmy +slosh +brawl +aphid +faked +hydra +brags +chide +yanks +allay +video +altos +eases +meted +chasm +longs +excel +taffy +impel +savor +koala +quays +dawns +proxy +clove +duets +dregs +tardy +briar +grimy +ultra +meaty +halve +wails +suede +mauve +envoy +arson +coves +gooey +brews +sofas +chums +amaze +zooms +abbot +halos +scour +suing +cribs +sagas +enema +wordy +harps +coupe +molar +flops +weeps +mints +ashen +felts +askew +munch +mewed +divan +vices +jumbo +blobs +blots +spunk +acrid +topaz +cubed +clans +flees +slurs +gnaws +welds +fords +emits +agate +pumas +mends +darks +dukes +plies +canny +hoots +oozes +lamed +fouls +clefs +nicks +mated +skims +brunt +tuber +tinge +fates +ditty +thins +frets +eider +bayou +mulch +fasts +amass +damps +morns +friar +palsy +vista +croon +conch +udder +tacos +skits +mikes +quits +preen +aster +adder +elegy +pulpy +scows +baled +hovel +lavas +crave +optic +welts +busts +knave +razed +shins +totes +scoot +dears +crock +mutes +trims +skein +doted +shuns +veers +fakes +yoked +wooed +hacks +sprig +wands +lulls +seers +snobs +nooks +pined +perky +mooed +frill +dines +booze +tripe +prong +drips +odder +levee +antic +sidle +pithy +corks +yelps +joker +fleck +buffs +scram +tiers +bogey +doled +irate +vales +coped +hails +elude +bulks +aired +vying +stags +strew +cocci +pacts +scabs +silos +dusts +yodel +terse +jaded +baser +jibes +foils +sways +forgo +slays +preys +treks +quell +peeks +assay +lurks +eject +boars +trite +belch +gnash +wanes +lutes +whims +dosed +chewy +snipe +umbra +teems +dozes +kelps +upped +brawn +doped +shush +rinds +slush +moron +voile +woken +fjord +sheik +jests +kayak +slews +toted +saner +drape +patty +raves +sulfa +grist +skied +vixen +civet +vouch +tiara +homey +moped +runts +serge +kinky +rills +corns +brats +pries +amble +fries +loons +tsars +datum +musky +pigmy +gnome +ravel +ovule +icily +liken +lemur +frays +silts +sifts +plods +ramps +tress +earls +dudes +waive +karat +jolts +peons +beers +horny +pales +wreak +lairs +lynch +stank +swoon +idler +abort +blitz +ensue +atone +bingo +roves +kilts +scald +adios +cynic +dulls +memos +elfin +dales +peels +peals +bares +sinus +crone +sable +hinds +shirk +enrol +wilts +roams +duped +cysts +mitts +safes +spats +coops +filet +knell +refit +covey +punks +kilns +fitly +abate +talcs +heeds +duels +wanly +ruffs +gauss +lapel +jaunt +whelp +cleat +gauzy +dirge +edits +wormy +moats +smear +prods +bowel +frisk +vests +bayed +rasps +tames +delve +embed +befit +wafer +ceded +novas +feign +spews +larch +huffs +doles +mamas +hulks +pried +brims +irked +aspic +swipe +mealy +skimp +bluer +slake +dowdy +penis +brays +pupas +egret +flunk +phlox +gripe +peony +douse +blurs +darns +slunk +lefts +chats +inane +vials +stilt +rinks +woofs +wowed +bongs +frond +ingot +evict +singe +shyer +flied +slops +dolts +drool +dells +whelk +hippy +feted +ether +cocos +hives +jibed +mazes +trios +sirup +squab +laths +leers +pasta +rifts +lopes +alias +whirs +diced +slags +lodes +foxed +idled +prows +plait +malts +chafe +cower +toyed +chefs +keels +sties +racer +etude +sucks +sulks +micas +czars +copse +ailed +abler +rabid +golds +croup +snaky +visas +palls +mopes +boned +wispy +raved +swaps +junky +doily +pawns +tamer +poach +baits +damns +gumbo +daunt +prank +hunks +buxom +heres +honks +stows +unbar +idles +routs +sages +goads +remit +copes +deign +culls +girds +haves +lucks +stunk +dodos +shams +snubs +icons +usurp +dooms +hells +soled +comas +paves +maths +perks +limps +wombs +blurb +daubs +cokes +sours +stuns +cased +musts +coeds +cowed +aping +zoned +rummy +fetes +skulk +quaff +rajah +deans +reaps +galas +tills +roved +kudos +toned +pared +scull +vexes +punts +snoop +bails +dames +hazes +lores +marts +voids +ameba +rakes +adzes +harms +rears +satyr +swill +hexes +colic +leeks +hurls +yowls +ivies +plops +musks +papaw +jells +bused +cruet +bided +filch +zests +rooks +laxly +rends +loams +basks +sires +carps +pokey +flits +muses +bawls +shuck +viler +lisps +peeps +sorer +lolls +prude +diked +floss +flogs +scums +dopes +bogie +pinky +leafs +tubas +scads +lowed +yeses +biked +qualm +evens +caned +gawks +whits +wooly +gluts +romps +bests +dunce +crony +joist +tunas +boner +malls +parch +avers +crams +pares +dally +bigot +kales +flays +leach +gushy +pooch +huger +slyer +golfs +mires +flues +loafs +arced +acnes +neons +fiefs +dints +dazes +pouts +cored +yules +lilts +beefs +mutts +fells +cowls +spuds +lames +jawed +dupes +deads +bylaw +noons +nifty +clued +vireo +gapes +metes +cuter +maims +droll +cupid +mauls +sedge +papas +wheys +eking +loots +hilts +meows +beaus +dices +peppy +riper +fogey +gists +yogas +gilts +skews +cedes +zeals +alums +okays +elope +grump +wafts +soots +blimp +hefts +mulls +hosed +cress +doffs +ruder +pixie +waifs +ousts +pucks +biers +gulch +suets +hobos +lints +brans +teals +garbs +pewee +helms +turfs +quips +wends +banes +napes +icier +swats +bagel +hexed +ogres +goner +gilds +pyres +lards +bides +paged +talon +flout +medic +veals +putts +dirks +dotes +tippy +blurt +piths +acing +barer +whets +gaits +wools +dunks +heros +swabs +dirts +jutes +hemps +surfs +okapi +chows +shoos +dusks +parry +decal +furls +cilia +sears +novae +murks +warps +slues +lamer +saris +weans +purrs +dills +togas +newts +meany +bunts +razes +goons +wicks +ruses +vends +geode +drake +judos +lofts +pulps +lauds +mucks +vises +mocha +oiled +roman +ethyl +gotta +fugue +smack +gourd +bumpy +radix +fatty +borax +cubit +cacti +gamma +focal +avail +papal +golly +elite +versa +billy +adieu +annum +howdy +rhino +norms +bobby +axiom +setup +yolks +terns +mixer +genre +knoll +abode +junta +gorge +combo +alpha +overt +kinda +spelt +prick +nobly +ephod +audio +modal +veldt +warty +fluke +bonny +bream +rosin +bolls +doers +downs +beady +motif +humph +fella +mould +crepe +kerns +aloha +glyph +azure +riser +blest +locus +lumpy +beryl +wanna +brier +tuner +rowdy +mural +timer +canst +krill +quoth +lemme +triad +tenon +amply +deeps +padre +leant +pacer +octal +dolly +trans +sumac +foamy +lolly +giver +quipu +codex +manna +unwed +vodka +ferny +salon +duple +boron +revue +crier +alack +inter +dilly +whist +cults +spake +reset +loess +decor +mover +verve +ethic +gamut +lingo +dunno +align +sissy +incur +reedy +avant +piper +waxer +calyx +basil +coons +seine +piney +lemma +trams +winch +whirr +saith +ionic +heady +harem +tummy +sally +shied +dross +farad +saver +tilde +jingo +bower +serif +facto +belle +inset +bogus +caved +forte +sooty +bongo +toves +credo +basal +yella +aglow +glean +gusto +hymen +ethos +terra +brash +scrip +swash +aleph +tinny +itchy +wanta +trice +jowls +gongs +garde +boric +twill +sower +henry +awash +libel +spurn +sabre +rebut +penal +obese +sonny +quirt +mebbe +tacit +greek +xenon +hullo +pique +roger +negro +hadst +gecko +beget +uncut +aloes +louis +quint +clunk +raped +salvo +diode +matey +hertz +xylem +kiosk +apace +cawed +peter +wench +cohos +sorta +gamba +bytes +tango +nutty +axial +aleck +natal +clomp +gored +siree +bandy +gunny +runic +whizz +rupee +fated +wiper +bards +briny +staid +hocks +ochre +yummy +gents +soupy +roper +swath +cameo +edger +spate +gimme +ebbed +breve +theta +deems +dykes +servo +telly +tabby +tares +blocs +welch +ghoul +vitae +cumin +dinky +bronc +tabor +teeny +comer +borer +sired +privy +mammy +deary +gyros +sprit +conga +quire +thugs +furor +bloke +runes +bawdy +cadre +toxin +annul +egged +anion +nodes +picky +stein +jello +audit +echos +fagot +letup +eyrie +fount +caped +axons +amuck +banal +riled +petit +umber +miler +fibre +agave +bated +bilge +vitro +feint +pudgy +mater +manic +umped +pesky +strep +slurp +pylon +puree +caret +temps +newel +yawns +seedy +treed +coups +rangy +brads +mangy +loner +circa +tibia +afoul +mommy +titer +carne +kooky +motes +amity +suave +hippo +curvy +samba +newsy +anise +imams +tulle +aways +liven +hallo +wales +opted +canto +idyll +bodes +curio +wrack +hiker +chive +yokel +dotty +demur +cusps +specs +quads +laity +toner +decry +writs +saute +clack +aught +logos +tipsy +natty +ducal +bidet +bulgy +metre +lusts +unary +goeth +baler +sited +shies +hasps +brung +holed +swank +looky +melee +huffy +loamy +pimps +titan +binge +shunt +femur +libra +seder +honed +annas +coypu +shims +zowie +jihad +savvy +nadir +basso +monic +maned +mousy +omega +laver +prima +picas +folio +mecca +reals +troth +testy +balky +crimp +chink +abets +splat +abaci +vaunt +cutie +pasty +moray +levis +ratty +islet +joust +motet +viral +nukes +grads +comfy +voila +woozy +blued +whomp +sward +metro +skeet +chine +aerie +bowie +tubby +emirs +coati +unzip +slobs +trike +funky +ducat +dewey +skoal +wadis +oomph +taker +minim +getup +stoic +synod +runty +flyby +braze +inlay +venue +louts +peaty +orlon +humpy +radon +beaut +raspy +unfed +crick +nappy +vizor +yipes +rebus +divot +kiwis +vetch +squib +sitar +kiddo +dyers +cotta +matzo +lager +zebus +crass +dacha +kneed +dicta +fakir +knurl +runny +unpin +julep +globs +nudes +sushi +tacky +stoke +kaput +butch +hulas +croft +achoo +genii +nodal +outgo +spiel +viols +fetid +cagey +fudgy +epoxy +leggy +hanky +lapis +felon +beefy +coots +melba +caddy +segue +betel +frizz +drear +kooks +turbo +hoagy +moult +helix +zonal +arias +nosey +paean +lacey +banns +swain +fryer +retch +tenet +gigas +whiny +ogled +rumen +begot +cruse +abuts +riven +balks +sines +sigma +abase +ennui +gores +unset +augur +sated +odium +latin +dings +moire +scion +henna +kraut +dicks +lifer +prigs +bebop +gages +gazer +fanny +gibes +aural +tempi +hooch +rapes +snuck +harts +techs +emend +ninny +guava +scarp +liege +tufty +sepia +tomes +carob +emcee +prams +poser +verso +hubba +joule +baize +blips +scrim +cubby +clave +winos +rearm +liens +lumen +chump +nanny +trump +fichu +chomp +homos +purty +maser +woosh +patsy +shill +rusks +avast +swami +boded +ahhhh +lobed +natch +shish +tansy +snoot +payer +altho +sappy +laxer +hubby +aegis +riles +ditto +jazzy +dingo +quasi +septa +peaky +lorry +heerd +bitty +payee +seamy +apses +imbue +belie +chary +spoof +phyla +clime +babel +wacky +sumps +skids +khans +crypt +inure +nonce +outen +faire +hooey +anole +kazoo +calve +limbo +argot +ducky +faker +vibes +gassy +unlit +nervy +femme +biter +fiche +boors +gaffe +saxes +recap +synch +facie +dicey +ouija +hewer +legit +gurus +edify +tweak +caron +typos +rerun +polly +surds +hamza +nulls +hater +lefty +mogul +mafia +debug +pates +blabs +splay +talus +porno +moola +nixed +kilos +snide +horsy +gesso +jaggy +trove +nixes +creel +pater +iotas +cadge +skyed +hokum +furze +ankhs +curie +nutsy +hilum +remix +angst +burls +jimmy +veiny +tryst +codon +befog +gamed +flume +axman +doozy +lubes +rheas +bozos +butyl +kelly +mynah +jocks +donut +avian +wurst +chock +quash +quals +hayed +bombe +cushy +spacy +puked +leery +thews +prink +amens +tesla +intro +fiver +frump +capos +opine +coder +namer +jowly +pukes +haled +chard +duffs +bruin +reuse +whang +toons +frats +silty +telex +cutup +nisei +neato +decaf +softy +bimbo +adlib +loony +shoed +agues +peeve +noway +gamey +sarge +reran +epact +potty +coned +upend +narco +ikats +whorl +jinks +tizzy +weepy +posit +marge +vegan +clops +numbs +reeks +rubes +rower +biped +tiffs +hocus +hammy +bunco +fixit +tykes +chaws +yucky +hokey +resew +maven +adman +scuzz +slogs +souse +nacho +mimed +melds +boffo +debit +pinup +vagus +gulag +randy +bosun +educe +faxes +auras +pesto +antsy +betas +fizzy +dorky +snits +moxie +thane +mylar +nobby +gamin +gouty +esses +goyim +paned +druid +jades +rehab +gofer +tzars +octet +homed +socko +dorks +eared +anted +elide +fazes +oxbow +dowse +situs +macaw +scone +drily +hyper +salsa +mooch +gated +unjam +lipid +mitre +venal +knish +ritzy +divas +torus +mange +dimer +recut +meson +wined +fends +phage +fiats +caulk +cavil +panty +roans +bilks +hones +botch +estop +sully +sooth +gelds +ahold +raper +pager +fixer +infix +hicks +tuxes +plebe +twits +abash +twixt +wacko +primp +nabla +girts +miffs +emote +xerox +rebid +shahs +rutty +grout +grift +deify +biddy +kopek +semis +bries +acmes +piton +hussy +torts +disco +whore +boozy +gibed +vamps +amour +soppy +gonzo +durst +wader +tutus +perms +catty +glitz +brigs +nerds +barmy +gizmo +owlet +sayer +molls +shard +whops +comps +corer +colas +matte +droid +ploys +vapid +cairn +deism +mixup +yikes +prosy +raker +flubs +whish +reify +craps +shags +clone +hazed +macho +recto +refix +drams +biker +aquas +porky +doyen +exude +goofs +divvy +noels +jived +hulky +cager +harpy +oldie +vivas +admix +codas +zilch +deist +orcas +retro +pilaf +parse +rants +zingy +toddy +chiff +micro +veeps +girly +nexus +demos +bibbs +antes +lulus +gnarl +zippy +ivied +epees +wimps +tromp +grail +yoyos +poufs +hales +roust +cabal +rawer +pampa +mosey +kefir +burgs +unmet +cuspy +boobs +boons +hypes +dynes +nards +lanai +yogis +sepal +quark +toked +prate +ayins +hawed +swigs +vitas +toker +doper +bossa +linty +foist +mondo +stash +kayos +twerp +zesty +capon +wimpy +rewed +fungo +tarot +frosh +kabob +pinko +redid +mimeo +heist +tarps +lamas +sutra +dinar +whams +busty +spays +mambo +nabob +preps +odour +cabby +conks +sluff +dados +houri +swart +balms +gutsy +faxed +egads +pushy +retry +agora +drubs +daffy +chits +mufti +karma +lotto +toffs +burps +deuce +zings +kappa +clads +doggy +duper +scams +ogler +mimes +throe +zetas +waled +promo +blats +muffs +oinks +viand +coset +finks +faddy +minis +snafu +sauna +usury +muxes +craws +stats +condo +coxes +loopy +dorms +ascot +dippy +execs +dopey +envoi +umpty +gismo +fazed +strop +jives +slims +batik +pings +sonly +leggo +pekoe +prawn +luaus +campy +oodle +prexy +proms +touts +ogles +tweet +toady +naiad +hider +nuked +fatso +sluts +obits +narcs +tyros +delis +wooer +hyped +poset +byway +texas +scrod +avows +futon +torte +tuple +carom +kebab +tamps +jilts +duals +artsy +repro +modem +toped +psych +sicko +klutz +tarns +coxed +drays +cloys +anded +piker +aimer +suras +limos +flack +hapax +dutch +mucky +shire +klieg +staph +layup +tokes +axing +toper +duvet +cowry +profs +blahs +addle +sudsy +batty +coifs +suety +gabby +hafta +pitas +gouda +deice +taupe +topes +duchy +nitro +carny +limey +orals +hirer +taxer +roils +ruble +elate +dolor +wryer +snots +quais +coked +gimel +gorse +minas +goest +agape +manta +jings +iliac +admen +offen +cills +offal +lotta +bolas +thwap +alway +boggy +donna +locos +belay +gluey +bitsy +mimsy +hilar +outta +vroom +fetal +raths +renal +dyads +crocs +vires +culpa +kivas +feist +teats +thats +yawls +whens +abaca +ohhhh +aphis +fusty +eclat +perdu +mayst +exeat +molly +supra +wetly +plasm +buffa +semen +pukka +tagua +paras +stoat +secco +carte +haute +molal +shads +forma +ovoid +pions +modus +bueno +rheum +scurf +parer +ephah +doest +sprue +flams +molto +dieth +choos +miked +bronx +goopy +bally +plumy +moony +morts +yourn +bipod +spume +algal +ambit +mucho +spued +dozer +harum +groat +skint +laude +thrum +pappy +oncet +rimed +gigue +limed +plein +redly +humpf +lites +seest +grebe +absit +thanx +pshaw +yawps +plats +payed +areal +tilth +youse +gwine +thees +watsa +lento +spitz +yawed +gipsy +sprat +cornu +amahs +blowy +wahoo +lubra +mecum +whooo +coqui +sabra +edema +mrads +dicot +astro +kited +ouzel +didos +grata +bonne +axmen +klunk +summa +laves +purls +yawny +teary +masse +largo +bazar +pssst +sylph +lulab +toque +fugit +plunk +ortho +lucre +cooch +whipt +folky +tyres +wheee +corky +injun +solon +didot +kerfs +rayed +wassa +chile +begat +nippy +litre +magna +rebox +hydro +milch +brent +gyves +lazed +feued +mavis +inapt +baulk +casus +scrum +wised +fossa +dower +kyrie +bhoys +scuse +feuar +ohmic +juste +ukase +beaux +tusky +orate +musta +lardy +intra +quiff +epsom +neath +ocher +tared +homme +mezzo +corms +psoas +beaky +terry +infra +spivs +tuans +belli +bergs +anima +weirs +mahua +scops +manse +titre +curia +kebob +cycad +talky +fucks +tapis +amide +dolce +sloes +jakes +russe +blash +tutti +pruta +panga +blebs +tench +swarf +herem +missy +merse +pawky +limen +vivre +chert +unsee +tiros +brack +foots +welsh +fosse +knops +ileum +noire +firma +podgy +laird +thunk +shute +rowan +shoji +poesy +uncap +fames +glees +costa +turps +fores +solum +imago +byres +fondu +coney +polis +dictu +kraal +sherd +mumbo +wroth +chars +unbox +vacuo +slued +weest +hades +wiled +syncs +muser +excon +hoars +sibyl +passe +joeys +lotsa +lepta +shays +bocks +endue +darer +nones +ileus +plash +busby +wheal +buffo +yobbo +biles +poxes +rooty +licit +terce +bromo +hayey +dweeb +imbed +saran +bruit +punky +softs +biffs +loppy +agars +aquae +livre +biome +bunds +shews +diems +ginny +degum +polos +desex +unman +dungy +vitam +wedgy +glebe +apers +ridgy +roids +wifey +vapes +whoas +bunko +yolky +ulnas +reeky +bodge +brant +davit +deque +liker +jenny +tacts +fulls +treap +ligne +acked +refry +vower +aargh +churl +momma +gaols +whump +arras +marls +tiler +grogs +memes +midis +tided +haler +duces +twiny +poste +unrig +prise +drabs +quids +facer +spier +baric +geoid +remap +trier +gunks +steno +stoma +airer +ovate +torah +apian +smuts +pocks +yurts +exurb +defog +nuder +bosky +nimbi +mothy +joyed +labia +pards +jammy +bigly +faxer +hoppy +nurbs +cotes +dishy +vised +celeb +pismo +casas +withs +dodgy +scudi +mungs +muons +ureas +ioctl +unhip +krone +sager +verst +expat +gronk +uvula +shawm +bilgy +braes +cento +webby +lippy +gamic +lordy +mazed +tings +shoat +faery +wirer +diazo +carer +rater +greps +rente +zloty +viers +unapt +poops +fecal +kepis +taxon +eyers +wonts +spina +stoae +yenta +pooey +buret +japan +bedew +hafts +selfs +oared +herby +pryer +oakum +dinks +titty +sepoy +penes +fusee +winey +gimps +nihil +rille +giber +ousel +umiak +cuppy +hames +shits +azine +glads +tacet +bumph +coyer +honky +gamer +gooky +waspy +sedgy +bents +varia +djinn +junco +pubic +wilco +lazes +idyls +lupus +rives +snood +schmo +spazz +finis +noter +pavan +orbed +bates +pipet +baddy +goers +shako +stets +sebum +seeth +lobar +raver +ajuga +riced +velds +dribs +ville +dhows +unsew +halma +krona +limby +jiffs +treys +bauds +pffft +mimer +plebs +caner +jiber +cuppa +washy +chuff +unarm +yukky +styes +waker +flaks +maces +rimes +gimpy +guano +liras +kapok +scuds +bwana +oring +aider +prier +klugy +monte +golem +velar +firer +pieta +umbel +campo +unpeg +fovea +abeam +boson +asker +goths +vocab +vined +trows +tikis +loper +indie +boffs +spang +grapy +tater +ichor +kilty +lochs +supes +degas +flics +torsi +beths +weber +resaw +lawny +coven +mujik +relet +therm +heigh +shnor +trued +zayin +liest +barfs +bassi +qophs +roily +flabs +punny +okras +hanks +dipso +nerfs +fauns +calla +pseud +lurer +magus +obeah +atria +twink +palmy +pocky +pends +recta +plonk +slaws +keens +nicad +pones +inker +whews +groks +mosts +trews +ulnar +gyppy +cocas +expos +eruct +oiler +vacua +dreck +dater +arums +tubal +voxel +dixit +beery +assai +lades +actin +ghoti +buzzy +meads +grody +ribby +clews +creme +email +pyxie +kulak +bocci +rived +duddy +hoper +lapin +wonks +petri +phial +fugal +holon +boomy +duomo +musos +shier +hayer +porgy +hived +litho +fisty +stagy +luvya +maria +smogs +asana +yogic +slomo +fawny +amine +wefts +gonad +twirp +brava +plyer +fermi +loges +niter +revet +unate +gyved +totty +zappy +honer +giros +dicer +calks +luxes +monad +cruft +quoin +fumer +amped +shlep +vinca +yahoo +vulva +zooey +dryad +nixie +moper +iambs +lunes +nudie +limns +weals +nohow +miaow +gouts +mynas +mazer +kikes +oxeye +stoup +jujus +debar +pubes +taels +defun +rands +blear +paver +goosy +sprog +oleos +toffy +pawer +maced +crits +kluge +tubed +sahib +ganef +scats +sputa +vaned +acned +taxol +plink +oweth +tribs +resay +boule +thous +haply +glans +maxis +bezel +antis +porks +quoit +alkyd +glary +beamy +hexad +bonks +tecum +kerbs +filar +frier +redux +abuzz +fader +shoer +couth +trues +guyed +goony +booky +fuzes +hurly +genet +hodad +calix +filer +pawls +iodic +utero +henge +unsay +liers +piing +weald +sexed +folic +poxed +cunts +anile +kiths +becks +tatty +plena +rebar +abled +toyer +attar +teaks +aioli +awing +anent +feces +redip +wists +prats +mesne +muter +smurf +owest +bahts +lossy +ftped +hunky +hoers +slier +sicks +fatly +delft +hiver +himbo +pengo +busks +loxes +zonks +ilium +aport +ikons +mulct +reeve +civvy +canna +barfy +kaiak +scudo +knout +gaper +bhang +pease +uteri +lases +paten +rasae +axels +stoas +ombre +styli +gunky +hazer +kenaf +ahoys +ammos +weeny +urger +kudzu +paren +bolos +fetor +nitty +techy +lieth +somas +darky +villi +gluon +janes +cants +farts +socle +jinns +ruing +slily +ricer +hadda +wowee +rices +nerts +cauls +swive +lilty +micks +arity +pasha +finif +oinky +gutty +tetra +wises +wolds +balds +picot +whats +shiki +bungs +snarf +legos +dungs +stogy +berms +tangs +vails +roods +morel +sware +elans +latus +gules +razer +doxie +buena +overs +gutta +zincs +nates +kirks +tikes +donee +jerry +mohel +ceder +doges +unmap +folia +rawly +snark +topoi +ceils +immix +yores +diest +bubba +pomps +forky +turdy +lawzy +poohs +worts +gloms +beano +muley +barky +tunny +auric +funks +gaffs +cordy +curdy +lisle +toric +soyas +reman +mungy +carpy +apish +oaten +gappy +aurae +bract +rooky +axled +burry +sizer +proem +turfy +impro +mashy +miens +nonny +olios +grook +sates +agley +corgi +dashy +doser +dildo +apsos +xored +laker +playa +selah +malty +dulse +frigs +demit +whoso +rials +sawer +spics +bedim +snugs +fanin +azoic +icers +suers +wizen +koine +topos +shirr +rifer +feral +laded +lased +turds +swede +easts +cozen +unhit +pally +aitch +sedum +coper +ruche +geeks +swags +etext +algin +offed +ninja +holer +doter +toter +besot +dicut +macer +peens +pewit +redox +poler +yecch +fluky +doeth +twats +cruds +bebug +bider +stele +hexer +wests +gluer +pilau +abaft +whelm +lacer +inode +tabus +gator +cuing +refly +luted +cukes +bairn +bight +arses +crump +loggy +blini +spoor +toyon +harks +wazoo +fenny +naves +keyer +tufas +morph +rajas +typal +spiff +oxlip +unban +mussy +finny +rimer +login +molas +cirri +huzza +agone +unsex +unwon +peats +toile +zombi +dewed +nooky +alkyl +ixnay +dovey +holey +cuber +amyls +podia +chino +apnea +prims +lycra +johns +primo +fatwa +egger +hempy +snook +hying +fuzed +barms +crink +moots +yerba +rhumb +unarc +direr +munge +eland +nares +wrier +noddy +atilt +jukes +ender +thens +unfix +doggo +zooks +diddy +shmoo +brusk +prest +curer +pasts +kelpy +bocce +kicky +taros +lings +dicky +nerdy +abend +stela +biggy +laved +baldy +pubis +gooks +wonky +stied +hypos +assed +spumy +osier +roble +rumba +biffy +pupal