7 package com.google.appinventor.components.runtime;
9 import android.content.Context;
10 import android.content.Intent;
12 import android.os.Bundle;
13 import android.os.Looper;
15 import android.util.Log;
17 import android.view.Menu;
18 import android.view.MenuItem;
19 import android.view.MenuItem.OnMenuItemClickListener;
21 import android.widget.Toast;
37 import dalvik.system.DexClassLoader;
39 import gnu.expr.Language;
42 import java.io.FileNotFoundException;
43 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.HashSet;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Random;
52 import kawa.standard.Scheme;
64 private static final String LOG_TAG =
ReplForm.class.getSimpleName();
67 private String replAssetDir;
68 private String replCompDir;
69 private boolean IsUSBRepl =
false;
70 private boolean assetsLoaded =
false;
72 private Object replResult =
null;
73 private String replResultFormName =
null;
74 private List<String> loadedExternalDexs;
80 private static final String SPLASH_ACTIVITY_CLASS =
SplashActivity.class
89 Language scheme = Scheme.getInstance(
"scheme");
92 gnu.expr.ModuleExp.mustNeverCompile();
95 private void adoptMainThreadClassLoader() {
96 ClassLoader mainClassLoader = Looper.getMainLooper().getThread().getContextClassLoader();
97 Thread myThread = Thread.currentThread();
98 if (myThread.getContextClassLoader() != mainClassLoader) {
99 myThread.setContextClassLoader(mainClassLoader);
103 public void eval(
final String sexp) {
104 runOnUiThread(
new Runnable() {
105 @Override
public void run() {
107 adoptMainThreadClassLoader();
108 if (sexp.equals(
"#DONE#")) {
113 }
catch (Throwable e) {
114 Log.e(LOG_TAG,
"Exception in scheme processing", e);
123 Log.d(LOG_TAG,
"onCreate");
125 replCompDir = replAssetDir +
"external_comps/";
126 super.onCreate(icicle);
127 loadedExternalDexs =
new ArrayList<String>();
128 Intent intent = getIntent();
129 processExtrasAndData(intent,
false);
134 void onCreateFinish() {
135 super.onCreateFinish();
136 Log.d(LOG_TAG,
"onCreateFinish() Called in Repl");
141 if (!
isEmulator() && AppInventorFeatures.doCompanionSplashScreen())
143 Intent webviewIntent =
new Intent(Intent.ACTION_MAIN);
147 Intent intent = getIntent();
148 Log.d(LOG_TAG,
"Intent = " + intent);
149 final String data = intent.getDataString();
151 Log.d(LOG_TAG,
"Got data = " + data);
153 Log.d(LOG_TAG,
"Did not receive any data");
156 if (data !=
null && (data.startsWith(
"aicompanion"))) {
159 public void onInitialize() {
160 startChromebook(data);
179 if (httpdServer !=
null) {
197 Log.d(LOG_TAG,
"formName is now " +
formName);
206 Log.d(LOG_TAG,
"setResult: " + result);
214 runOnUiThread(
new Runnable() {
216 String message =
"Closing forms is not currently supported during development.";
217 Toast.makeText(
ReplForm.this, message, Toast.LENGTH_LONG).show();
229 super.onCreateOptionsMenu(menu);
236 MenuItem showSettingsItem = menu.add(Menu.NONE, Menu.NONE, 3,
237 "Settings").setOnMenuItemClickListener(
new OnMenuItemClickListener() {
239 public boolean onMenuItemClick(MenuItem item) {
244 showSettingsItem.setIcon(android.R.drawable.sym_def_app_icon);
251 MenuItem showSettingsItem = menu.add(Menu.NONE, Menu.NONE, 4,
252 "Send Error Report").setOnMenuItemClickListener(
new OnMenuItemClickListener() {
254 public boolean onMenuItemClick(MenuItem item) {
255 String reportId = genReportId();
258 "<br />Use this ID when reporting this error.",
"Error Report Id",
"OK");
262 showSettingsItem.setIcon(android.R.drawable.stat_sys_warning);
267 super.onNewIntent(intent);
268 Log.d(LOG_TAG,
"onNewIntent Called");
269 processExtrasAndData(intent,
true);
270 String data = intent.getDataString();
271 if (data !=
null && (data.startsWith(
"aicompanion"))) {
272 startChromebook(data);
276 void HandleReturnValues() {
277 Log.d(LOG_TAG,
"HandleReturnValues() Called, replResult = " + replResult);
278 if (replResult !=
null) {
280 Log.d(LOG_TAG,
"Called OtherScreenClosed");
285 private void processExtrasAndData(Intent intent,
boolean restart) {
286 Bundle extras = intent.getExtras();
287 if (extras !=
null) {
288 Log.d(LOG_TAG,
"extras: " + extras);
289 Iterator<String> keys = extras.keySet().iterator();
290 while (keys.hasNext()) {
291 Log.d(LOG_TAG,
"Extra Key: " + keys.next());
294 String data = intent.getDataString();
295 if (data !=
null && (data.startsWith(
"aicompanion"))) {
299 if ((extras !=
null) && extras.getBoolean(
"rundirect")) {
300 Log.d(LOG_TAG,
"processExtrasAndData rundirect is true and restart is " + restart);
305 if (httpdServer !=
null) {
330 private void startChromebook(String data) {
331 String code = data.substring(data.indexOf(
"//comp/") + 7);
332 PhoneStatus status =
new PhoneStatus(
this);
334 code = status.setHmacSeedReturnCode(code,
"rendezvous.appinventor.mit.edu");
335 String ipAddress = PhoneStatus.GetWifiIpAddress();
336 int api = status.SdkLevel();
337 String version = status.GetVersionName();
338 String aid = status.InstallationId();
339 Log.d(LOG_TAG,
"InstallationId = " + aid);
340 Web web =
new Web(
this);
341 web.Url(
"http://rendezvous.appinventor.mit.edu/rendezvous/");
342 web.PostText(
"ipaddr=" + ipAddress +
"&port=9987&webrtc=true" +
343 "&version=" + version +
"&api=" + api +
"&aid=" +
344 aid +
"&installer=" + status.GetInstaller() +
"&r2=true&key=" + code);
345 status.startWebRTC(
"rendezvous.appinventor.mit.edu",
"OK");
359 if (httpdServer ==
null) {
362 httpdServer =
new AppInvHTTPD(8001,
new File(replAssetDir), secure,
this);
363 Log.i(LOG_TAG,
"started AppInvHTTPD");
365 }
catch (IOException ex) {
366 Log.e(LOG_TAG,
"Setting up NanoHTTPD: " + ex.toString());
371 private void checkAssetDir() {
378 private boolean checkComponentDir() {
379 File f =
new File(replCompDir);
405 Set<String> extensions =
new HashSet<String>(extensionNames);
408 File componentFolder =
new File(replCompDir);
409 if (!checkComponentDir()) {
410 Log.d(LOG_TAG,
"Unable to create components directory");
412 1,
"App Inventor",
"Unable to create component directory.");
416 ClassLoader parentClassLoader =
ReplForm.class.getClassLoader();
417 StringBuilder sb =
new StringBuilder();
418 loadedExternalDexs.clear();
419 for (
File compFolder : componentFolder.listFiles()) {
420 if (compFolder.isDirectory()) {
421 if (!extensions.contains(compFolder.getName()))
continue;
422 File component =
new File(compFolder.getPath() +
File.separator +
"classes.jar");
423 File loadComponent =
new File(compFolder.getPath() +
File.separator + compFolder.getName() +
".jar");
424 component.renameTo(loadComponent);
425 if (loadComponent.exists() && !loadedExternalDexs.contains(loadComponent.getName())) {
426 Log.d(LOG_TAG,
"Loading component dex " + loadComponent.getAbsolutePath());
427 loadedExternalDexs.add(loadComponent.getName());
428 sb.append(
File.pathSeparatorChar);
429 sb.append(loadComponent.getAbsolutePath());
433 DexClassLoader dexCloader =
new DexClassLoader(sb.substring(1), dexOutput.getAbsolutePath(),
434 null, parentClassLoader);
435 Thread.currentThread().setContextClassLoader(dexCloader);
436 Log.d(LOG_TAG, Thread.currentThread().toString());
437 Log.d(LOG_TAG, Looper.getMainLooper().getThread().toString());
438 Looper.getMainLooper().getThread().setContextClassLoader(dexCloader);
444 currentTheme = theme;
451 Log.d(LOG_TAG,
"returnRetvals: " + retvals);
456 if (webRTCNativeMgr ==
null) {
457 Log.i(LOG_TAG,
"No WebRTCNativeMgr!");
460 webRTCNativeMgr.
send(data);
464 webRTCNativeMgr = mgr;
468 schemeInterface.
eval(sexp);
473 return "file://" + replAssetDir + asset;
478 throws FileNotFoundException {
483 if (annotation !=
null && !annotation.
external()) {
487 String extensionId = component.getClass().getName();
488 String pkgPath =
null;
490 while (extensionId.contains(
".")) {
491 File dir =
new File(replCompDir + extensionId +
"/assets");
492 if (dir.exists() && dir.isDirectory()) {
494 pkgPath = dir.getAbsolutePath();
499 extensionId = extensionId.substring(0, extensionId.lastIndexOf(
'.'));
501 if (pkgPath !=
null) {
502 File result =
new File(pkgPath, asset);
503 Log.d(LOG_TAG,
"result = " + result.getAbsolutePath());
504 if (result.exists()) {
505 return "file://" + result.getAbsolutePath();
508 throw new FileNotFoundException();
521 private String genReportId() {
522 String [] words = {
"A",
"ABE",
"ACE",
"ACT",
"AD",
"ADA",
"ADD",
523 "AGO",
"AID",
"AIM",
"AIR",
"ALL",
"ALP",
"AM",
"AMY",
524 "AN",
"ANA",
"AND",
"ANN",
"ANT",
"ANY",
"APE",
"APS",
525 "APT",
"ARC",
"ARE",
"ARK",
"ARM",
"ART",
"AS",
"ASH",
526 "ASK",
"AT",
"ATE",
"AUG",
"AUK",
"AVE",
"AWE",
"AWK",
527 "AWL",
"AWN",
"AX",
"AYE",
"BAD",
"BAG",
"BAH",
"BAM",
528 "BAN",
"BAR",
"BAT",
"BAY",
"BE",
"BED",
"BEE",
"BEG",
529 "BEN",
"BET",
"BEY",
"BIB",
"BID",
"BIG",
"BIN",
"BIT",
530 "BOB",
"BOG",
"BON",
"BOO",
"BOP",
"BOW",
"BOY",
"BUB",
531 "BUD",
"BUG",
"BUM",
"BUN",
"BUS",
"BUT",
"BUY",
"BY",
532 "BYE",
"CAB",
"CAL",
"CAM",
"CAN",
"CAP",
"CAR",
"CAT",
533 "CAW",
"COD",
"COG",
"COL",
"CON",
"COO",
"COP",
"COT",
534 "COW",
"COY",
"CRY",
"CUB",
"CUE",
"CUP",
"CUR",
"CUT",
535 "DAB",
"DAD",
"DAM",
"DAN",
"DAR",
"DAY",
"DEE",
"DEL",
536 "DEN",
"DES",
"DEW",
"DID",
"DIE",
"DIG",
"DIN",
"DIP",
537 "DO",
"DOE",
"DOG",
"DON",
"DOT",
"DOW",
"DRY",
"DUB",
538 "DUD",
"DUE",
"DUG",
"DUN",
"EAR",
"EAT",
"ED",
"EEL",
539 "EGG",
"EGO",
"ELI",
"ELK",
"ELM",
"ELY",
"EM",
"END",
540 "EST",
"ETC",
"EVA",
"EVE",
"EWE",
"EYE",
"FAD",
"FAN",
541 "FAR",
"FAT",
"FAY",
"FED",
"FEE",
"FEW",
"FIB",
"FIG",
542 "FIN",
"FIR",
"FIT",
"FLO",
"FLY",
"FOE",
"FOG",
"FOR",
543 "FRY",
"FUM",
"FUN",
"FUR",
"GAB",
"GAD",
"GAG",
"GAL",
544 "GAM",
"GAP",
"GAS",
"GAY",
"GEE",
"GEL",
"GEM",
"GET",
545 "GIG",
"GIL",
"GIN",
"GO",
"GOT",
"GUM",
"GUN",
"GUS",
546 "GUT",
"GUY",
"GYM",
"GYP",
"HA",
"HAD",
"HAL",
"HAM",
547 "HAN",
"HAP",
"HAS",
"HAT",
"HAW",
"HAY",
"HE",
"HEM",
548 "HEN",
"HER",
"HEW",
"HEY",
"HI",
"HID",
"HIM",
"HIP",
549 "HIS",
"HIT",
"HO",
"HOB",
"HOC",
"HOE",
"HOG",
"HOP",
550 "HOT",
"HOW",
"HUB",
"HUE",
"HUG",
"HUH",
"HUM",
"HUT",
551 "I",
"ICY",
"IDA",
"IF",
"IKE",
"ILL",
"INK",
"INN",
552 "IO",
"ION",
"IQ",
"IRA",
"IRE",
"IRK",
"IS",
"IT",
553 "ITS",
"IVY",
"JAB",
"JAG",
"JAM",
"JAN",
"JAR",
"JAW",
554 "JAY",
"JET",
"JIG",
"JIM",
"JO",
"JOB",
"JOE",
"JOG",
555 "JOT",
"JOY",
"JUG",
"JUT",
"KAY",
"KEG",
"KEN",
"KEY",
556 "KID",
"KIM",
"KIN",
"KIT",
"LA",
"LAB",
"LAC",
"LAD",
557 "LAG",
"LAM",
"LAP",
"LAW",
"LAY",
"LEA",
"LED",
"LEE",
558 "LEG",
"LEN",
"LEO",
"LET",
"LEW",
"LID",
"LIE",
"LIN",
559 "LIP",
"LIT",
"LO",
"LOB",
"LOG",
"LOP",
"LOS",
"LOT",
560 "LOU",
"LOW",
"LOY",
"LUG",
"LYE",
"MA",
"MAC",
"MAD",
561 "MAE",
"MAN",
"MAO",
"MAP",
"MAT",
"MAW",
"MAY",
"ME",
562 "MEG",
"MEL",
"MEN",
"MET",
"MEW",
"MID",
"MIN",
"MIT",
563 "MOB",
"MOD",
"MOE",
"MOO",
"MOP",
"MOS",
"MOT",
"MOW",
564 "MUD",
"MUG",
"MUM",
"MY",
"NAB",
"NAG",
"NAN",
"NAP",
565 "NAT",
"NAY",
"NE",
"NED",
"NEE",
"NET",
"NEW",
"NIB",
566 "NIL",
"NIP",
"NIT",
"NO",
"NOB",
"NOD",
"NON",
"NOR",
567 "NOT",
"NOV",
"NOW",
"NU",
"NUN",
"NUT",
"O",
"OAF",
568 "OAK",
"OAR",
"OAT",
"ODD",
"ODE",
"OF",
"OFF",
"OFT",
569 "OH",
"OIL",
"OK",
"OLD",
"ON",
"ONE",
"OR",
"ORB",
570 "ORE",
"ORR",
"OS",
"OTT",
"OUR",
"OUT",
"OVA",
"OW",
571 "OWE",
"OWL",
"OWN",
"OX",
"PA",
"PAD",
"PAL",
"PAM",
572 "PAN",
"PAP",
"PAR",
"PAT",
"PAW",
"PAY",
"PEA",
"PEG",
573 "PEN",
"PEP",
"PER",
"PET",
"PEW",
"PHI",
"PI",
"PIE",
574 "PIN",
"PIT",
"PLY",
"PO",
"POD",
"POE",
"POP",
"POT",
575 "POW",
"PRO",
"PRY",
"PUB",
"PUG",
"PUN",
"PUP",
"PUT",
576 "QUO",
"RAG",
"RAM",
"RAN",
"RAP",
"RAT",
"RAW",
"RAY",
577 "REB",
"RED",
"REP",
"RET",
"RIB",
"RID",
"RIG",
"RIM",
578 "RIO",
"RIP",
"ROB",
"ROD",
"ROE",
"RON",
"ROT",
"ROW",
579 "ROY",
"RUB",
"RUE",
"RUG",
"RUM",
"RUN",
"RYE",
"SAC",
580 "SAD",
"SAG",
"SAL",
"SAM",
"SAN",
"SAP",
"SAT",
"SAW",
581 "SAY",
"SEA",
"SEC",
"SEE",
"SEN",
"SET",
"SEW",
"SHE",
582 "SHY",
"SIN",
"SIP",
"SIR",
"SIS",
"SIT",
"SKI",
"SKY",
583 "SLY",
"SO",
"SOB",
"SOD",
"SON",
"SOP",
"SOW",
"SOY",
584 "SPA",
"SPY",
"SUB",
"SUD",
"SUE",
"SUM",
"SUN",
"SUP",
585 "TAB",
"TAD",
"TAG",
"TAN",
"TAP",
"TAR",
"TEA",
"TED",
586 "TEE",
"TEN",
"THE",
"THY",
"TIC",
"TIE",
"TIM",
"TIN",
587 "TIP",
"TO",
"TOE",
"TOG",
"TOM",
"TON",
"TOO",
"TOP",
588 "TOW",
"TOY",
"TRY",
"TUB",
"TUG",
"TUM",
"TUN",
"TWO",
589 "UN",
"UP",
"US",
"USE",
"VAN",
"VAT",
"VET",
"VIE",
590 "WAD",
"WAG",
"WAR",
"WAS",
"WAY",
"WE",
"WEB",
"WED",
591 "WEE",
"WET",
"WHO",
"WHY",
"WIN",
"WIT",
"WOK",
"WON",
592 "WOO",
"WOW",
"WRY",
"WU",
"YAM",
"YAP",
"YAW",
"YE",
593 "YEA",
"YES",
"YET",
"YOU",
"ABED",
"ABEL",
"ABET",
"ABLE",
594 "ABUT",
"ACHE",
"ACID",
"ACME",
"ACRE",
"ACTA",
"ACTS",
"ADAM",
595 "ADDS",
"ADEN",
"AFAR",
"AFRO",
"AGEE",
"AHEM",
"AHOY",
"AIDA",
596 "AIDE",
"AIDS",
"AIRY",
"AJAR",
"AKIN",
"ALAN",
"ALEC",
"ALGA",
597 "ALIA",
"ALLY",
"ALMA",
"ALOE",
"ALSO",
"ALTO",
"ALUM",
"ALVA",
598 "AMEN",
"AMES",
"AMID",
"AMMO",
"AMOK",
"AMOS",
"AMRA",
"ANDY",
599 "ANEW",
"ANNA",
"ANNE",
"ANTE",
"ANTI",
"AQUA",
"ARAB",
"ARCH",
600 "AREA",
"ARGO",
"ARID",
"ARMY",
"ARTS",
"ARTY",
"ASIA",
"ASKS",
601 "ATOM",
"AUNT",
"AURA",
"AUTO",
"AVER",
"AVID",
"AVIS",
"AVON",
602 "AVOW",
"AWAY",
"AWRY",
"BABE",
"BABY",
"BACH",
"BACK",
"BADE",
603 "BAIL",
"BAIT",
"BAKE",
"BALD",
"BALE",
"BALI",
"BALK",
"BALL",
604 "BALM",
"BAND",
"BANE",
"BANG",
"BANK",
"BARB",
"BARD",
"BARE",
605 "BARK",
"BARN",
"BARR",
"BASE",
"BASH",
"BASK",
"BASS",
"BATE",
606 "BATH",
"BAWD",
"BAWL",
"BEAD",
"BEAK",
"BEAM",
"BEAN",
"BEAR",
607 "BEAT",
"BEAU",
"BECK",
"BEEF",
"BEEN",
"BEER",
"BEET",
"BELA",
608 "BELL",
"BELT",
"BEND",
"BENT",
"BERG",
"BERN",
"BERT",
"BESS",
609 "BEST",
"BETA",
"BETH",
"BHOY",
"BIAS",
"BIDE",
"BIEN",
"BILE",
610 "BILK",
"BILL",
"BIND",
"BING",
"BIRD",
"BITE",
"BITS",
"BLAB",
611 "BLAT",
"BLED",
"BLEW",
"BLOB",
"BLOC",
"BLOT",
"BLOW",
"BLUE",
612 "BLUM",
"BLUR",
"BOAR",
"BOAT",
"BOCA",
"BOCK",
"BODE",
"BODY",
613 "BOGY",
"BOHR",
"BOIL",
"BOLD",
"BOLO",
"BOLT",
"BOMB",
"BONA",
614 "BOND",
"BONE",
"BONG",
"BONN",
"BONY",
"BOOK",
"BOOM",
"BOON",
615 "BOOT",
"BORE",
"BORG",
"BORN",
"BOSE",
"BOSS",
"BOTH",
"BOUT",
616 "BOWL",
"BOYD",
"BRAD",
"BRAE",
"BRAG",
"BRAN",
"BRAY",
"BRED",
617 "BREW",
"BRIG",
"BRIM",
"BROW",
"BUCK",
"BUDD",
"BUFF",
"BULB",
618 "BULK",
"BULL",
"BUNK",
"BUNT",
"BUOY",
"BURG",
"BURL",
"BURN",
619 "BURR",
"BURT",
"BURY",
"BUSH",
"BUSS",
"BUST",
"BUSY",
"BYTE",
620 "CADY",
"CAFE",
"CAGE",
"CAIN",
"CAKE",
"CALF",
"CALL",
"CALM",
621 "CAME",
"CANE",
"CANT",
"CARD",
"CARE",
"CARL",
"CARR",
"CART",
622 "CASE",
"CASH",
"CASK",
"CAST",
"CAVE",
"CEIL",
"CELL",
"CENT",
623 "CERN",
"CHAD",
"CHAR",
"CHAT",
"CHAW",
"CHEF",
"CHEN",
"CHEW",
624 "CHIC",
"CHIN",
"CHOU",
"CHOW",
"CHUB",
"CHUG",
"CHUM",
"CITE",
625 "CITY",
"CLAD",
"CLAM",
"CLAN",
"CLAW",
"CLAY",
"CLOD",
"CLOG",
626 "CLOT",
"CLUB",
"CLUE",
"COAL",
"COAT",
"COCA",
"COCK",
"COCO",
627 "CODA",
"CODE",
"CODY",
"COED",
"COIL",
"COIN",
"COKE",
"COLA",
628 "COLD",
"COLT",
"COMA",
"COMB",
"COME",
"COOK",
"COOL",
"COON",
629 "COOT",
"CORD",
"CORE",
"CORK",
"CORN",
"COST",
"COVE",
"COWL",
630 "CRAB",
"CRAG",
"CRAM",
"CRAY",
"CREW",
"CRIB",
"CROW",
"CRUD",
631 "CUBA",
"CUBE",
"CUFF",
"CULL",
"CULT",
"CUNY",
"CURB",
"CURD",
632 "CURE",
"CURL",
"CURT",
"CUTS",
"DADE",
"DALE",
"DAME",
"DANA",
633 "DANE",
"DANG",
"DANK",
"DARE",
"DARK",
"DARN",
"DART",
"DASH",
634 "DATA",
"DATE",
"DAVE",
"DAVY",
"DAWN",
"DAYS",
"DEAD",
"DEAF",
635 "DEAL",
"DEAN",
"DEAR",
"DEBT",
"DECK",
"DEED",
"DEEM",
"DEER",
636 "DEFT",
"DEFY",
"DELL",
"DENT",
"DENY",
"DESK",
"DIAL",
"DICE",
637 "DIED",
"DIET",
"DIME",
"DINE",
"DING",
"DINT",
"DIRE",
"DIRT",
638 "DISC",
"DISH",
"DISK",
"DIVE",
"DOCK",
"DOES",
"DOLE",
"DOLL",
639 "DOLT",
"DOME",
"DONE",
"DOOM",
"DOOR",
"DORA",
"DOSE",
"DOTE",
640 "DOUG",
"DOUR",
"DOVE",
"DOWN",
"DRAB",
"DRAG",
"DRAM",
"DRAW",
641 "DREW",
"DRUB",
"DRUG",
"DRUM",
"DUAL",
"DUCK",
"DUCT",
"DUEL",
642 "DUET",
"DUKE",
"DULL",
"DUMB",
"DUNE",
"DUNK",
"DUSK",
"DUST",
643 "DUTY",
"EACH",
"EARL",
"EARN",
"EASE",
"EAST",
"EASY",
"EBEN",
644 "ECHO",
"EDDY",
"EDEN",
"EDGE",
"EDGY",
"EDIT",
"EDNA",
"EGAN",
645 "ELAN",
"ELBA",
"ELLA",
"ELSE",
"EMIL",
"EMIT",
"EMMA",
"ENDS",
646 "ERIC",
"EROS",
"EVEN",
"EVER",
"EVIL",
"EYED",
"FACE",
"FACT",
647 "FADE",
"FAIL",
"FAIN",
"FAIR",
"FAKE",
"FALL",
"FAME",
"FANG",
648 "FARM",
"FAST",
"FATE",
"FAWN",
"FEAR",
"FEAT",
"FEED",
"FEEL",
649 "FEET",
"FELL",
"FELT",
"FEND",
"FERN",
"FEST",
"FEUD",
"FIEF",
650 "FIGS",
"FILE",
"FILL",
"FILM",
"FIND",
"FINE",
"FINK",
"FIRE",
651 "FIRM",
"FISH",
"FISK",
"FIST",
"FITS",
"FIVE",
"FLAG",
"FLAK",
652 "FLAM",
"FLAT",
"FLAW",
"FLEA",
"FLED",
"FLEW",
"FLIT",
"FLOC",
653 "FLOG",
"FLOW",
"FLUB",
"FLUE",
"FOAL",
"FOAM",
"FOGY",
"FOIL",
654 "FOLD",
"FOLK",
"FOND",
"FONT",
"FOOD",
"FOOL",
"FOOT",
"FORD",
655 "FORE",
"FORK",
"FORM",
"FORT",
"FOSS",
"FOUL",
"FOUR",
"FOWL",
656 "FRAU",
"FRAY",
"FRED",
"FREE",
"FRET",
"FREY",
"FROG",
"FROM",
657 "FUEL",
"FULL",
"FUME",
"FUND",
"FUNK",
"FURY",
"FUSE",
"FUSS",
658 "GAFF",
"GAGE",
"GAIL",
"GAIN",
"GAIT",
"GALA",
"GALE",
"GALL",
659 "GALT",
"GAME",
"GANG",
"GARB",
"GARY",
"GASH",
"GATE",
"GAUL",
660 "GAUR",
"GAVE",
"GAWK",
"GEAR",
"GELD",
"GENE",
"GENT",
"GERM",
661 "GETS",
"GIBE",
"GIFT",
"GILD",
"GILL",
"GILT",
"GINA",
"GIRD",
662 "GIRL",
"GIST",
"GIVE",
"GLAD",
"GLEE",
"GLEN",
"GLIB",
"GLOB",
663 "GLOM",
"GLOW",
"GLUE",
"GLUM",
"GLUT",
"GOAD",
"GOAL",
"GOAT",
664 "GOER",
"GOES",
"GOLD",
"GOLF",
"GONE",
"GONG",
"GOOD",
"GOOF",
665 "GORE",
"GORY",
"GOSH",
"GOUT",
"GOWN",
"GRAB",
"GRAD",
"GRAY",
666 "GREG",
"GREW",
"GREY",
"GRID",
"GRIM",
"GRIN",
"GRIT",
"GROW",
667 "GRUB",
"GULF",
"GULL",
"GUNK",
"GURU",
"GUSH",
"GUST",
"GWEN",
668 "GWYN",
"HAAG",
"HAAS",
"HACK",
"HAIL",
"HAIR",
"HALE",
"HALF",
669 "HALL",
"HALO",
"HALT",
"HAND",
"HANG",
"HANK",
"HANS",
"HARD",
670 "HARK",
"HARM",
"HART",
"HASH",
"HAST",
"HATE",
"HATH",
"HAUL",
671 "HAVE",
"HAWK",
"HAYS",
"HEAD",
"HEAL",
"HEAR",
"HEAT",
"HEBE",
672 "HECK",
"HEED",
"HEEL",
"HEFT",
"HELD",
"HELL",
"HELM",
"HERB",
673 "HERD",
"HERE",
"HERO",
"HERS",
"HESS",
"HEWN",
"HICK",
"HIDE",
674 "HIGH",
"HIKE",
"HILL",
"HILT",
"HIND",
"HINT",
"HIRE",
"HISS",
675 "HIVE",
"HOBO",
"HOCK",
"HOFF",
"HOLD",
"HOLE",
"HOLM",
"HOLT",
676 "HOME",
"HONE",
"HONK",
"HOOD",
"HOOF",
"HOOK",
"HOOT",
"HORN",
677 "HOSE",
"HOST",
"HOUR",
"HOVE",
"HOWE",
"HOWL",
"HOYT",
"HUCK",
678 "HUED",
"HUFF",
"HUGE",
"HUGH",
"HUGO",
"HULK",
"HULL",
"HUNK",
679 "HUNT",
"HURD",
"HURL",
"HURT",
"HUSH",
"HYDE",
"HYMN",
"IBIS",
680 "ICON",
"IDEA",
"IDLE",
"IFFY",
"INCA",
"INCH",
"INTO",
"IONS",
681 "IOTA",
"IOWA",
"IRIS",
"IRMA",
"IRON",
"ISLE",
"ITCH",
"ITEM",
682 "IVAN",
"JACK",
"JADE",
"JAIL",
"JAKE",
"JANE",
"JAVA",
"JEAN",
683 "JEFF",
"JERK",
"JESS",
"JEST",
"JIBE",
"JILL",
"JILT",
"JIVE",
684 "JOAN",
"JOBS",
"JOCK",
"JOEL",
"JOEY",
"JOHN",
"JOIN",
"JOKE",
685 "JOLT",
"JOVE",
"JUDD",
"JUDE",
"JUDO",
"JUDY",
"JUJU",
"JUKE",
686 "JULY",
"JUNE",
"JUNK",
"JUNO",
"JURY",
"JUST",
"JUTE",
"KAHN",
687 "KALE",
"KANE",
"KANT",
"KARL",
"KATE",
"KEEL",
"KEEN",
"KENO",
688 "KENT",
"KERN",
"KERR",
"KEYS",
"KICK",
"KILL",
"KIND",
"KING",
689 "KIRK",
"KISS",
"KITE",
"KLAN",
"KNEE",
"KNEW",
"KNIT",
"KNOB",
690 "KNOT",
"KNOW",
"KOCH",
"KONG",
"KUDO",
"KURD",
"KURT",
"KYLE",
691 "LACE",
"LACK",
"LACY",
"LADY",
"LAID",
"LAIN",
"LAIR",
"LAKE",
692 "LAMB",
"LAME",
"LAND",
"LANE",
"LANG",
"LARD",
"LARK",
"LASS",
693 "LAST",
"LATE",
"LAUD",
"LAVA",
"LAWN",
"LAWS",
"LAYS",
"LEAD",
694 "LEAF",
"LEAK",
"LEAN",
"LEAR",
"LEEK",
"LEER",
"LEFT",
"LEND",
695 "LENS",
"LENT",
"LEON",
"LESK",
"LESS",
"LEST",
"LETS",
"LIAR",
696 "LICE",
"LICK",
"LIED",
"LIEN",
"LIES",
"LIEU",
"LIFE",
"LIFT",
697 "LIKE",
"LILA",
"LILT",
"LILY",
"LIMA",
"LIMB",
"LIME",
"LIND",
698 "LINE",
"LINK",
"LINT",
"LION",
"LISA",
"LIST",
"LIVE",
"LOAD",
699 "LOAF",
"LOAM",
"LOAN",
"LOCK",
"LOFT",
"LOGE",
"LOIS",
"LOLA",
700 "LONE",
"LONG",
"LOOK",
"LOON",
"LOOT",
"LORD",
"LORE",
"LOSE",
701 "LOSS",
"LOST",
"LOUD",
"LOVE",
"LOWE",
"LUCK",
"LUCY",
"LUGE",
702 "LUKE",
"LULU",
"LUND",
"LUNG",
"LURA",
"LURE",
"LURK",
"LUSH",
703 "LUST",
"LYLE",
"LYNN",
"LYON",
"LYRA",
"MACE",
"MADE",
"MAGI",
704 "MAID",
"MAIL",
"MAIN",
"MAKE",
"MALE",
"MALI",
"MALL",
"MALT",
705 "MANA",
"MANN",
"MANY",
"MARC",
"MARE",
"MARK",
"MARS",
"MART",
706 "MARY",
"MASH",
"MASK",
"MASS",
"MAST",
"MATE",
"MATH",
"MAUL",
707 "MAYO",
"MEAD",
"MEAL",
"MEAN",
"MEAT",
"MEEK",
"MEET",
"MELD",
708 "MELT",
"MEMO",
"MEND",
"MENU",
"MERT",
"MESH",
"MESS",
"MICE",
709 "MIKE",
"MILD",
"MILE",
"MILK",
"MILL",
"MILT",
"MIMI",
"MIND",
710 "MINE",
"MINI",
"MINK",
"MINT",
"MIRE",
"MISS",
"MIST",
"MITE",
711 "MITT",
"MOAN",
"MOAT",
"MOCK",
"MODE",
"MOLD",
"MOLE",
"MOLL",
712 "MOLT",
"MONA",
"MONK",
"MONT",
"MOOD",
"MOON",
"MOOR",
"MOOT",
713 "MORE",
"MORN",
"MORT",
"MOSS",
"MOST",
"MOTH",
"MOVE",
"MUCH",
714 "MUCK",
"MUDD",
"MUFF",
"MULE",
"MULL",
"MURK",
"MUSH",
"MUST",
715 "MUTE",
"MUTT",
"MYRA",
"MYTH",
"NAGY",
"NAIL",
"NAIR",
"NAME",
716 "NARY",
"NASH",
"NAVE",
"NAVY",
"NEAL",
"NEAR",
"NEAT",
"NECK",
717 "NEED",
"NEIL",
"NELL",
"NEON",
"NERO",
"NESS",
"NEST",
"NEWS",
718 "NEWT",
"NIBS",
"NICE",
"NICK",
"NILE",
"NINA",
"NINE",
"NOAH",
719 "NODE",
"NOEL",
"NOLL",
"NONE",
"NOOK",
"NOON",
"NORM",
"NOSE",
720 "NOTE",
"NOUN",
"NOVA",
"NUDE",
"NULL",
"NUMB",
"OATH",
"OBEY",
721 "OBOE",
"ODIN",
"OHIO",
"OILY",
"OINT",
"OKAY",
"OLAF",
"OLDY",
722 "OLGA",
"OLIN",
"OMAN",
"OMEN",
"OMIT",
"ONCE",
"ONES",
"ONLY",
723 "ONTO",
"ONUS",
"ORAL",
"ORGY",
"OSLO",
"OTIS",
"OTTO",
"OUCH",
724 "OUST",
"OUTS",
"OVAL",
"OVEN",
"OVER",
"OWLY",
"OWNS",
"QUAD",
725 "QUIT",
"QUOD",
"RACE",
"RACK",
"RACY",
"RAFT",
"RAGE",
"RAID",
726 "RAIL",
"RAIN",
"RAKE",
"RANK",
"RANT",
"RARE",
"RASH",
"RATE",
727 "RAVE",
"RAYS",
"READ",
"REAL",
"REAM",
"REAR",
"RECK",
"REED",
728 "REEF",
"REEK",
"REEL",
"REID",
"REIN",
"RENA",
"REND",
"RENT",
729 "REST",
"RICE",
"RICH",
"RICK",
"RIDE",
"RIFT",
"RILL",
"RIME",
730 "RING",
"RINK",
"RISE",
"RISK",
"RITE",
"ROAD",
"ROAM",
"ROAR",
731 "ROBE",
"ROCK",
"RODE",
"ROIL",
"ROLL",
"ROME",
"ROOD",
"ROOF",
732 "ROOK",
"ROOM",
"ROOT",
"ROSA",
"ROSE",
"ROSS",
"ROSY",
"ROTH",
733 "ROUT",
"ROVE",
"ROWE",
"ROWS",
"RUBE",
"RUBY",
"RUDE",
"RUDY",
734 "RUIN",
"RULE",
"RUNG",
"RUNS",
"RUNT",
"RUSE",
"RUSH",
"RUSK",
735 "RUSS",
"RUST",
"RUTH",
"SACK",
"SAFE",
"SAGE",
"SAID",
"SAIL",
736 "SALE",
"SALK",
"SALT",
"SAME",
"SAND",
"SANE",
"SANG",
"SANK",
737 "SARA",
"SAUL",
"SAVE",
"SAYS",
"SCAN",
"SCAR",
"SCAT",
"SCOT",
738 "SEAL",
"SEAM",
"SEAR",
"SEAT",
"SEED",
"SEEK",
"SEEM",
"SEEN",
739 "SEES",
"SELF",
"SELL",
"SEND",
"SENT",
"SETS",
"SEWN",
"SHAG",
740 "SHAM",
"SHAW",
"SHAY",
"SHED",
"SHIM",
"SHIN",
"SHOD",
"SHOE",
741 "SHOT",
"SHOW",
"SHUN",
"SHUT",
"SICK",
"SIDE",
"SIFT",
"SIGH",
742 "SIGN",
"SILK",
"SILL",
"SILO",
"SILT",
"SINE",
"SING",
"SINK",
743 "SIRE",
"SITE",
"SITS",
"SITU",
"SKAT",
"SKEW",
"SKID",
"SKIM",
744 "SKIN",
"SKIT",
"SLAB",
"SLAM",
"SLAT",
"SLAY",
"SLED",
"SLEW",
745 "SLID",
"SLIM",
"SLIT",
"SLOB",
"SLOG",
"SLOT",
"SLOW",
"SLUG",
746 "SLUM",
"SLUR",
"SMOG",
"SMUG",
"SNAG",
"SNOB",
"SNOW",
"SNUB",
747 "SNUG",
"SOAK",
"SOAR",
"SOCK",
"SODA",
"SOFA",
"SOFT",
"SOIL",
748 "SOLD",
"SOME",
"SONG",
"SOON",
"SOOT",
"SORE",
"SORT",
"SOUL",
749 "SOUR",
"SOWN",
"STAB",
"STAG",
"STAN",
"STAR",
"STAY",
"STEM",
750 "STEW",
"STIR",
"STOW",
"STUB",
"STUN",
"SUCH",
"SUDS",
"SUIT",
751 "SULK",
"SUMS",
"SUNG",
"SUNK",
"SURE",
"SURF",
"SWAB",
"SWAG",
752 "SWAM",
"SWAN",
"SWAT",
"SWAY",
"SWIM",
"SWUM",
"TACK",
"TACT",
753 "TAIL",
"TAKE",
"TALE",
"TALK",
"TALL",
"TANK",
"TASK",
"TATE",
754 "TAUT",
"TEAL",
"TEAM",
"TEAR",
"TECH",
"TEEM",
"TEEN",
"TEET",
755 "TELL",
"TEND",
"TENT",
"TERM",
"TERN",
"TESS",
"TEST",
"THAN",
756 "THAT",
"THEE",
"THEM",
"THEN",
"THEY",
"THIN",
"THIS",
"THUD",
757 "THUG",
"TICK",
"TIDE",
"TIDY",
"TIED",
"TIER",
"TILE",
"TILL",
758 "TILT",
"TIME",
"TINA",
"TINE",
"TINT",
"TINY",
"TIRE",
"TOAD",
759 "TOGO",
"TOIL",
"TOLD",
"TOLL",
"TONE",
"TONG",
"TONY",
"TOOK",
760 "TOOL",
"TOOT",
"TORE",
"TORN",
"TOTE",
"TOUR",
"TOUT",
"TOWN",
761 "TRAG",
"TRAM",
"TRAY",
"TREE",
"TREK",
"TRIG",
"TRIM",
"TRIO",
762 "TROD",
"TROT",
"TROY",
"TRUE",
"TUBA",
"TUBE",
"TUCK",
"TUFT",
763 "TUNA",
"TUNE",
"TUNG",
"TURF",
"TURN",
"TUSK",
"TWIG",
"TWIN",
764 "TWIT",
"ULAN",
"UNIT",
"URGE",
"USED",
"USER",
"USES",
"UTAH",
765 "VAIL",
"VAIN",
"VALE",
"VARY",
"VASE",
"VAST",
"VEAL",
"VEDA",
766 "VEIL",
"VEIN",
"VEND",
"VENT",
"VERB",
"VERY",
"VETO",
"VICE",
767 "VIEW",
"VINE",
"VISE",
"VOID",
"VOLT",
"VOTE",
"WACK",
"WADE",
768 "WAGE",
"WAIL",
"WAIT",
"WAKE",
"WALE",
"WALK",
"WALL",
"WALT",
769 "WAND",
"WANE",
"WANG",
"WANT",
"WARD",
"WARM",
"WARN",
"WART",
770 "WASH",
"WAST",
"WATS",
"WATT",
"WAVE",
"WAVY",
"WAYS",
"WEAK",
771 "WEAL",
"WEAN",
"WEAR",
"WEED",
"WEEK",
"WEIR",
"WELD",
"WELL",
772 "WELT",
"WENT",
"WERE",
"WERT",
"WEST",
"WHAM",
"WHAT",
"WHEE",
773 "WHEN",
"WHET",
"WHOA",
"WHOM",
"WICK",
"WIFE",
"WILD",
"WILL",
774 "WIND",
"WINE",
"WING",
"WINK",
"WINO",
"WIRE",
"WISE",
"WISH",
775 "WITH",
"WOLF",
"WONT",
"WOOD",
"WOOL",
"WORD",
"WORE",
"WORK",
776 "WORM",
"WORN",
"WOVE",
"WRIT",
"WYNN",
"YALE",
"YANG",
"YANK",
777 "YARD",
"YARN",
"YAWL",
"YAWN",
"YEAH",
"YEAR",
"YELL",
"YOGA",
779 Random random =
new Random();
780 int r = random.nextInt(256);
781 int v = random.nextInt(256);
782 return words[r] +
" " + words[v];