{\n\t"casktype": [\n\t\t"oak",\n\t\t"pine",\n\t\t"mithril",\n\t\t"human bone",\n\t\t"ent",\n\t\t"laminated reed",\n\t\t"paper mache",\n\t\t"clay",\n\t\t"wood"\n\t],\n\t"genadj": [\n\t\t"nude",\n\t\t"provocative",\n\t\t"luscious",\n\t\t"opulent",\n\t\t"succulent",\n\t\t"ravishing",\n\t\t"voluptuous",\n\t\t"decadent",\n\t\t"sexy",\n\t\t"pretentious",\n\t\t"racy",\n\t\t"jammy",\n\t\t"medicinal",\n\t\t"firm",\n\t\t"smooth",\n\t\t"big",\n\t\t"full-bodied",\n\t\t"velvety",\n\t\t"unctuous",\n\t\t"oily",\n\t\t"smooth",\n\t\t"greasy",\n\t\t"confident",\n\t\t"serious",\n\t\t"complex",\n\t\t"open",\n\t\t"crisp",\n\t\t"juicy",\n\t\t"virginal",\n\t\t"vegetal",\n\t\t"nervy",\n\t\t"firm",\n\t\t"tongue spanking",\n\t\t"brooding",\n\t\t"leathery",\n\t\t"laser-like",\n\t\t"chunky",\n\t\t"canny",\n\t\t"pompous",\n\t\t"dense",\n\t\t"muscular",\n\t\t"aromatic",\n\t\t"mature",\n\t\t"youthful",\n\t\t"young",\n\t\t"angular",\n\t\t"austere",\n\t\t"barnyard",\n\t\t"buttery",\n\t\t"chewy",\n\t\t"creamy",\n\t\t"dense",\n\t\t"earthy",\n\t\t"elegant",\n\t\t"fat",\n\t\t"fleshy",\n\t\t"flamboyant",\n\t\t"flabby",\n\t\t"grippy",\n\t\t"intellectually satisfying",\n\t\t"opulent",\n\t\t"steely",\n\t\t"toasty",\n\t\t"orgasmic",\n\t\t"alcoholic",\n\t\t"pungent",\n\t\t"steampunk",\n\t\t"dance-y",\n\t\t"effulgent",\n\t\t"sweaty",\n\t\t"dickensian",\n\t\t"swampy",\n\t\t"tactical"\n\t],\n\t"note": [\n\t\t"gooseberry",\n\t\t"lychee",\n\t\t"cherry",\n\t\t"despair",\n\t\t"banana",\n\t\t"cinnamon",\n\t\t"licorice",\n\t\t"savory herb",\n\t\t"citrus",\n\t\t"blackberry",\n\t\t"blue coconut",\n\t\t"caramel",\n\t\t"cherry",\n\t\t"chocolate",\n\t\t"cotton candy",\n\t\t"lemon",\n\t\t"lime",\n\t\t"grape",\n\t\t"green apple",\n\t\t"lemonberry",\n\t\t"diet cherry",\n\t\t"mango",\n\t\t"mint",\n\t\t"orange",\n\t\t"peach",\n\t\t"raspberry",\n\t\t"sour blue raspberry",\n\t\t"strawberry",\n\t\t"watermelon",\n\t\t"chicken",\n\t\t"goose",\n\t\t"duck",\n\t\t"quail",\n\t\t"guinea hen",\n\t\t"salmon",\n\t\t"tilapia",\n\t\t"beef",\n\t\t"lamb",\n\t\t"pork",\n\t\t"mutton",\n\t\t"rabbit",\n\t\t"veal",\n\t\t"venison",\n\t\t"açai berry",\n\t\t"apple",\n\t\t"apricot",\n\t\t"avocado",\n\t\t"banana",\n\t\t"bilberry",\n\t\t"black raspberry",\n\t\t"blackberry",\n\t\t"blackcurrant",\n\t\t"blood orange",\n\t\t"blueberry",\n\t\t"boysenberry",\n\t\t"cantaloupe",\n\t\t"cantaloupe",\n\t\t"cherimoya",\n\t\t"cherry",\n\t\t"clementine",\n\t\t"cloudberry",\n\t\t"coconut",\n\t\t"cranberry",\n\t\t"currant",\n\t\t"date",\n\t\t"dragonfruit",\n\t\t"durian",\n\t\t"elderberry",\n\t\t"feijoa",\n\t\t"fig",\n\t\t"goji berry",\n\t\t"gooseberry",\n\t\t"grape",\n\t\t"grapefruit",\n\t\t"guava",\n\t\t"honeydew",\n\t\t"huckleberry",\n\t\t"jabouticaba",\n\t\t"jackfruit",\n\t\t"jambul",\n\t\t"jujube",\n\t\t"juniper berry",\n\t\t"kiwano",\n\t\t"kiwi fruit",\n\t\t"kumquat",\n\t\t"lemon",\n\t\t"lime",\n\t\t"loquat",\n\t\t"lychee",\n\t\t"mandarine",\n\t\t"mango",\n\t\t"marion berry",\n\t\t"melon",\n\t\t"miracle fruit",\n\t\t"mulberry",\n\t\t"nectarine",\n\t\t"olive",\n\t\t"orange",\n\t\t"papaya",\n\t\t"passionfruit",\n\t\t"peach",\n\t\t"pear",\n\t\t"persimmon",\n\t\t"physalis",\n\t\t"pineapple",\n\t\t"plum",\n\t\t"pomegranate",\n\t\t"pomelo",\n\t\t"pumpkin",\n\t\t"purple mangosteen",\n\t\t"quince",\n\t\t"raisin",\n\t\t"rambutan",\n\t\t"raspberry",\n\t\t"redcurrant",\n\t\t"salal berry",\n\t\t"salmon berry",\n\t\t"satsuma",\n\t\t"squash",\n\t\t"star fruit",\n\t\t"strawberry",\n\t\t"tamarillo",\n\t\t"tangerine",\n\t\t"tomato",\n\t\t"ugli fruit",\n\t\t"watermelon",\n\t\t"acorn squash",\n\t\t"alfalfa sprouts",\n\t\t"amaranth",\n\t\t"artichoke",\n\t\t"arugula",\n\t\t"asparagus",\n\t\t"azuki beans",\n\t\t"banana squash",\n\t\t"bean sprouts",\n\t\t"beet",\n\t\t"black beans",\n\t\t"black-eyed peas",\n\t\t"bok choy",\n\t\t"borlotti bean",\n\t\t"broad beans",\n\t\t"broccoflower",\n\t\t"broccoli",\n\t\t"brussels sprouts",\n\t\t"butternut squash",\n\t\t"cabbage",\n\t\t"calabrese",\n\t\t"cannabis",\n\t\t"carrot",\n\t\t"carrots",\n\t\t"cauliflower",\n\t\t"celeriac",\n\t\t"celery",\n\t\t"plastic",\n\t\t"horsey",\n\t\t"old bones",\n\t\t"charcoal",\n\t\t"tennis ball",\n\t\t"cigar box",\n\t\t"blanched almond",\n\t\t"cherry blossom",\n\t\t"plutonium",\n\t\t"grape",\n\t\t"grape",\n\t\t"grape",\n\t\t"grape",\n\t\t"toxic waste",\n\t\t"peat",\n\t\t"dirt",\n\t\t"soil",\n\t\t"human sweat",\n\t\t"hemlock",\n\t\t"arsenic",\n\t\t"aluminum",\n\t\t"otaku",\n\t\t"anime body pillows",\n\t\t"rusty",\n\t\t"Flintstone vitamins",\n\t\t"ass"\n\t],\n\t"winetype": [\n\t\t"Fabergé",\n\t\t"Cabernet Sauvignon",\n\t\t"Merlot",\n\t\t"Pinot Noir",\n\t\t"Zinfandel",\n\t\t"Chardonnay",\n\t\t"Riesling",\n\t\t"Sauvignon Blanc",\n\t\t"Gewurztraminer",\n\t\t"Rose Champagne",\n\t\t"Prosecco",\n\t\t"Sparkling Red",\n\t\t"Rosé",\n\t\t"Blanc de Blanc",\n\t\t"Blanc de Noir",\n\t\t"Brut",\n\t\t"Brut Rosé",\n\t\t"Demi Sec",\n\t\t"Sauvage",\n\t\t"Sauvage Rose",\n\t\t"Red Blend",\n\t\t"Blanc de Blancs",\n\t\t"Grand Rosé",\n\t\t"Grande Reserve",\n\t\t"Vintage Sauvage",\n\t\t"Cabernet Doré",\n\t\t"Bubbly Brut",\n\t\t"Riesling Moscato",\n\t\t"Bubbly Pink Moscato",\n\t\t"Moscato",\n\t\t"Sangria",\n\t\t"Pink Moscato",\n\t\t"Pinot Grigio",\n\t\t"Sweet Red",\n\t\t"Chardonnay Moscato",\n\t\t"White Merlot",\n\t\t"Chenin Blanc",\n\t\t"White Zinfandel",\n\t\t"Red Moscato",\n\t\t"Malbec",\n\t\t"Chablis"\n\t],\n\t"finish": [\n\t\t"#genadj#"\n\t],\n\t"timeperiod": [\n\t\t"2 years",\n\t\t"5 years",\n\t\t"7 years"\n\t],\n\t"amount": [\n\t\t"mild",\n\t\t"a few",\n\t\t"a couple of",\n\t\t"just a fucking shitload of",\n\t\t"a buttload of",\n\t\t"like, a TON of",\n\t\t"plenty of"\n\t],\n\t"noun": [\n\t\t"tannins",\n\t\t"mouthfeel",\n\t\t"legs",\n\t\t"aroma",\n\t\t"nose",\n\t\t"structure",\n\t\t"skeleton",\n\t\t"vas deferens"\n\t],\n\t"dish": [\n\t\t"roasted nuts",\n\t\t"curried nuts",\n\t\t"roasted chestnuts",\n\t\t"toasted pumpkin seeds",\n\t\t"toasted sunflower seeds",\n\t\t"popcorn",\n\t\t"Spanish style marinated olives",\n\t\t"sour cream dip",\n\t\t"clam dip",\n\t\t"shrimp dip",\n\t\t"red onion dip",\n\t\t"guacamole",\n\t\t"Texas caviar",\n\t\t"hot chorizo and cheese dip",\n\t\t"hot crab dip",\n\t\t"baked artichoke dip",\n\t\t"seven-layer dip",\n\t\t"hummus",\n\t\t"baba ghanoush",\n\t\t"eggplant caviar",\n\t\t"garlic cheese spread",\n\t\t"marinated mozzarella",\n\t\t"fried mozzarella spread",\n\t\t"nachos",\n\t\t"quesadillas",\n\t\t"honey yogurt dip",\n\t\t"crudites",\n\t\t"crispy potato skins",\n\t\t"buffalo chicken wings",\n\t\t"lemon rosemary chicken",\n\t\t"chicken fingers",\n\t\t"beef satay",\n\t\t"cocktail meatballs",\n\t\t"salami rolls",\n\t\t"smoked turkey and arugula rolls",\n\t\t"beef and scallion rolls",\n\t\t"baked honey shrimp",\n\t\t"cajun popcorn shrimp",\n\t\t"beer-batter shrimp",\n\t\t"coconut shrimp",\n\t\t"smoked salmon rolls",\n\t\t"ham biscuits",\n\t\t"mushroom triangles",\n\t\t"spinach and feta triangles",\n\t\t"turnovers",\n\t\t"cocktail tartlets",\n\t\t"miniature quiches",\n\t\t"stuffed choux puffs",\n\t\t"cheese puffs",\n\t\t"pigs in a blanket",\n\t\t"egg rolls",\n\t\t"summer rolls",\n\t\t"pot stickers",\n\t\t"fried wontons",\n\t\t"bagel chips",\n\t\t"pita chips",\n\t\t"soda crackers",\n\t\t"potato chips",\n\t\t"root vegetable chips",\n\t\t"tortilla chips",\n\t\t"drip coffee",\n\t\t"steeped coffee",\n\t\t"turkish coffee",\n\t\t"jamaican coffee",\n\t\t"irish coffee",\n\t\t"cafe diablo",\n\t\t"spiced tea",\n\t\t"sweet southern iced tea",\n\t\t"hot cocoa",\n\t\t"egg cream",\n\t\t"broth on the rocks",\n\t\t"citrus juice medley",\n\t\t"pineapple grapefruit juice",\n\t\t"raspberry or blackberry shrub",\n\t\t"cranberry juice",\n\t\t"hot cranberry juice",\n\t\t"mulled cider",\n\t\t"celery-apple-watermelon splash",\n\t\t"pineapple juice",\n\t\t"tropical juice",\n\t\t"fruit soda",\n\t\t"ice cream soda",\n\t\t"milk shake",\n\t\t"tropical smoothie",\n\t\t"mango lassi",\n\t\t"fruit kefir",\n\t\t"pink lemonade",\n\t\t"watermelon punch",\n\t\t"pineapple punch",\n\t\t"fruit punch",\n\t\t"Cocomoka",\n\t\t"sugar syrup",\n\t\t"fruit syrup",\n\t\t"spiced syrup",\n\t\t"casserole",\n\t\t"tetrazzini",\n\t\t"crab strata",\n\t\t"pork shoulder",\n\t\t"seafood stew",\n\t\t"hearty meat ragu",\n\t\t"hamburger pie",\n\t\t"shepard's pie",\n\t\t"chicken potpie",\n\t\t"enchiladas",\n\t\t"chop suey",\n\t\t"chow mein",\n\t\t"sweet and sour pork",\n\t\t"curry",\n\t\t"hot chicken salad",\n\t\t"ham loaf",\n\t\t"fish loaf",\n\t\t"corned beef ",\n\t\t"quiche lorraine",\n\t\t"quiche",\n\t\t"leek tart",\n\t\t"cheese custard",\n\t\t"fondue",\n\t\t"welsh rarebit",\n\t\t"shrimp wiggle",\n\t\t"cornmeal mush",\n\t\t"polenta",\n\t\t"fried polenta",\n\t\t"grits",\n\t\t"shrimp and grits",\n\t\t"posole",\n\t\t"tamales",\n\t\t"millet cakes",\n\t\t"granola",\n\t\t"muesli",\n\t\t"quinoa pilaf",\n\t\t"baked white rice",\n\t\t"rice pilaf",\n\t\t"spanish rice",\n\t\t"chicken jambalaya",\n\t\t"fried rice",\n\t\t"risotto",\n\t\t"tabbouleh",\n\t\t"pasta",\n\t\t"egg noodles",\n\t\t"macaroni and cheese",\n\t\t"pasta primavera",\n\t\t"fettuccine alfredo",\n\t\t"spaghetti carbonara",\n\t\t"lo mein",\n\t\t"pad thai",\n\t\t"szechuan noodles",\n\t\t"moon-viewing noodles",\n\t\t"dumplings",\n\t\t"gnocchi",\n\t\t"spatzle",\n\t\t"pastitsio",\n\t\t"cheese filling",\n\t\t"meat filling",\n\t\t"ravioli",\n\t\t"tortellini",\n\t\t"cannelloni",\n\t\t"lasagne",\n\t\t"lasagne bolognese",\n\t\t"vareniki",\n\t\t"pierogi",\n\t\t"wontons",\n\t\t"vegetable wontons",\n\t\t"stuffed artichokes",\n\t\t"fried artichokes",\n\t\t"roasted asparagus",\n\t\t"green beans",\n\t\t"boiled beans",\n\t\t"refried beans",\n\t\t"vegetarian chili",\n\t\t"caribbean red bean stew",\n\t\t"baked beans",\n\t\t"tuscan beans",\n\t\t"mashed fava beans",\n\t\t"red beans and rice",\n\t\t"brazilian black beans",\n\t\t"steamed broccoli",\n\t\t"deep-fried broccoli",\n\t\t"stir-fry",\n\t\t"creamed cabbage",\n\t\t"stuffed cabbage rolls",\n\t\t"braised red cabbage",\n\t\t"sauerkraut",\n\t\t"carrot puree",\n\t\t"carrots vichy",\n\t\t"braised carrots",\n\t\t"glazed carrots",\n\t\t"roasted carrots",\n\t\t"steamed cauliflower",\n\t\t"mashed cauliflower",\n\t\t"scalloped cauliflower",\n\t\t"celery",\n\t\t"corn on the cob",\n\t\t"creamed corn",\n\t\t"corn pudding",\n\t\t"fresh corn fritters",\n\t\t"fried eggplant",\n\t\t"eggplant parmigiana",\n\t\t"moussaka",\n\t\t"roasted garlic",\n\t\t"grilled mushrooms",\n\t\t"sauteed mushrooms",\n\t\t"creamed mushrooms",\n\t\t"mushroom ragout",\n\t\t"fried okra",\n\t\t"steamed onions",\n\t\t"grilled sweet onions",\n\t\t"sauteed onions",\n\t\t"caramelized onions",\n\t\t"onion rings",\n\t\t"deep-fried parsley",\n\t\t"french parsnips",\n\t\t"roasted peppers",\n\t\t"stuffed bell peppers",\n\t\t"deep-fried plantains",\n\t\t"tostones",\n\t\t"mashed potatoes",\n\t\t"creamed potatoes",\n\t\t"scalloped potatoe",\n\t\t"au gratin potatoes",\n\t\t"baked potatoes",\n\t\t"twice-baked potatoes",\n\t\t"hash browns",\n\t\t"potato pancakes",\n\t\t"latkes",\n\t\t"french fries",\n\t\t"potato croquettes",\n\t\t"boiled spinach",\n\t\t"creamed spinach",\n\t\t"wilted spinach",\n\t\t"saag paneer",\n\t\t"deep-fried zucchini",\n\t\t"baked winter squas",\n\t\t"taro cakes",\n\t\t"stewed tomatoes",\n\t\t"fried green tomatoes",\n\t\t"turnip puree",\n\t\t"moo shu tempeh",\n\t\t"szechuan-style tempeh",\n\t\t"dinner loaf",\n\t\t"seitan",\n\t\t"soft-boiled eggs",\n\t\t"hard-boiled eggs",\n\t\t"coddled eggs",\n\t\t"creamed eggs au gratin",\n\t\t"curried eggs",\n\t\t"deviled eggs",\n\t\t"scotch eggs",\n\t\t"fried eggs",\n\t\t"eggs in a basket",\n\t\t"huevos rancheros",\n\t\t"poached eggs",\n\t\t"eggs florentine",\n\t\t"eggs benedict",\n\t\t"scrambled eggs",\n\t\t"matzo brei",\n\t\t"baked egg",\n\t\t"eggs in a nest",\n\t\t"french omelet",\n\t\t"omelet",\n\t\t"frittata",\n\t\t"hangtown fry",\n\t\t"denver omelet",\n\t\t"potato omelet",\n\t\t"tortilla espanola",\n\t\t"spinach souffle",\n\t\t"mushroom souffle",\n\t\t"meat glaze",\n\t\t"dashi",\n\t\t"egg drop soup",\n\t\t"avgolemono",\n\t\t"stracciatella",\n\t\t"garlic soup with eggs",\n\t\t"sopa de ajo",\n\t\t"miso",\n\t\t"chicken noodle soup",\n\t\t"matzo ball soup",\n\t\t"wonton soup",\n\t\t"minestrone",\n\t\t"borscht",\n\t\t"bean soup",\n\t\t"white bean soup",\n\t\t"black bean soup",\n\t\t"lentil soup",\n\t\t"split pea soup",\n\t\t"mock turtle soup",\n\t\t"scotch broth",\n\t\t"caldo verde",\n\t\t"pepper pot",\n\t\t"charleston crab",\n\t\t"lobster bisque",\n\t\t"cream of mussel soup",\n\t\t"bisque",\n\t\t"gumbo",\n\t\t"bouillabaisse",\n\t\t"new england clam chowder",\n\t\t"manhattan clam chowder",\n\t\t"corn chowder",\n\t\t"cream of broccoli soup",\n\t\t"chestnut soup",\n\t\t"milk toast",\n\t\t"new year's soup",\n\t\t"gazpacho",\n\t\t"soup",\n\t\t"beef stew",\n\t\t"dried fruit compote",\n\t\t"poached fruit",\n\t\t"apple rings",\n\t\t"honey apples",\n\t\t"sauteed apples",\n\t\t"applesauce",\n\t\t"baked apples",\n\t\t"honey-grilled bananas",\n\t\t"strawberries romanoff",\n\t\t"blueberry syrup",\n\t\t"syrup",\n\t\t"cranberry sauce",\n\t\t"poached cherries",\n\t\t"citrus salad",\n\t\t"kumquat compote",\n\t\t"stuffed dates",\n\t\t"baked figs",\n\t\t"poached pears",\n\t\t"stuffed pears",\n\t\t"walnut butter",\n\t\t"honey butter",\n\t\t"cream cheese",\n\t\t"waffles",\n\t\t"BLT",\n\t\t"club sandwich",\n\t\t"twin sandwich",\n\t\t"reuben",\n\t\t"croque monsieur",\n\t\t"croque madame sandwich",\n\t\t"monte cristo",\n\t\t"cuban sandwich",\n\t\t"panini",\n\t\t"muffuletta",\n\t\t"cheese toast",\n\t\t"tuna melt",\n\t\t"pizza",\n\t\t"lox",\n\t\t"submarine sandwich",\n\t\t"po-boy",\n\t\t"hot dog",\n\t\t"corn dog",\n\t\t"tea sandwiches",\n\t\t"gyro",\n\t\t"falafel",\n\t\t"taco",\n\t\t"fajitas",\n\t\t"pizza margherita",\n\t\t"calzone",\n\t\t"stromboli",\n\t\t"green salad",\n\t\t"green salad",\n\t\t"caesar salad",\n\t\t"greek salad",\n\t\t"spinach salad",\n\t\t"wilted greens",\n\t\t"coleslaw",\n\t\t"hot slaw",\n\t\t"chef's salad",\n\t\t"cobb salad",\n\t\t"salade nicoise",\n\t\t"vinaigrette",\n\t\t"taco salad",\n\t\t"chicken salad",\n\t\t"tuna salad",\n\t\t"seafood salad",\n\t\t"marinated cucumbers",\n\t\t"potato salad",\n\t\t"waldorf salad",\n\t\t"chickpea salad",\n\t\t"pasta salad",\n\t\t"tomato aspic",\n\t\t"broiled oysters",\n\t\t"grilled oysters",\n\t\t"fried breaded oysters",\n\t\t"steamed mussels",\n\t\t"buttered baked mussels",\n\t\t"grilled mussels",\n\t\t"steamed clams",\n\t\t"broiled clams",\n\t\t"clambake i",\n\t\t"poached scallops",\n\t\t"crab cakes",\n\t\t"steamed lobster",\n\t\t"lobster thermidor",\n\t\t"lobster newburg",\n\t\t"shrimp scampi",\n\t\t"deep-fried shrimp",\n\t\t"tempura",\n\t\t"stuffed squid",\n\t\t"whelk salad",\n\t\t"turtle soup",\n\t\t"snails",\n\t\t"deep-fried frog legs",\n\t\t"chili sauce",\n\t\t"catsup",\n\t\t"pickled ginger",\n\t\t"pickled peppers",\n\t\t"grape jelly",\n\t\t"gooseberry jam",\n\t\t"plum jam",\n\t\t"baked apple butter",\n\t\t"preserves",\n\t\t"marmalade",\n\t\t"truffles",\n\t\t"truffle cups",\n\t\t"chocolate bark",\n\t\t"peanut butter cup",\n\t\t"joy of coconut",\n\t\t"chocolate clusters",\n\t\t"fudge cockaigne",\n\t\t"peanut butter fudge",\n\t\t"cream caramels",\n\t\t"turtles",\n\t\t"caramel corn",\n\t\t"fondant",\n\t\t"peppermint wafers",\n\t\t"nougat",\n\t\t"divinity",\n\t\t"marshmallow",\n\t\t"vanilla taffy",\n\t\t"saltwater taffy",\n\t\t"english toffee",\n\t\t"buttercrunch",\n\t\t"butterscotch",\n\t\t"coffee drops",\n\t\t"lollipop",\n\t\t"rock candy",\n\t\t"pralines",\n\t\t"marzipan",\n\t\t"bourbon balls",\n\t\t"heavenly hash",\n\t\t"candied apples",\n\t\t"caramel apples",\n\t\t"candied citrus peel",\n\t\t"candied ginger",\n\t\t"ice cream pie",\n\t\t"ice cream",\n\t\t"ice milk",\n\t\t"gelato",\n\t\t"frozen yogurt",\n\t\t"sorbet",\n\t\t"blackberry sorbet",\n\t\t"blueberry sorbet",\n\t\t"strawberry sorbet",\n\t\t"mango sorbet",\n\t\t"peach sorbet",\n\t\t"lemon sorbet",\n\t\t"lime sorbet",\n\t\t"orange sorbet",\n\t\t"lemon sherbet",\n\t\t"lime sherbet",\n\t\t"cranberry sherbet",\n\t\t"ice pops",\n\t\t"berry granita",\n\t\t"espresso granita",\n\t\t"caffe latte granita",\n\t\t"granita",\n\t\t"coffee parfait",\n\t\t"hazelnut semifreddo",\n\t\t"semifreddo",\n\t\t"souffle",\n\t\t"baked alaska",\n\t\t"hot lemon sauce",\n\t\t"custard sauce",\n\t\t"hot fudge sauce",\n\t\t"mocha sauce",\n\t\t"caramel sauce",\n\t\t"caramel syrup",\n\t\t"butterscotch sauce",\n\t\t"rum sauce",\n\t\t"marshmallow sauce",\n\t\t"sour cream sauce",\n\t\t"raspberry coulis",\n\t\t"decorative icing",\n\t\t"creamy decorating icing",\n\t\t"royal icing",\n\t\t"caramel frosting",\n\t\t"buttercream",\n\t\t"cream cheese frosting",\n\t\t"chocolate satin frosting",\n\t\t"Meringue",\n\t\t"translucent sugar glaze",\n\t\t"brownies",\n\t\t"blondies",\n\t\t"cheesecake",\n\t\t"toffee bars",\n\t\t"nut bars",\n\t\t"energy bars",\n\t\t"lemon bars",\n\t\t"gingersnaps",\n\t\t"peanut butter cookies",\n\t\t"oatmeal raisin cookies",\n\t\t"oatmeal chocolate chip cookies",\n\t\t"snickerdoodles",\n\t\t"ginger thins",\n\t\t"hermits",\n\t\t"orange marmalade drops",\n\t\t"butterscotch nut cookies",\n\t\t"macaroons",\n\t\t"meringue kisses",\n\t\t"sand tarts",\n\t\t"tarts",\n\t\t"gingerbread men",\n\t\t"viennese crescents",\n\t\t"letter cookies",\n\t\t"mandelplattchen",\n\t\t"biscotti",\n\t\t"cinnamon stars",\n\t\t"scotch shortbread",\n\t\t"shortbread",\n\t\t"rugelach",\n\t\t"ice cream cones",\n\t\t"fortune cookies",\n\t\t"gingerbread house",\n\t\t"ginger sauce",\n\t\t"roasted red pepper sauce",\n\t\t"burgundy sauce",\n\t\t"mole",\n\t\t"mustard",\n\t\t"ghee",\n\t\t"butter",\n\t\t"black butter",\n\t\t"lemon butter",\n\t\t"walnut butter",\n\t\t"anchovy butter",\n\t\t"mint sauce",\n\t\t"raisin sauce",\n\t\t"chimichurri",\n\t\t"hot sauce",\n\t\t"tzatziki",\n\t\t"pesto",\n\t\t"peanut sauce",\n\t\t"wasabi",\n\t\t"vinaigrette",\n\t\t"horseradish",\n\t\t"avocado dressing",\n\t\t"blue cheese vinaigrette",\n\t\t"anchovy dressing",\n\t\t"celery seed dressing",\n\t\t"parmesan vinaigrette",\n\t\t"roasted red pepper dressing",\n\t\t"tangerine shallot dressing",\n\t\t"apricot dressing",\n\t\t"mayonnaise",\n\t\t"souffleed mayonnaise",\n\t\t"watercress mayonnaise",\n\t\t"brown sugar glaze",\n\t\t"cranberry glaze",\n\t\t"marmalade glaze",\n\t\t"mustard glaze",\n\t\t"pineapple glaze",\n\t\t"glaze",\n\t\t"white bread",\n\t\t"milk bread",\n\t\t"cinnamon raisin bread",\n\t\t"cheese bread",\n\t\t"herb bread",\n\t\t"buttermilk potato bread",\n\t\t"challah",\n\t\t"french bread",\n\t\t"sourdough bread",\n\t\t"tuscan loaf",\n\t\t"naan",\n\t\t"sopapillas",\n\t\t"hot cross buns",\n\t\t"cheese rolls",\n\t\t"sticky buns",\n\t\t"bear claws",\n\t\t"whole wheat rolls",\n\t\t"rye rolls",\n\t\t"oat rolls",\n\t\t"brioche",\n\t\t"brioche au chocolat",\n\t\t"croissants",\n\t\t"english muffins",\n\t\t"crumpets",\n\t\t"bagels",\n\t\t"pretzels",\n\t\t"bread sticks ",\n\t\t"yeasted coffee cake",\n\t\t"kneaded filled coffee cake",\n\t\t"kugelhopf",\n\t\t"raspberry danish pinwheels",\n\t\t"orange bread",\n\t\t"banana bread",\n\t\t"pumpkin bread",\n\t\t"carrot nut bread",\n\t\t"beer bread",\n\t\t"irish soda bread",\n\t\t"poppy seed loaf",\n\t\t"brown bread",\n\t\t"bishop's bread",\n\t\t"crumb cake",\n\t\t"corn bread",\n\t\t"hush puppies",\n\t\t"muffins",\n\t\t"sour cream muffins",\n\t\t"lemon poppy seed muffins",\n\t\t"pumpkin or sweet potato muffins",\n\t\t"blueberry muffins",\n\t\t"herb or roasted garlic muffins",\n\t\t"whole wheat muffins",\n\t\t"bran muffins",\n\t\t"cheese muffins",\n\t\t"apple walnut muffins",\n\t\t"banana nut muffins",\n\t\t"popovers",\n\t\t"cheese popovers",\n\t\t"yorkshire pudding",\n\t\t"cornmeal biscuits",\n\t\t"buttermilk biscuits",\n\t\t"shortcake",\n\t\t"scones",\n\t\t"lemon scones",\n\t\t"chocolate chip orange scones",\n\t\t"melba cheese rounds",\n\t\t"crostini",\n\t\t"honey-butter toast",\n\t\t"orange toast",\n\t\t"angel cake",\n\t\t"sponge cake",\n\t\t"daffodil cake",\n\t\t"tres leches cake",\n\t\t"genoise",\n\t\t"white cake",\n\t\t"marble cake",\n\t\t"german chocolate cake",\n\t\t"velvet spice cake",\n\t\t"brown sugar spice cake",\n\t\t"burnt sugar cake",\n\t\t"applesauce cake",\n\t\t"rombauer jam cake",\n\t\t"oatmeal cake",\n\t\t"blitzkuchen",\n\t\t"texas sheet cake",\n\t\t"mississippi mud cake",\n\t\t"rum cake",\n\t\t"orange almond cake",\n\t\t"apple cake",\n\t\t"carrot cake",\n\t\t"gingerbread",\n\t\t"Guy Fawkes day cake",\n\t\t"honey cake",\n\t\t"fruitcake cockaigne",\n\t\t"fruitcake",\n\t\t"torte",\n\t\t"jelly roll",\n\t\t"chiffon cake sheet",\n\t\t"angel cake sheet",\n\t\t"chocolate cupcakes",\n\t\t"caramel cupcakes",\n\t\t"petit fours",\n\t\t"madeleines",\n\t\t"ladyfingers",\n\t\t"meringue",\n\t\t"chocolate cheesecake",\n\t\t"pumpkin cheesecake",\n\t\t"lemon syrup",\n\t\t"apple strudel",\n\t\t"baklava",\n\t\t"apple pie",\n\t\t"apple tartlets",\n\t\t"peach pie",\n\t\t"rhubarb pie",\n\t\t"strawberry rhubarb pie",\n\t\t"concord grape pie",\n\t\t"raisin pie",\n\t\t"fresh fruit tart",\n\t\t"pecan pie",\n\t\t"bourbon pie",\n\t\t"shoofly pie",\n\t\t"chess pie",\n\t\t"jefferson davis pie",\n\t\t"buttermilk chess pie",\n\t\t"lemon chess pie",\n\t\t"chess tarts",\n\t\t"maple syrup pie",\n\t\t"peanut butter pie",\n\t\t"custard pie",\n\t\t"chocolate glazed custard pie",\n\t\t"vanilla cream pie",\n\t\t"chocolate cream pie",\n\t\t"banana cream pie",\n\t\t"butterscotch cream pie",\n\t\t"coconut cream pie",\n\t\t"lemon meringue pie",\n\t\t"lemon tart",\n\t\t"raspberry bavarian pie",\n\t\t"black bottom pie",\n\t\t"pumpkin chiffon pie",\n\t\t"pineapple upside-down cake",\n\t\t"apple dumplings",\n\t\t"pear turnovers",\n\t\t"linzertorte",\n\t\t"dessert pizza",\n\t\t"pancakes",\n\t\t"buttermilk pancakes",\n\t\t"silver dollar pancakes",\n\t\t"flapjacks",\n\t\t"oatmeal pancakes",\n\t\t"waffles",\n\t\t"buttermilk waffles",\n\t\t"french toast",\n\t\t"crepes",\n\t\t"crepes suzette",\n\t\t"crepes with caramelized apples",\n\t\t"blueberry blintzes",\n\t\t"cake doughnuts",\n\t\t"jelly doughnuts",\n\t\t"crullers",\n\t\t"beignets",\n\t\t"tempura",\n\t\t"fritters",\n\t\t"croquettes",\n\t\t"stuffing",\n\t\t"chicken farce",\n\t\t"sauteed rabbit",\n\t\t"fricassee ",\n\t\t"rabbit ala mode",\n\t\t"chili",\n\t\t"burger",\n\t\t"boar chops",\n\t\t"braised bear",\n\t\t"buffalo rib roast",\n\t\t"buffalo burgers",\n\t\t"chicken-fried steak",\n\t\t"beef stroganoff",\n\t\t"sukiyaki",\n\t\t"pot roast",\n\t\t"beef stew",\n\t\t"sweet and sour brisket",\n\t\t"smoked brisket",\n\t\t"chuck roast",\n\t\t"short ribs",\n\t\t"corned beef",\n\t\t"roast leg of lamb",\n\t\t"stuffed butterflied leg of lamb",\n\t\t"rack of lamb",\n\t\t"sauteed lamb chops",\n\t\t"kebabs",\n\t\t"braised shoulder of lamb",\n\t\t"irish stew",\n\t\t"pork roast",\n\t\t"pulled pork",\n\t\t"roast suckling pig",\n\t\t"pork adobo",\n\t\t"grilled pork tenderloin",\n\t\t"pork chops",\n\t\t"spareribs",\n\t\t"baked ham ",\n\t\t"broiled ham steak",\n\t\t"bacon",\n\t\t"hamburgers",\n\t\t"cheeseburgers",\n\t\t"patty melt",\n\t\t"sloppy joe",\n\t\t"meat loaf",\n\t\t"swedish meatballs",\n\t\t"chili con carne",\n\t\t"country sausage",\n\t\t"liver and onions",\n\t\t"pickled beef tongue",\n\t\t"oxtail stew",\n\t\t"poached chicken or turkey",\n\t\t"roast chicken",\n\t\t"broiled chicken",\n\t\t"jamaican jerk chicken",\n\t\t"tandoori chicken",\n\t\t"fried chicken",\n\t\t"coq au vin",\n\t\t"sesame chicken",\n\t\t"chicken and rice",\n\t\t"arroz con pollo",\n\t\t"chicken piccata",\n\t\t"stir-fried garlic chicken",\n\t\t"roast turkey",\n\t\t"turned roast turkey",\n\t\t"roast brined turkey",\n\t\t"chutney turkey burgers",\n\t\t"roast duck",\n\t\t"crispy roast duck",\n\t\t"goose confit",\n\t\t"pheasant",\n\t\t"grouse",\n\t\t"partridge",\n\t\t"wild rice pilau",\n\t\t"poached fish",\n\t\t"fish fillets",\n\t\t"sardine toast",\n\t\t"kedgeree",\n\t\t"rice pudding",\n\t\t"cheese curds",\n\t\t"fish fry",\n\t\t"fish and chips",\n\t\t"Cornish pasties",\n\t\t"carne adovada",\n\t\t"fish boil",\n\t\t"bratwurst",\n\t\t"cranberry wine",\n\t\t"beer cheese soup",\n\t\t"brandy old fashioned",\n\t\t"rhubarb pie",\n\t\t"mango kulfi",\n\t\t"Bedfordshire clanger",\n\t\t"spotted dick",\n\t\t"head cheese",\n\t\t"fairy bread",\n\t\t"sliders",\n\t\t"po-boy",\n\t\t"Vegemite sandwiches",\n\t\t"filet mignon",\n\t\t"cube steak",\n\t\t"tiramisu"\n\t],\n\t"basephrase": [\n\t\t"Our featured wine is #genadj.a# #winetype# with #note# and #note# notes and #finish.a# finish.",\n\t\t"Aged in #casktype# casks for #timeperiod#, this #winetype# is #genadj# with notes of #note# and a #finish# finish.",\n\t\t"Grown in #location#, this #genadj# #winetype# features notes of #note# and #note# and offers a #finish# and #finish# finish.",\n\t\t"This #genadj# #winetype# features #genadj# #noun# and notes of #note#.",\n\t\t"This #genadj.a# #winetype# has #note# and #note# notes, a distinctive #casktype#-aged flavor and #amount# tannins.",\n\t\t"This #winetype# is #genadj# with #note# and #note# notes, a distinctive #casktype#-aged flavor and #amount# #noun#.",\n\t\t"A subtle bouquet of #note# and #note#, this #winetype# features #amount# #noun# and #finish.a# finish.",\n\t\t"This #genadj.a# #winetype# has a bouquet of #note# and #note#, undercurrents of #note# and #finish.a# finish.",\n\t\t"Today's featured wine is #casktype.a#-aged #winetype#; it has #genadj.a# bouquet and hints of #note#.",\n\t\t"This #winetype# is #genadj# with slight hints of #note#, #genadj.a# bouquet and #amount# #noun#.",\n\t\t"Today's featured wine is #genadj.a# #winetype# with #note# and #note# notes and #finish.a# finish; pairs well with #dish#.",\n\t\t"Grown in #location#, this #genadj# #winetype# features notes of #note# and #note# and offers #finish.a# and #finish# finish; serve with #dish#.",\n\t\t"From the finest vineyards of #location#, our #winetype# has #note# and #note# notes and a #finish# finish.",\n\t\t"Aged in #genadj# #casktype# #casktype# in #location#, our #winetype# has #note# undertones and pairs well with #dish#."\n\t],\n\t"origin": [\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#",\n\t\t"#basephrase# $#price#, #corkphrase#"\n\t],\n\t"price": [\n\t\t"#1numeral##numeral#",\n\t\t"#1numeral##numeral##numeral#",\n\t\t"1#1numeral##numeral#",\n\t\t"#1numeral##numeral#",\n\t\t"#1numeral##numeral#",\n\t\t"#1numeral##numeral#",\n\t\t"#1numeral##numeral#",\n\t\t"1#numeral#",\n\t\t"1#numeral#",\n\t\t"69"\n\t],\n\t"numeral": [\n\t\t"1",\n\t\t"2",\n\t\t"3",\n\t\t"4",\n\t\t"5",\n\t\t"6",\n\t\t"7",\n\t\t"8",\n\t\t"9",\n\t\t"0"\n\t],\n\t"1numeral": [\n\t\t"1",\n\t\t"2",\n\t\t"3",\n\t\t"4",\n\t\t"5",\n\t\t"6",\n\t\t"7",\n\t\t"8",\n\t\t"9"\n\t],\n\t"corkphrase": [\n\t\t"comes with free cork",\n\t\t"cork included"\n\t],\n\t"placeprefix": [\n\t\t"Aber",\n\t\t"Inver",\n\t\t"Ac",\n\t\t"Acc",\n\t\t"Ock",\n\t\t"Afon",\n\t\t"Avon",\n\t\t"Ar",\n\t\t"Ard",\n\t\t"Ast",\n\t\t"Auch",\n\t\t"Auchen",\n\t\t"Achin",\n\t\t"Ach",\n\t\t"Auchter",\n\t\t"Axe",\n\t\t"Exe",\n\t\t"Usk",\n\t\t"Esk",\n\t\t"Bal",\n\t\t"Balla",\n\t\t"Bally",\n\t\t"Ball",\n\t\t"Beck",\n\t\t"Berg",\n\t\t"Berry",\n\t\t"Bex",\n\t\t"Blen",\n\t\t"Blean",\n\t\t"Bourne",\n\t\t"Burn",\n\t\t"Brad",\n\t\t"Bre",\n\t\t"Bi",\n\t\t"Caer",\n\t\t"Car",\n\t\t"Cheap",\n\t\t"Chipping",\n\t\t"Combe",\n\t\t"Coombe",\n\t\t"Cwn",\n\t\t"Coed",\n\t\t"Craig",\n\t\t"Crag",\n\t\t"Creag",\n\t\t"Dal",\n\t\t"Din",\n\t\t"Dinas",\n\t\t"Dol",\n\t\t"Drum",\n\t\t"Dubh",\n\t\t"Dow",\n\t\t"Dhu",\n\t\t"Duff",\n\t\t"Eagles",\n\t\t"Eglos",\n\t\t"Eglews",\n\t\t"Eccles",\n\t\t"Eilean",\n\t\t"Ey",\n\t\t"Ea",\n\t\t"Eig",\n\t\t"Fin",\n\t\t"Firth",\n\t\t"Ford",\n\t\t"Forth",\n\t\t"Fos",\n\t\t"Foss",\n\t\t"Gate",\n\t\t"Gar",\n\t\t"Gart",\n\t\t"Garth",\n\t\t"Gill",\n\t\t"Ghyll",\n\t\t"Glen",\n\t\t"Gowt",\n\t\t"Hithe",\n\t\t"Hythe",\n\t\t"Holm",\n\t\t"Hope",\n\t\t"Howe",\n\t\t"Hurst",\n\t\t"Hirst",\n\t\t"Inch",\n\t\t"Inner",\n\t\t"Keld",\n\t\t"Kil",\n\t\t"Kin",\n\t\t"King",\n\t\t"Kirk",\n\t\t"Knock",\n\t\t"Kyle",\n\t\t"Kyles",\n\t\t"Lan",\n\t\t"Lhan",\n\t\t"Llan",\n\t\t"Lang",\n\t\t"Law",\n\t\t"Low",\n\t\t"Lin",\n\t\t"Llyn",\n\t\t"Ling",\n\t\t"Lyng",\n\t\t"Loch",\n\t\t"Lough",\n\t\t"Mawr",\n\t\t"Fawr",\n\t\t"Mere",\n\t\t"Minster",\n\t\t"More",\n\t\t"Moss",\n\t\t"Mynydd",\n\t\t"Nan",\n\t\t"Nans",\n\t\t"Nant",\n\t\t"Nor",\n\t\t"Pant",\n\t\t"Pen",\n\t\t"Pit",\n\t\t"Pont",\n\t\t"Porth",\n\t\t"Shep",\n\t\t"Ship",\n\t\t"Stan",\n\t\t"Camp",\n\t\t"Strath",\n\t\t"Streat",\n\t\t"Sud",\n\t\t"Sut",\n\t\t"Swin",\n\t\t"Tarn",\n\t\t"Arse",\n\t\t"Butt",\n\t\t"Thorp",\n\t\t"Thorpe",\n\t\t"Tre",\n\t\t"Tra",\n\t\t"Tilly",\n\t\t"Tullie",\n\t\t"Tulloch",\n\t\t"Tun",\n\t\t"Ton",\n\t\t"Weald",\n\t\t"Wold",\n\t\t"Whel",\n\t\t"Win"\n\t],\n\t"placesuffix": [\n\t\t"ac",\n\t\t"acc",\n\t\t"ock",\n\t\t"afon",\n\t\t"avon",\n\t\t"ar",\n\t\t"ard",\n\t\t"ast",\n\t\t"axe",\n\t\t"exe",\n\t\t"usk",\n\t\t"esk",\n\t\t"a",\n\t\t"y",\n\t\t"ey",\n\t\t"beck",\n\t\t"berg",\n\t\t"berry",\n\t\t"bex",\n\t\t"blen",\n\t\t"blean",\n\t\t"bost",\n\t\t"bourne",\n\t\t"burn",\n\t\t"bury",\n\t\t"borough",\n\t\t"brough",\n\t\t"burgh",\n\t\t"by",\n\t\t"carden",\n\t\t"caster",\n\t\t"chester",\n\t\t"cester",\n\t\t"ceter",\n\t\t"cheap",\n\t\t"chipping",\n\t\t"combe",\n\t\t"coombe",\n\t\t"cwn",\n\t\t"coed",\n\t\t"cot",\n\t\t"cott",\n\t\t"craig",\n\t\t"crag",\n\t\t"creag",\n\t\t"dale",\n\t\t"dean",\n\t\t"den",\n\t\t"don",\n\t\t"dubh",\n\t\t"dow",\n\t\t"dhu",\n\t\t"duff",\n\t\t"eagles",\n\t\t"eglos",\n\t\t"eglews",\n\t\t"eccles",\n\t\t"eilean",\n\t\t"ey",\n\t\t"ea",\n\t\t"eig",\n\t\t"field",\n\t\t"firth",\n\t\t"frith",\n\t\t"fos",\n\t\t"foss",\n\t\t"gate",\n\t\t"gar",\n\t\t"gart",\n\t\t"garth",\n\t\t"gill",\n\t\t"ghyll",\n\t\t"glen",\n\t\t"gowt",\n\t\t"ham",\n\t\t"hithe",\n\t\t"hythe",\n\t\t"holm",\n\t\t"hope",\n\t\t"howe",\n\t\t"hurst",\n\t\t"hirst",\n\t\t"inch",\n\t\t"ing",\n\t\t"keld",\n\t\t"kelth",\n\t\t"chelth",\n\t\t"king",\n\t\t"kirk",\n\t\t"knock",\n\t\t"law",\n\t\t"low",\n\t\t"lea",\n\t\t"ley",\n\t\t"leigh",\n\t\t"llyn",\n\t\t"ling",\n\t\t"lyng",\n\t\t"loch",\n\t\t"lough",\n\t\t"mawr",\n\t\t"fawr",\n\t\t"mere",\n\t\t"minster",\n\t\t"more",\n\t\t"moss",\n\t\t"mouth",\n\t\t"ness",\n\t\t"pool",\n\t\t"port",\n\t\t"shaw",\n\t\t"stead",\n\t\t"ster",\n\t\t"stoke",\n\t\t"swin",\n\t\t"tarn",\n\t\t"thorp",\n\t\t"thorpe",\n\t\t"thwaite",\n\t\t"twatt",\n\t\t"toft",\n\t\t"treath",\n\t\t"tun",\n\t\t"ton",\n\t\t"weald",\n\t\t"wold",\n\t\t"wick",\n\t\t"wich",\n\t\t"wych",\n\t\t"wyke",\n\t\t"wick",\n\t\t"whel",\n\t\t"drake",\n\t\t"chester",\n\t\t"borne",\n\t\t"worth",\n\t\t"worthy",\n\t\t"wardine"\n\t],\n\t"placestandalone": [\n\t\t"Magna",\n\t\t"Parva",\n\t\t"Shaw",\n\t\t"Stoke",\n\t\t"Street",\n\t\t"Head",\n\t\t"Ynys",\n\t\t"Law",\n\t\t"Low"\n\t],\n\t"placeinterim": [\n\t\t"y",\n\t\t"cum",\n\t\t"upon",\n\t\t"on",\n\t\t"over",\n\t\t"under",\n\t\t"le",\n\t\t"in the"\n\t],\n\t"placemodifier": [\n\t\t"North",\n\t\t"South",\n\t\t"East",\n\t\t"West",\n\t\t"Upper",\n\t\t"Lower"\n\t],\n\t"location": [\n\t\t"#placeprefix##placesuffix#",\n\t\t"#placeprefix##placesuffix##placesuffix#",\n\t\t"#placeprefix##placesuffix#-#placeinterim#-#placeprefix#",\n\t\t"#placeprefix##placesuffix#-#placeinterim#-#placestandalone#",\n\t\t"#placeprefix##placesuffix#",\n\t\t"#placeprefix##placesuffix#",\n\t\t"#placeprefix##placesuffix# #placestandalone#",\n\t\t"#placemodifier# #placeprefix##placesuffix#",\n\t\t"#placeprefix##placesuffix# #placeinterim# #placestandalone#",\n\t\t"#placeprefix##placesuffix#"\n\t]\n}\n\n
v.2016-09-05
//requires jquery\n\n// input: an array of objects\n//\t\t a property that each of those object have\n// output: an array of the properties of all the objects\nwindow.skimObjectArray = function(objectArray, property){\n\tconsole.log("skimObjectArray(", "objectArray", objectArray, "property", property, ")")\n\tvar values = [];\n\n\tfor (var i = 0; i < objectArray.length; i++) {\n\t\tvar thingToAdd = objectArray[i][property];\n\t\tif(typeof thingToAdd === "object"){\n\t\t\t// i hope to god this works\n\t\t\tthingToAdd = objectArray[i][property].join("\sn")\n\t\t}\n\t\tvalues.push( thingToAdd );\n\t};\n\n\tvalues = values.join("\sn");\n\tvalues = values.split("\sn")\n\n\treturn values;\n}\n\nStory.prototype.appendCorpora = function(){\n\tvar corporaToAppend = tale.lookup("tags", "corpus");\n\tif(!corporaToAppend.length) return;\n\n\tfor(var i in corporaToAppend){\n\t\tvar currentPassage = corporaToAppend[i].title;\n\n\t\t// the rules are the concatenation of each symbol in this passage\n\t\tvar rules = [];\n\t\tvar lines = tale.passages[currentPassage].text.split("\sn")\n\t\tfor(var j in lines){\n\t\t\tvar line = lines[j];\n\t\t\tvar location = line.split("#");\n\t\t\tconsole.log("location: ", location);\n\t\t\tvar corpusLocation = location[0];\n\n\t\t\t// fetch me that sweet sweet boy\n\t\t\tvar corpus = $.ajax({\n\t\t\t\tdataType: "json",\n\t\t\t\turl: corpusLocation,\n\t\t\t\tasync: false\n\t\t\t});\n\t\t\tcorpus = corpus.responseJSON;\n\n\t\t\t// drill down to the array we want\n\t\t\tfor (var i = 1; i < location.length; i++) {\n\t\t\t\tconsole.log("corpus: ", corpus);\n\t\t\t\t// if there's a ! at the beginning of a location, skim the objArray for that property\n\t\t\t\tif(location[i][0] === "!"){\n\t\t\t\t\tcorpus = skimObjectArray(corpus, location[i].substring(1));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcorpus = corpus[ location[i] ]\n\t\t\t};\n\n\t\t\tconsole.log("corpus: ", corpus);\n\t\t\t// add this into the symbol-in-progress\n\t\t\trules = rules.concat(corpus);\n\t\t\tconsole.log("rules: ", rules)\n\t\t}\n\n\t\t// the name of this symbol is the name of the passage\n\t\tvar finalJSON = "{ \s"" + currentPassage + "\s": " + JSON.stringify(rules) + " }";\n\n\t\t// save our dark deeds to the passage\n\t\ttale.passages[currentPassage].text = finalJSON;\n\n\t\t//tag this as JSON so it gets appended in the next step\n\t\ttale.passages[currentPassage].tags.push("JSON")\n\t}\n\n\tconsole.log("corpora loaded")\n}\n\nStory.prototype.appendJSON = function() {\n\tvar JSONtoAppend = tale.lookup("tags", "JSON");\n\tif(!JSONtoAppend.length) return;\n\n\tfor(i in JSONtoAppend){\n\t\tvar newJSON = JSON.parse(JSONtoAppend[i].text);\n\t\t$.extend(this.data, newJSON);\n\t}\n\tconsole.log("JSON appended");\n}\n\nfunction Story(){\n\tvar grammars = tale.lookup("tags", "grammar", "title");\n\tthis.data = {};\n\n\tvar links = /(\s[\s[\sb)(.+?)(\sb\s]\s])/g;\n\tvar sublinks = /([^\s[\s]]+)*(.+)/\n\n\tfunction convertSyntax(match, p1, p2, p3){\n\t\t// If a passage is invoked that's tagged as a grammar, change Twine links into Tracery symbols.\n\t\t// e.g.: [[animal]] => #animal#\n\t\t// e.g.: [[animal][capitalize]] => #animal.capitalize#\n\n\t\t// p1 is left brackets, p3 is right brackets\n\t\tvar targetLink = p2.split("][")[0];\n\t\tvar modifiers = p2.split("][").slice(1, p2.length).join(".");\n\t\tmodifiers = modifiers?("." + modifiers):"";\n\t\t\n\t\tvar trace = "#" + targetLink + modifiers + "#";\n\t\t\n\t\tvar linkIsGrammar = false;\n\t\tvar tags = tale.get(targetLink).tags\n\t\tfor(var i = 0; i < tags.length; i++){\n\t\t\tif(tags[i] == "grammar" || tags[i] == "corpus"){\n\t\t\t\tlinkIsGrammar = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn linkIsGrammar?trace:match;\n\t}\n\n\tfor(var i in grammars){\n\t\tif(grammars[i] == undefined) continue;\n\n\t\t// Passage names become grammar names, Passage text becomes grammar text. \n\t\tvar newSymbol = grammars[i].title\n\t\tvar newText = grammars[i].text\n\n\t\tvar link = /(\s[\s[\sb)(.+?)(\sb\s]\s])/g;\n\t\tnewText = newText.replace(link, convertSyntax);\n\t\t// Get everything that's being linked to.\n\n\t\tthis.data[newSymbol] = newText.split('\sn');\n\t}\n\n\tthis.appendCorpora();\n\tthis.appendJSON();\n\tconsole.log("Story: ", this);\n}\nStory.prototype.constructor = Story;\n\n// Append this to the tale object because I don't know where else to put it.\nTale.prototype.story = new Story();\n\nStory.prototype.toHTML = function() {\n\tvar output = [];\n\tvar tab = " ";\n\tvar beg = '\sn' + tab + "\s"<span class=\s"grammarContents\s">{{{"\n\tvar end = "}}}</span>\s""\n\n\tfor(var i in this.data){\n\t\tvar gram = "<span class=\s"grammarTitle\s">\s"" + i + "\s"</span>: [";\n\t\tgram += beg + this.data[i].join(end + ',' + beg) + end;\n\t\tgram += "]";\n\t\toutput.push(gram);\n\t}\n\treturn "{\sn" + output.join(",\sn") + "\sn}";\n}\n\nTale.prototype.JSONtoTwee = function() {\n\tvar JSONtoConvert = tale.lookup("tags", "JSON");\n\tvar combinedJSON = ""\n\n\tfor (var i in JSONtoConvert){\n\t\tcombinedJSON += JSONtoConvert[i].text;\n\t}\n\n\t// Note the {{{}}} delimiters in textPost. This is intended for display in Twine, so\n\t// if you're just running these raw they aren't necessary.\n\tvar regex = {titlesPre: /\st"(.+)": \s[/g, titlesPost: "<br>:: $1 [grammar]",\n\t\t\t\t textPre: /\st*"(.+)",*(?:\sn\st)?(?:\s],)*\sn/g, textPost: "{{{$1}}}<br>"}\n\n\tvar tweeOutput = combinedJSON.replace(regex.titlesPre, regex.titlesPost);\n\ttweeOutput = tweeOutput.replace(regex.textPre, regex.textPost);\n\ttweeOutput = tweeOutput.replace(/({\sn)|(]\sn})/g, "")\n\n\treturn tweeOutput;\n}
window.tracery = {\n utilities : {}\n};\n\n(function () {/**\n * @author Kate Compton\n */\n\nfunction inQuotes(s) {\n return '"' + s + '"';\n};\n\nfunction parseAction(action) {\n return action;\n};\n\n// tag format\n// a thing to expand, plus actions\n\nfunction parseTag(tag) {\n var errors = [];\n var prefxns = [];\n var postfxns = [];\n\n var lvl = 0;\n var start = 0;\n\n var inPre = true;\n\n var symbol,\n mods;\n\n function nonAction(end) {\n if (start !== end) {\n var section = tag.substring(start, end);\n if (!inPre) {\n errors.push("multiple possible expansion symbols in tag!" + tag);\n } else {\n inPre = false;\n var split = section.split(".");\n symbol = split[0];\n mods = split.slice(1, split.length);\n }\n\n }\n start = end;\n };\n\n for (var i = 0; i < tag.length; i++) {\n var c = tag.charAt(i);\n\n switch(c) {\n case '[':\n if (lvl === 0) {\n nonAction(i);\n }\n\n lvl++;\n break;\n case ']':\n lvl--;\n if (lvl === 0) {\n var section = tag.substring(start + 1, i);\n if (inPre)\n prefxns.push(parseAction(section));\n else\n postfxns.push(parseAction(section));\n start = i + 1;\n }\n break;\n\n default:\n if (lvl === 0) {\n\n }\n break;\n\n }\n }\n nonAction(i);\n\n if (lvl > 0) {\n var error = "Too many '[' in rule " + inQuotes(tag);\n errors.push(error);\n\n }\n\n if (lvl < 0) {\n var error = "Too many ']' in rule " + inQuotes(tag);\n errors.push(error);\n\n }\n\n return {\n preActions : prefxns,\n postActions : postfxns,\n symbol : symbol,\n mods : mods,\n raw : tag,\n errors : errors,\n };\n};\n\n// Split a rule into sections\nfunction parseRule(rule) {\n var sections = [];\n var errors = [];\n if (!( typeof rule == 'string' || rule instanceof String)) {\n errors.push("Cannot parse non-string rule " + rule);\n sections.errors = errors;\n return sections;\n }\n\n if (rule.length === 0) {\n return [];\n }\n\n var lvl = 0;\n var start = 0;\n var inTag = false;\n\n function createSection(end) {\n var section = rule.substring(start, end);\n if (section.length > 0) {\n if (inTag)\n sections.push(parseTag(section));\n else\n sections.push(section);\n }\n inTag = !inTag;\n start = end + 1;\n\n }\n\n for (var i = 0; i < rule.length; i++) {\n var c = rule.charAt(i);\n\n switch(c) {\n case '[':\n lvl++;\n break;\n case ']':\n lvl--;\n break;\n case '#':\n if (lvl === 0) {\n createSection(i);\n }\n break;\n default:\n break;\n\n }\n\n }\n\n if (lvl > 0) {\n var error = "Too many '[' in rule " + inQuotes(rule);\n errors.push(error);\n\n }\n\n if (lvl < 0) {\n var error = "Too many ']' in rule " + inQuotes(rule);\n errors.push(error);\n\n }\n\n if (inTag) {\n var error = "Odd number of '#' in rule " + inQuotes(rule);\n errors.push(error);\n }\n\n createSection(rule.length);\n sections.errors = errors;\n return sections;\n};\n\nfunction testParse(rule, shouldFail) {\n console.log("-------");\n console.log("Test parse rule: " + inQuotes(rule) + " " + shouldFail);\n var parsed = parseRule(rule);\n if (parsed.errors && parsed.errors.length > 0) {\n for (var i = 0; i < parsed.errors.length; i++) {\n console.log(parsed.errors[i]);\n }\n }\n \n\n}\n\nfunction testParseTag(tag, shouldFail) {\n console.log("-------");\n console.log("Test parse tag: " + inQuotes(tag) + " " + shouldFail);\n var parsed = parseTag(tag);\n if (parsed.errors && parsed.errors.length > 0) {\n for (var i = 0; i < parsed.errors.length; i++) {\n console.log(parsed.errors[i]);\n }\n }\n}\n\ntracery.testParse = testParse;\ntracery.testParseTag = testParseTag;\ntracery.parseRule = parseRule;\ntracery.parseTag = parseTag;\n\n\nfunction spacer(size) {\n var s = "";\n for (var i = 0; i < size * 3; i++) {\n s += " ";\n }\n return s;\n}\n\n/* Simple JavaScript Inheritance\n * By John Resig http://ejohn.org/\n * MIT Licensed.\n */\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\n// Inspired by base2 and Prototype\n(function() {\n var initializing = false,\n fnTest = /xyz/.test(function() { xyz;\n }) ? /\sb_super\sb/ : /.*/;\n\n // The base Class implementation (does nothing)\n this.Class = function() {\n };\n\n // Create a new Class that inherits from this class\n Class.extend = function(prop) {\n var _super = this.prototype;\n\n // Instantiate a base class (but only create the instance,\n // don't run the init constructor)\n initializing = true;\n var prototype = new this();\n initializing = false;\n\n // Copy the properties over onto the new prototype\n for (var name in prop) {\n // Check if we're overwriting an existing function\n prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn) {\n return function() {\n var tmp = this._super;\n\n // Add a new ._super() method that is the same method\n // but on the super-class\n this._super = _super[name];\n\n // The method only need to be bound temporarily, so we\n // remove it when we're done executing\n var ret = fn.apply(this, arguments);\n this._super = tmp;\n\n return ret;\n };\n })(name, prop[name]) : prop[name];\n }\n\n // The dummy class constructor\n function Class() {\n // All construction is actually done in the init method\n if (!initializing && this.init)\n this.init.apply(this, arguments);\n }\n\n // Populate our constructed prototype object\n Class.prototype = prototype;\n\n // Enforce the constructor to be what we expect\n Class.prototype.constructor = Class;\n\n // And make this class extendable\n Class.extend = arguments.callee;\n\n return Class;\n };\n})();\n\n/**\n * @author Kate\n */\n\nvar Rule = function(raw) {\n this.raw = raw;\n this.sections = parseRule(raw);\n\n};\n\nRule.prototype.getParsed = function() {\n if (!this.sections)\n this.sections = parseRule(raw);\n\n return this.sections;\n};\n\nRule.prototype.toString = function() {\n return this.raw;\n};\n\nRule.prototype.toJSONString = function() {\n return this.raw;\n};\n\n/**\n * @author Kate\n */\n\nvar RuleWeighting = Object.freeze({\n RED : 0,\n GREEN : 1,\n BLUE : 2\n});\n\nvar RuleSet = function(rules) {\n // is the rules obj an array? A RuleSet, or a string?\n if (rules.constructor === Array) {\n // make a copy\n rules = rules.slice(0, rules.length);\n } else if (rules.prototype === RuleSet) {\n // clone\n } else if ( typeof rules == 'string' || rules instanceof String) {\n var args = Array.prototype.slice.call(arguments);\n rules = args;\n } else {\n console.log(rules);\n throw ("creating ruleset with unknown object type!");\n }\n\n // create rules and their use counts\n\n this.rules = rules;\n this.parseAll();\n\n this.uses = [];\n this.startUses = [];\n this.totalUses = 0;\n for (var i = 0; i < this.rules.length; i++) {\n this.uses[i] = 0;\n this.startUses[i] = this.uses[i];\n this.totalUses += this.uses[i];\n }\n\n};\n\n//========================================================\n// Iterating over rules\n\nRuleSet.prototype.parseAll = function(fxn) {\n for (var i = 0; i < this.rules.length; i++) {\n if (this.rules[i].prototype !== Rule)\n this.rules[i] = new Rule(this.rules[i]);\n }\n\n};\n\n//========================================================\n// Iterating over rules\n\nRuleSet.prototype.mapRules = function(fxn) {\n return this.rules.map(function(rule, index) {\n return fxn(rule, index);\n });\n};\n\nRuleSet.prototype.applyToRules = function(fxn) {\n for (var i = 0; i < this.rules.length; i++) {\n fxn(this.rules[i], i);\n }\n};\n//========================================================\nRuleSet.prototype.get = function() {\n var index = this.getIndex();\n\n return this.rules[index];\n};\n\nRuleSet.prototype.getRandomIndex = function() {\n return Math.floor(this.uses.length * Math.random());\n};\n\nRuleSet.prototype.getIndex = function() {\n // Weighted distribution\n // Imagine a bar of length 1, how to divide the length\n // s.t. a random dist will result in the dist we want?\n\n var index = this.getRandomIndex();\n // What if the uses determine the chance of rerolling?\n\n var median = this.totalUses / this.uses.length;\n\n var count = 0;\n while (this.uses[index] > median && count < 20) {\n index = this.getRandomIndex();\n count++;\n }\n\n // reroll more likely if index is too much higher\n\n return index;\n};\n\nRuleSet.prototype.decayUses = function(pct) {\n this.totalUses = 0;\n for (var i = 0; i < this.uses; i++) {\n\n this.uses[index] *= 1 - pct;\n this.totalUses += this.uses[index];\n }\n};\n\nRuleSet.prototype.testRandom = function() {\n console.log("Test random");\n var counts = [];\n for (var i = 0; i < this.uses.length; i++) {\n counts[i] = 0;\n }\n\n var testCount = 10 * this.uses.length;\n for (var i = 0; i < testCount; i++) {\n\n var index = this.getIndex();\n this.uses[index] += 1;\n\n counts[index]++;\n this.decayUses(.1);\n }\n\n for (var i = 0; i < this.uses.length; i++) {\n console.log(i + ":\st" + counts[i] + " \st" + this.uses[i]);\n }\n};\n\nRuleSet.prototype.getSaveRules = function() {\n var jsonRules = this.rules.map(function(rule) {\n return rule.toJSONString();\n });\n\n return jsonRules;\n};\n\n/**\n * @author Kate Compton\n */\n\nvar Action = function(node, raw) {\n\n this.node = node;\n this.grammar = node.grammar;\n this.raw = raw;\n\n};\n\nAction.prototype.activate = function() {\n\n var node = this.node;\n node.actions.push(this);\n\n // replace any hashtags\n this.amended = this.grammar.flatten(this.raw);\n\n var parsed = parseTag(this.amended);\n var subActionRaw = parsed.preActions;\n if (subActionRaw && subActionRaw.length > 0) {\n this.subactions = subActionRaw.map(function(action) {\n return new Action(node, action);\n });\n\n }\n\n if (parsed.symbol) {\n var split = parsed.symbol.split(":");\n\n if (split.length === 2) {\n this.push = {\n symbol : split[0],\n\n // split into multiple rules\n rules : split[1].split(","),\n };\n // push\n node.grammar.pushRules(this.push.symbol, this.push.rules);\n\n } else\n throw ("Unknown action: " + parsed.symbol);\n }\n\n if (this.subactions) {\n for (var i = 0; i < this.subactions.length; i++) {\n this.subactions[i].activate();\n }\n }\n\n};\n\nAction.prototype.deactivate = function() {\n if (this.subactions) {\n for (var i = 0; i < this.subactions.length; i++) {\n this.subactions[i].deactivate();\n }\n }\n\n if (this.push) {\n this.node.grammar.popRules(this.push.symbol, this.push.rules);\n }\n};\n\n/**\n * @author Kate Compton\n */\n\nvar isConsonant = function(c) {\n c = c.toLowerCase();\n switch(c) {\n case 'a':\n return false;\n case 'e':\n return false;\n case 'i':\n return false;\n case 'o':\n return false;\n case 'u':\n return false;\n\n }\n return true;\n};\n\nfunction endsWithConY(s) {\n if (s.charAt(s.length - 1) === 'y') {\n return isConsonant(s.charAt(s.length - 2));\n }\n return false;\n};\n\nvar universalModifiers = {\n capitalizeAll : function(s) {\n return s.replace(/(?:^|\ss)\sS/g, function(a) {\n return a.toUpperCase();\n });\n\n },\n\n capitalize : function(s) {\n return s.charAt(0).toUpperCase() + s.slice(1);\n\n },\n\n inQuotes : function(s) {\n return '"' + s + '"';\n },\n\n comma : function(s) {\n var last = s.charAt(s.length - 1);\n if (last === ",")\n return s;\n if (last === ".")\n return s;\n if (last === "?")\n return s;\n if (last === "!")\n return s;\n return s + ",";\n },\n\n beeSpeak : function(s) {\n // s = s.replace("s", "zzz");\n\n s = s.replace(/s/, 'zzz');\n return s;\n },\n\n a : function(s) {\n if (!isConsonant(s.charAt()))\n return "an " + s;\n return "a " + s;\n\n },\n\n s : function(s) {\n\n var last = s.charAt(s.length - 1);\n\n switch(last) {\n case 'y':\n\n // rays, convoys\n if (!isConsonant(s.charAt(s.length - 2))) {\n return s + "s";\n }\n // harpies, cries\n else {\n return s.slice(0, s.length - 1) + "ies";\n }\n break;\n\n // oxen, boxen, foxen\n case 'x':\n return s.slice(0, s.length - 1) + "en";\n case 'z':\n return s.slice(0, s.length - 1) + "es";\n case 'h':\n return s.slice(0, s.length - 1) + "es";\n\n default:\n return s + "s";\n };\n\n },\n\n ed : function(s) {\n\n var index = s.indexOf(" ");\n var s = s;\n var rest = "";\n if (index > 0) {\n rest = s.substring(index, s.length);\n s = s.substring(0, index);\n\n }\n\n var last = s.charAt(s.length - 1);\n\n switch(last) {\n case 'y':\n\n // rays, convoys\n if (isConsonant(s.charAt(s.length - 2))) {\n return s.slice(0, s.length - 1) + "ied" + rest;\n\n }\n // harpies, cries\n else {\n return s + "ed" + rest;\n }\n break;\n case 'e':\n return s + "d" + rest;\n\n break;\n\n default:\n return s + "ed" + rest;\n };\n }\n};\n/**\n * @author Kate Compton\n */\n\n// A tracery expansion node\nvar nodeCount = 0;\n\nvar ExpansionNode = Class.extend({\n init : function() {\n this.depth = 0;\n this.id = nodeCount;\n nodeCount++;\n this.childText = "[[UNEXPANDED]]";\n },\n\n setParent : function(parent) {\n if (parent) {\n this.depth = parent.depth + 1;\n this.parent = parent;\n this.grammar = parent.grammar;\n }\n },\n\n expand : function() {\n // do nothing\n return "???";\n },\n\n expandChildren : function() {\n\n if (this.children) {\n this.childText = "";\n for (var i = 0; i < this.children.length; i++) {\n this.children[i].expand();\n this.childText += this.children[i].finalText;\n }\n this.finalText = this.childText;\n }\n\n },\n\n createChildrenFromSections : function(sections) {\n var root = this;\n this.children = sections.map(function(section) {\n\n if ( typeof section == 'string' || section instanceof String) {\n // Plaintext\n return new TextNode(root, section);\n } else {\n return new TagNode(root, section);\n }\n });\n }\n});\n\nvar RootNode = ExpansionNode.extend({\n init : function(grammar, rawRule) {\n this._super();\n this.grammar = grammar;\n this.parsedRule = parseRule(rawRule);\n },\n\n expand : function() {\n var root = this;\n this.createChildrenFromSections(this.parsedRule);\n\n // expand the children\n this.expandChildren();\n },\n});\n\nvar TagNode = ExpansionNode.extend({\n init : function(parent, parsedTag) {\n this._super();\n\n if (!(parsedTag !== null && typeof parsedTag === 'object')) {\n if ( typeof parsedTag == 'string' || parsedTag instanceof String) {\n console.warn("Can't make tagNode from unparsed string!");\n parsedTag = parseTag(parsedTag);\n\n } else {\n console.log("Unknown tagNode input: ", parsedTag);\n throw ("Can't make tagNode from strange tag!");\n\n }\n }\n\n this.setParent(parent);\n $.extend(this, parsedTag);\n },\n\n expand : function() {\n if (tracery.outputExpansionTrace)\n console.log(r.sections);\n\n this.rule = this.grammar.getRule(this.symbol);\n\n this.actions = [];\n\n // Parse the rule if it hasn't been already\n this.createChildrenFromSections(this.rule.getParsed());\n\n // Do any pre-expansion actions!\n for (var i = 0; i < this.preActions.length; i++) {\n var action = new Action(this, this.preActions[i]);\n action.activate();\n }\n\n // Map each child section to a node\n if (!this.rule.sections)\n console.log(this.rule);\n\n this.expandChildren();\n\n for (var i = 0; i < this.actions.length; i++) {\n\n this.actions[i].deactivate();\n }\n\n this.finalText = this.childText;\n for (var i = 0; i < this.mods.length; i++) {\n this.finalText = this.grammar.applyMod(this.mods[i], this.finalText);\n }\n\n },\n\n toLabel : function() {\n return this.symbol;\n },\n toString : function() {\n return "TagNode '" + this.symbol + "' mods:" + this.mods + ", preactions:" + this.preActions + ", postactions" + this.postActions;\n }\n});\n\nvar TextNode = ExpansionNode.extend({\n isLeaf : true,\n init : function(parent, text) {\n this._super();\n\n this.setParent(parent);\n\n this.text = text;\n\n this.finalText = text;\n },\n expand : function() {\n // do nothing\n },\n\n toLabel : function() {\n return this.text;\n }\n});\n\n/**\n * @author Kate Compton\n */\n\nfunction Symbol(grammar, key) {\n this.grammar = grammar;\n this.key = key;\n this.currentRules = undefined;\n this.ruleSets = [];\n\n};\n\nSymbol.prototype.loadFrom = function(rules) {\n\n rules = this.wrapRules(rules);\n this.baseRules = rules;\n\n this.ruleSets.push(rules);\n this.currentRules = this.ruleSets[this.ruleSets.length - 1];\n\n};\n\n//========================================================\n// Iterating over rules\n\nSymbol.prototype.mapRules = function(fxn) {\n\n return this.currentRules.mapRules(fxn);\n};\n\nSymbol.prototype.applyToRules = function(fxn) {\n this.currentRules.applyToRules(fxn);\n};\n\n//==================================================\n// Rule pushpops\nSymbol.prototype.wrapRules = function(rules) {\n if (rules.prototype !== RuleSet) {\n if (Array.isArray(rules)) {\n return new RuleSet(rules);\n } else if ( typeof rules == 'string' || rules instanceof String) {\n return new RuleSet(rules);\n } else {\n throw ("Unknown rules type: " + rules);\n }\n }\n // already a ruleset\n return rules;\n};\n\nSymbol.prototype.pushRules = function(rules) {\n rules = this.wrapRules(rules);\n this.ruleSets.push(rules);\n this.currentRules = this.ruleSets[this.ruleSets.length - 1];\n};\n\nSymbol.prototype.popRules = function() {\n var exRules = this.ruleSets.pop();\n\n if (this.ruleSets.length === 0) {\n //console.warn("No more rules for " + this + "!");\n }\n this.currentRules = this.ruleSets[this.ruleSets.length - 1];\n};\n\n// Clear everything and set the rules\nSymbol.prototype.setRules = function(rules) {\n\n rules = this.wrapRules(rules);\n this.ruleSets = [rules];\n this.currentRules = rules;\n\n};\n\nSymbol.prototype.addRule = function(rule) {\n this.currentRules.addRule(seed);\n};\n\n//========================================================\n// selection\n\nSymbol.prototype.select = function() {\n this.isSelected = true;\n\n};\n\nSymbol.prototype.deselect = function() {\n this.isSelected = false;\n};\n\n//==================================================\n// Getters\n\nSymbol.prototype.getRule = function(seed) {\n return this.currentRules.get(seed);\n};\n\n//==================================================\n\nSymbol.prototype.toString = function() {\n return this.key + ": " + this.currentRules + "(overlaying " + (this.ruleSets.length - 1) + ")";\n};\nSymbol.prototype.toJSON = function() {\n\n var rules = this.baseRules.rules.map(function(rule) {\n return '"' + rule.raw + '"';\n });\n return '"' + this.key + '"' + ": [" + rules.join(", ") + "]";\n};\n\nSymbol.prototype.toHTML = function(useSpans) {\n var keySpan = '"' + this.key + '"';\n if (useSpans)\n keySpan = "<span class='symbol symbol_" + this.key + "'>" + keySpan + "</span>";\n\n var rules = this.baseRules.rules.map(function(rule) {\n var s = '"' + rule.raw + '"';\n if (useSpans)\n s = "<span class='rule'>" + s + "</span>";\n return s;\n });\n return keySpan + ": [" + rules.join(", ") + "]";\n};\n\n/**\n * @author Kate Compton\n */\n\nfunction Grammar() {\n this.clear();\n};\n\nGrammar.prototype.clear = function() {\n // Symbol library\n this.symbols = {};\n \n this.errors = [];\n \n // Modifier library\n this.modifiers = {};\n\n // add the universal mods\n for (var mod in universalModifiers) {\n if (universalModifiers.hasOwnProperty(mod))\n this.modifiers[mod] = universalModifiers[mod];\n }\n};\n//========================================================\n// Loading\n\nGrammar.prototype.loadFrom = function(obj) {\n var symbolSrc;\n\n this.clear();\n\n if (obj.symbols !== undefined) {\n symbolSrc = obj.symbols;\n } else {\n symbolSrc = obj;\n }\n\n // get all json keys\n var keys = Object.keys(symbolSrc);\n\n this.symbolNames = [];\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n this.symbolNames.push(key);\n\n this.symbols[key] = new Symbol(this, key);\n this.symbols[key].loadFrom(symbolSrc[key]);\n }\n\n};\n\nGrammar.prototype.toHTML = function(useSpans) {\n // get all json keys\n var keys = Object.keys(this.symbols);\n\n this.symbolNames = [];\n\n var lines = [];\n\n var count = 0;\n for (var i = 0; i < keys.length; i++) {\n\n var key = keys[i];\n var symbol = this.symbols[key];\n\n if (symbol && symbol.baseRules) {\n\n lines.push(" " + this.symbols[key].toHTML(useSpans));\n\n }\n };\n\n var s;\n s = lines.join(",</p><p>");\n s = "{<p>" + s + "</p>}";\n return s;\n};\n\nGrammar.prototype.toJSON = function() {\n // get all json keys\n var keys = Object.keys(this.symbols);\n\n this.symbolNames = [];\n\n var lines = [];\n\n var count = 0;\n for (var i = 0; i < keys.length; i++) {\n\n var key = keys[i];\n var symbol = this.symbols[key];\n\n if (symbol && symbol.baseRules) {\n\n lines.push(" " + this.symbols[key].toJSON());\n\n }\n };\n\n var s;\n s = lines.join(",\sn");\n s = "{\sn" + s + "\sn}";\n return s;\n};\n\n//========================================================\n// selection\n\nGrammar.prototype.select = function() {\n this.isSelected = true;\n};\n\nGrammar.prototype.deselect = function() {\n this.isSelected = false;\n};\n\n//========================================================\n// Iterating over symbols\n\nGrammar.prototype.mapSymbols = function(fxn) {\n var symbols = this.symbols;\n return this.symbolNames.map(function(name) {\n return fxn(symbols[name], name);\n });\n};\n\nGrammar.prototype.applyToSymbols = function(fxn) {\n for (var i = 0; i < this.symbolNames.length; i++) {\n var key = this.symbolNames[i];\n fxn(this.symbols[key], key);\n }\n};\n\n//========================================================\nGrammar.prototype.addOrGetSymbol = function(key) {\n if (this.symbols[key] === undefined)\n this.symbols[key] = new Symbol(key);\n\n return this.symbols[key];\n};\n\nGrammar.prototype.pushRules = function(key, rules) {\n var symbol = this.addOrGetSymbol(key);\n symbol.pushRules(rules);\n};\n\nGrammar.prototype.popRules = function(key, rules) {\n var symbol = this.addOrGetSymbol(key);\n var popped = symbol.popRules();\n\n if (symbol.ruleSets.length === 0) {\n // remove symbol\n this.symbols[key] = undefined;\n }\n};\n\nGrammar.prototype.applyMod = function(modName, text) {\n if (!this.modifiers[modName]) {\n console.log(this.modifiers);\n throw ("Unknown mod: " + modName);\n }\n return this.modifiers[modName](text);\n};\n\n//============================================================\nGrammar.prototype.getRule = function(key, seed) {\n var symbol = this.symbols[key];\n if (symbol === undefined) {\n var r = new Rule("{{" + key + "}}");\n\n r.error = "Missing symbol " + key;\n return r;\n }\n\n var rule = symbol.getRule();\n if (rule === undefined) {\n var r = new Rule("[" + key + "]");\n console.log(r.sections);\n r.error = "Symbol " + key + " has no rule";\n return r;\n }\n\n return rule;\n};\n\n//============================================================\n// Expansions\nGrammar.prototype.expand = function(raw) {\n\n // Start a new tree\n var root = new RootNode(this, raw);\n\n root.expand();\n\n return root;\n};\n\nGrammar.prototype.flatten = function(raw) {\n\n // Start a new tree\n var root = new RootNode(this, raw);\n\n root.expand();\n\n return root.childText;\n};\n\n//===============\n\nGrammar.prototype.analyze = function() {\n this.symbolNames = [];\n for (var name in this.symbols) {\n if (this.symbols.hasOwnProperty(name)) {\n this.symbolNames.push(name);\n }\n }\n\n // parse every rule\n\n for (var i = 0; i < this.symbolNames.length; i++) {\n var key = this.symbolNames[i];\n var symbol = this.symbols[key];\n // parse all\n for (var j = 0; j < symbol.baseRules.length; j++) {\n var rule = symbol.baseRules[j];\n rule.parsed = tracery.parse(rule.raw);\n // console.log(rule);\n\n }\n }\n\n};\n\nGrammar.prototype.selectSymbol = function(key) {\n console.log(this);\n var symbol = this.get(key);\n};\n/**\n * @author Kate Compton\n\n */\n\ntracery.createGrammar = function(obj) {\n var grammar = new Grammar();\n grammar.loadFrom(obj);\n return grammar;\n};\n\ntracery.test = function() {\n\n console.log("==========================================");\n console.log("test tracery");\n\n // good\n tracery.testParse("", false);\n tracery.testParse("fooo", false);\n tracery.testParse("####", false);\n tracery.testParse("#[]#[]##", false);\n tracery.testParse("#someSymbol# and #someOtherSymbol#", false);\n tracery.testParse("#someOtherSymbol.cap.pluralize#", false);\n tracery.testParse("#[#do some things#]symbol.mod[someotherthings[and a function]]#", false);\n tracery.testParse("#[fxn][fxn][fxn[subfxn]]symbol[[fxn]]#", false);\n tracery.testParse("#[fxn][#fxn#][fxn[#subfxn#]]symbol[[fxn]]#", false);\n tracery.testParse("#hero# ate some #color# #animal.s#", false);\n tracery.testParseTag("[action]symbol.mod1.mod2[postAction]", false);\n\n // bad\n tracery.testParse("#someSymbol# and #someOtherSymbol", true);\n tracery.testParse("#[fxn][fxn][fxn[subfxn]]symbol[fxn]]#", true);\n\n // bad\n tracery.testParseTag("stuff[action]symbol.mod1.mod2[postAction]", true);\n tracery.testParseTag("[action]symbol.mod1.mod2[postAction]stuff", true);\n\n tracery.testParse("#hero# ate some #color# #animal.s#", true);\n tracery.testParse("#[#setPronouns#][#setOccupation#][hero:#name#]story#", true);\n\n};\n \n})();
jquery:on\nhash:off\nbookmark:on\nmodernizr:off\nundo:on\nobfuscate:off\nexitprompt:off\nblankcss:off\n
<<silently>>\nUses the parameter if one was passed. Then, checks for the $symbol variable. If neither is present, uses "origin". Clears $symbol at the end.\n\n<<if parameter(0)>>\n\t<<set $symbol to parameter(0)>>\n<<else>><<if $symbol>>\n\tNo need to do anything.\n<<else>>\n\t<<set $symbol to "origin">>\n<<endif>><<endif>>\n\n<<endsilently>><<print console.log("trace " + $symbol)>><<print tale.grammar.flatten("#" + $symbol + "#")>><<forget $symbol>>
// Returns an array of traces, each different from the one preceding it unless retrace() maxes out attempts.\n\nwindow.traceArray = function(symbol, num){\n\tvar output = [];\n\toutput.push( trace(symbol) );\n\n\tfor (var i = 1; i < num; i++) {\n\t\toutput.push( retrace(symbol, output[i-1]) );\n\t};\n\n\treturn output;\n}
<<twineceryInit>>\n<<traceryInit>>
String.prototype.contains = function(substring){\n\tif (substring.constructor === Array){\n\t\tfor (var i = 0; i < substring.length; i++){\n\t\t\tif(this.contains(substring[i])){\n\t\t\t\treturn substring[i]; // Non-empty string evaluates to true\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t} else {\n\t\treturn this.indexOf(substring) > 0;\n\t}\n}
// Returns a new version of a given expansion.\nwindow.retrace = function(symbol, old, maxAttempts){\n\tif(maxAttempts === undefined){\n\t\tmaxAttempts = 32;\n\t}\n\tif(!(maxAttempts > 1)){\n\t\tmaxAttempts = 1;\n\t}\n\t\n\tvar output = "", attempts = 0;\n\tdo{\n\t\toutput = trace(symbol);\n\t\tattempts++;\n\t}while(output == old && attempts < maxAttempts)\n\n//\tconsole.log("retrace:"\n//\t\t\t\t+ "\sn\stold: " + old\n//\t\t\t\t+ "\sn\stnew: " + output\n//\t\t\t\t+ "\sn\stattempts: " + attempts)\n\treturn output;\n}
<<tracelink "origin">>\n
body {\n margin: 2%;\n}\n#passages{\n margin: 0;\n padding: 0;\n border: 0;\n width:96%;\n margin: auto;\n}\n.passage {\n font-size:6em; \n color: #888;\n text-shadow: #888 0 0 0.05em;\n}\n@media screen and (max-width: 960px) {\n .passage {\n font-size: 4em;\n }\n}\n@media screen and (max-width: 640px) {\n .passage {\n font-size: 3em;\n }\n}\na.internalLink, a.externalLink {\n color: #eee;\n text-shadow: #eee 0 0 0.07em;\n}\na.internalLink:hover, a.externalLink:hover {\n color: #fff;\n text-decoration: none;\n text-shadow: #fff 0 0 0.09em;\n}\n#sidebar {\n\tdisplay:none;\n}\nbody\n{\n background-color: #660066;\n}
window.grammar = function(rule){\n\treturn tale.get(rule).text.split('\sn');\n}
// Expands a symbol and returns the output.\nwindow.trace = function(symbol){\n\tif(symbol === undefined){\n\t\tsymbol = "origin";\n\t}\n\tif(tale.grammar === undefined){\n\t\tconsole.log("Couldn't find the grammar object.");\n\t\treturn "ERROR: Grammar object not found.";\n\t}\n\n\tvar output = tale.grammar.flatten("#" + symbol + "#")\t\n//\tconsole.log(symbol + " expands to:\sn" + output);\n\treturn output;\n}
// This is a slightly modified version of Leon Arnott's cyclinglink macro.\n\nversion.extensions.tracelinkMacro = {\n\tmajor: 0,\n\tminor: 1,\n\trevision: 0\n};\nmacros.tracelink = {\n\thandler: function(a, b, c) {\n\t\tvar rl = "traceLink";\n\n\t\tfunction toggleText(w) {\n\t\t\tw.classList.remove("traceLinkInit");\n\t\t\tw.classList.toggle(rl + "Enabled");\n\t\t\tw.classList.toggle(rl + "Disabled");\n\t\t\tw.style.display = ((w.style.display == "none") ? "inline" : "none")\n\t\t}\n\t\tswitch (c[c.length - 1]) {\n\t\t\tcase "end":\n\t\t\t\tvar end = true;\n\t\t\t\tc.pop();\n\t\t\t\tbreak;\n\t\t\tcase "out":\n\t\t\t\tvar out = true;\n\t\t\t\tc.pop();\n\t\t\t\tbreak\n\t\t}\n\t\tvar v = "";\n\t\tif (c.length && c[0][0] == "$") {\n\t\t\tv = c[0].slice(1);\n\t\t\tc.shift()\n\t\t}\n\t\tvar h = state.history[0].variables;\n\t\tif (out && h[v] === "") {\n\t\t\treturn\n\t\t}\n\t\tvar l = Wikifier.createInternalLink(a, null);\n\t\tl.className = "internalLink cyclingLink";\n\t\tl.setAttribute("data-cycle", 0);\n\n\t\t// Prebake a bunch of traces and use those as our links to cycle through.\n\t\tc = traceArray(c[0], 64);\n\n\t\tfor (var i = 0; i < c.length; i++) {\n\t\t\tvar on = (i == Math.max(c.indexOf(h[v]), 0));\n\t\t\tvar d = insertElement(null, "span", null, "traceLinkInit traceLink" + ((on) ? "En" : "Dis") + "abled");\n\t\t\tif (on) {\n\t\t\t\th[v] = c[i];\n\t\t\t\tl.setAttribute("data-cycle", i)\n\t\t\t} else {\n\t\t\t\td.style.display = "none"\n\t\t\t}\n\t\t\tinsertText(d, c[i]);\n\t\t\tif (on && end && i == c.length - 1) {\n\t\t\t\tl.parentNode.replaceChild(d, l)\n\t\t\t} else {\n\t\t\t\tl.appendChild(d)\n\t\t\t}\n\t\t}\n\t\tl.onclick = function() {\n\t\t\tvar t = this.childNodes;\n\t\t\tvar u = this.getAttribute("data-cycle") - 0;\n\t\t\tvar m = t.length;\n\t\t\ttoggleText(t[u]);\n\t\t\tu = (u + 1);\n\t\t\tif (!(out && u == m)) {\n\t\t\t\tu %= m;\n\t\t\t\tif (v) {\n\t\t\t\t\th[v] = c[u]\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\th[v] = ""\n\t\t\t}\n\t\t\tif ((end || out) && u == m - (end ? 1 : 0)) {\n\t\t\t\tif (end) {\n\t\t\t\t\tvar n = this.removeChild(t[u]);\n\t\t\t\t\tn.className = rl + "End";\n\t\t\t\t\tn.style.display = "inline";\n\t\t\t\t\tthis.parentNode.replaceChild(n, this)\n\t\t\t\t} else {\n\t\t\t\t\tthis.parentNode.removeChild(this);\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttoggleText(t[u]);\n\t\t\tthis.setAttribute("data-cycle", u)\n\t\t}\n\t}\n};
Automata Winery
Nora Reed with help from Vin Tanner
<<if !tale.grammar>>\n\t<<if tracery>>\n\t\t<<set tale.grammar = tracery.createGrammar(tale.story.data)>>\n\t\t<<print console.log("grammar: ", tale.grammar)>>\n\t<<else>>\n\t\t<<print console.log("grammar instantiation failed")>>\n\t<<endif>>\n<<endif>>