Merge the last green changeset of mozilla-inbound to mozilla-central
authorEd Morley <bmo@edmorley.co.uk>
Sat, 24 Sep 2011 04:35:02 +0100
changeset 78751 c7122998435301a0d116867024a94558dc109e0f
parent 78715 b4fd4fd0dc3f3e1aff2c351c0ffc60b8dadefb44 (current diff)
parent 78750 4297a90d3beab95f18357ebb281fe21c1a0d9ae6 (diff)
child 78753 42c3496d967d1cd636b495f1ce96a4fa660cbcab
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone9.0a1
first release with
nightly linux32
c71229984353 / 9.0a1 / 20110924030858 / files
nightly linux64
c71229984353 / 9.0a1 / 20110924030858 / files
nightly mac
c71229984353 / 9.0a1 / 20110924030858 / files
nightly win32
c71229984353 / 9.0a1 / 20110924030858 / files
nightly win64
c71229984353 / 9.0a1 / 20110924030858 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last green changeset of mozilla-inbound to mozilla-central
browser/base/content/test/test_contextmenu.html
js/src/resource.h
js/src/t/3d-cube.js
js/src/t/3d-morph.js
js/src/t/3d-raytrace.js
js/src/t/access-binary-trees.js
js/src/t/access-fannkuch.js
js/src/t/access-nbody.js
js/src/t/access-nsieve.js
js/src/t/bitops-3bit-bits-in-byte.js
js/src/t/bitops-bits-in-byte.js
js/src/t/bitops-bitwise-and.js
js/src/t/bitops-nsieve-bits.js
js/src/t/controlflow-recursive.js
js/src/t/crypto-aes.js
js/src/t/crypto-md5.js
js/src/t/crypto-sha1.js
js/src/t/date-format-tofte.js
js/src/t/date-format-xparb.js
js/src/t/math-cordic.js
js/src/t/math-partial-sums.js
js/src/t/math-spectral-norm.js
js/src/t/regexp-dna.js
js/src/t/string-base64.js
js/src/t/string-fasta.js
js/src/t/string-tagcloud.js
js/src/t/string-unpack-code.js
js/src/t/string-validate-input.js
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -487,40 +487,39 @@ GroupItem.prototype = Utils.extend(new I
   // ----------
   // Function: getContentBounds
   // Returns a <Rect> for the groupItem's content area (which doesn't include the title, etc).
   //
   // Parameters:
   //   options - an object with additional parameters, see below
   //
   // Possible options:
-  //   forceStacked - true to force content bounds for stacked mode
+  //   stacked - true to get content bounds for stacked mode
   getContentBounds: function GroupItem_getContentBounds(options) {
-    var box = this.getBounds();
-    var titleHeight = this.$titlebar.height();
+    let box = this.getBounds();
+    let titleHeight = this.$titlebar.height();
     box.top += titleHeight;
     box.height -= titleHeight;
 
     let appTabTrayContainer = iQ(this.$appTabTray[0].parentNode);
-    var appTabTrayWidth = appTabTrayContainer.width();
+    let appTabTrayWidth = appTabTrayContainer.width();
     if (appTabTrayWidth)
       appTabTrayWidth += parseInt(appTabTrayContainer.css(UI.rtl ? "left" : "right"));
 
     box.width -= appTabTrayWidth;
     if (UI.rtl) {
       box.left += appTabTrayWidth;
     }
 
     // Make the computed bounds' "padding" and expand button margin actually be
     // themeable --OR-- compute this from actual bounds. Bug 586546
     box.inset(6, 6);
 
-    // make some room for the expand button if we're stacked
-    let isStacked = (options && options.forceStacked) || this.isStacked();
-    if (isStacked)
+    // make some room for the expand button in stacked mode
+    if (options && options.stacked)
       box.height -= this.$expander.height() + 9; // the button height plus padding
 
     return box;
   },
 
   // ----------
   // Function: setBounds
   // Sets the bounds with the given <Rect>, animating unless "immediately" is false.
@@ -1291,18 +1290,18 @@ GroupItem.prototype = Utils.extend(new I
   // ----------
   // Function: shouldStack
   // Returns true if the groupItem, given "count", should stack (instead of 
   // grid).
   shouldStack: function GroupItem_shouldStack(count) {
     if (count <= 1)
       return false;
 
-    var bb = this.getContentBounds();
-    var options = {
+    let bb = this.getContentBounds();
+    let options = {
       return: 'widthAndColumns',
       count: count || this._children.length,
       hideTitle: false
     };
     let arrObj = Items.arrange(this._children, bb, options);
 
     let shouldStack = arrObj.childWidth < TabItems.minTabWidth * 1.35;
     this._columns = shouldStack ? null : arrObj.columns;
@@ -1398,30 +1397,30 @@ GroupItem.prototype = Utils.extend(new I
       else
         childrenToArrange.push(child);
     });
 
     if (GroupItems._arrangePaused) {
       GroupItems.pushArrange(this, options);
       return false;
     }
-    
+
     let shouldStack = this.shouldStack(childrenToArrange.length + (options.addTab ? 1 : 0));
     let shouldStackArrange = (shouldStack && !this.expanded);
     let box;
 
     // if we should stack and we're not expanded
     if (shouldStackArrange) {
       this.showExpandControl();
-      box = this.getContentBounds({forceStacked: true});
+      box = this.getContentBounds({stacked: true});
       this._stackArrange(childrenToArrange, box, options);
       return false;
     } else {
       this.hideExpandControl();
-      box = this.getContentBounds({forceStacked: false});
+      box = this.getContentBounds();
       // a dropIndex is returned
       return this._gridArrange(childrenToArrange, box, options);
     }
   },
 
   // ----------
   // Function: _stackArrange
   // Arranges the children in a stack.
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -153,16 +153,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug663421.js \
                  browser_tabview_bug665502.js \
                  browser_tabview_bug669694.js \
                  browser_tabview_bug673196.js \
                  browser_tabview_bug673729.js \
                  browser_tabview_bug677310.js \
                  browser_tabview_bug679853.js \
                  browser_tabview_bug681599.js \
+                 browser_tabview_bug686654.js \
                  browser_tabview_click_group.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_expander.js \
                  browser_tabview_firstrun_pref.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
                  browser_tabview_multiwindow_search.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug686654.js
@@ -0,0 +1,46 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test() {
+  waitForExplicitFinish();
+
+  newWindowWithTabView(function(win) {
+    let cw = win.TabView.getContentWindow();
+    let groupItem = cw.GroupItems.groupItems[0];
+
+    // set the group to 180 x 100 so it shows two tab items without going into
+    // the stacked mode
+    groupItem.setBounds(new cw.Rect(100, 0, 180, 100));
+
+    hideTabView(function() {
+      groupItem.addSubscriber("childAdded", function onChildAdded(data) {
+        groupItem.removeSubscriber("childAdded", onChildAdded);
+
+        is(groupItem.getChildren().length, 3, "The number of children in group is 3");
+        ok(groupItem.isStacked(), "The group item is stacked after adding a new tab");
+
+        let tabItem = groupItem.getChild(2);
+        groupItem.addSubscriber("childRemoved", function onChildRemoved() {
+          tabItem.removeSubscriber("childRemoved", onChildRemoved);
+
+          is(groupItem.getChildren().length, 2, "The number of children in group is 2");
+          // give a delay for the active item to be set
+          executeSoon(function() {
+            showTabView(function() {
+              ok(!groupItem.isStacked(), "The group item is not stacked after removing a tab");
+              finish();
+            }, win);
+          });
+        });
+        win.BrowserCloseTabOrWindow();
+      });
+      win.gBrowser.loadOneTab("", {inBackground: true});
+    }, win);
+  }, function(win) {
+    registerCleanupFunction(function () {
+      win.close();
+    });
+
+    win.gBrowser.addTab();
+  });
+}
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -286,17 +286,17 @@ function runTest(testNum) {
         // Context menu for text input field
         checkContextMenu(["context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
-                          "context-selectall",   true,
+                          "context-selectall",   false,
                           "---",                 null,
                           "spell-check-enabled", true,
                           "---",                  null,
                           "context-inspect",      true]);
         closeContextMenu();
         openContextMenuFor(img); // Invoke context menu for next test.
         break;
 
--- a/content/base/test/test_bug622088.html
+++ b/content/base/test/test_bug622088.html
@@ -16,16 +16,18 @@
 <script>function getXHRObject() { return new XMLHttpRequest(); }</script>
 </head><body onload='parent.dataWindowLoaded()'>Hello!!</body></html>"></iframe>
 
 <script class="testbody" type="application/javascript;version=1.8">
 
 // Bug 622088 - Test that XHR gives the referrer corresponding to the
 // dynamic script context.
 
+const kOriginalLocation = location.href;
+
 SimpleTest.waitForExplicitFinish();
 
 var innerFinishedLoading = false;
 function innerLoaded(inner) {
   // Here, we're being called through inner's onload handler, so our referrer
   // should be inner's URL.
   var referrer = inner.doXHR();
   is (referrer, inner.document.location, 'Expected inner frame location');
@@ -72,16 +74,17 @@ function callXHR() {
     todo_is (referrer, document.location,
              "Expected outer frame location when called with data's XHR object " +
              "after replaceState.");
 
     // In case you're temped, you probably don't want to do history.pushState
     // here and test again with the outer frame.  Calling pushState on the
     // outer frame messes up Mochitest in subtle ways.
 
+    history.replaceState('', '', kOriginalLocation);
     SimpleTest.finish();
   }
   else {
     // ugh.
     setTimeout(callXHR, 0);
   }
 }
 
--- a/docshell/test/chrome/docshell_helpers.js
+++ b/docshell/test/chrome/docshell_helpers.js
@@ -312,26 +312,30 @@ function pageEventListener(event) {
 function finish() {
   // Work around bug 467960.
   var history = TestWindow.getBrowser().webNavigation.sessionHistory;
   history.PurgeHistory(history.count);
   
   // If the test changed the value of max_total_viewers via a call to
   // enableBFCache(), then restore it now.
   if (typeof(gOrigMaxTotalViewers) != "undefined") {
-    SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+    var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+                .getService(Components.interfaces.nsIPrefBranch);
+    prefs.setIntPref("browser.sessionhistory.max_total_viewers",
       gOrigMaxTotalViewers);
   }
 
   // Close the test window and signal the framework that the test is done.
   let opener = window.opener;
   let SimpleTest = opener.wrappedJSObject.SimpleTest;
 
   // Wait for the window to be closed before finishing the test
-  let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher);
+  let ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+	             .getService(Components.interfaces.nsIWindowWatcher);
   ww.registerNotification(function(subject, topic, data) {
     if (topic == "domwindowclosed") {
       ww.unregisterNotification(arguments.callee);
       SimpleTest.waitForFocus(function() {
         SimpleTest.finish();
       }, opener);
     }
   });
@@ -391,31 +395,36 @@ function waitForTrue(fn, onWaitComplete,
  * Enable or disable the bfcache.
  *
  * Parameters:
  *
  *   enable: if true, set max_total_viewers to -1 (the default); if false, set 
  *           to 0 (disabled), if a number, set it to that specific number
  */
 function enableBFCache(enable) {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+              .getService(Components.interfaces.nsIPrefBranch);
+  
   // If this is the first time the test called enableBFCache(),
   // store the original value of max_total_viewers, so it can
   // be restored at the end of the test.
   if (typeof(gOrigMaxTotalViewers) == "undefined") {
-    gOrigMaxTotalViewers = SpecialPowers.getIntPref("browser.sessionhistory.max_total_viewers");
+    gOrigMaxTotalViewers =
+      prefs.getIntPref("browser.sessionhistory.max_total_viewers");
   }
   
   if (typeof(enable) == "boolean") {
     if (enable)
-      SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", -1);
+      prefs.setIntPref("browser.sessionhistory.max_total_viewers", -1);
     else
-      SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", 0);    
+      prefs.setIntPref("browser.sessionhistory.max_total_viewers", 0);    
   }
   else if (typeof(enable) == "number") {
-    SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers", enable);    
+    prefs.setIntPref("browser.sessionhistory.max_total_viewers", enable);    
   }
 }
 
 /*
  * get http root for local tests.  Use a single extractJarToTmp instead of 
  * extracting for each test.  
  * Returns a file://path if we have a .jar file
  */
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -78,19 +78,23 @@ struct StorageClone
 // cloned (see nsDOMStorage2::Clone)
 union StorageConstructData
 {
     null_t;
     StorageClone;
 };
 
 struct FontListEntry {
-    nsCString familyName;
+    nsString  familyName;
+    nsString  faceName;
     nsCString filepath;
-    PRUint32  index;
+    PRUint16  weight;
+    PRInt16   stretch;
+    PRUint8   italic;
+    PRUint8   index;
 };
 
 rpc protocol PContent
 {
     manages PAudio;
     manages PBrowser;
     manages PCrashReporter;
     manages PTestShell;
--- a/dom/src/storage/Makefile.in
+++ b/dom/src/storage/Makefile.in
@@ -43,16 +43,17 @@ VPATH          = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = dom
 LIBRARY_NAME   = jsdomstorage_s
 LIBXUL_LIBRARY = 1
 
 CPPSRCS = \
        nsDOMStorage.cpp \
+       nsDOMStorageBaseDB.cpp \
        nsDOMStorageDBWrapper.cpp \
        nsDOMStoragePersistentDB.cpp \
        nsDOMStorageMemoryDB.cpp \
        StorageChild.cpp \
        StorageParent.cpp \
        $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
--- a/dom/src/storage/nsDOMStorage.cpp
+++ b/dom/src/storage/nsDOMStorage.cpp
@@ -721,17 +721,17 @@ DOMStorageImpl::DOMStorageImpl(nsDOMStor
   : DOMStorageBase(aThat)
 {
   Init(aStorage);
 }
 
 void
 DOMStorageImpl::Init(nsDOMStorage* aStorage)
 {
-  mItemsCached = PR_FALSE;
+  mItemsCachedVersion = 0;
   mItems.Init(8);
   mOwner = aStorage;
   if (nsDOMStorageManager::gStorageManager)
     nsDOMStorageManager::gStorageManager->AddToStoragesHash(this);
 }
 
 DOMStorageImpl::~DOMStorageImpl()
 {
@@ -887,18 +887,16 @@ DOMStorageImpl::SetDBValue(const nsAStri
                                   CanUseChromePersist());
 
   PRInt32 usage;
   rv = gStorageDB->SetKey(this, aKey, aValue, aSecure, quota,
                          !IS_PERMISSION_ALLOWED(offlineAppPermission),
                          &usage);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Before bug 536544 got fixed we were dropping mItemsCached flag here
-
   if (warnQuota >= 0 && usage > warnQuota) {
     // try to include the window that exceeded the warn quota
     nsCOMPtr<nsIDOMWindow> window;
     JSContext *cx;
     nsCOMPtr<nsIJSContextStack> stack =
         do_GetService("@mozilla.org/js/xpc/ContextStack;1");
     if (stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx) {
       nsCOMPtr<nsIScriptContext> scriptContext;
@@ -942,17 +940,17 @@ ClearStorageItem(nsSessionStorageEntry* 
   aEntry->mItem->SetValueInternal(EmptyString());
   return PL_DHASH_NEXT;
 }
 
 void
 DOMStorageImpl::ClearAll()
 {
   mItems.EnumerateEntries(ClearStorageItem, nsnull);
-  mItemsCached = PR_FALSE;
+  mItemsCachedVersion = 0;
 }
 
 struct CopyArgs {
   DOMStorageImpl* storage;
   bool callerSecure;
 };
 
 static PLDHashOperator
@@ -992,26 +990,26 @@ DOMStorageImpl::CloneFrom(bool aCallerSe
 }
 
 nsresult
 DOMStorageImpl::CacheKeysFromDB()
 {
   // cache all the keys in the hash. This is used by the Length and Key methods
   // use this cache for better performance. The disadvantage is that the
   // order may break if someone changes the keys in the database directly.
-  if (!mItemsCached) {
+  if (gStorageDB->IsScopeDirty(this)) {
     nsresult rv = InitDB();
     NS_ENSURE_SUCCESS(rv, rv);
 
     mItems.Clear();
 
     rv = gStorageDB->GetAllKeys(this, &mItems);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    mItemsCached = PR_TRUE;
+    gStorageDB->MarkScopeCached(this);
   }
 
   return NS_OK;
 }
 
 struct KeysArrayBuilderStruct
 {
   PRBool callerIsSecure;
@@ -1070,17 +1068,16 @@ ItemCounter(nsSessionStorageEntry* aEntr
   return PL_DHASH_NEXT;
 }
 
 nsresult
 DOMStorageImpl::GetLength(bool aCallerSecure, PRUint32* aLength)
 {
   // Force reload of items from database.  This ensures sync localStorages for
   // same origins among different windows.
-  mItemsCached = PR_FALSE;
   if (UseDB())
     CacheKeysFromDB();
 
   ItemCounterState state(aCallerSecure);
 
   mItems.EnumerateEntries(ItemCounter, &state);
 
   *aLength = state.mCount;
@@ -1130,17 +1127,16 @@ DOMStorageImpl::GetKey(bool aCallerSecur
   // passed in.
 
   // XXX: This does a linear search for the key at index, which would
   // suck if there's a large numer of indexes. Do we care? If so,
   // maybe we need to have a lazily populated key array here or
   // something?
 
   if (UseDB()) {
-    mItemsCached = PR_FALSE;
     CacheKeysFromDB();
   }
 
   IndexFinderData data(aCallerSecure, aIndex);
   mItems.EnumerateEntries(IndexFinder, &data);
 
   if (!data.mItem) {
     // aIndex was larger than the number of accessible keys. Throw.
@@ -1250,18 +1246,16 @@ DOMStorageImpl::RemoveValue(bool aCaller
     if (!aCallerSecure && secureItem)
       return NS_ERROR_DOM_SECURITY_ERR;
 
     oldValue = value;
 
     rv = gStorageDB->RemoveKey(this, aKey, !IsOfflineAllowed(mDomain),
                                aKey.Length() + value.Length());
     NS_ENSURE_SUCCESS(rv, rv);
-
-    // Before bug 536544 got fixed we were dropping mItemsCached flag here
   }
   else if (entry) {
     // clear string as StorageItems may be referencing this item
     oldValue = entry->mItem->GetValueInternal();
     entry->mItem->ClearValue();
   }
 
   if (entry) {
--- a/dom/src/storage/nsDOMStorage.h
+++ b/dom/src/storage/nsDOMStorage.h
@@ -265,16 +265,19 @@ public:
   virtual nsresult SetValue(bool aCallerSecure, const nsAString& aKey,
                             const nsAString& aData, nsAString& aOldValue);
   virtual nsresult RemoveValue(bool aCallerSecure, const nsAString& aKey,
                                nsAString& aOldValue);
   virtual nsresult Clear(bool aCallerSecure, PRInt32* aOldCount);
 
   // cache the keys from the database for faster lookup
   nsresult CacheKeysFromDB();
+
+  PRUint64 CachedVersion() { return mItemsCachedVersion; }
+  void SetCachedVersion(PRUint64 version) { mItemsCachedVersion = version; }
   
   // Some privileged internal pages can use a persistent storage even in
   // session-only or private-browsing modes.
   bool CanUseChromePersist();
 
   // retrieve the value and secure state corresponding to a key out of storage
   // that has been cached in mItems hash table.
   nsresult
@@ -323,18 +326,19 @@ private:
                      const nsACString& aScopeDBKey,
                      const nsACString& aQuotaDomainDBKey,
                      const nsACString& aQuotaETLDplus1DomainDBKey,
                      PRUint32 aStorageType);
   void SetSessionOnly(bool aSessionOnly);
 
   static nsresult InitDB();
 
-  // true if items from the database are cached
-  PRPackedBool mItemsCached;
+  // 0 initially or a positive data version number assigned by gStorageDB
+  // after keys have been cached from the database
+  PRUint64 mItemsCachedVersion;
 
   // the key->value item pairs
   nsTHashtable<nsSessionStorageEntry> mItems;
 
   // Weak reference to the owning storage instance
   nsDOMStorage* mOwner;
 };
 
new file mode 100644
--- /dev/null
+++ b/dom/src/storage/nsDOMStorageBaseDB.cpp
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Honza Bambas <honzab@firemni.cz>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDOMStorageBaseDB.h"
+#include "nsDOMStorage.h"
+
+PRUint64 nsDOMStorageBaseDB::sGlobalVersion = 1;
+
+nsDOMStorageBaseDB::nsDOMStorageBaseDB()
+{
+  mScopesVersion.Init(8);
+}
+
+// public
+
+void
+nsDOMStorageBaseDB::MarkScopeCached(DOMStorageImpl* aStorage)
+{
+  aStorage->SetCachedVersion(CachedScopeVersion(aStorage));
+}
+
+bool
+nsDOMStorageBaseDB::IsScopeDirty(DOMStorageImpl* aStorage)
+{
+  return !aStorage->CachedVersion() ||
+         (aStorage->CachedVersion() != CachedScopeVersion(aStorage));
+}
+
+// protected
+
+// static
+PRUint64
+nsDOMStorageBaseDB::NextGlobalVersion()
+{
+  sGlobalVersion++;
+  if (sGlobalVersion == 0) // Control overlap, never return 0
+    sGlobalVersion = 1;
+  return sGlobalVersion;
+}
+
+PRUint64
+nsDOMStorageBaseDB::CachedScopeVersion(DOMStorageImpl* aStorage)
+{
+  PRUint64 currentVersion;
+  if (mScopesVersion.Get(aStorage->GetScopeDBKey(), &currentVersion))
+    return currentVersion;
+
+  mScopesVersion.Put(aStorage->GetScopeDBKey(), sGlobalVersion);
+  return sGlobalVersion;
+}
+
+void
+nsDOMStorageBaseDB::MarkScopeDirty(DOMStorageImpl* aStorage)
+{
+  PRUint64 nextVersion = NextGlobalVersion();
+  mScopesVersion.Put(aStorage->GetScopeDBKey(), nextVersion);
+
+  // We may do this because the storage updates its cache along with
+  // updating the database.
+  aStorage->SetCachedVersion(nextVersion);
+}
+
+void
+nsDOMStorageBaseDB::MarkAllScopesDirty()
+{
+  mScopesVersion.Clear();
+  NextGlobalVersion();
+}
new file mode 100644
--- /dev/null
+++ b/dom/src/storage/nsDOMStorageBaseDB.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Honza Bambas <honzab@firemni.cz>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsDOMStorageBaseDB_h___
+#define nsDOMStorageBaseDB_h___
+
+#include "nscore.h"
+#include "nsDataHashtable.h"
+
+class DOMStorageImpl;
+
+class nsDOMStorageBaseDB
+{
+public:
+  nsDOMStorageBaseDB();
+  virtual ~nsDOMStorageBaseDB() {}
+
+  /**
+   * Marks the storage as "cached" after the DOMStorageImpl object has loaded
+   * all items to its memory copy of the entries - IsScopeDirty returns false
+   * after call of this method for this storage.
+   *
+   * When a key is changed or deleted in the storage, the storage scope is
+   * marked as "dirty" again and makes the DOMStorageImpl object recache its
+   * keys on next access, because IsScopeDirty returns true again.
+   */
+  void MarkScopeCached(DOMStorageImpl* aStorage);
+
+  /**
+   * Test whether the storage for the scope (i.e. origin or host) has been
+   * changed since the last MarkScopeCached call.
+   */
+  bool IsScopeDirty(DOMStorageImpl* aStorage);
+
+protected:
+  nsDataHashtable<nsCStringHashKey, PRUint64> mScopesVersion;
+
+  static PRUint64 NextGlobalVersion();
+  PRUint64 CachedScopeVersion(DOMStorageImpl* aStorage);
+
+  void MarkScopeDirty(DOMStorageImpl* aStorage);
+  void MarkAllScopesDirty();
+
+private:
+  static PRUint64 sGlobalVersion;
+};
+
+#endif /* nsDOMStorageDB_h___ */
--- a/dom/src/storage/nsDOMStorageDBWrapper.cpp
+++ b/dom/src/storage/nsDOMStorageDBWrapper.cpp
@@ -108,27 +108,33 @@ nsDOMStorageDBWrapper::FlushAndDeleteTem
   // Everything flushed?  Then no need for a timer.
   if (!mChromePersistentDB.mTempTableLoads.Count() && 
       !mPersistentDB.mTempTableLoads.Count())
     StopTempTableFlushTimer();
 
   return NS_FAILED(rv1) ? rv1 : rv2;
 }
 
-#define IMPL_FORWARDER(_code)                                         \
+#define IMPL_FORWARDER_GUTS(_return, _code)                                \
   PR_BEGIN_MACRO                                                      \
   if (aStorage->CanUseChromePersist())                                \
-    return mChromePersistentDB._code;                                 \
+    _return mChromePersistentDB._code;                                \
   if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())  \
-    return mPrivateBrowsingDB._code;                                  \
+    _return mPrivateBrowsingDB._code;                                 \
   if (aStorage->SessionOnly())                                        \
-    return mSessionOnlyDB._code;                                      \
-  return mPersistentDB._code;                                         \
+    _return mSessionOnlyDB._code;                                     \
+  _return mPersistentDB._code;                                        \
   PR_END_MACRO
 
+#define IMPL_FORWARDER(_code)                                  \
+  IMPL_FORWARDER_GUTS(return, _code)
+
+#define IMPL_VOID_FORWARDER(_code)                                    \
+  IMPL_FORWARDER_GUTS((void), _code)
+
 nsresult
 nsDOMStorageDBWrapper::GetAllKeys(DOMStorageImpl* aStorage,
                                   nsTHashtable<nsSessionStorageEntry>* aKeys)
 {
   IMPL_FORWARDER(GetAllKeys(aStorage, aKeys));
 }
 
 nsresult
@@ -171,16 +177,28 @@ nsDOMStorageDBWrapper::RemoveKey(DOMStor
 }
 
 nsresult
 nsDOMStorageDBWrapper::ClearStorage(DOMStorageImpl* aStorage)
 {
   IMPL_FORWARDER(ClearStorage(aStorage));
 }
 
+void
+nsDOMStorageDBWrapper::MarkScopeCached(DOMStorageImpl* aStorage)
+{
+  IMPL_VOID_FORWARDER(MarkScopeCached(aStorage));
+}
+
+bool
+nsDOMStorageDBWrapper::IsScopeDirty(DOMStorageImpl* aStorage)
+{
+  IMPL_FORWARDER(IsScopeDirty(aStorage));
+}
+
 nsresult
 nsDOMStorageDBWrapper::DropSessionOnlyStoragesForHost(const nsACString& aHostName)
 {
   return mSessionOnlyDB.RemoveOwner(aHostName, PR_TRUE);
 }
 
 nsresult
 nsDOMStorageDBWrapper::DropPrivateBrowsingStorages()
--- a/dom/src/storage/nsDOMStorageDBWrapper.h
+++ b/dom/src/storage/nsDOMStorageDBWrapper.h
@@ -186,16 +186,35 @@ public:
 
   /**
     * Returns usage of the domain and optionaly by any subdomain.
     */
   nsresult
   GetUsage(const nsACString& aDomain, PRBool aIncludeSubDomains, PRInt32 *aUsage);
 
   /**
+   * Marks the storage as "cached" after the DOMStorageImpl object has loaded
+   * all items to its memory copy of the entries - IsScopeDirty returns false
+   * after call of this method for this storage.
+   *
+   * When a key is changed or deleted in the storage, the storage scope is
+   * marked as "dirty" again and makes the DOMStorageImpl object recache its
+   * keys on next access, because IsScopeDirty returns true again.
+   */
+  void
+  MarkScopeCached(DOMStorageImpl* aStorage);
+
+  /**
+   * Test whether the storage for the scope (i.e. origin or host) has been
+   * changed since the last MarkScopeCached call.
+   */
+  bool
+  IsScopeDirty(DOMStorageImpl* aStorage);
+
+  /**
     * Turns "http://foo.bar.com:80" to "moc.rab.oof.:http:80",
     * i.e. reverses the host, appends a dot, appends the schema
     * and a port number.
     */
   static nsresult CreateOriginScopeDBKey(nsIURI* aUri, nsACString& aKey);
 
   /**
     * Turns "http://foo.bar.com" to "moc.rab.oof.",
--- a/dom/src/storage/nsDOMStorageMemoryDB.cpp
+++ b/dom/src/storage/nsDOMStorageMemoryDB.cpp
@@ -230,16 +230,18 @@ nsDOMStorageMemoryDB::SetKey(DOMStorageI
 
   storage->mUsageDelta += aValue.Length() - item->mValue.Length();
 
   item->mValue = aValue;
   item->mSecure = aSecure;
 
   *aNewUsage = usage;
 
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStorageMemoryDB::SetSecure(DOMStorageImpl* aStorage,
                                 const nsAString& aKey,
                                 const PRBool aSecure)
 {
@@ -250,16 +252,18 @@ nsDOMStorageMemoryDB::SetSecure(DOMStora
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsInMemoryItem* item;
   if (!storage->mTable.Get(aKey, &item))
     return NS_ERROR_DOM_NOT_FOUND_ERR;
 
   item->mSecure = aSecure;
 
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStorageMemoryDB::RemoveKey(DOMStorageImpl* aStorage,
                                 const nsAString& aKey,
                                 PRBool aExcludeOfflineFromUsage,
                                 PRInt32 aKeyUsage)
@@ -272,16 +276,18 @@ nsDOMStorageMemoryDB::RemoveKey(DOMStora
 
   nsInMemoryItem* item;
   if (!storage->mTable.Get(aKey, &item))
     return NS_ERROR_DOM_NOT_FOUND_ERR;
 
   storage->mUsageDelta -= aKey.Length() + item->mValue.Length();
   storage->mTable.Remove(aKey);
 
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 static PLDHashOperator
 RemoveAllKeysEnum(const nsAString& keyname,
                   nsAutoPtr<nsDOMStorageMemoryDB::nsInMemoryItem>& item,
                   void *closure)
 {
@@ -297,23 +303,27 @@ nsDOMStorageMemoryDB::ClearStorage(DOMSt
 {
   nsresult rv;
 
   nsInMemoryStorage* storage;
   rv = GetItemsTable(aStorage, &storage);
   NS_ENSURE_SUCCESS(rv, rv);
 
   storage->mTable.Enumerate(RemoveAllKeysEnum, storage);
+
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStorageMemoryDB::DropStorage(DOMStorageImpl* aStorage)
 {
   mData.Remove(aStorage->GetScopeDBKey());
+  MarkScopeDirty(aStorage);
   return NS_OK;
 }
 
 struct RemoveOwnersStruc
 {
   nsCString* mSubDomain;
   PRBool mMatch;
 };
@@ -341,16 +351,18 @@ nsDOMStorageMemoryDB::RemoveOwner(const 
   if (!aIncludeSubDomains)
     subdomainsDBKey.AppendLiteral(":");
 
   RemoveOwnersStruc struc;
   struc.mSubDomain = &subdomainsDBKey;
   struc.mMatch = PR_TRUE;
   mData.Enumerate(RemoveOwnersEnum, &struc);
 
+  MarkAllScopesDirty();
+
   return NS_OK;
 }
 
 
 nsresult
 nsDOMStorageMemoryDB::RemoveOwners(const nsTArray<nsString> &aOwners,
                                    PRBool aIncludeSubDomains,
                                    PRBool aMatch)
@@ -373,23 +385,28 @@ nsDOMStorageMemoryDB::RemoveOwners(const
       quotaKey.AppendLiteral(":");
 
     RemoveOwnersStruc struc;
     struc.mSubDomain = &quotaKey;
     struc.mMatch = aMatch;
     mData.Enumerate(RemoveOwnersEnum, &struc);
   }
 
+  MarkAllScopesDirty();
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStorageMemoryDB::RemoveAll()
 {
   mData.Clear(); // XXX Check this releases all instances
+
+  MarkAllScopesDirty();
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStorageMemoryDB::GetUsage(DOMStorageImpl* aStorage,
                                PRBool aExcludeOfflineFromUsage, PRInt32 *aUsage)
 {
   return GetUsageInternal(aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage),
--- a/dom/src/storage/nsDOMStorageMemoryDB.h
+++ b/dom/src/storage/nsDOMStorageMemoryDB.h
@@ -35,22 +35,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsDOMStorageMemoryDB_h___
 #define nsDOMStorageMemoryDB_h___
 
 #include "nscore.h"
+#include "nsDOMStorageBaseDB.h"
 #include "nsClassHashtable.h"
 #include "nsDataHashtable.h"
 
 class nsDOMStoragePersistentDB;
 
-class nsDOMStorageMemoryDB
+class nsDOMStorageMemoryDB : public nsDOMStorageBaseDB
 {
 public:
   nsDOMStorageMemoryDB() : mPreloading(PR_FALSE) {}
   ~nsDOMStorageMemoryDB() {}
 
   class nsInMemoryItem
   {
   public:
--- a/dom/src/storage/nsDOMStoragePersistentDB.cpp
+++ b/dom/src/storage/nsDOMStoragePersistentDB.cpp
@@ -721,16 +721,18 @@ nsDOMStoragePersistentDB::SetKey(DOMStor
 
   if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
     mCachedOwner = aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage);
     mCachedUsage = usage;
   }
 
   *aNewUsage = usage;
 
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStoragePersistentDB::SetSecure(DOMStorageImpl* aStorage,
                                     const nsAString& aKey,
                                     const PRBool aSecure)
 {
@@ -755,17 +757,22 @@ nsDOMStoragePersistentDB::SetSecure(DOMS
   NS_ENSURE_SUCCESS(rv, rv);
   rv = binder->BindInt32ByName(NS_LITERAL_CSTRING("secure"),
                                aSecure ? 1 : 0);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = binder.Add();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return mSetSecureStatement->Execute();
+  rv = mSetSecureStatement->Execute();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  MarkScopeDirty(aStorage);
+
+  return NS_OK;
 }
 
 nsresult
 nsDOMStoragePersistentDB::RemoveKey(DOMStorageImpl* aStorage,
                                     const nsAString& aKey,
                                     PRBool aExcludeOfflineFromUsage,
                                     PRInt32 aKeyUsage)
 {
@@ -791,16 +798,18 @@ nsDOMStoragePersistentDB::RemoveKey(DOMS
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = binder.Add();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = mRemoveKeyStatement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStoragePersistentDB::ClearStorage(DOMStorageImpl* aStorage)
 {
   nsresult rv;
 
@@ -820,16 +829,18 @@ nsDOMStoragePersistentDB::ClearStorage(D
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = binder.Add();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = mRemoveStorageStatement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  MarkScopeDirty(aStorage);
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner,
                                       PRBool aIncludeSubDomains)
 {
   nsresult rv;
@@ -859,16 +870,18 @@ nsDOMStoragePersistentDB::RemoveOwner(co
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = binder.Add();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = mRemoveOwnerStatement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  MarkAllScopesDirty();
+
   return NS_OK;
 }
 
 
 nsresult
 nsDOMStoragePersistentDB::RemoveOwners(const nsTArray<nsString> &aOwners,
                                        PRBool aIncludeSubDomains,
                                        PRBool aMatch)
@@ -936,32 +949,36 @@ nsDOMStoragePersistentDB::RemoveOwners(c
   }
 
   rv = binder.Add();
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = statement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  MarkAllScopesDirty();
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStoragePersistentDB::RemoveAll()
 {
   nsresult rv;
 
   rv = MaybeCommitInsertTransaction();
   NS_ENSURE_SUCCESS(rv, rv);
 
   mozStorageStatementScoper scope(mRemoveAllStatement);
 
   rv = mRemoveAllStatement->Execute();
   NS_ENSURE_SUCCESS(rv, rv);
 
+  MarkAllScopesDirty();
+
   return NS_OK;
 }
 
 nsresult
 nsDOMStoragePersistentDB::GetUsage(DOMStorageImpl* aStorage,
                                    PRBool aExcludeOfflineFromUsage,
                                    PRInt32 *aUsage)
 {
--- a/dom/src/storage/nsDOMStoragePersistentDB.h
+++ b/dom/src/storage/nsDOMStoragePersistentDB.h
@@ -35,29 +35,30 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsDOMStoragePersistentDB_h___
 #define nsDOMStoragePersistentDB_h___
 
 #include "nscore.h"
+#include "nsDOMStorageBaseDB.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
 #include "nsTHashtable.h"
 #include "nsDataHashtable.h"
 #include "mozilla/TimeStamp.h"
 
 class DOMStorageImpl;
 class nsSessionStorageEntry;
 
 using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 
-class nsDOMStoragePersistentDB
+class nsDOMStoragePersistentDB : public nsDOMStorageBaseDB
 {
 public:
   nsDOMStoragePersistentDB();
   ~nsDOMStoragePersistentDB() {}
 
   nsresult
   Init(const nsString& aDatabaseName);
 
--- a/dom/tests/mochitest/bugs/test_bug593174.html
+++ b/dom/tests/mochitest/bugs/test_bug593174.html
@@ -13,16 +13,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 <script>
 
 SimpleTest.waitForExplicitFinish();
 
 var loadCount = 0;
 var popup = null;
 
+const kOriginalLocation = location.href;
+
 function iframeLoaded(identifier) {
   loadCount++;
   dump("iframeLoaded. loadCount=" + loadCount +
                     " identifier='" + identifier + "'\n");
 
   var iframe = document.getElementById('iframe');
   var iframeCw = iframe.contentWindow;
 
@@ -65,16 +67,17 @@ function iframeLoaded(identifier) {
   }
   else if (loadCount == 5) {
     is(popup.document.referrer, document.location, 'popup referrer after replaceState');
     popup.navigateInnerIframe();
   }
   else if (loadCount == 6) {
     is(popup.getInnerIframeReferrer(), popup.location, 'popup/inner iframe referrer');
     popup.close();
+    history.replaceState('', '', kOriginalLocation);
     SimpleTest.finish();
   }
 }
 
 </script>
 
 <iframe onload='iframeLoaded("outer")' id='iframe' src='file_bug593174_1.html'></iframe>
 
--- a/editor/libeditor/base/nsEditorCommands.cpp
+++ b/editor/libeditor/base/nsEditorCommands.cpp
@@ -656,24 +656,34 @@ nsDeleteCommand::GetCommandStateParams(c
 
 NS_IMETHODIMP
 nsSelectAllCommand::IsCommandEnabled(const char * aCommandName,
                                      nsISupports *aCommandRefCon,
                                      PRBool *outCmdEnabled)
 {
   NS_ENSURE_ARG_POINTER(outCmdEnabled);
 
-  // you can select all if there is an editor (and potentially no contents)
-  // some day we may want to change this
+  nsresult rv = NS_OK;
+  *outCmdEnabled = PR_FALSE;
+  PRBool docIsEmpty, selectionIsEditable;
+ 
+  // you can select all if there is an editor which is non-empty
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
-  if (editor)
-    return editor->GetIsSelectionEditable(outCmdEnabled);
+  if (editor) {
+    rv = editor->GetIsSelectionEditable(&selectionIsEditable);
+    NS_ENSURE_SUCCESS(rv, rv);
 
-  *outCmdEnabled = PR_FALSE;
-  return NS_OK;
+    if (selectionIsEditable) {
+      rv = editor->GetDocumentIsEmpty(&docIsEmpty);
+      NS_ENSURE_SUCCESS(rv, rv);
+      *outCmdEnabled = !docIsEmpty;
+    }
+  } 
+
+  return rv;
 }
 
 
 NS_IMETHODIMP
 nsSelectAllCommand::DoCommand(const char *aCommandName,
                               nsISupports *aCommandRefCon)
 {
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
--- a/editor/libeditor/base/tests/Makefile.in
+++ b/editor/libeditor/base/tests/Makefile.in
@@ -49,16 +49,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug514156.html \
 		test_bug567213.html \
 		file_bug586662.html \
 		test_bug586662.html \
 		$(NULL)
 
 _CHROME_TEST_FILES = \
 		test_selection_move_commands.xul \
+                test_bug46555.html \
 		test_bug646194.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs:: $(_CHROME_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/base/tests/test_bug46555.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is Editor Test code
+   -
+   - The Initial Developer of the Original Code is
+   - Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk>.
+   - Portions created by the Initial Developer are Copyright (C) 2011
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the GPL or the LGPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=46555
+-->
+
+<head>
+  <title>Test for Bug 46555</title>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+
+<body>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=46555">Mozilla Bug 46555</a>
+  <p id="display"></p>
+  <div id="content" style="display: none">
+  </div>
+
+  <input type="text" value="" id="t1" />
+
+  <pre id="test">
+    <script type="application/javascript">
+
+      /** Test for Bug 46555 **/
+      SimpleTest.waitForExplicitFinish();
+      SimpleTest.waitForFocus(function() {
+        const kCmd = "cmd_selectAll";
+
+        var input = document.getElementById("t1");
+        input.focus();
+        var controller = input.controllers.getControllerForCommand(kCmd);
+
+        // Test 1: Select All should be disabled if editor is empty
+        is(controller.isCommandEnabled(kCmd), false,
+           "Select All command disabled when editor is empty");
+
+        SimpleTest.finish();
+      });
+   </script>
+  </pre>
+
+</body>
+</html>
--- a/embedding/android/GeckoInputConnection.java
+++ b/embedding/android/GeckoInputConnection.java
@@ -52,25 +52,46 @@ import android.content.*;
 import android.R;
 
 import android.util.*;
 
 public class GeckoInputConnection
     extends BaseInputConnection
     implements TextWatcher
 {
+    private class ChangeNotification {
+        public String mText;
+        public int mStart;
+        public int mEnd;
+        public int mNewEnd;
+
+        ChangeNotification(String text, int start, int oldEnd, int newEnd) {
+            mText = text;
+            mStart = start;
+            mEnd = oldEnd;
+            mNewEnd = newEnd;
+        }
+
+        ChangeNotification(int start, int end) {
+            mText = null;
+            mStart = start;
+            mEnd = end;
+            mNewEnd = 0;
+        }
+    }
+
     public GeckoInputConnection (View targetView) {
         super(targetView, true);
         mQueryResult = new SynchronousQueue<String>();
     }
 
     @Override
     public boolean beginBatchEdit() {
         //Log.d("GeckoAppJava", "IME: beginBatchEdit");
-
+        mBatchMode = true;
         return true;
     }
 
     @Override
     public boolean commitCompletion(CompletionInfo text) {
         //Log.d("GeckoAppJava", "IME: commitCompletion");
 
         return commitText(text.getText(), 1);
@@ -84,16 +105,18 @@ public class GeckoInputConnection
         finishComposingText();
 
         return true;
     }
 
     @Override
     public boolean deleteSurroundingText(int leftLength, int rightLength) {
         //Log.d("GeckoAppJava", "IME: deleteSurroundingText");
+        if (leftLength == 0 && rightLength == 0)
+            return true;
 
         /* deleteSurroundingText is supposed to ignore the composing text,
             so we cancel any pending composition, delete the text, and then
             restart the composition */
 
         if (mComposing) {
             // Cancel current composition
             GeckoAppShell.sendEventToGecko(
@@ -136,16 +159,31 @@ public class GeckoInputConnection
         }
         return true;
     }
 
     @Override
     public boolean endBatchEdit() {
         //Log.d("GeckoAppJava", "IME: endBatchEdit");
 
+        mBatchMode = false;
+
+        if (!mBatchChanges.isEmpty()) {
+            InputMethodManager imm = (InputMethodManager)
+                GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+            if (imm != null) {
+                for (ChangeNotification n : mBatchChanges) {
+                    if (n.mText != null)
+                        notifyTextChange(imm, n.mText, n.mStart, n.mEnd, n.mNewEnd);
+                    else
+                        notifySelectionChange(imm, n.mStart, n.mEnd);
+                }
+            }
+            mBatchChanges.clear();
+        }
         return true;
     }
 
     @Override
     public boolean finishComposingText() {
         //Log.d("GeckoAppJava", "IME: finishComposingText");
 
         if (mComposing) {
@@ -154,20 +192,22 @@ public class GeckoInputConnection
                 new GeckoEvent(0, mComposingText.length(),
                                GeckoEvent.IME_RANGE_RAWINPUT, 0, 0, 0,
                                mComposingText));
             GeckoAppShell.sendEventToGecko(
                 new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
             mComposing = false;
             mComposingText = "";
 
-            // Make sure caret stays at the same position
-            GeckoAppShell.sendEventToGecko(
-                new GeckoEvent(GeckoEvent.IME_SET_SELECTION,
-                               mCompositionStart + mCompositionSelStart, 0));
+            if (!mBatchMode) {
+                // Make sure caret stays at the same position
+                GeckoAppShell.sendEventToGecko(
+                    new GeckoEvent(GeckoEvent.IME_SET_SELECTION,
+                                   mCompositionStart + mCompositionSelStart, 0));
+            }
         }
         return true;
     }
 
     @Override
     public int getCursorCapsMode(int reqModes) {
         //Log.d("GeckoAppJava", "IME: getCursorCapsMode");
 
@@ -451,16 +491,51 @@ public class GeckoInputConnection
                                GeckoEvent.IME_RANGE_UNDERLINE, 0, 0));
         }
 
         // Change composition (treating selection end as where the caret is)
         GeckoAppShell.sendEventToGecko(
             new GeckoEvent(mCompositionSelStart + mCompositionSelLen, 0,
                            GeckoEvent.IME_RANGE_CARETPOSITION, 0, 0, 0,
                            mComposingText));
+
+        return true;
+    }
+
+    @Override
+    public boolean setComposingRegion(int start, int end) {
+        //Log.d("GeckoAppJava", "IME: setComposingRegion(start=" + start + ", end=" + end + ")");
+        if (start < 0 || end < start)
+            return true;
+
+        CharSequence text = null;
+        if (start == mCompositionStart && end - start == mComposingText.length()) {
+            // Use mComposingText to avoid extra call to Gecko
+            text = mComposingText;
+        }
+
+        finishComposingText();
+
+        if (text == null && start < end) {
+            GeckoAppShell.sendEventToGecko(
+                new GeckoEvent(GeckoEvent.IME_GET_TEXT, start, end - start));
+            try {
+                text = mQueryResult.take();
+            } catch (InterruptedException e) {
+                Log.e("GeckoAppJava", "IME: setComposingRegion interrupted", e);
+                return false;
+            }
+        }
+
+        GeckoAppShell.sendEventToGecko(
+            new GeckoEvent(GeckoEvent.IME_SET_SELECTION, start, end - start));
+
+        // Call setComposingText with the same text to start composition and let Gecko know about new composing region
+        setComposingText(text, 1);
+
         return true;
     }
 
     @Override
     public boolean setSelection(int start, int end) {
         //Log.d("GeckoAppJava", "IME: setSelection");
 
         if (mComposing) {
@@ -507,16 +582,21 @@ public class GeckoInputConnection
         return true;
     }
 
     public void notifyTextChange(InputMethodManager imm, String text,
                                  int start, int oldEnd, int newEnd) {
         // Log.d("GeckoAppShell", String.format("IME: notifyTextChange: text=%s s=%d ne=%d oe=%d",
         //                                      text, start, newEnd, oldEnd));
 
+        if (mBatchMode) {
+            mBatchChanges.add(new ChangeNotification(text, start, oldEnd, newEnd));
+            return;
+        }
+
         mNumPendingChanges = Math.max(mNumPendingChanges - 1, 0);
 
         // If there are pending changes, that means this text is not the most up-to-date version
         // and we'll step on ourselves if we change the editable right now.
         if (mNumPendingChanges == 0 && !text.contentEquals(GeckoApp.surfaceView.mEditable))
             GeckoApp.surfaceView.setEditable(text);
 
         if (mUpdateRequest == null)
@@ -538,16 +618,20 @@ public class GeckoInputConnection
 
         imm.updateExtractedText(GeckoApp.surfaceView,
             mUpdateRequest.token, mUpdateExtract);
     }
 
     public void notifySelectionChange(InputMethodManager imm,
                                       int start, int end) {
         // Log.d("GeckoAppJava", String.format("IME: notifySelectionChange: s=%d e=%d", start, end));
+        if (mBatchMode) {
+            mBatchChanges.add(new ChangeNotification(start, end));
+            return;
+        }
 
         if (mComposing)
             imm.updateSelection(GeckoApp.surfaceView,
                 mCompositionStart + mCompositionSelStart,
                 mCompositionStart + mCompositionSelStart + mCompositionSelLen,
                 mCompositionStart,
                 mCompositionStart + mComposingText.length());
         else
@@ -564,16 +648,18 @@ public class GeckoInputConnection
                                Math.min(end, maxLen));
     }
 
     public void reset() {
         mComposing = false;
         mComposingText = "";
         mUpdateRequest = null;
         mNumPendingChanges = 0;
+        mBatchMode = false;
+        mBatchChanges.clear();
     }
 
     // TextWatcher
     public void onTextChanged(CharSequence s, int start, int before, int count)
     {
         // Log.d("GeckoAppShell", String.format("IME: onTextChanged: t=%s s=%d b=%d l=%d",
         //                                      s, start, before, count));
 
@@ -624,15 +710,19 @@ public class GeckoInputConnection
         therefore we keep our own offsets to emulate selection */
     // Start of fake selection, relative to start of composition
     int mCompositionSelStart;
     // Length of fake selection
     int mCompositionSelLen;
     // Number of in flight changes
     int mNumPendingChanges;
 
+    boolean mBatchMode;
+    private CopyOnWriteArrayList<ChangeNotification> mBatchChanges =
+        new CopyOnWriteArrayList<ChangeNotification>();
+
     ExtractedTextRequest mUpdateRequest;
     final ExtractedText mUpdateExtract = new ExtractedText();
 
     int mSelectionStart, mSelectionLength;
     SynchronousQueue<String> mQueryResult;
 }
 
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -383,17 +383,20 @@ mozSpellChecker::SetCurrentDictionary(co
     mSpellCheckingEngine = spellCheckingEngines[i];
 
     rv = mSpellCheckingEngine->SetDictionary(PromiseFlatString(aDictionary).get());
 
     if (NS_SUCCEEDED(rv)) {
       nsCOMPtr<mozIPersonalDictionary> personalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
       mSpellCheckingEngine->SetPersonalDictionary(personalDictionary.get());
 
-      return NS_OK;
+      nsXPIDLString language;
+      nsCOMPtr<mozISpellI18NManager> serv(do_GetService("@mozilla.org/spellchecker/i18nmanager;1", &rv));
+      NS_ENSURE_SUCCESS(rv, rv);
+      return serv->GetUtil(language.get(),getter_AddRefs(mConverter));
     }
   }
 
   mSpellCheckingEngine = NULL;
   
   // We could not find any engine with the requested dictionary
   return NS_ERROR_NOT_AVAILABLE;
 }
--- a/gfx/thebes/GLContextProviderEGL.cpp
+++ b/gfx/thebes/GLContextProviderEGL.cpp
@@ -184,20 +184,20 @@ typedef void *GLeglImageOES;
     (_array).AppendElement(_k);                 \
     (_array).AppendElement(_v);                 \
 } while (0)
 
 #define ADD_ATTR_1(_array, _k) do {             \
     (_array).AppendElement(_k);                 \
 } while (0)
 
-EGLSurface
+static EGLSurface
 CreateSurfaceForWindow(nsIWidget *aWidget, EGLConfig config);
-EGLConfig
-CreateConfig();
+static bool
+CreateConfig(EGLConfig* aConfig);
 #ifdef MOZ_X11
 
 #ifdef MOZ_EGL_XRENDER_COMPOSITE
 static EGLSurface
 CreateBasicEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig);
 #endif
 
 static EGLConfig
@@ -793,17 +793,18 @@ public:
     PRBool MakeCurrentImpl(PRBool aForce = PR_FALSE) {
         PRBool succeeded = PR_TRUE;
 
         // Assume that EGL has the same problem as WGL does,
         // where MakeCurrent with an already-current context is
         // still expensive.
 #ifndef MOZ_WIDGET_QT
         if (!mSurface) {
-            EGLConfig config = CreateConfig();
+            EGLConfig config;
+            CreateConfig(&config);
             mSurface = CreateSurfaceForWindow(NULL, config);
             aForce = PR_TRUE;
         }
 #endif
         if (aForce || sEGLLibrary.fGetCurrentContext() != mContext) {
             succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
                                                  mSurface, mSurface,
                                                  mContext);
@@ -818,17 +819,18 @@ public:
     RenewSurface() {
         /* We don't support renewing on QT because we don't create the surface ourselves */
         return PR_FALSE;
     }
 #else
     virtual PRBool
     RenewSurface() {
         ReleaseSurface();
-        EGLConfig config = CreateConfig();
+        EGLConfig config;
+        CreateConfig(&config);
         mSurface = CreateSurfaceForWindow(NULL, config);
 
         return sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
                                         mSurface, mSurface,
                                         mContext);
     }
 #endif
 
@@ -1169,21 +1171,21 @@ class TextureImageEGL
 {
 public:
     TextureImageEGL(GLuint aTexture,
                     const nsIntSize& aSize,
                     GLenum aWrapMode,
                     ContentType aContentType,
                     GLContext* aContext)
         : TextureImage(aSize, aWrapMode, aContentType)
-        , mTexture(aTexture)
         , mGLContext(aContext)
         , mUpdateFormat(gfxASurface::ImageFormatUnknown)
         , mSurface(nsnull)
         , mConfig(nsnull)
+        , mTexture(aTexture)
         , mImageKHR(nsnull)
         , mTextureState(Created)
         , mBound(PR_FALSE)
         , mIsLocked(PR_FALSE)
     {
         mUpdateFormat = gfxASurface::FormatFromContent(GetContentType());
 
         if (gUseBackingSurface) {
@@ -1701,17 +1703,17 @@ GLContextEGL::TileGenFunc(const nsIntSiz
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 
   return teximage.forget();
 }
 
-static ContextFormat
+inline static ContextFormat
 DepthToGLFormat(int aDepth)
 {
     switch (aDepth) {
         case 32:
             return ContextFormat::BasicRGBA32;
         case 24:
             return ContextFormat::BasicRGB24;
         case 16:
@@ -1759,74 +1761,95 @@ GLContextProviderEGL::CreateForWindow(ns
     NS_ERROR("Failed to get QGLContext");
 
     // Switch to software rendering here
     return nsnull;
 }
 
 #else
 
-EGLConfig
-CreateConfig()
+static const EGLint kEGLConfigAttribsRGB16[] = {
+    LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
+    LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
+    LOCAL_EGL_RED_SIZE,        5,
+    LOCAL_EGL_GREEN_SIZE,      6,
+    LOCAL_EGL_BLUE_SIZE,       5,
+    LOCAL_EGL_ALPHA_SIZE,      0,
+    LOCAL_EGL_NONE
+};
+
+
+static const EGLint kEGLConfigAttribsRGBA32[] = {
+    LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
+    LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
+    LOCAL_EGL_RED_SIZE,        8,
+    LOCAL_EGL_GREEN_SIZE,      8,
+    LOCAL_EGL_BLUE_SIZE,       8,
+    LOCAL_EGL_ALPHA_SIZE,      8,
+    LOCAL_EGL_NONE
+};
+
+// Return true if a suitable EGLConfig was found and pass it out
+// through aConfig.  Return false otherwise.
+//
+// NB: It's entirely legal for the returned EGLConfig to be valid yet
+// have the value null.
+static bool
+CreateConfig(EGLConfig* aConfig)
 {
-    EGLConfig  config;
-    EGLint attribs[] = {
-        LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
-        LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
-
+    struct EGLAttribs {
+        gfxASurface::gfxImageFormat mFormat;
+        const EGLint* mAttribs;
+    } attribsToTry[] = {
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
-        LOCAL_EGL_RED_SIZE,        5,
-        LOCAL_EGL_GREEN_SIZE,      6,
-        LOCAL_EGL_BLUE_SIZE,       5,
-        LOCAL_EGL_ALPHA_SIZE,      0,
-#else
-        LOCAL_EGL_RED_SIZE,        8,
-        LOCAL_EGL_GREEN_SIZE,      8,
-        LOCAL_EGL_BLUE_SIZE,       8,
-        LOCAL_EGL_ALPHA_SIZE,      8,
+        // Prefer r5g6b5 for potential savings in memory bandwidth.
+        // This needs to be reevaluated for newer devices.
+        { gfxASurface::ImageFormatRGB16_565, kEGLConfigAttribsRGB16 },
 #endif
-
-        LOCAL_EGL_NONE
+        { gfxASurface::ImageFormatARGB32, kEGLConfigAttribsRGBA32 },
     };
 
     EGLConfig configs[64];
-    EGLint ncfg = 64;
-    if (!sEGLLibrary.fChooseConfig(EGL_DISPLAY(), attribs, configs, ncfg, &ncfg) ||
-        ncfg < 1)
-    {
-        return nsnull;
+    for (unsigned i = 0; i < NS_ARRAY_LENGTH(attribsToTry); ++i) {
+        const EGLAttribs& attribs = attribsToTry[i];
+        EGLint ncfg = NS_ARRAY_LENGTH(configs);
+
+        if (!sEGLLibrary.fChooseConfig(EGL_DISPLAY(), attribs.mAttribs,
+                                       configs, ncfg, &ncfg) ||
+            ncfg < 1)
+        {
+            continue;
+        }
+
+        for (int j = 0; j < ncfg; ++j) {
+            EGLConfig config = configs[j];
+            EGLint r, g, b, a;
+
+            if (sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+                                             LOCAL_EGL_RED_SIZE, &r) &&
+                sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+                                             LOCAL_EGL_GREEN_SIZE, &g) &&
+                sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+                                             LOCAL_EGL_BLUE_SIZE, &b) &&
+                sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), config,
+                                             LOCAL_EGL_ALPHA_SIZE, &a) &&
+                ((gfxASurface::ImageFormatRGB16_565 == attribs.mFormat &&
+                  r == 5 && g == 6 && b == 5) ||
+                 (gfxASurface::ImageFormatARGB32 == attribs.mFormat &&
+                  r == 8 && g == 8 && b == 8 && a == 8)))
+            {
+                *aConfig = config;
+                return true;
+            }
+        }
     }
-
-    config = 0;
-
-    for (int i = 0; i < ncfg; ++i) {
-        EGLint r, g, b, a;
-
-        sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), configs[i], LOCAL_EGL_RED_SIZE, &r);
-        sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), configs[i], LOCAL_EGL_GREEN_SIZE, &g);
-        sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), configs[i], LOCAL_EGL_BLUE_SIZE, &b);
-        sEGLLibrary.fGetConfigAttrib(EGL_DISPLAY(), configs[i], LOCAL_EGL_ALPHA_SIZE, &a);
-
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-        if (r == 5 && g == 6 && b == 5) {
-            config = configs[i];
-            break;
-        }
-#else
-        if (r == 8 && g == 8 && b == 8 && a == 8) {
-            config = configs[i];
-            break;
-        }
-#endif
-    }
-
-    return config;
+    return false;
 }
 
-EGLSurface
+static EGLSurface
 CreateSurfaceForWindow(nsIWidget *aWidget, EGLConfig config)
 {
     EGLSurface surface;
 
 
 #ifdef DEBUG
     sEGLLibrary.DumpEGLConfig(config);
 #endif
@@ -1863,19 +1886,17 @@ already_AddRefed<GLContext>
 GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
 {
     EGLConfig config;
 
     if (!sEGLLibrary.EnsureInitialized()) {
         return nsnull;
     }
 
-    config = CreateConfig();
-
-    if (!config) {
+    if (!CreateConfig(&config)) {
         printf_stderr("Failed to create EGL config!\n");
         return nsnull;
     }
 
     EGLSurface surface = CreateSurfaceForWindow(aWidget, config);
 
     if (!surface) {
         return nsnull;
@@ -2234,34 +2255,16 @@ GLContextProviderEGL::CreateOffscreen(co
         return nsnull;
     }
     return glContext.forget();
 #else
     return nsnull;
 #endif
 }
 
-static ContextFormat
-ContentTypeToGLFormat(gfxASurface::gfxContentType aCType)
-{
-    switch (aCType) {
-        case gfxASurface::CONTENT_COLOR_ALPHA:
-            return ContextFormat::BasicRGBA32;
-        case gfxASurface::CONTENT_COLOR:
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-            return ContextFormat::BasicRGB16_565;
-#else
-            return ContextFormat::BasicRGB24;
-#endif
-        default:
-            break;
-    }
-    return ContextFormat::BasicRGBA32;
-}
-
 already_AddRefed<GLContext>
 GLContextProviderEGL::CreateForNativePixmapSurface(gfxASurface* aSurface)
 {
     if (!sEGLLibrary.EnsureInitialized())
         return nsnull;
 
 #ifdef MOZ_X11
     EGLSurface surface = nsnull;
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -30,64 +30,34 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-#include "mozilla/dom/ContentChild.h"
-#include "nsXULAppAPI.h"
-
-#include <android/log.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
 
 #include "gfxAndroidPlatform.h"
 
-#include "cairo.h"
-#include "cairo-ft.h"
-
+#include "gfxFT2FontList.h"
 #include "gfxImageSurface.h"
 
-#include "nsUnicharUtils.h"
-
-#include "nsMathUtils.h"
-#include "nsTArray.h"
-
-#include "qcms.h"
+#include "cairo.h"
 
 #include "ft2build.h"
 #include FT_FREETYPE_H
-#include "gfxFT2Fonts.h"
-#include "gfxPlatformFontList.h"
-#include "gfxFT2FontList.h"
-#include "mozilla/scache/StartupCache.h"
-#include "nsXPCOMStrings.h"
-
-using namespace mozilla;
-using namespace dom;
 
 static FT_Library gPlatformFTLibrary = NULL;
 
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoFonts" , ## args)
 
 gfxAndroidPlatform::gfxAndroidPlatform()
 {
     FT_Init_FreeType(&gPlatformFTLibrary);
-
-    mFonts.Init(200);
-    mFontAliases.Init(20);
-    mFontSubstitutes.Init(50);
-    mPrefFonts.Init(10);
-
-    UpdateFontList();
 }
 
 gfxAndroidPlatform::~gfxAndroidPlatform()
 {
     cairo_debug_reset_static_data();
 
     FT_Done_FreeType(gPlatformFTLibrary);
     gPlatformFTLibrary = NULL;
@@ -101,480 +71,61 @@ gfxAndroidPlatform::CreateOffscreenSurfa
     if (contentType == gfxImageSurface::CONTENT_COLOR)
         newSurface = new gfxImageSurface (size, GetOffscreenFormat());
     else
         newSurface = new gfxImageSurface (size, gfxASurface::FormatFromContent(contentType));
 
     return newSurface.forget();
 }
 
-struct FontListData {
-    FontListData(nsIAtom *aLangGroup, const nsACString& aGenericFamily, nsTArray<nsString>& aListOfFonts) :
-        mLangGroup(aLangGroup), mGenericFamily(aGenericFamily), mStringArray(aListOfFonts) {}
-    nsIAtom *mLangGroup;
-    const nsACString& mGenericFamily;
-    nsTArray<nsString>& mStringArray;
-};
-
-static PLDHashOperator
-FontListHashEnumFunc(nsStringHashKey::KeyType aKey,
-                     nsRefPtr<FontFamily>& aFontFamily,
-                     void* userArg)
-{
-    FontListData *data = (FontListData*)userArg;
-
-    // use the first variation for now.  This data should be the same
-    // for all the variations and should probably be moved up to
-    // the Family
-    gfxFontStyle style;
-    style.language = data->mLangGroup;
-    nsRefPtr<FontEntry> aFontEntry = aFontFamily->FindFontEntry(style);
-    NS_ASSERTION(aFontEntry, "couldn't find any font entry in family");
-    if (!aFontEntry)
-        return PL_DHASH_NEXT;
-
-
-    data->mStringArray.AppendElement(aFontFamily->Name());
-
-    return PL_DHASH_NEXT;
-}
-
 nsresult
 gfxAndroidPlatform::GetFontList(nsIAtom *aLangGroup,
                                 const nsACString& aGenericFamily,
                                 nsTArray<nsString>& aListOfFonts)
 {
-    FontListData data(aLangGroup, aGenericFamily, aListOfFonts);
-
-    mFonts.Enumerate(FontListHashEnumFunc, &data);
-
-    aListOfFonts.Sort();
-    aListOfFonts.Compact();
-
+    gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup,
+                                                         aGenericFamily,
+                                                         aListOfFonts);
     return NS_OK;
 }
 
-class FontNameCache {
-public:
-    typedef nsAutoTArray<PRUint32, 8> IndexList;
-    PLDHashTableOps ops;
-    FontNameCache() : mWriteNeeded(PR_FALSE) {
-        ops = (PLDHashTableOps) {
-            PL_DHashAllocTable,
-            PL_DHashFreeTable,
-            StringHash,
-            HashMatchEntry,
-            MoveEntry,
-            PL_DHashClearEntryStub,
-            PL_DHashFinalizeStub,
-            NULL};
-        if (!PL_DHashTableInit(&mMap, &ops, nsnull,
-                               sizeof(FNCMapEntry), 0)) {
-            mMap.ops = nsnull;
-            LOG("initializing the map failed");
-        }
-        NS_ABORT_IF_FALSE(XRE_GetProcessType() == GeckoProcessType_Default,
-                          "StartupCacheFontNameCache should only be used in chrome procsess");
-        mCache = mozilla::scache::StartupCache::GetSingleton();
-        Init();
-    }
-
-    void Init()
-    {
-        if (!mMap.ops || !mCache)
-            return;
-        nsCAutoString prefName("font.cache");
-        PRUint32 size;
-        char* buf;
-        if (NS_FAILED(mCache->GetBuffer(prefName.get(), &buf, &size)))
-            return;
-
-        LOG("got: %s from the cache", nsDependentCString(buf, size).get());
-        char* entry = strtok(buf, ";");
-        while (entry) {
-            nsCString faceList, filename, indexes;
-            PRUint32 timestamp, fileSize;
-            filename.Assign(entry);
-            entry = strtok(NULL, ";");
-            if (!entry)
-                break;
-            faceList.Assign(entry);
-            entry = strtok(NULL, ";");
-            if (!entry)
-                break;
-            char* endptr;
-            timestamp = strtoul(entry, &endptr, 10);
-            if (*endptr != '\0')
-                break;
-            entry = strtok(NULL, ";");
-            if (!entry)
-                break;
-            fileSize = strtoul(entry, &endptr, 10);
-            if (*endptr != '\0')
-                break;
-            entry = strtok(NULL, ";");
-            if (!entry)
-                break;
-            indexes.Assign(entry);
-            FNCMapEntry* mapEntry =
-                static_cast<FNCMapEntry*>
-                (PL_DHashTableOperate(&mMap, filename.get(), PL_DHASH_ADD));
-            if (mapEntry) {
-                mapEntry->mFilename = filename;
-                mapEntry->mTimestamp = timestamp;
-                mapEntry->mFilesize = fileSize;
-                mapEntry->mFaces.AssignWithConversion(faceList);
-                mapEntry->mIndexes = indexes;
-            }
-            entry = strtok(NULL, ";");
-        }
-        free(buf);
-    }
-
-    virtual void
-    GetInfoForFile(nsCString& aFileName, nsAString& aFaceList,
-                   PRUint32 *aTimestamp, PRUint32 *aFileSize,
-                   IndexList &aIndexList)
-    {
-        if (!mMap.ops)
-            return;
-        PLDHashEntryHdr *hdr = PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_LOOKUP);
-        if (!hdr)
-            return;
-        FNCMapEntry* entry = static_cast<FNCMapEntry*>(hdr);
-        if (entry && entry->mTimestamp && entry->mFilesize) {
-            *aTimestamp = entry->mTimestamp;
-            *aFileSize = entry->mFilesize;
-            char* indexes = const_cast<char*>(entry->mIndexes.get());
-            char* endptr = indexes + 1;
-            unsigned long index = strtoul(indexes, &endptr, 10);
-            while (indexes < endptr && indexes[0] != '\0') {
-                aIndexList.AppendElement(index);
-                indexes = endptr + 1;
-            }
-            aFaceList.Assign(entry->mFaces);
-        }
-    }
-
-    virtual void
-    CacheFileInfo(nsCString& aFileName, nsAString& aFaceList,
-                  PRUint32 aTimestamp, PRUint32 aFileSize,
-                  IndexList &aIndexList)
-    {
-        if (!mMap.ops)
-            return;
-        FNCMapEntry* entry =
-            static_cast<FNCMapEntry*>
-            (PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_ADD));
-        if (entry) {
-            entry->mFilename = aFileName;
-            entry->mTimestamp = aTimestamp;
-            entry->mFilesize = aFileSize;
-            entry->mFaces.Assign(aFaceList);
-            for (PRUint32 i = 0; i < aIndexList.Length(); i++) {
-                entry->mIndexes.AppendInt(aIndexList[i]);
-                entry->mIndexes.Append(",");
-            }
-        }
-        mWriteNeeded = PR_TRUE;
-    }
-    ~FontNameCache() {
-        if (!mMap.ops)
-            return;
-
-        if (!mWriteNeeded || !mCache) {
-            PL_DHashTableFinish(&mMap);
-            return;
-        }
-
-        nsCAutoString buf;
-        PL_DHashTableEnumerate(&mMap, WriteOutMap, &buf);
-        PL_DHashTableFinish(&mMap);
-        nsCAutoString prefName("font.cache");
-        mCache->PutBuffer(prefName.get(), buf.get(), buf.Length() + 1);
-    }
-private:
-    mozilla::scache::StartupCache* mCache;
-    PLDHashTable mMap;
-    PRBool mWriteNeeded;
-
-    static PLDHashOperator WriteOutMap(PLDHashTable *aTable,
-                                       PLDHashEntryHdr *aHdr,
-                                       PRUint32 aNumber, void *aData)
-    {
-        nsCAutoString* buf = (nsCAutoString*)aData;
-        FNCMapEntry* entry = static_cast<FNCMapEntry*>(aHdr);
-
-        buf->Append(entry->mFilename);
-        buf->Append(";");
-        buf->AppendWithConversion(entry->mFaces);
-        buf->Append(";");
-        buf->AppendInt(entry->mTimestamp);
-        buf->Append(";");
-        buf->AppendInt(entry->mFilesize);
-        buf->Append(";");
-        buf->Append(entry->mIndexes);
-        buf->Append(";");
-
-        return PL_DHASH_NEXT;
-    }
-
-    typedef struct : public PLDHashEntryHdr {
-    public:
-        nsCString mFilename;
-        PRUint32 mTimestamp;
-        PRUint32 mFilesize;
-        nsString mFaces;
-        nsCString mIndexes;
-    } FNCMapEntry;
-
-
-    static PLDHashNumber StringHash(PLDHashTable *table, const void *key) {
-        PLDHashNumber h = 0;
-        for (const char *s = reinterpret_cast<const char*>(key); *s; ++s)
-            h = PR_ROTATE_LEFT32(h, 4) ^ NS_ToLower(*s);
-        return h;
-    }
-
-    static PRBool HashMatchEntry(PLDHashTable *table,
-                                 const PLDHashEntryHdr *aHdr, const void *key)
-    {
-        const FNCMapEntry* entry =
-            static_cast<const FNCMapEntry*>(aHdr);
-        return entry->mFilename.Equals((char*)key);
-    }
-
-    static void MoveEntry(PLDHashTable *table, const PLDHashEntryHdr *aFrom,
-                          PLDHashEntryHdr *aTo)
-    {
-        FNCMapEntry* to =
-            static_cast<FNCMapEntry*>(aTo);
-        const FNCMapEntry* from =
-            static_cast<const FNCMapEntry*>(aFrom);
-        to->mFilename.Assign(from->mFilename);
-        to->mTimestamp = from->mTimestamp;
-        to->mFilesize = from->mFilesize;
-        to->mFaces.Assign(from->mFaces);
-        to->mIndexes.Assign(from->mIndexes);
-    }
-
-};
-
-void
-gfxAndroidPlatform::AppendFacesFromFontFile(const char *aFileName, FontNameCache* aFontCache, InfallibleTArray<FontListEntry>* aFontList)
-{
-    nsString faceList;
-    PRUint32 timestamp = 0;
-    PRUint32 filesize = 0;
-    FontNameCache::IndexList indexList;
-    nsCString fileName(aFileName);
-    if (aFontCache)
-        aFontCache->GetInfoForFile(fileName, faceList, &timestamp, &filesize, indexList);
-    struct stat s;
-    int stat_ret = stat(aFileName, &s);
-    if (!faceList.IsEmpty() && indexList.Length() && 0 == stat_ret &&
-        s.st_mtime == timestamp && s.st_size == filesize) {
-        PRInt32 beginning = 0;
-        PRInt32 end = faceList.Find(",", PR_TRUE, beginning, -1);
-        for (PRUint32 i = 0; i < indexList.Length() && end != kNotFound; i++) {
-            nsDependentSubstring name(faceList, beginning, end);
-            ToLowerCase(name);
-            FontListEntry fle(NS_ConvertUTF16toUTF8(name), fileName,
-                              indexList[i]);
-            aFontList->AppendElement(fle);
-            beginning = end + 1;
-            end = faceList.Find(",", PR_TRUE, beginning, -1);
-        }
-        return;
-    }
-
-    faceList.AssignLiteral("");
-    timestamp = s.st_mtime;
-    filesize = s.st_size;
-    FT_Face dummy;
-    if (FT_Err_Ok == FT_New_Face(GetFTLibrary(), aFileName, -1, &dummy)) {
-        for (FT_Long i = 0; i < dummy->num_faces; i++) {
-            FT_Face face;
-            if (FT_Err_Ok != FT_New_Face(GetFTLibrary(), aFileName,
-                                         i, &face))
-                continue;
-            nsDependentCString name(face->family_name);
-            ToLowerCase(name);
-
-            nsRefPtr<FontFamily> ff;
-            faceList.AppendWithConversion(name);
-            faceList.AppendLiteral(",");
-            indexList.AppendElement(i);
-            ToLowerCase(name);
-            FontListEntry fle(name, fileName, i);
-            aFontList->AppendElement(fle);
-        }
-        FT_Done_Face(dummy);
-        if (aFontCache && 0 == stat_ret)
-            aFontCache->CacheFileInfo(fileName, faceList, timestamp, filesize, indexList);
-    }
-}
-
-void
-gfxAndroidPlatform::FindFontsInDirectory(const nsCString& aFontsDir,
-                                         FontNameCache* aFontCache)
-{
-    static const char* sStandardFonts[] = {
-        "DroidSans.ttf",
-        "DroidSans-Bold.ttf",
-        "DroidSerif-Regular.ttf",
-        "DroidSerif-Bold.ttf",
-        "DroidSerif-Italic.ttf",
-        "DroidSerif-BoldItalic.ttf",
-        "DroidSansMono.ttf",
-        "DroidSansArabic.ttf",
-        "DroidSansHebrew.ttf",
-        "DroidSansThai.ttf",
-        "MTLmr3m.ttf",
-        "MTLc3m.ttf",
-        "DroidSansJapanese.ttf",
-        "DroidSansFallback.ttf"
-    };
-
-    DIR *d = opendir(aFontsDir.get());
-    struct dirent *ent = NULL;
-    while(d && (ent = readdir(d)) != NULL) {
-        int namelen = strlen(ent->d_name);
-        if (namelen > 4 &&
-            strcasecmp(ent->d_name + namelen - 4, ".ttf") == 0)
-        {
-            bool isStdFont = false;
-            for (unsigned int i = 0; i < NS_ARRAY_LENGTH(sStandardFonts) && !isStdFont; i++) {
-                isStdFont = strcmp(sStandardFonts[i], ent->d_name) == 0;
-            }
-            if (!isStdFont) {
-                nsCString s(aFontsDir);
-                s.Append(nsDependentCString(ent->d_name));
-
-                AppendFacesFromFontFile(s.get(), aFontCache, &mFontList);
-            }
-        }
-    }
-    closedir(d);
-    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(sStandardFonts); i++) {
-        nsCString s(aFontsDir);
-        s.Append(nsDependentCString(sStandardFonts[i]));
-
-        AppendFacesFromFontFile(s.get(), aFontCache, &mFontList);
-    }
-}
-
 void
 gfxAndroidPlatform::GetFontList(InfallibleTArray<FontListEntry>* retValue)
 {
-    if (XRE_GetProcessType() != GeckoProcessType_Default) {
-        mozilla::dom::ContentChild::GetSingleton()->SendReadFontList(retValue);
-        return;
-    }
-
-    if (mFontList.Length() > 0) {
-        *retValue = mFontList;
-        return;
-    }
-
-    // ANDROID_ROOT is the root of the android system, typically /system
-    // font files are in /$ANDROID_ROOT/fonts/
-    FontNameCache fnc;
-    FindFontsInDirectory(NS_LITERAL_CSTRING("/system/fonts/"), &fnc);
-    char *androidRoot = PR_GetEnv("ANDROID_ROOT");
-    if (androidRoot && strcmp(androidRoot, "/system")) {
-        nsCString root(androidRoot);
-        root.Append("/fonts/");
-        FindFontsInDirectory(root, &fnc);
-    }
-
-    *retValue = mFontList;
+    gfxFT2FontList::PlatformFontList()->GetFontList(retValue);
 }
 
 nsresult
 gfxAndroidPlatform::UpdateFontList()
 {
-    gfxFontCache *fc = gfxFontCache::GetCache();
-    if (fc)
-        fc->AgeAllGenerations();
-    mFonts.Clear();
-    mFontAliases.Clear();
-    mFontSubstitutes.Clear();
-    mPrefFonts.Clear();
-    mCodepointsWithNoFonts.reset();
-
-    InfallibleTArray<FontListEntry> fontList;
-    GetFontList(&fontList);
-    for (PRUint32 i = 0; i < fontList.Length(); i++) {
-        NS_ConvertUTF8toUTF16 name(fontList[i].familyName());
-        nsRefPtr<FontFamily> ff;
-        if (!mFonts.Get(name, &ff)) {
-            ff = new FontFamily(name);
-            mFonts.Put(name, ff);
-        }
-        ff->AddFontFileAndIndex(fontList[i].filepath(), fontList[i].index());
-    }
-
-    // initialize the cmap loading process after font list has been initialized
-    //StartLoader(kDelayBeforeLoadingCmaps, kIntervalBetweenLoadingCmaps);
-
-    // initialize ranges of characters for which system-wide font search should be skipped
-    mCodepointsWithNoFonts.SetRange(0,0x1f);     // C0 controls
-    mCodepointsWithNoFonts.SetRange(0x7f,0x9f);  // C1 controls
-
+    gfxPlatformFontList::PlatformFontList()->UpdateFontList();
     return NS_OK;
 }
 
 nsresult
 gfxAndroidPlatform::ResolveFontName(const nsAString& aFontName,
                                     FontResolverCallback aCallback,
                                     void *aClosure,
                                     PRBool& aAborted)
 {
-    if (aFontName.IsEmpty())
-        return NS_ERROR_FAILURE;
-
     nsAutoString resolvedName;
-    gfxPlatformFontList* platformFontList = gfxPlatformFontList::PlatformFontList();
-    if (platformFontList) {
-        if (!platformFontList->ResolveFontName(aFontName, resolvedName)) {
-            aAborted = PR_FALSE;
-            return NS_OK;
-        }
+    if (!gfxPlatformFontList::PlatformFontList()->
+             ResolveFontName(aFontName, resolvedName)) {
+        aAborted = PR_FALSE;
+        return NS_OK;
     }
-
-    nsAutoString keyName(aFontName);
-    ToLowerCase(keyName);
-
-    nsRefPtr<FontFamily> ff;
-    if (mFonts.Get(keyName, &ff) ||
-        mFontSubstitutes.Get(keyName, &ff) ||
-        mFontAliases.Get(keyName, &ff))
-    {
-        aAborted = !(*aCallback)(ff->Name(), aClosure);
-    } else {
-        aAborted = PR_FALSE;
-    }
-
+    aAborted = !(*aCallback)(resolvedName, aClosure);
     return NS_OK;
 }
 
-static PRBool SimpleResolverCallback(const nsAString& aName, void* aClosure)
-{
-    nsString *result = static_cast<nsString*>(aClosure);
-    result->Assign(aName);
-    return PR_FALSE;
-}
-
 nsresult
 gfxAndroidPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
 {
-    aFamilyName.Truncate();
-    PRBool aborted;
-    return ResolveFontName(aFontName, SimpleResolverCallback, &aFamilyName, aborted);
+    gfxPlatformFontList::PlatformFontList()->GetStandardFamilyName(aFontName, aFamilyName);
+    return NS_OK;
 }
 
 gfxPlatformFontList*
 gfxAndroidPlatform::CreatePlatformFontList()
 {
     gfxPlatformFontList* list = new gfxFT2FontList();
     if (NS_SUCCEEDED(list->InitFontList())) {
         return list;
@@ -606,99 +157,26 @@ gfxAndroidPlatform::IsFontFormatSupporte
     return PR_TRUE;
 }
 
 gfxFontGroup *
 gfxAndroidPlatform::CreateFontGroup(const nsAString &aFamilies,
                                const gfxFontStyle *aStyle,
                                gfxUserFontSet* aUserFontSet)
 {
-    return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
+    return new gfxFontGroup(aFamilies, aStyle, aUserFontSet);
 }
 
 FT_Library
 gfxAndroidPlatform::GetFTLibrary()
 {
     return gPlatformFTLibrary;
 }
 
-FontFamily *
-gfxAndroidPlatform::FindFontFamily(const nsAString& aName)
-{
-    nsAutoString name(aName);
-    ToLowerCase(name);
-
-    nsRefPtr<FontFamily> ff;
-    if (!mFonts.Get(name, &ff) &&
-        !mFontSubstitutes.Get(name, &ff) &&
-        !mFontAliases.Get(name, &ff)) {
-        return nsnull;
-    }
-    return ff.get();
-}
-
-FontEntry *
-gfxAndroidPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
-{
-    nsRefPtr<FontFamily> ff = FindFontFamily(aName);
-    if (!ff)
-        return nsnull;
-
-    return ff->FindFontEntry(aFontStyle);
-}
-
-static PLDHashOperator
-FindFontForCharProc(nsStringHashKey::KeyType aKey,
-                    nsRefPtr<FontFamily>& aFontFamily,
-                    void* aUserArg)
-{
-    FontSearch *data = (FontSearch*)aUserArg;
-    aFontFamily->FindFontForChar(data);
-    return PL_DHASH_NEXT;
-}
-
-already_AddRefed<gfxFont>
-gfxAndroidPlatform::FindFontForChar(PRUint32 aCh, gfxFont *aFont)
-{
-    // is codepoint with no matching font? return null immediately
-    if (mCodepointsWithNoFonts.test(aCh)) {
-        return nsnull;
-    }
-
-    FontSearch data(aCh, aFont);
-
-    // find fonts that support the character
-    mFonts.Enumerate(FindFontForCharProc, &data);
-
-    if (data.mBestMatch) {
-        nsRefPtr<gfxFT2Font> font =
-            gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
-                                      aFont->GetStyle());
-        gfxFont* ret = font.forget().get();
-        return already_AddRefed<gfxFont>(ret);
-    }
-
-    // no match? add to set of non-matching codepoints
-    mCodepointsWithNoFonts.set(aCh);
-
-    return nsnull;
-}
-
 gfxFontEntry* 
 gfxAndroidPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                      const PRUint8 *aFontData, PRUint32 aLength)
 {
     return gfxPlatformFontList::PlatformFontList()->MakePlatformFont(aProxyEntry,
                                                                      aFontData,
                                                                      aLength);
 }
 
-PRBool
-gfxAndroidPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList)
-{
-    return mPrefFonts.Get(aKey, aFontEntryList);
-}
-
-void
-gfxAndroidPlatform::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList)
-{
-    mPrefFonts.Put(aKey, aFontEntryList);
-}
--- a/gfx/thebes/gfxAndroidPlatform.h
+++ b/gfx/thebes/gfxAndroidPlatform.h
@@ -34,93 +34,68 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GFX_PLATFORM_ANDROID_H
 #define GFX_PLATFORM_ANDROID_H
 
-#include "gfxFontUtils.h"
 #include "gfxFT2Fonts.h"
 #include "gfxPlatform.h"
-#include "nsDataHashtable.h"
+#include "gfxUserFontSet.h"
 #include "nsTArray.h"
 
-typedef struct FT_LibraryRec_ *FT_Library;
-
-class FontFamily;
-class FontEntry;
 namespace mozilla {
     namespace dom {
         class FontListEntry;
     };
 };
+using mozilla::dom::FontListEntry;
 
-using namespace mozilla;
-using namespace dom;
-
-class FontNameCache;
+typedef struct FT_LibraryRec_ *FT_Library;
 
 class THEBES_API gfxAndroidPlatform : public gfxPlatform {
 public:
     gfxAndroidPlatform();
     virtual ~gfxAndroidPlatform();
 
     static gfxAndroidPlatform *GetPlatform() {
         return (gfxAndroidPlatform*) gfxPlatform::GetPlatform();
     }
 
+    virtual already_AddRefed<gfxASurface>
+    CreateOffscreenSurface(const gfxIntSize& size,
+                           gfxASurface::gfxContentType contentType);
+
+    virtual gfxImageFormat GetOffscreenFormat() { return gfxASurface::ImageFormatRGB16_565; }
+
+    // to support IPC font list (sharing between chrome and content)
     void GetFontList(InfallibleTArray<FontListEntry>* retValue);
 
-    already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
-                                                         gfxASurface::gfxContentType contentType);
-
+    // platform implementations of font functions
     virtual PRBool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags);
     virtual gfxPlatformFontList* CreatePlatformFontList();
     virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
-                                     const PRUint8 *aFontData, PRUint32 aLength);
-
-    nsresult GetFontList(nsIAtom *aLangGroup,
-                         const nsACString& aGenericFamily,
-                         nsTArray<nsString>& aListOfFonts);
+                                           const PRUint8 *aFontData, PRUint32 aLength);
 
-    nsresult UpdateFontList();
+    virtual nsresult GetFontList(nsIAtom *aLangGroup,
+                                 const nsACString& aGenericFamily,
+                                 nsTArray<nsString>& aListOfFonts);
 
-    nsresult ResolveFontName(const nsAString& aFontName,
-                             FontResolverCallback aCallback,
-                             void *aClosure, PRBool& aAborted);
+    virtual nsresult UpdateFontList();
 
-    nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
-
-    gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
-                                  const gfxFontStyle *aStyle,
-                                  gfxUserFontSet* aUserFontSet);
+    virtual nsresult ResolveFontName(const nsAString& aFontName,
+                                     FontResolverCallback aCallback,
+                                     void *aClosure, PRBool& aAborted);
 
-    FontFamily *FindFontFamily(const nsAString& aName);
-    FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
-    already_AddRefed<gfxFont> FindFontForChar(PRUint32 aCh, gfxFont *aFont);
-    PRBool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
-    void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
+    virtual nsresult GetStandardFamilyName(const nsAString& aFontName,
+                                           nsAString& aFamilyName);
+
+    virtual gfxFontGroup *CreateFontGroup(const nsAString &aFamilies,
+                                          const gfxFontStyle *aStyle,
+                                          gfxUserFontSet* aUserFontSet);
 
     FT_Library GetFTLibrary();
-
-    virtual gfxImageFormat GetOffscreenFormat() { return gfxASurface::ImageFormatRGB16_565; }
-
-protected:
-    void AppendFacesFromFontFile(const char *aFileName, FontNameCache* aFontCache, InfallibleTArray<FontListEntry>* retValue);
-    void FindFontsInDirectory(const nsCString& aFontsDir, FontNameCache* aFontCache);
-
-    typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
-
-    FontTable mFonts;
-    FontTable mFontAliases;
-    FontTable mFontSubstitutes;
-    InfallibleTArray<FontListEntry> mFontList;
-
-    // when system-wide font lookup fails for a character, cache it to skip future searches
-    gfxSparseBitSet mCodepointsWithNoFonts;
-    
-    nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > mPrefFonts;
 };
 
 #endif /* GFX_PLATFORM_ANDROID_H */
 
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -34,137 +34,782 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "gfxFT2FontList.h"
-#include "gfxUserFontSet.h"
-#include "gfxFontUtils.h"
+#if defined(MOZ_WIDGET_GTK2)
+#include "gfxPlatformGtk.h"
+#define gfxToolkitPlatform gfxPlatformGtk
+#elif defined(MOZ_WIDGET_QT)
+#include <qfontinfo.h>
+#include "gfxQtPlatform.h"
+#define gfxToolkitPlatform gfxQtPlatform
+#elif defined(XP_WIN)
+#include "gfxWindowsPlatform.h"
+#define gfxToolkitPlatform gfxWindowsPlatform
+#elif defined(ANDROID)
+#include "mozilla/dom/ContentChild.h"
+#include "gfxAndroidPlatform.h"
+#define gfxToolkitPlatform gfxAndroidPlatform
+#endif
+
+#ifdef ANDROID
+#include "nsXULAppAPI.h"
+#include <dirent.h>
+#include <android/log.h>
+#define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args)
+#endif
 
 #include "ft2build.h"
 #include FT_FREETYPE_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_TRUETYPE_TABLES_H
+#include "cairo-ft.h"
+
+#include "gfxFT2FontList.h"
 #include "gfxFT2Fonts.h"
+#include "gfxUserFontSet.h"
+#include "gfxFontUtils.h"
 
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 #include "nsUnicharUtils.h"
 
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsISimpleEnumerator.h"
 
+#include "mozilla/scache/StartupCache.h"
+#include <sys/stat.h>
+
 #ifdef XP_WIN
 #include "nsIWindowsRegKey.h"
 #include <windows.h>
 #endif
 
-#define ROUND(x) floor((x) + 0.5)
-
 #ifdef PR_LOGGING
 static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog");
 #endif /* PR_LOGGING */
 
-#ifdef ANDROID
-#include "gfxAndroidPlatform.h"
-#include <dirent.h>
-#include <android/log.h>
-#define ALOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args)
-
-#endif
+#undef LOG
 #define LOG(args) PR_LOG(gFontInfoLog, PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(gFontInfoLog, PR_LOG_DEBUG)
 
 static __inline void
 BuildKeyNameFromFontName(nsAString &aName)
 {
 #ifdef XP_WIN
     if (aName.Length() >= LF_FACESIZE)
         aName.Truncate(LF_FACESIZE - 1);
 #endif
     ToLowerCase(aName);
 }
 
+/*
+ * FT2FontEntry
+ * gfxFontEntry subclass corresponding to a specific face that can be
+ * rendered by freetype. This is associated with a face index in a
+ * file (normally a .ttf/.otf file holding a single face, but in principle
+ * there could be .ttc files with multiple faces).
+ * The FT2FontEntry can create the necessary FT_Face on demand, and can
+ * then create a Cairo font_face and scaled_font for drawing.
+ */
+
+cairo_scaled_font_t *
+FT2FontEntry::CreateScaledFont(const gfxFontStyle *aStyle)
+{
+    cairo_scaled_font_t *scaledFont = NULL;
+
+    cairo_matrix_t sizeMatrix;
+    cairo_matrix_t identityMatrix;
+
+    // XXX deal with adjusted size
+    cairo_matrix_init_scale(&sizeMatrix, aStyle->size, aStyle->size);
+    cairo_matrix_init_identity(&identityMatrix);
+
+    // synthetic oblique by skewing via the font matrix
+    PRBool needsOblique = !IsItalic() &&
+            (aStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE));
+
+    if (needsOblique) {
+        const double kSkewFactor = 0.25;
+
+        cairo_matrix_t style;
+        cairo_matrix_init(&style,
+                          1,                //xx
+                          0,                //yx
+                          -1 * kSkewFactor,  //xy
+                          1,                //yy
+                          0,                //x0
+                          0);               //y0
+        cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
+    }
+
+    cairo_font_options_t *fontOptions = cairo_font_options_create();
+
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+    cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
+#endif
+
+    scaledFont = cairo_scaled_font_create(CairoFontFace(),
+                                          &sizeMatrix,
+                                          &identityMatrix, fontOptions);
+    cairo_font_options_destroy(fontOptions);
+
+    NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
+                 "Failed to make scaled font");
+
+    return scaledFont;
+}
+
+FT2FontEntry::~FT2FontEntry()
+{
+    // Do nothing for mFTFace here since FTFontDestroyFunc is called by cairo.
+    mFTFace = nsnull;
+
+#ifndef ANDROID
+    if (mFontFace) {
+        cairo_font_face_destroy(mFontFace);
+        mFontFace = nsnull;
+    }
+#endif
+}
+
+gfxFont*
+FT2FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold)
+{
+    cairo_scaled_font_t *scaledFont = CreateScaledFont(aFontStyle);
+    gfxFont *font = new gfxFT2Font(scaledFont, this, aFontStyle, aNeedsBold);
+    cairo_scaled_font_destroy(scaledFont);
+    return font;
+}
+
+/* static */
+FT2FontEntry*
+FT2FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
+                              const PRUint8 *aFontData,
+                              PRUint32 aLength)
+{
+    // Ownership of aFontData is passed in here; the fontEntry must
+    // retain it as long as the FT_Face needs it, and ensure it is
+    // eventually deleted.
+    FT_Face face;
+    FT_Error error =
+        FT_New_Memory_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(),
+                           aFontData, aLength, 0, &face);
+    if (error != FT_Err_Ok) {
+        NS_Free((void*)aFontData);
+        return nsnull;
+    }
+    FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(face, nsnull, 0, aFontData);
+    if (fe) {
+        fe->mItalic = aProxyEntry.mItalic;
+        fe->mWeight = aProxyEntry.mWeight;
+        fe->mStretch = aProxyEntry.mStretch;
+    }
+    return fe;
+}
+
+class FTUserFontData {
+public:
+    FTUserFontData(FT_Face aFace, const PRUint8* aData)
+        : mFace(aFace), mFontData(aData)
+    {
+    }
+
+    ~FTUserFontData()
+    {
+        FT_Done_Face(mFace);
+        if (mFontData) {
+            NS_Free((void*)mFontData);
+        }
+    }
+
+private:
+    FT_Face        mFace;
+    const PRUint8 *mFontData;
+};
+
+static void
+FTFontDestroyFunc(void *data)
+{
+    FTUserFontData *userFontData = static_cast<FTUserFontData*>(data);
+    delete userFontData;
+}
+
+/* static */
+FT2FontEntry*
+FT2FontEntry::CreateFontEntry(const FontListEntry& aFLE)
+{
+    FT2FontEntry *fe = new FT2FontEntry(aFLE.faceName());
+    fe->mFilename = aFLE.filepath();
+    fe->mFTFontIndex = aFLE.index();
+    fe->mWeight = aFLE.weight();
+    fe->mStretch = aFLE.stretch();
+    fe->mItalic = aFLE.italic();
+    return fe;
+}
+
+/* static */
+FT2FontEntry*
+FT2FontEntry::CreateFontEntry(FT_Face aFace,
+                              const char* aFilename, PRUint8 aIndex,
+                              const PRUint8 *aFontData)
+{
+    static cairo_user_data_key_t key;
+
+    if (!aFace->family_name) {
+        FT_Done_Face(aFace);
+        return nsnull;
+    }
+    // Construct font name from family name and style name, regular fonts
+    // do not have the modifier by convention.
+    NS_ConvertUTF8toUTF16 fontName(aFace->family_name);
+    if (aFace->style_name && strcmp("Regular", aFace->style_name)) {
+        fontName.AppendLiteral(" ");
+        AppendUTF8toUTF16(aFace->style_name, fontName);
+    }
+    FT2FontEntry *fe = new FT2FontEntry(fontName);
+    fe->mItalic = aFace->style_flags & FT_STYLE_FLAG_ITALIC;
+    fe->mFTFace = aFace;
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
+#else
+    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, 0);
+#endif
+    fe->mFilename = aFilename;
+    fe->mFTFontIndex = aIndex;
+    FTUserFontData *userFontData = new FTUserFontData(aFace, aFontData);
+    cairo_font_face_set_user_data(fe->mFontFace, &key,
+                                  userFontData, FTFontDestroyFunc);
+
+    TT_OS2 *os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(aFace, ft_sfnt_os2));
+    PRUint16 os2weight = 0;
+    if (os2 && os2->version != 0xffff) {
+        // Technically, only 100 to 900 are valid, but some fonts
+        // have this set wrong -- e.g. "Microsoft Logo Bold Italic" has
+        // it set to 6 instead of 600.  We try to be nice and handle that
+        // as well.
+        if (os2->usWeightClass >= 100 && os2->usWeightClass <= 900)
+            os2weight = os2->usWeightClass;
+        else if (os2->usWeightClass >= 1 && os2->usWeightClass <= 9)
+            os2weight = os2->usWeightClass * 100;
+    }
+
+    if (os2weight != 0)
+        fe->mWeight = os2weight;
+    else if (aFace->style_flags & FT_STYLE_FLAG_BOLD)
+        fe->mWeight = 700;
+    else
+        fe->mWeight = 400;
+
+    NS_ASSERTION(fe->mWeight >= 100 && fe->mWeight <= 900, "Invalid final weight in font!");
+
+    return fe;
+}
+
+FT2FontEntry*
+gfxFT2Font::GetFontEntry()
+{
+    return static_cast<FT2FontEntry*> (mFontEntry.get());
+}
+
+cairo_font_face_t *
+FT2FontEntry::CairoFontFace()
+{
+    static cairo_user_data_key_t key;
+
+    if (!mFontFace) {
+        FT_Face face;
+        FT_New_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(), mFilename.get(), mFTFontIndex, &face);
+        mFTFace = face;
+#ifdef MOZ_GFX_OPTIMIZE_MOBILE
+        mFontFace = cairo_ft_font_face_create_for_ft_face(face, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
+#else
+        mFontFace = cairo_ft_font_face_create_for_ft_face(face, 0);
+#endif
+        FTUserFontData *userFontData = new FTUserFontData(face, nsnull);
+        cairo_font_face_set_user_data(mFontFace, &key,
+                                      userFontData, FTFontDestroyFunc);
+    }
+    return mFontFace;
+}
+
+nsresult
+FT2FontEntry::ReadCMAP()
+{
+    if (mCmapInitialized) {
+        return NS_OK;
+    }
+
+    // attempt this once, if errors occur leave a blank cmap
+    mCmapInitialized = PR_TRUE;
+
+    AutoFallibleTArray<PRUint8,16384> buffer;
+    nsresult rv = GetFontTable(TTAG_cmap, buffer);
+    
+    if (NS_SUCCEEDED(rv)) {
+        PRPackedBool unicodeFont;
+        PRPackedBool symbolFont;
+        rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
+                                    mCharacterMap, mUVSOffset,
+                                    unicodeFont, symbolFont);
+    }
+
+    mHasCmapTable = NS_SUCCEEDED(rv);
+    return rv;
+}
+
+nsresult
+FT2FontEntry::GetFontTable(PRUint32 aTableTag,
+                           FallibleTArray<PRUint8>& aBuffer)
+{
+    // Ensure existence of mFTFace
+    CairoFontFace();
+    NS_ENSURE_TRUE(mFTFace, NS_ERROR_FAILURE);
+
+    FT_Error status;
+    FT_ULong len = 0;
+    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nsnull, &len);
+    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(len != 0, NS_ERROR_FAILURE);
+
+    if (!aBuffer.SetLength(len)) {
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    PRUint8 *buf = aBuffer.Elements();
+    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, buf, &len);
+    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
+
+    return NS_OK;
+}
+
+/*
+ * FT2FontFamily
+ * A standard gfxFontFamily; just adds a method used to support sending
+ * the font list from chrome to content via IPC.
+ */
+
+void
+FT2FontFamily::AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList)
+{
+    for (int i = 0, n = mAvailableFonts.Length(); i < n; ++i) {
+        const FT2FontEntry *fe =
+            static_cast<const FT2FontEntry*>(mAvailableFonts[i].get());
+        if (!fe) {
+            continue;
+        }
+        
+        aFontList->AppendElement(FontListEntry(Name(), fe->Name(),
+                                               fe->mFilename,
+                                               fe->Weight(), fe->Stretch(),
+                                               fe->IsItalic(),
+                                               fe->mFTFontIndex));
+    }
+}
+
+/*
+ * Startup cache support for the font list:
+ * We store the list of families and faces, with their style attributes and the
+ * corresponding font files, in the startup cache.
+ * This allows us to recreate the gfxFT2FontList collection of families and
+ * faces without instantiating Freetype faces for each font file (in order to
+ * find their attributes), leading to significantly quicker startup.
+ */
+
+#define CACHE_KEY "font.cached-list"
+
+class FontNameCache {
+public:
+    FontNameCache()
+        : mWriteNeeded(PR_FALSE)
+    {
+        mOps = (PLDHashTableOps) {
+            PL_DHashAllocTable,
+            PL_DHashFreeTable,
+            StringHash,
+            HashMatchEntry,
+            MoveEntry,
+            PL_DHashClearEntryStub,
+            PL_DHashFinalizeStub,
+            NULL
+        };
+
+        if (!PL_DHashTableInit(&mMap, &mOps, nsnull,
+                               sizeof(FNCMapEntry), 0))
+        {
+            mMap.ops = nsnull;
+            LOG(("initializing the map failed"));
+        }
+
+        NS_ABORT_IF_FALSE(XRE_GetProcessType() == GeckoProcessType_Default,
+                          "StartupCacheFontNameCache should only be used in chrome process");
+        mCache = mozilla::scache::StartupCache::GetSingleton();
+
+        Init();
+    }
+
+    ~FontNameCache()
+    {
+        if (!mMap.ops) {
+            return;
+        }
+        if (!mWriteNeeded || !mCache) {
+            PL_DHashTableFinish(&mMap);
+            return;
+        }
+
+        nsCAutoString buf;
+        PL_DHashTableEnumerate(&mMap, WriteOutMap, &buf);
+        PL_DHashTableFinish(&mMap);
+        mCache->PutBuffer(CACHE_KEY, buf.get(), buf.Length() + 1);
+    }
+
+    void Init()
+    {
+        if (!mMap.ops || !mCache) {
+            return;
+        }
+        PRUint32 size;
+        char* buf;
+        if (NS_FAILED(mCache->GetBuffer(CACHE_KEY, &buf, &size))) {
+            return;
+        }
+
+        LOG(("got: %s from the cache", nsDependentCString(buf, size).get()));
+
+        const char* beginning = buf;
+        const char* end = strchr(beginning, ';');
+        while (end) {
+            nsCString filename(beginning, end - beginning);
+            beginning = end + 1;
+            if (!(end = strchr(beginning, ';'))) {
+                break;
+            }
+            nsCString faceList(beginning, end - beginning);
+            beginning = end + 1;
+            if (!(end = strchr(beginning, ';'))) {
+                break;
+            }
+            PRUint32 timestamp = strtoul(beginning, NULL, 10);
+            beginning = end + 1;
+            if (!(end = strchr(beginning, ';'))) {
+                break;
+            }
+            PRUint32 filesize = strtoul(beginning, NULL, 10);
+
+            FNCMapEntry* mapEntry =
+                static_cast<FNCMapEntry*>
+                (PL_DHashTableOperate(&mMap, filename.get(), PL_DHASH_ADD));
+            if (mapEntry) {
+                mapEntry->mFilename.Assign(filename);
+                mapEntry->mTimestamp = timestamp;
+                mapEntry->mFilesize = filesize;
+                mapEntry->mFaces.Assign(faceList);
+                // entries from the startupcache are marked "non-existing"
+                // until we have confirmed that the file still exists
+                mapEntry->mFileExists = PR_FALSE;
+            }
+
+            beginning = end + 1;
+            end = strchr(beginning, ';');
+        }
+
+        // Should we use free() or delete[] here? See bug 684700.
+        free(buf);
+    }
+
+    virtual void
+    GetInfoForFile(nsCString& aFileName, nsCString& aFaceList,
+                   PRUint32 *aTimestamp, PRUint32 *aFilesize)
+    {
+        if (!mMap.ops) {
+            return;
+        }
+        PLDHashEntryHdr *hdr =
+            PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_LOOKUP);
+        if (!hdr) {
+            return;
+        }
+        FNCMapEntry* entry = static_cast<FNCMapEntry*>(hdr);
+        if (entry && entry->mTimestamp && entry->mFilesize) {
+            *aTimestamp = entry->mTimestamp;
+            *aFilesize = entry->mFilesize;
+            aFaceList.Assign(entry->mFaces);
+            // this entry does correspond to an existing file
+            // (although it might not be up-to-date, in which case
+            // it will get overwritten via CacheFileInfo)
+            entry->mFileExists = PR_TRUE;
+        }
+    }
+
+    virtual void
+    CacheFileInfo(nsCString& aFileName, nsCString& aFaceList,
+                  PRUint32 aTimestamp, PRUint32 aFilesize)
+    {
+        if (!mMap.ops) {
+            return;
+        }
+        FNCMapEntry* entry =
+            static_cast<FNCMapEntry*>
+            (PL_DHashTableOperate(&mMap, aFileName.get(), PL_DHASH_ADD));
+        if (entry) {
+            entry->mFilename.Assign(aFileName);
+            entry->mTimestamp = aTimestamp;
+            entry->mFilesize = aFilesize;
+            entry->mFaces.Assign(aFaceList);
+            entry->mFileExists = PR_TRUE;
+        }
+        mWriteNeeded = PR_TRUE;
+    }
+
+private:
+    mozilla::scache::StartupCache* mCache;
+    PLDHashTable mMap;
+    PRBool mWriteNeeded;
+
+    PLDHashTableOps mOps;
+
+    static PLDHashOperator WriteOutMap(PLDHashTable *aTable,
+                                       PLDHashEntryHdr *aHdr,
+                                       PRUint32 aNumber, void *aData)
+    {
+        FNCMapEntry* entry = static_cast<FNCMapEntry*>(aHdr);
+        if (!entry->mFileExists) {
+            // skip writing entries for files that are no longer present
+            return PL_DHASH_NEXT;
+        }
+
+        nsCAutoString* buf = reinterpret_cast<nsCAutoString*>(aData);
+        buf->Append(entry->mFilename);
+        buf->Append(';');
+        buf->Append(entry->mFaces);
+        buf->Append(';');
+        buf->AppendInt(entry->mTimestamp);
+        buf->Append(';');
+        buf->AppendInt(entry->mFilesize);
+        buf->Append(';');
+        return PL_DHASH_NEXT;
+    }
+
+    typedef struct : public PLDHashEntryHdr {
+    public:
+        nsCString mFilename;
+        PRUint32  mTimestamp;
+        PRUint32  mFilesize;
+        nsCString mFaces;
+        PRBool    mFileExists;
+    } FNCMapEntry;
+
+    static PLDHashNumber StringHash(PLDHashTable *table, const void *key)
+    {
+        return HashString(reinterpret_cast<const char*>(key));
+    }
+
+    static PRBool HashMatchEntry(PLDHashTable *table,
+                                 const PLDHashEntryHdr *aHdr, const void *key)
+    {
+        const FNCMapEntry* entry =
+            static_cast<const FNCMapEntry*>(aHdr);
+        return entry->mFilename.Equals(reinterpret_cast<const char*>(key));
+    }
+
+    static void MoveEntry(PLDHashTable *table, const PLDHashEntryHdr *aFrom,
+                          PLDHashEntryHdr *aTo)
+    {
+        FNCMapEntry* to = static_cast<FNCMapEntry*>(aTo);
+        const FNCMapEntry* from = static_cast<const FNCMapEntry*>(aFrom);
+        to->mFilename.Assign(from->mFilename);
+        to->mTimestamp = from->mTimestamp;
+        to->mFilesize = from->mFilesize;
+        to->mFaces.Assign(from->mFaces);
+        to->mFileExists = from->mFileExists;
+    }
+};
+
 /***************************************************************
  *
  * gfxFT2FontList
  *
  */
 
-// For Mobile, we use gfxFT2Fonts, and we build the font list by directly scanning
-// the system's Fonts directory for OpenType and TrueType files.
-//
-// FontEntry is currently defined in gfxFT2Fonts.h, but will probably be moved here
-// as part of the Freetype/Linux font restructuring for Harfbuzz integration.
-//
-// TODO: investigate startup performance - we might be able to improve by avoiding
-// the creation of FT_Faces here, and just reading names directly from the file;
-// or even consider caching a mapping from font family name to (list of) filenames,
-// so that we don't have to scan all the files before we can do any font lookups.
+// For Mobile, we use gfxFT2Fonts, and we build the font list by directly
+// scanning the system's Fonts directory for OpenType and TrueType files.
 
 gfxFT2FontList::gfxFT2FontList()
 {
 }
 
 void
-gfxFT2FontList::AppendFacesFromFontFile(const PRUnichar *aFileName)
+gfxFT2FontList::AppendFacesFromCachedFaceList(nsCString& aFileName,
+                                              PRBool aStdFile,
+                                              nsCString& aFaceList)
 {
-    AppendFacesFromFontFile(NS_ConvertUTF16toUTF8(aFileName).get());
+    const char *beginning = aFaceList.get();
+    const char *end = strchr(beginning, ',');
+    while (end) {
+        nsString familyName =
+            NS_ConvertUTF8toUTF16(beginning, end - beginning);
+        ToLowerCase(familyName);
+        beginning = end + 1;
+        if (!(end = strchr(beginning, ','))) {
+            break;
+        }
+        nsString faceName =
+            NS_ConvertUTF8toUTF16(beginning, end - beginning);
+        beginning = end + 1;
+        if (!(end = strchr(beginning, ','))) {
+            break;
+        }
+        PRUint32 index = strtoul(beginning, NULL, 10);
+        beginning = end + 1;
+        if (!(end = strchr(beginning, ','))) {
+            break;
+        }
+        PRBool italic = (*beginning != '0');
+        beginning = end + 1;
+        if (!(end = strchr(beginning, ','))) {
+            break;
+        }
+        PRUint32 weight = strtoul(beginning, NULL, 10);
+        beginning = end + 1;
+        if (!(end = strchr(beginning, ','))) {
+            break;
+        }
+        PRInt32 stretch = strtol(beginning, NULL, 10);
+
+        FontListEntry fle(familyName, faceName, aFileName,
+                          weight, stretch, italic, index);
+        AppendFaceFromFontListEntry(fle, aStdFile);
+
+        beginning = end + 1;
+        end = strchr(beginning, ',');
+    }
+}
+
+static void
+AppendToFaceList(nsCString& aFaceList,
+                 nsAString& aFamilyName, FT2FontEntry* aFontEntry)
+{
+    aFaceList.Append(NS_ConvertUTF16toUTF8(aFamilyName));
+    aFaceList.Append(',');
+    aFaceList.Append(NS_ConvertUTF16toUTF8(aFontEntry->Name()));
+    aFaceList.Append(',');
+    aFaceList.AppendInt(aFontEntry->mFTFontIndex);
+    aFaceList.Append(',');
+    aFaceList.Append(aFontEntry->IsItalic() ? '1' : '0');
+    aFaceList.Append(',');
+    aFaceList.AppendInt(aFontEntry->Weight());
+    aFaceList.Append(',');
+    aFaceList.AppendInt(aFontEntry->Stretch());
+    aFaceList.Append(',');
 }
 
 void
-gfxFT2FontList::AppendFacesFromFontFile(const char *aFileName)
+gfxFT2FontList::AppendFacesFromFontFile(nsCString& aFileName,
+                                        PRBool aStdFile,
+                                        FontNameCache *aCache)
 {
+    nsCString faceList;
+    PRUint32 filesize = 0, timestamp = 0;
+    if (aCache) {
+        aCache->GetInfoForFile(aFileName, faceList, &timestamp, &filesize);
+    }
+
+    struct stat s;
+    int statRetval = stat(aFileName.get(), &s);
+    if (!faceList.IsEmpty() && 0 == statRetval &&
+        s.st_mtime == timestamp && s.st_size == filesize)
+    {
+        LOG(("using cached font info for %s", aFileName.get()));
+        AppendFacesFromCachedFaceList(aFileName, aStdFile, faceList);
+        return;
+    }
+
 #ifdef XP_WIN
     FT_Library ftLibrary = gfxWindowsPlatform::GetPlatform()->GetFTLibrary();
 #elif defined(ANDROID)
     FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary();
 #endif
     FT_Face dummy;
-    if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName, -1, &dummy)) {
+    if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName.get(), -1, &dummy)) {
+        LOG(("reading font info via FreeType for %s", aFileName.get()));
+        nsCString faceList;
+        timestamp = s.st_mtime;
+        filesize = s.st_size;
         for (FT_Long i = 0; i < dummy->num_faces; i++) {
             FT_Face face;
-            if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName, i, &face))
+            if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName.get(), i, &face)) {
                 continue;
+            }
 
-            FontEntry* fe = FontEntry::CreateFontEntryFromFace(face);
+            FT2FontEntry* fe =
+                FT2FontEntry::CreateFontEntry(face, aFileName.get(), i);
             if (fe) {
                 NS_ConvertUTF8toUTF16 name(face->family_name);
                 BuildKeyNameFromFontName(name);       
                 gfxFontFamily *family = mFontFamilies.GetWeak(name);
                 if (!family) {
-                    family = new gfxFontFamily(name);
+                    family = new FT2FontFamily(name);
                     mFontFamilies.Put(name, family);
-                    if (mBadUnderlineFamilyNames.Contains(name))
+                    if (mBadUnderlineFamilyNames.Contains(name)) {
                         family->SetBadUnderlineFamily();
+                    }
                 }
+                fe->mStandardFace = aStdFile;
                 family->AddFontEntry(fe);
-                family->SetHasStyles(PR_TRUE);
-                if (family->IsBadUnderlineFamily())
+                if (family->IsBadUnderlineFamily()) {
                     fe->mIsBadUnderlineFont = PR_TRUE;
+                }
+                AppendToFaceList(faceList, name, fe);
 #ifdef PR_LOGGING
                 if (LOG_ENABLED()) {
                     LOG(("(fontinit) added (%s) to family (%s)"
                          " with style: %s weight: %d stretch: %d",
                          NS_ConvertUTF16toUTF8(fe->Name()).get(), 
                          NS_ConvertUTF16toUTF8(family->Name()).get(), 
                          fe->IsItalic() ? "italic" : "normal",
                          fe->Weight(), fe->Stretch()));
                 }
 #endif
             }
         }
         FT_Done_Face(dummy);
+        if (aCache && 0 == statRetval && !faceList.IsEmpty()) {
+            aCache->CacheFileInfo(aFileName, faceList, timestamp, filesize);
+        }
     }
 }
 
+// Called on each family after all fonts are added to the list;
+// this will sort faces to give priority to "standard" font files
+// if aUserArg is non-null (i.e. we're using it as a boolean flag)
+static PLDHashOperator
+FinalizeFamilyMemberList(nsStringHashKey::KeyType aKey,
+                         nsRefPtr<gfxFontFamily>& aFamily,
+                         void* aUserArg)
+{
+    gfxFontFamily *family = aFamily.get();
+    PRBool sortFaces = (aUserArg != nsnull);
+
+    family->SetHasStyles(PR_TRUE);
+
+    if (sortFaces) {
+        family->SortAvailableFonts();
+    }
+    family->CheckForSimpleFamily();
+
+    return PL_DHASH_NEXT;
+}
+
 void
 gfxFT2FontList::FindFonts()
 {
 #ifdef XP_WIN
     nsTArray<nsString> searchPaths(3);
     nsTArray<nsString> fontPatterns(3);
     fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.ttf"));
     fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.ttc"));
@@ -194,53 +839,168 @@ gfxFT2FontList::FindFonts()
                                              FindExSearchNameMatch,
                                              NULL,
                                              0);
             PRBool moreFiles = handle != INVALID_HANDLE_VALUE;
             while (moreFiles) {
                 nsAutoString filePath(path);
                 filePath.AppendLiteral("\\");
                 filePath.Append(results.cFileName);
-                AppendFacesFromFontFile(static_cast<const PRUnichar*>(filePath.get()));
+                AppendFacesFromFontFile(NS_ConvertUTF16toUTF8(filePath));
                 moreFiles = FindNextFile(handle, &results);
             }
             if (handle != INVALID_HANDLE_VALUE)
                 FindClose(handle);
         }
     }
 #elif defined(ANDROID)
     gfxFontCache *fc = gfxFontCache::GetCache();
     if (fc)
         fc->AgeAllGenerations();
     mPrefFonts.Clear();
     mCodepointsWithNoFonts.reset();
 
-    DIR *d = opendir("/system/fonts");
-    struct dirent *ent = NULL;
-    while(d && (ent = readdir(d)) != NULL) {
-        int namelen = strlen(ent->d_name);
-        if (namelen > 4 &&
-            strcasecmp(ent->d_name + namelen - 4, ".ttf") == 0)
-        {
-            nsCString s("/system/fonts");
-            s.Append("/");
-            s.Append(nsDependentCString(ent->d_name));
-
-            AppendFacesFromFontFile(nsPromiseFlatCString(s).get());
-        }
-    }
-    if (d) {
-      closedir(d);
-    }
     mCodepointsWithNoFonts.SetRange(0,0x1f);     // C0 controls
     mCodepointsWithNoFonts.SetRange(0x7f,0x9f);  // C1 controls
 
+    if (XRE_GetProcessType() != GeckoProcessType_Default) {
+        // Content process: ask the Chrome process to give us the list
+        InfallibleTArray<FontListEntry> fonts;
+        mozilla::dom::ContentChild::GetSingleton()->SendReadFontList(&fonts);
+        for (PRUint32 i = 0, n = fonts.Length(); i < n; ++i) {
+            AppendFaceFromFontListEntry(fonts[i], PR_FALSE);
+        }
+        // Passing null for userdata tells Finalize that it does not need
+        // to sort faces (because they were already sorted by chrome,
+        // so we just maintain the existing order)
+        mFontFamilies.Enumerate(FinalizeFamilyMemberList, nsnull);
+        LOG(("got font list from chrome process: %d faces in %d families",
+            fonts.Length(), mFontFamilies.Count()));
+        return;
+    }
+
+    // Chrome process: get the cached list (if any)
+    FontNameCache fnc;
+
+    // ANDROID_ROOT is the root of the android system, typically /system;
+    // font files are in /$ANDROID_ROOT/fonts/
+    nsCString root;
+    char *androidRoot = PR_GetEnv("ANDROID_ROOT");
+    if (androidRoot) {
+        root = androidRoot;
+    } else {
+        root = NS_LITERAL_CSTRING("/system");
+    }
+    root.Append("/fonts");
+
+    static const char* sStandardFonts[] = {
+        "DroidSans.ttf",
+        "DroidSans-Bold.ttf",
+        "DroidSerif-Regular.ttf",
+        "DroidSerif-Bold.ttf",
+        "DroidSerif-Italic.ttf",
+        "DroidSerif-BoldItalic.ttf",
+        "DroidSansMono.ttf",
+        "DroidSansArabic.ttf",
+        "DroidSansHebrew.ttf",
+        "DroidSansThai.ttf",
+        "MTLmr3m.ttf",
+        "MTLc3m.ttf",
+        "DroidSansJapanese.ttf",
+        "DroidSansFallback.ttf"
+    };
+
+    DIR *d = opendir(root.get());
+    if (!d) {
+        // if we can't find/read the font directory, we are doomed!
+        NS_RUNTIMEABORT("Could not read the system fonts directory");
+    }
+
+    struct dirent *ent = NULL;
+    while ((ent = readdir(d)) != NULL) {
+        int namelen = strlen(ent->d_name);
+        if (namelen <= 4) {
+            // cannot be a usable font filename
+            continue;
+        }
+        const char *ext = ent->d_name + namelen - 4;
+        if (strcasecmp(ext, ".ttf") == 0 ||
+            strcasecmp(ext, ".otf") == 0 ||
+            strcasecmp(ext, ".ttc") == 0)
+        {
+            bool isStdFont = false;
+            for (unsigned int i = 0;
+                 i < NS_ARRAY_LENGTH(sStandardFonts) && !isStdFont; i++)
+            {
+                isStdFont = strcmp(sStandardFonts[i], ent->d_name) == 0;
+            }
+
+            nsCString s(root);
+            s.Append('/');
+            s.Append(ent->d_name, namelen);
+
+            // Add the face(s) from this file to our font list;
+            // note that if we have cached info for this file in fnc,
+            // and the file is unchanged, we won't actually need to read it.
+            // If the file is new/changed, this will update the FontNameCache.
+            AppendFacesFromFontFile(s, isStdFont, &fnc);
+        }
+    }
+    closedir(d);
+
+    // Finalize the families by sorting faces into standard order
+    // and marking "simple" families.
+    // Passing non-null userData here says that we want faces to be sorted.
+    mFontFamilies.Enumerate(FinalizeFamilyMemberList, this);
 #endif // XP_WIN && ANDROID
 }
 
+void
+gfxFT2FontList::AppendFaceFromFontListEntry(const FontListEntry& aFLE,
+                                            PRBool aStdFile)
+{
+    FT2FontEntry* fe = FT2FontEntry::CreateFontEntry(aFLE);
+    if (fe) {
+        fe->mStandardFace = aStdFile;
+        nsAutoString name(aFLE.familyName());
+        gfxFontFamily *family = mFontFamilies.GetWeak(name);
+        if (!family) {
+            family = new FT2FontFamily(name);
+            mFontFamilies.Put(name, family);
+            if (mBadUnderlineFamilyNames.Contains(name)) {
+                family->SetBadUnderlineFamily();
+            }
+        }
+        family->AddFontEntry(fe);
+        if (family->IsBadUnderlineFamily()) {
+            fe->mIsBadUnderlineFont = PR_TRUE;
+        }
+    }
+}
+
+static PLDHashOperator
+AddFamilyToFontList(nsStringHashKey::KeyType aKey,
+                    nsRefPtr<gfxFontFamily>& aFamily,
+                    void* aUserArg)
+{
+    InfallibleTArray<FontListEntry>* fontlist =
+        reinterpret_cast<InfallibleTArray<FontListEntry>*>(aUserArg);
+
+    FT2FontFamily *family = static_cast<FT2FontFamily*>(aFamily.get());
+    family->AddFacesToFontList(fontlist);
+
+    return PL_DHASH_NEXT;
+}
+
+void
+gfxFT2FontList::GetFontList(InfallibleTArray<FontListEntry>* retValue)
+{
+    mFontFamilies.Enumerate(AddFamilyToFontList, retValue);
+}
+
 nsresult
 gfxFT2FontList::InitFontList()
 {
     // reset font lists
     gfxPlatformFontList::InitFontList();
     
     FindFonts();
 
@@ -283,17 +1043,17 @@ FindFullName(nsStringHashKey::KeyType aK
         }
     }
 
     return PL_DHASH_NEXT;
 }
 
 gfxFontEntry* 
 gfxFT2FontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
-                                       const nsAString& aFontName)
+                                const nsAString& aFontName)
 {
     // walk over list of names
     FullFontNameSearch data(aFontName);
 
     mFontFamilies.Enumerate(FindFullName, &data);
 
     return data.mFontEntry;
 }
@@ -322,10 +1082,11 @@ gfxFT2FontList::GetDefaultFont(const gfx
 gfxFontEntry*
 gfxFT2FontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                  const PRUint8 *aFontData,
                                  PRUint32 aLength)
 {
     // The FT2 font needs the font data to persist, so we do NOT free it here
     // but instead pass ownership to the font entry.
     // Deallocation will happen later, when the font face is destroyed.
-    return FontEntry::CreateFontEntry(*aProxyEntry, aFontData, aLength);
+    return FT2FontEntry::CreateFontEntry(*aProxyEntry, aFontData, aLength);
 }
+
--- a/gfx/thebes/gfxFT2FontList.h
+++ b/gfx/thebes/gfxFT2FontList.h
@@ -42,34 +42,119 @@
 #define GFX_FT2FONTLIST_H
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
 #include <windows.h>
 #endif
 #include "gfxPlatformFontList.h"
 
-#include <bitset>
+namespace mozilla {
+    namespace dom {
+        class FontListEntry;
+    };
+};
+using mozilla::dom::FontListEntry;
+
+class FontNameCache;
+typedef struct FT_FaceRec_* FT_Face;
+
+class FT2FontEntry : public gfxFontEntry
+{
+public:
+    FT2FontEntry(const nsAString& aFaceName) :
+        gfxFontEntry(aFaceName)
+    {
+        mFTFace = nsnull;
+        mFontFace = nsnull;
+        mFTFontIndex = 0;
+    }
+
+    ~FT2FontEntry();
+
+    const nsString& GetName() const {
+        return Name();
+    }
+
+    // create a font entry for a downloaded font
+    static FT2FontEntry* 
+    CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
+                    const PRUint8 *aFontData, PRUint32 aLength);
+
+    // create a font entry representing an installed font, identified by
+    // a FontListEntry; the freetype and cairo faces will not be instantiated
+    // until actually needed
+    static FT2FontEntry*
+    CreateFontEntry(const FontListEntry& aFLE);
+
+    // create a font entry for a given freetype face; if it is an installed font,
+    // also record the filename and index
+    static FT2FontEntry* 
+    CreateFontEntry(FT_Face aFace, const char *aFilename, PRUint8 aIndex,
+                    const PRUint8 *aFontData = nsnull);
+        // aFontData is NS_Malloc'ed data that aFace depends on, to be freed
+        // after the face is destroyed; null if there is no such buffer
+
+    virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle,
+                                        PRBool aNeedsBold);
+
+    cairo_font_face_t *CairoFontFace();
+    cairo_scaled_font_t *CreateScaledFont(const gfxFontStyle *aStyle);
+
+    nsresult ReadCMAP();
+    nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
+
+    FT_Face mFTFace;
+    cairo_font_face_t *mFontFace;
+
+    nsCString mFilename;
+    PRUint8 mFTFontIndex;
+};
+
+class FT2FontFamily : public gfxFontFamily
+{
+public:
+    FT2FontFamily(const nsAString& aName) :
+        gfxFontFamily(aName) { }
+
+    // Append this family's faces to the IPC fontlist
+    void AddFacesToFontList(InfallibleTArray<FontListEntry>* aFontList);
+};
 
 class gfxFT2FontList : public gfxPlatformFontList
 {
 public:
     gfxFT2FontList();
 
     virtual gfxFontEntry* GetDefaultFont(const gfxFontStyle* aStyle,
                                          PRBool& aNeedsBold);
 
     virtual gfxFontEntry* LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
                                           const nsAString& aFontName);
 
     virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
                                            const PRUint8 *aFontData,
                                            PRUint32 aLength);
 
+    void GetFontList(InfallibleTArray<FontListEntry>* retValue);
+
+    static gfxFT2FontList* PlatformFontList() {
+        return static_cast<gfxFT2FontList*>(gfxPlatformFontList::PlatformFontList());
+    }
+
 protected:
     virtual nsresult InitFontList();
 
-    void AppendFacesFromFontFile(const PRUnichar *aFileName);
-    void AppendFacesFromFontFile(const char *aFileName);
+    void AppendFaceFromFontListEntry(const FontListEntry& aFLE,
+                                     PRBool isStdFile);
+
+    void AppendFacesFromFontFile(nsCString& aFileName,
+                                 PRBool isStdFile = PR_FALSE,
+                                 FontNameCache *aCache = nsnull);
+
+    void AppendFacesFromCachedFaceList(nsCString& aFileName,
+                                       PRBool isStdFile,
+                                       nsCString& aFaceList);
+
     void FindFonts();
 };
 
 #endif /* GFX_FT2FONTLIST_H */
--- a/gfx/thebes/gfxFT2Fonts.cpp
+++ b/gfx/thebes/gfxFT2Fonts.cpp
@@ -39,305 +39,50 @@
 #define gfxToolkitPlatform gfxPlatformGtk
 #elif defined(MOZ_WIDGET_QT)
 #include <qfontinfo.h>
 #include "gfxQtPlatform.h"
 #define gfxToolkitPlatform gfxQtPlatform
 #elif defined(XP_WIN)
 #include "gfxWindowsPlatform.h"
 #define gfxToolkitPlatform gfxWindowsPlatform
-#include "gfxFT2FontList.h"
 #elif defined(ANDROID)
 #include "gfxAndroidPlatform.h"
 #define gfxToolkitPlatform gfxAndroidPlatform
 #endif
 
 #include "gfxTypes.h"
 #include "gfxFT2Fonts.h"
 #include "gfxFT2FontBase.h"
 #include "gfxFT2Utils.h"
+#include "gfxFT2FontList.h"
 #include <locale.h>
-#include "cairo-ft.h"
-#include FT_TRUETYPE_TAGS_H
-#include FT_TRUETYPE_TABLES_H
-#include "gfxFontUtils.h"
 #include "gfxHarfBuzzShaper.h"
 #include "gfxUnicodeProperties.h"
 #include "gfxAtoms.h"
 #include "nsTArray.h"
 #include "nsUnicodeRange.h"
 #include "nsCRT.h"
 
 #include "prlog.h"
 #include "prinit.h"
 
 #include "mozilla/Preferences.h"
 
-using namespace mozilla;
-
 static PRLogModuleInfo *gFontLog = PR_NewLogModule("ft2fonts");
 
-static const char *sCJKLangGroup[] = {
-    "ja",
-    "ko",
-    "zh-cn",
-    "zh-hk",
-    "zh-tw"
-};
-#define COUNT_OF_CJK_LANG_GROUP 5
-
 // rounding and truncation functions for a Freetype floating point number
 // (FT26Dot6) stored in a 32bit integer with high 26 bits for the integer
 // part and low 6 bits for the fractional part.
 #define MOZ_FT_ROUND(x) (((x) + 32) & ~63) // 63 = 2^6 - 1
 #define MOZ_FT_TRUNC(x) ((x) >> 6)
 #define CONVERT_DESIGN_UNITS_TO_PIXELS(v, s) \
         MOZ_FT_TRUNC(MOZ_FT_ROUND(FT_MulFix((v) , (s))))
 
-/**
- * FontEntry
- */
-
-FontEntry::~FontEntry()
-{
-    // Do nothing for mFTFace here since FTFontDestroyFunc is called by cairo.
-    mFTFace = nsnull;
-
-#ifndef ANDROID
-    if (mFontFace) {
-        cairo_font_face_destroy(mFontFace);
-        mFontFace = nsnull;
-    }
-#endif
-}
-
-gfxFont*
-FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold) {
-    already_AddRefed<gfxFT2Font> font = gfxFT2Font::GetOrMakeFont(this, aFontStyle, aNeedsBold);
-    return font.get();
-}
-
-/* static */
-FontEntry*
-FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
-                           const PRUint8 *aFontData,
-                           PRUint32 aLength)
-{
-    // Ownership of aFontData is passed in here; the fontEntry must
-    // retain it as long as the FT_Face needs it, and ensure it is
-    // eventually deleted.
-    FT_Face face;
-    FT_Error error =
-        FT_New_Memory_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(),
-                           aFontData, aLength, 0, &face);
-    if (error != FT_Err_Ok) {
-        NS_Free((void*)aFontData);
-        return nsnull;
-    }
-    FontEntry* fe = FontEntry::CreateFontEntryFromFace(face, aFontData);
-    if (fe) {
-        fe->mItalic = aProxyEntry.mItalic;
-        fe->mWeight = aProxyEntry.mWeight;
-        fe->mStretch = aProxyEntry.mStretch;
-    }
-    return fe;
-}
-
-class FTUserFontData {
-public:
-    FTUserFontData(FT_Face aFace, const PRUint8* aData)
-        : mFace(aFace), mFontData(aData)
-    {
-    }
-
-    ~FTUserFontData()
-    {
-        FT_Done_Face(mFace);
-        if (mFontData) {
-            NS_Free((void*)mFontData);
-        }
-    }
-
-private:
-    FT_Face        mFace;
-    const PRUint8 *mFontData;
-};
-
-static void
-FTFontDestroyFunc(void *data)
-{
-    FTUserFontData *userFontData = static_cast<FTUserFontData*>(data);
-    delete userFontData;
-}
-
-/* static */ FontEntry*
-FontEntry::CreateFontEntryFromFace(FT_Face aFace, const PRUint8 *aFontData) {
-    static cairo_user_data_key_t key;
-
-    if (!aFace->family_name) {
-        FT_Done_Face(aFace);
-        return nsnull;
-    }
-    // Construct font name from family name and style name, regular fonts
-    // do not have the modifier by convention.
-    NS_ConvertUTF8toUTF16 fontName(aFace->family_name);
-    if (aFace->style_name && strcmp("Regular", aFace->style_name)) {
-        fontName.AppendLiteral(" ");
-        AppendUTF8toUTF16(aFace->style_name, fontName);
-    }
-    FontEntry *fe = new FontEntry(fontName);
-    fe->mItalic = aFace->style_flags & FT_STYLE_FLAG_ITALIC;
-    fe->mFTFace = aFace;
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
-#else
-    fe->mFontFace = cairo_ft_font_face_create_for_ft_face(aFace, 0);
-#endif
-    FTUserFontData *userFontData = new FTUserFontData(aFace, aFontData);
-    cairo_font_face_set_user_data(fe->mFontFace, &key,
-                                  userFontData, FTFontDestroyFunc);
-
-    TT_OS2 *os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(aFace, ft_sfnt_os2));
-    PRUint16 os2weight = 0;
-    if (os2 && os2->version != 0xffff) {
-        // Technically, only 100 to 900 are valid, but some fonts
-        // have this set wrong -- e.g. "Microsoft Logo Bold Italic" has
-        // it set to 6 instead of 600.  We try to be nice and handle that
-        // as well.
-        if (os2->usWeightClass >= 100 && os2->usWeightClass <= 900)
-            os2weight = os2->usWeightClass;
-        else if (os2->usWeightClass >= 1 && os2->usWeightClass <= 9)
-            os2weight = os2->usWeightClass * 100;
-    }
-
-    if (os2weight != 0)
-        fe->mWeight = os2weight;
-    else if (aFace->style_flags & FT_STYLE_FLAG_BOLD)
-        fe->mWeight = 700;
-    else
-        fe->mWeight = 400;
-
-    NS_ASSERTION(fe->mWeight >= 100 && fe->mWeight <= 900, "Invalid final weight in font!");
-
-    return fe;
-}
-
-FontEntry*
-gfxFT2Font::GetFontEntry()
-{
-    return static_cast<FontEntry*> (mFontEntry.get());
-}
-
-cairo_font_face_t *
-FontEntry::CairoFontFace()
-{
-    static cairo_user_data_key_t key;
-
-    if (!mFontFace) {
-        FT_Face face;
-        FT_New_Face(gfxToolkitPlatform::GetPlatform()->GetFTLibrary(), mFilename.get(), mFTFontIndex, &face);
-        mFTFace = face;
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-        mFontFace = cairo_ft_font_face_create_for_ft_face(face, FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING);
-#else
-        mFontFace = cairo_ft_font_face_create_for_ft_face(face, 0);
-#endif
-        FTUserFontData *userFontData = new FTUserFontData(face, nsnull);
-        cairo_font_face_set_user_data(mFontFace, &key,
-                                      userFontData, FTFontDestroyFunc);
-    }
-    return mFontFace;
-}
-
-nsresult
-FontEntry::ReadCMAP()
-{
-    if (mCmapInitialized) {
-        return NS_OK;
-    }
-
-    // attempt this once, if errors occur leave a blank cmap
-    mCmapInitialized = PR_TRUE;
-
-    AutoFallibleTArray<PRUint8,16384> buffer;
-    nsresult rv = GetFontTable(TTAG_cmap, buffer);
-    
-    if (NS_SUCCEEDED(rv)) {
-        PRPackedBool unicodeFont;
-        PRPackedBool symbolFont;
-        rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
-                                    mCharacterMap, mUVSOffset,
-                                    unicodeFont, symbolFont);
-    }
-
-    mHasCmapTable = NS_SUCCEEDED(rv);
-    return rv;
-}
-
-nsresult
-FontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
-{
-    // Ensure existence of mFTFace
-    CairoFontFace();
-    NS_ENSURE_TRUE(mFTFace, NS_ERROR_FAILURE);
-
-    FT_Error status;
-    FT_ULong len = 0;
-    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nsnull, &len);
-    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
-    NS_ENSURE_TRUE(len != 0, NS_ERROR_FAILURE);
-
-    if (!aBuffer.SetLength(len)) {
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-    PRUint8 *buf = aBuffer.Elements();
-    status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, buf, &len);
-    NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
-
-    return NS_OK;
-}
-
-FontEntry *
-FontFamily::FindFontEntry(const gfxFontStyle& aFontStyle)
-{
-    PRBool needsBold = PR_FALSE;
-    return static_cast<FontEntry*>(FindFontForStyle(aFontStyle, needsBold));
-}
-
-void FontFamily::AddFontFileAndIndex(nsCString aFilename, PRUint32 aIndex)
-{
-    SetHasStyles(PR_FALSE);
-    mFilenames.AppendElement(new FileAndIndex(aFilename, aIndex));
-}
-    
-
-
-void
-FontFamily::FindStyleVariations()
-{
-    if (mHasStyles) {
-        return;
-    }
-    mHasStyles = PR_TRUE;
-
-    for (int i = 0; i < mFilenames.Length(); i++) {
-        FT_Face face;
-        gfxToolkitPlatform* platform = gfxToolkitPlatform::GetPlatform();
-        if (FT_Err_Ok == FT_New_Face(platform->GetFTLibrary(),
-                                     mFilenames[i].filename.get(), 
-                                     mFilenames[i].index, &face)) {
-            FontEntry* fe = FontEntry::CreateFontEntryFromFace(face);
-            if (fe)
-                AddFontEntry(fe);
-        }
-    }
-    mFilenames.Clear();
-    SetHasStyles(PR_TRUE);
-}
-
+#ifndef ANDROID // not needed on Android, we use the generic gfxFontGroup
 /**
  * gfxFT2FontGroup
  */
 
 PRBool
 gfxFT2FontGroup::FontCallback(const nsAString& fontName,
                               const nsACString& genericName,
                               PRBool aUseFontSet,
@@ -646,17 +391,17 @@ gfxFT2FontGroup::WhichPrefFontSupportsCh
     }
 
     return nsnull;
 }
 
 already_AddRefed<gfxFont>
 gfxFT2FontGroup::WhichSystemFontSupportsChar(PRUint32 aCh)
 {
-#ifdef XP_WIN
+#if defined(XP_WIN) || defined(ANDROID)
     FontEntry *fe = static_cast<FontEntry*>
         (gfxPlatformFontList::PlatformFontList()->FindFontForChar(aCh, GetFontAt(0)));
     if (fe) {
         nsRefPtr<gfxFT2Font> f = gfxFT2Font::GetOrMakeFont(fe, &mStyle);
         nsRefPtr<gfxFont> font = f.get();
         return font.forget();
     }
 #else
@@ -665,16 +410,18 @@ gfxFT2FontGroup::WhichSystemFontSupports
     gfxToolkitPlatform *platform = gfxToolkitPlatform::GetPlatform();
     selectedFont = platform->FindFontForChar(aCh, refFont);
     if (selectedFont)
         return selectedFont.forget();
 #endif
     return nsnull;
 }
 
+#endif // !ANDROID
+
 /**
  * gfxFT2Font
  */
 
 PRBool
 gfxFT2Font::InitTextRun(gfxContext *aContext,
                         gfxTextRun *aTextRun,
                         const PRUnichar *aString,
@@ -799,17 +546,17 @@ gfxFT2Font::AddRange(gfxTextRun *aTextRu
             details.mYOffset = 0;
             g.SetComplex(aTextRun->IsClusterStart(offset + i), PR_TRUE, 1);
             aTextRun->SetGlyphs(offset + i, g, &details);
         }
     }
 }
 
 gfxFT2Font::gfxFT2Font(cairo_scaled_font_t *aCairoFont,
-                       FontEntry *aFontEntry,
+                       FT2FontEntry *aFontEntry,
                        const gfxFontStyle *aFontStyle,
                        PRBool aNeedsBold)
     : gfxFT2FontBase(aCairoFont, aFontEntry, aFontStyle)
 {
     NS_ASSERTION(mFontEntry, "Unable to find font entry for font.  Something is whack.");
     mApplySyntheticBold = aNeedsBold;
     mCharGlyphCache.Init(64);
 }
@@ -819,87 +566,49 @@ gfxFT2Font::~gfxFT2Font()
 }
 
 cairo_font_face_t *
 gfxFT2Font::CairoFontFace()
 {
     return GetFontEntry()->CairoFontFace();
 }
 
-static cairo_scaled_font_t *
-CreateScaledFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle)
-{
-    cairo_scaled_font_t *scaledFont = NULL;
-
-    cairo_matrix_t sizeMatrix;
-    cairo_matrix_t identityMatrix;
-
-    // XXX deal with adjusted size
-    cairo_matrix_init_scale(&sizeMatrix, aStyle->size, aStyle->size);
-    cairo_matrix_init_identity(&identityMatrix);
-
-    // synthetic oblique by skewing via the font matrix
-    PRBool needsOblique = (!aFontEntry->mItalic && (aStyle->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
-
-    if (needsOblique) {
-        const double kSkewFactor = 0.25;
-
-        cairo_matrix_t style;
-        cairo_matrix_init(&style,
-                          1,                //xx
-                          0,                //yx
-                          -1 * kSkewFactor,  //xy
-                          1,                //yy
-                          0,                //x0
-                          0);               //y0
-        cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
-    }
-
-    cairo_font_options_t *fontOptions = cairo_font_options_create();
-
-#ifdef MOZ_GFX_OPTIMIZE_MOBILE
-    cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
-#endif
-
-    scaledFont = cairo_scaled_font_create(aFontEntry->CairoFontFace(),
-                                          &sizeMatrix,
-                                          &identityMatrix, fontOptions);
-    cairo_font_options_destroy(fontOptions);
-
-    NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
-                 "Failed to make scaled font");
-
-    return scaledFont;
-}
-
 /**
  * Look up the font in the gfxFont cache. If we don't find it, create one.
  * In either case, add a ref, append it to the aFonts array, and return it ---
  * except for OOM in which case we do nothing and return null.
  */
 already_AddRefed<gfxFT2Font>
-gfxFT2Font::GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle, PRBool aNeedsBold)
+gfxFT2Font::GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle,
+                          PRBool aNeedsBold)
 {
-    FontEntry *fe = static_cast<FontEntry*>
+#ifdef ANDROID
+    FT2FontEntry *fe = static_cast<FT2FontEntry*>
+        (gfxPlatformFontList::PlatformFontList()->
+            FindFontForFamily(aName, aStyle, aNeedsBold));
+#else
+    FT2FontEntry *fe = static_cast<FT2FontEntry*>
         (gfxToolkitPlatform::GetPlatform()->FindFontEntry(aName, *aStyle));
+#endif
     if (!fe) {
         NS_WARNING("Failed to find font entry for font!");
         return nsnull;
     }
 
     nsRefPtr<gfxFT2Font> font = GetOrMakeFont(fe, aStyle, aNeedsBold);
     return font.forget();
 }
 
 already_AddRefed<gfxFT2Font>
-gfxFT2Font::GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle, PRBool aNeedsBold)
+gfxFT2Font::GetOrMakeFont(FT2FontEntry *aFontEntry, const gfxFontStyle *aStyle,
+                          PRBool aNeedsBold)
 {
     nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aFontEntry, aStyle);
     if (!font) {
-        cairo_scaled_font_t *scaledFont = CreateScaledFont(aFontEntry, aStyle);
+        cairo_scaled_font_t *scaledFont = aFontEntry->CreateScaledFont(aStyle);
         font = new gfxFT2Font(scaledFont, aFontEntry, aStyle, aNeedsBold);
         cairo_scaled_font_destroy(scaledFont);
         if (!font)
             return nsnull;
         gfxFontCache::GetCache()->AddNew(font);
     }
     gfxFont *f = nsnull;
     font.swap(f);
--- a/gfx/thebes/gfxFT2Fonts.h
+++ b/gfx/thebes/gfxFT2Fonts.h
@@ -42,107 +42,37 @@
 #include "cairo.h"
 #include "gfxTypes.h"
 #include "gfxFont.h"
 #include "gfxFT2FontBase.h"
 #include "gfxContext.h"
 #include "gfxFontUtils.h"
 #include "gfxUserFontSet.h"
 
-typedef struct FT_FaceRec_* FT_Face;
-
-class FileAndIndex {
-public:
-    FileAndIndex(nsCString aFilename, PRUint32 aIndex) :
-        filename(aFilename), index(aIndex) {}
-    FileAndIndex(FileAndIndex* fai) :
-        filename(fai->filename), index(fai->index) {}
-    nsCString filename;
-    PRUint32 index;
-};
-
-/**
- * FontFamily is a class that describes one of the fonts on the users system.  It holds
- * each FontEntry (maps more directly to a font face) which holds font type, charset info
- * and character map info.
- */
-class FontEntry;
-class FontFamily : public gfxFontFamily
-{
-public:
-    FontFamily(const nsAString& aName) :
-        gfxFontFamily(aName) { }
-
-    FontEntry *FindFontEntry(const gfxFontStyle& aFontStyle);
-    virtual void FindStyleVariations();
-    void AddFontFileAndIndex(nsCString aFilename, PRUint32 aIndex);
-
-private:
-    // mFilenames are queus of font files that
-    // need to be lazily processed into font entries
-    nsTArray<FileAndIndex> mFilenames;
-};
-
-class FontEntry : public gfxFontEntry
-{
-public:
-    FontEntry(const nsAString& aFaceName) :
-        gfxFontEntry(aFaceName)
-    {
-        mFTFace = nsnull;
-        mFontFace = nsnull;
-        mFTFontIndex = 0;
-    }
-
-    ~FontEntry();
-
-    const nsString& GetName() const {
-        return Name();
-    }
-
-    static FontEntry* 
-    CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
-                    const PRUint8 *aFontData, PRUint32 aLength);
-
-    static FontEntry* 
-    CreateFontEntryFromFace(FT_Face aFace, const PRUint8 *aFontData = nsnull);
-        // aFontData is NS_Malloc'ed data that aFace depends on, to be freed
-        // after the face is destroyed; null if there is no such buffer
-
-    virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold);
-
-    cairo_font_face_t *CairoFontFace();
-    nsresult ReadCMAP();
-
-    nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
-
-    FT_Face mFTFace;
-    cairo_font_face_t *mFontFace;
-
-    nsCString mFilename;
-    PRUint8 mFTFontIndex;
-};
-
+class FT2FontEntry;
 
 class gfxFT2Font : public gfxFT2FontBase {
 public: // new functions
     gfxFT2Font(cairo_scaled_font_t *aCairoFont,
-               FontEntry *aFontEntry,
+               FT2FontEntry *aFontEntry,
                const gfxFontStyle *aFontStyle,
                PRBool aNeedsBold);
     virtual ~gfxFT2Font ();
 
     cairo_font_face_t *CairoFontFace();
 
-    FontEntry *GetFontEntry();
+    FT2FontEntry *GetFontEntry();
 
     static already_AddRefed<gfxFT2Font>
-    GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle, PRBool aNeedsBold = PR_FALSE);
+    GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle,
+                  PRBool aNeedsBold = PR_FALSE);
+
     static already_AddRefed<gfxFT2Font>
-    GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle, PRBool aNeedsBold = PR_FALSE);
+    GetOrMakeFont(FT2FontEntry *aFontEntry, const gfxFontStyle *aStyle,
+                  PRBool aNeedsBold = PR_FALSE);
 
     struct CachedGlyphData {
         CachedGlyphData()
             : glyphIndex(0xffffffffU) { }
 
         CachedGlyphData(PRUint32 gid)
             : glyphIndex(gid) { }
 
@@ -179,16 +109,17 @@ protected:
 
     void AddRange(gfxTextRun *aTextRun, const PRUnichar *str, PRUint32 offset, PRUint32 len);
 
     typedef nsBaseHashtableET<nsUint32HashKey, CachedGlyphData> CharGlyphMapEntryType;
     typedef nsTHashtable<CharGlyphMapEntryType> CharGlyphMap;
     CharGlyphMap mCharGlyphCache;
 };
 
+#ifndef ANDROID // not needed on Android, uses the standard gfxFontGroup directly
 class THEBES_API gfxFT2FontGroup : public gfxFontGroup {
 public: // new functions
     gfxFT2FontGroup (const nsAString& families,
                     const gfxFontStyle *aStyle,
                     gfxUserFontSet *aUserFontSet);
     virtual ~gfxFT2FontGroup ();
 
 protected: // from gfxFontGroup
@@ -213,11 +144,12 @@ protected: // new functions
     already_AddRefed<gfxFT2Font> WhichFontSupportsChar(const nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList,
                                                        PRUint32 aCh);
     already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);
     already_AddRefed<gfxFont> WhichSystemFontSupportsChar(PRUint32 aCh);
 
     nsTArray<gfxTextRange> mRanges;
     nsString mString;
 };
+#endif // !ANDROID
 
 #endif /* GFX_FT2FONTS_H */
 
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -535,25 +535,31 @@ gfxFontFamily::FindFontForStyle(const gf
     }
 
     return matchFE;
 }
 
 void
 gfxFontFamily::CheckForSimpleFamily()
 {
-    if (mAvailableFonts.Length() > 4 || mAvailableFonts.Length() == 0) {
+    PRUint32 count = mAvailableFonts.Length();
+    if (count > 4 || count == 0) {
         return; // can't be "simple" if there are >4 faces;
                 // if none then the family is unusable anyway
     }
 
+    if (count == 1) {
+        mIsSimpleFamily = PR_TRUE;
+        return;
+    }
+
     PRInt16 firstStretch = mAvailableFonts[0]->Stretch();
 
     gfxFontEntry *faces[4] = { 0 };
-    for (PRUint8 i = 0; i < mAvailableFonts.Length(); ++i) {
+    for (PRUint8 i = 0; i < count; ++i) {
         gfxFontEntry *fe = mAvailableFonts[i];
         if (fe->Stretch() != firstStretch) {
             return; // font-stretch doesn't match, don't treat as simple family
         }
         PRUint8 faceIndex = (fe->IsItalic() ? kItalicMask : 0) |
                             (fe->Weight() >= 600 ? kBoldMask : 0);
         if (faces[faceIndex]) {
             return; // two faces resolve to the same slot; family isn't "simple"
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testMathMinMax.js
@@ -0,0 +1,74 @@
+for (var i = 2; i < 10; i++) {
+    assertEq(Math.min(i, 1), 1);
+    assertEq(Math.min(i, -1), -1);
+    assertEq(Math.min(1, i), 1);
+    assertEq(Math.min(-1, i), -1);
+    assertEq(Math.min(5, 2), 2);
+    assertEq(Math.min(2, 5), 2);
+    assertEq(Math.min(5, -2), -2);
+    assertEq(Math.min(-2, 5), -2);
+}
+
+for (i = 2; i < 10; i++) {
+    assertEq(Math.max(i, 1), i);
+    assertEq(Math.max(i, -1), i);
+    assertEq(Math.max(1, i), i);
+    assertEq(Math.max(-1, i), i);
+    assertEq(Math.max(5, -2), 5);
+    assertEq(Math.max(-2, 5), 5);
+    assertEq(Math.max(5, 2), 5);
+    assertEq(Math.max(2, 5), 5);
+}
+
+for (i = 2.1; i < 13; i += 3.17584) {
+    assertEq(Math.max(i, 1), i);
+    assertEq(Math.max(i, 1.5), i);
+    assertEq(Math.max(1, i), i);
+    assertEq(Math.max(1.5, i), i);
+    
+    assertEq(Math.max(NaN, NaN), NaN);
+    assertEq(Math.max(NaN, Infinity), NaN);
+    assertEq(Math.max(Infinity, NaN), NaN);
+    
+    assertEq(Math.max(NaN, i), NaN);
+    assertEq(Math.max(i, NaN), NaN);
+    
+    assertEq(Math.max(i, Infinity), Infinity);
+    assertEq(Math.max(Infinity, i), Infinity);
+    
+    assertEq(Math.max(i, -Infinity), i);
+    assertEq(Math.max(-Infinity, i), i);    
+}
+
+for (i = 2.1; i < 13; i += 3.17584) {
+    assertEq(Math.min(i, 1), 1);
+    assertEq(Math.min(i, 1.5), 1.5);
+    assertEq(Math.min(1, i), 1);
+    assertEq(Math.min(1.5, i), 1.5);
+    
+    assertEq(Math.min(NaN, NaN), NaN);
+    assertEq(Math.min(NaN, Infinity), NaN);
+    assertEq(Math.min(Infinity, NaN), NaN);
+    
+    assertEq(Math.min(NaN, i), NaN);
+    assertEq(Math.min(i, NaN), NaN);
+    
+    assertEq(Math.min(i, Infinity), i);
+    assertEq(Math.min(Infinity, i), i);
+    
+    assertEq(Math.min(i, -Infinity), -Infinity);
+    assertEq(Math.min(-Infinity, i), -Infinity);
+}
+
+function isNegZero(n) {
+    return n === 0 && 1/n === -Infinity;
+}
+
+for (i = 0; i < 5; i++) {
+    assertEq(isNegZero(Math.min(0, -0)), true);
+    assertEq(isNegZero(Math.min(-0, 0)), true);
+    assertEq(isNegZero(Math.min(-0, -0)), true);
+    assertEq(isNegZero(Math.max(0, -0)), false);
+    assertEq(isNegZero(Math.max(-0, 0)), false);
+    assertEq(isNegZero(Math.max(-0, -0)), true);
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug687768.js
@@ -0,0 +1,17 @@
+
+expected = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,';
+function slice(a, b) {
+  return expected;
+}
+function f() {
+  var length = 4;
+  var index = 0;
+  function get3() {
+    if (length - index < 3)
+      return null;
+    return slice(index, ++index);
+  }
+  var bytes = null;
+  while (bytes = get3()) {  }
+}
+f();
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1324,18 +1324,27 @@ JSVAL_TO_DOUBLE(jsval v)
     JS_ASSERT(JSVAL_IS_DOUBLE(v));
     l = JSVAL_TO_IMPL(v);
     return l.asDouble;
 }
 
 static JS_ALWAYS_INLINE jsval
 DOUBLE_TO_JSVAL(jsdouble d)
 {
-    d = JS_CANONICALIZE_NAN(d);
-    return IMPL_TO_JSVAL(DOUBLE_TO_JSVAL_IMPL(d));
+    /* This is a manually inlined version of:
+     *    d = JS_CANONICALIZE_NAN(d);
+     *    return IMPL_TO_JSVAL(DOUBLE_TO_JSVAL_IMPL(d));
+     * because GCC from XCode 3.1.4 miscompiles the above code. */
+    jsval_layout l;
+    if (JS_UNLIKELY(d != d)) {
+        l.asBits = 0x7FF8000000000000LL;
+    } else {
+        l.asDouble = d;
+    }
+    return IMPL_TO_JSVAL(l);
 }
 
 static JS_ALWAYS_INLINE jsval
 UINT_TO_JSVAL(uint32 i)
 {
     if (i <= JSVAL_INT_MAX)
         return INT_TO_JSVAL((int32)i);
     return DOUBLE_TO_JSVAL((jsdouble)i);
--- a/js/src/jsnum.h
+++ b/js/src/jsnum.h
@@ -36,19 +36,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef jsnum_h___
 #define jsnum_h___
 
 #include <math.h>
-#ifdef WIN32
-#include <float.h>
-#endif
 
 #include "jsstdint.h"
 #include "jsobj.h"
 
 /*
  * JS number (IEEE double) interface.
  *
  * JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
@@ -76,29 +73,28 @@ typedef union jsdpun {
         uint32 hi, lo;
 #endif
     } s;
     uint64   u64;
     jsdouble d;
 } jsdpun;
 
 /* Low-level floating-point predicates. See bug 640494. */
+#define JSDOUBLE_HI32_SIGNBIT   0x80000000
+#define JSDOUBLE_HI32_EXPMASK   0x7ff00000
+#define JSDOUBLE_HI32_MANTMASK  0x000fffff
+#define JSDOUBLE_HI32_NAN       0x7ff80000
+#define JSDOUBLE_LO32_NAN       0x00000000
 
 static inline int
 JSDOUBLE_IS_NaN(jsdouble d)
 {
-/* Visual Studio PGO miscompiles the bitwise version, so keep using _isnan
- * from float.h until we figure out what's going on. */
-#ifdef WIN32
-    return _isnan(d);
-#else
     jsdpun u;
     u.d = d;
-    return (u.u64 & ~JSDOUBLE_SIGNBIT) > JSDOUBLE_EXPMASK;
-#endif
+    return (u.s.hi & JSDOUBLE_HI32_NAN) == JSDOUBLE_HI32_NAN;
 }
 
 static inline int
 JSDOUBLE_IS_FINITE(jsdouble d)
 {
     /* -0 is finite. NaNs are not. */
     jsdpun u;
     u.d = d;
@@ -108,22 +104,16 @@ JSDOUBLE_IS_FINITE(jsdouble d)
 static inline int
 JSDOUBLE_IS_INFINITE(jsdouble d)
 {
     jsdpun u;
     u.d = d;
     return (u.u64 & ~JSDOUBLE_SIGNBIT) == JSDOUBLE_EXPMASK;
 }
 
-#define JSDOUBLE_HI32_SIGNBIT   0x80000000
-#define JSDOUBLE_HI32_EXPMASK   0x7ff00000
-#define JSDOUBLE_HI32_MANTMASK  0x000fffff
-#define JSDOUBLE_HI32_NAN       0x7ff80000
-#define JSDOUBLE_LO32_NAN       0x00000000
-
 static inline bool
 JSDOUBLE_IS_NEG(jsdouble d)
 {
     jsdpun u;
     u.d = d;
     return (u.s.hi & JSDOUBLE_HI32_SIGNBIT) != 0;
 }
 
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -308,16 +308,27 @@ mjit::Compiler::scanInlineCalls(uint32 i
             JSFunction *fun = obj->getFunctionPrivate();
             if (!fun->isInterpreted()) {
                 okay = false;
                 break;
             }
             JSScript *script = fun->script();
 
             /*
+             * Don't inline calls to scripts which haven't been analyzed.
+             * We need to analyze the inlined scripts to compile them, and
+             * doing so can change type information we have queried already
+             * in making inlining decisions.
+             */
+            if (!script->hasAnalysis() || !script->analysis()->ranInference()) {
+                okay = false;
+                break;
+            }
+
+            /*
              * The outer and inner scripts must have the same scope. This only
              * allows us to inline calls between non-inner functions. Also
              * check for consistent strictness between the functions.
              */
             if (!globalObj ||
                 fun->getParent() != globalObj ||
                 outerScript->strictModeCode != script->strictModeCode) {
                 okay = false;
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -758,16 +758,20 @@ class Compiler : public BaseCompiler
     /* Fast builtins. */
     JSObject *pushedSingleton(unsigned pushed);
     CompileStatus callArrayBuiltin(uint32 argc, bool callingNew);
     CompileStatus inlineNativeFunction(uint32 argc, bool callingNew);
     CompileStatus inlineScriptedFunction(uint32 argc, bool callingNew);
     CompileStatus compileMathAbsInt(FrameEntry *arg);
     CompileStatus compileMathAbsDouble(FrameEntry *arg);
     CompileStatus compileMathSqrt(FrameEntry *arg);
+    CompileStatus compileMathMinMaxDouble(FrameEntry *arg1, FrameEntry *arg2, 
+                                          Assembler::DoubleCondition cond); 
+    CompileStatus compileMathMinMaxInt(FrameEntry *arg1, FrameEntry *arg2, 
+                                       Assembler::Condition cond);                                       
     CompileStatus compileMathPowSimple(FrameEntry *arg1, FrameEntry *arg2);
     CompileStatus compileArrayPush(FrameEntry *thisv, FrameEntry *arg);
     CompileStatus compileArrayPop(FrameEntry *thisv, bool isPacked);
     CompileStatus compileArrayWithLength(uint32 argc);
     CompileStatus compileArrayWithArgs(uint32 argc);
 
     enum RoundingMode { Floor, Round };
     CompileStatus compileRound(FrameEntry *arg, RoundingMode mode);
--- a/js/src/methodjit/FastBuiltins.cpp
+++ b/js/src/methodjit/FastBuiltins.cpp
@@ -171,16 +171,110 @@ mjit::Compiler::compileMathSqrt(FrameEnt
 
     frame.popn(3);
     frame.pushDouble(fpResultReg);
 
     return Compile_Okay;
 }
 
 CompileStatus
+mjit::Compiler::compileMathMinMaxDouble(FrameEntry *arg1, FrameEntry *arg2, 
+                                        Assembler::DoubleCondition cond)
+{
+    FPRegisterID fpReg1;
+    FPRegisterID fpReg2;
+    bool allocate;
+
+    DebugOnly<MaybeJump> notNumber = loadDouble(arg1, &fpReg1, &allocate);
+    JS_ASSERT(!((MaybeJump)notNumber).isSet());
+
+    if (!allocate) {
+        FPRegisterID fpResultReg = frame.allocFPReg();
+        masm.moveDouble(fpReg1, fpResultReg);
+        fpReg1 = fpResultReg;
+    }
+
+    DebugOnly<MaybeJump> notNumber2 = loadDouble(arg2, &fpReg2, &allocate);
+    JS_ASSERT(!((MaybeJump)notNumber2).isSet());
+
+
+    /* Slow path for 0 and NaN, because they have special requriments. */
+    masm.zeroDouble(Registers::FPConversionTemp);
+    Jump zeroOrNan = masm.branchDouble(Assembler::DoubleEqualOrUnordered, fpReg1, 
+                                       Registers::FPConversionTemp);
+    stubcc.linkExit(zeroOrNan, Uses(4));
+    Jump zeroOrNan2 = masm.branchDouble(Assembler::DoubleEqualOrUnordered, fpReg2, 
+                                        Registers::FPConversionTemp);
+    stubcc.linkExit(zeroOrNan2, Uses(4));
+
+
+    Jump ifTrue = masm.branchDouble(cond, fpReg1, fpReg2);
+    masm.moveDouble(fpReg2, fpReg1);
+
+    ifTrue.linkTo(masm.label(), &masm);
+
+    if (allocate)
+        frame.freeReg(fpReg2);
+
+    stubcc.leave();
+    stubcc.masm.move(Imm32(2), Registers::ArgReg1);
+    OOL_STUBCALL(stubs::SlowCall, REJOIN_FALLTHROUGH);
+
+    frame.popn(4);
+    frame.pushDouble(fpReg1);
+
+    stubcc.rejoin(Changes(1));
+    return Compile_Okay;
+}
+
+CompileStatus
+mjit::Compiler::compileMathMinMaxInt(FrameEntry *arg1, FrameEntry *arg2, Assembler::Condition cond)
+{
+    /* Get this case out of the way */
+    if (arg1->isConstant() && arg2->isConstant()) {
+        int32 a = arg1->getValue().toInt32();
+        int32 b = arg2->getValue().toInt32();
+
+        frame.popn(4);
+        if (cond == Assembler::LessThan)
+            frame.push(Int32Value(a < b ? a : b));
+        else
+            frame.push(Int32Value(a > b ? a : b));
+        return Compile_Okay;
+    }
+
+    Jump ifTrue;
+    RegisterID reg;
+    if (arg1->isConstant()) {
+        reg = frame.copyDataIntoReg(arg2);
+        int32_t v = arg1->getValue().toInt32();
+
+        ifTrue = masm.branch32(cond, reg, Imm32(v));
+        masm.move(Imm32(v), reg);
+    } else if (arg2->isConstant()) {
+        reg = frame.copyDataIntoReg(arg1);
+        int32_t v = arg2->getValue().toInt32();
+
+        ifTrue = masm.branch32(cond, reg, Imm32(v));
+        masm.move(Imm32(v), reg);
+    } else {
+        reg = frame.copyDataIntoReg(arg1);
+        RegisterID regB = frame.tempRegForData(arg2);
+
+        ifTrue = masm.branch32(cond, reg, regB);
+        masm.move(regB, reg);
+    }
+
+    ifTrue.linkTo(masm.label(), &masm);
+    frame.popn(4);
+    frame.pushTypedPayload(JSVAL_TYPE_INT32, reg);
+    return Compile_Okay;
+}
+
+CompileStatus
 mjit::Compiler::compileMathPowSimple(FrameEntry *arg1, FrameEntry *arg2)
 {
     FPRegisterID fpScratchReg = frame.allocFPReg();
     FPRegisterID fpResultReg = frame.allocFPReg();
 
     FPRegisterID fpReg;
     bool allocate;
 
@@ -651,12 +745,27 @@ mjit::Compiler::inlineNativeFunction(uin
         if (native == js_math_pow && type == JSVAL_TYPE_DOUBLE &&
             (arg1Type == JSVAL_TYPE_DOUBLE || arg1Type == JSVAL_TYPE_INT32) &&
             arg2Type == JSVAL_TYPE_DOUBLE && arg2->isConstant())
         {
             Value arg2Value = arg2->getValue();
             if (arg2Value.toDouble() == -0.5 || arg2Value.toDouble() == 0.5)
                 return compileMathPowSimple(arg1, arg2);
         }
+        if ((native == js_math_min || native == js_math_max)) {
+            if (arg1Type == JSVAL_TYPE_INT32 && arg2Type == JSVAL_TYPE_INT32 &&
+                type == JSVAL_TYPE_INT32) {
+                return compileMathMinMaxInt(arg1, arg2, 
+                        native == js_math_min ? Assembler::LessThan : Assembler::GreaterThan);
+            }
+            if ((arg1Type == JSVAL_TYPE_INT32 || arg1Type == JSVAL_TYPE_DOUBLE) &&
+                (arg2Type == JSVAL_TYPE_INT32 || arg2Type == JSVAL_TYPE_DOUBLE) &&
+                type == JSVAL_TYPE_DOUBLE) {
+                return compileMathMinMaxDouble(arg1, arg2,
+                        (native == js_math_min)
+                        ? Assembler::DoubleLessThan
+                        : Assembler::DoubleGreaterThan);
+            }
+        }
     }
     return Compile_InlineAbort;
 }
 
--- a/js/src/methodjit/FrameState.cpp
+++ b/js/src/methodjit/FrameState.cpp
@@ -739,17 +739,17 @@ FrameState::syncForAllocation(RegisterAl
              * in syncFe below.
              */
             forgetAllRegs(fe);
             fe->resetSynced();
             continue;
         }
 
         /* Force syncs for locals which are dead at the current PC. */
-        if (isLocal(fe) && !a->analysis->slotEscapes(entrySlot(fe))) {
+        if (isLocal(fe) && !fe->copied && !a->analysis->slotEscapes(entrySlot(fe))) {
             Lifetime *lifetime = a->analysis->liveness(entrySlot(fe)).live(a->PC - a->script->code);
             if (!lifetime)
                 fakeSync(fe);
         }
 
         /* If returning from a script, fake syncs for dead locals in the immediate parent. */
         if (inlineReturn && fe >= a->parent->locals &&
             fe - a->parent->locals < a->parent->script->nfixed &&
@@ -796,17 +796,18 @@ FrameState::syncForAllocation(RegisterAl
             relocateReg(reg, alloc, uses);
 
         if (reg.isReg()) {
             RegisterID nreg = reg.reg();
             if (fe->isType(JSVAL_TYPE_DOUBLE)) {
                 JS_ASSERT(!a->analysis->trackSlot(entrySlot(fe)));
                 syncFe(fe);
                 forgetAllRegs(fe);
-                fe->resetSynced();
+                fe->type.setMemory();
+                fe->data.setMemory();
             }
             if (fe->data.inMemory()) {
                 masm.loadPayload(addressOf(fe), nreg);
             } else if (fe->isConstant()) {
                 masm.loadValuePayload(fe->getValue(), nreg);
             } else {
                 JS_ASSERT(fe->data.inRegister() && fe->data.reg() != nreg);
                 masm.move(fe->data.reg(), nreg);
deleted file mode 100644
--- a/js/src/resource.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by js3240.rc
-//
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        101
-#define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1000
-#define _APS_NEXT_SYMED_VALUE           101
-#endif
-#endif
deleted file mode 100644
--- a/js/src/t/3d-cube.js
+++ /dev/null
@@ -1,337 +0,0 @@
-// 3D Cube Rotation
-// http://www.speich.net/computer/moztesting/3d.htm
-// Created by Simon Speich
-
-var Q = new Array();
-var MTrans = new Array();  // transformation matrix
-var MQube = new Array();  // position information of qube
-var I = new Array();      // entity matrix
-var Origin = new Object();
-var Testing = new Object();
-var LoopTimer;
-
-var DisplArea = new Object();
-DisplArea.Width = 300;
-DisplArea.Height = 300;
-
-function DrawLine(From, To) {
-  var x1 = From.V[0];
-  var x2 = To.V[0];
-  var y1 = From.V[1];
-  var y2 = To.V[1];
-  var dx = Math.abs(x2 - x1);
-  var dy = Math.abs(y2 - y1);
-  var x = x1;
-  var y = y1;
-  var IncX1, IncY1;
-  var IncX2, IncY2;  
-  var Den;
-  var Num;
-  var NumAdd;
-  var NumPix;
-
-  if (x2 >= x1) {  IncX1 = 1; IncX2 = 1;  }
-  else { IncX1 = -1; IncX2 = -1; }
-  if (y2 >= y1)  {  IncY1 = 1; IncY2 = 1; }
-  else { IncY1 = -1; IncY2 = -1; }
-  if (dx >= dy) {
-    IncX1 = 0;
-    IncY2 = 0;
-    Den = dx;
-    Num = dx / 2;
-    NumAdd = dy;
-    NumPix = dx;
-  }
-  else {
-    IncX2 = 0;
-    IncY1 = 0;
-    Den = dy;
-    Num = dy / 2;
-    NumAdd = dx;
-    NumPix = dy;
-  }
-
-  NumPix = Math.round(Q.LastPx + NumPix);
-
-  var i = Q.LastPx;
-  for (; i < NumPix; i++) {
-    Num += NumAdd;
-    if (Num >= Den) {
-      Num -= Den;
-      x += IncX1;
-      y += IncY1;
-    }
-    x += IncX2;
-    y += IncY2;
-  }
-  Q.LastPx = NumPix;
-}
-
-function CalcCross(V0, V1) {
-  var Cross = new Array();
-  Cross[0] = V0[1]*V1[2] - V0[2]*V1[1];
-  Cross[1] = V0[2]*V1[0] - V0[0]*V1[2];
-  Cross[2] = V0[0]*V1[1] - V0[1]*V1[0];
-  return Cross;
-}
-
-function CalcNormal(V0, V1, V2) {
-  var A = new Array();   var B = new Array(); 
-  for (var i = 0; i < 3; i++) {
-    A[i] = V0[i] - V1[i];
-    B[i] = V2[i] - V1[i];
-  }
-  A = CalcCross(A, B);
-  var Length = Math.sqrt(A[0]*A[0] + A[1]*A[1] + A[2]*A[2]); 
-  for (var i = 0; i < 3; i++) A[i] = A[i] / Length;
-  A[3] = 1;
-  return A;
-}
-
-function CreateP(X,Y,Z) {
-  this.V = [X,Y,Z,1];
-}
-
-// multiplies two matrices
-function MMulti(M1, M2) {
-  var M = [[],[],[],[]];
-  var i = 0;
-  var j = 0;
-  for (; i < 4; i++) {
-    j = 0;
-    for (; j < 4; j++) M[i][j] = M1[i][0] * M2[0][j] + M1[i][1] * M2[1][j] + M1[i][2] * M2[2][j] + M1[i][3] * M2[3][j];
-  }
-  return M;
-}
-
-//multiplies matrix with vector
-function VMulti(M, V) {
-  var Vect = new Array();
-  var i = 0;
-  for (;i < 4; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2] + M[i][3] * V[3];
-  return Vect;
-}
-
-function VMulti2(M, V) {
-  var Vect = new Array();
-  var i = 0;
-  for (;i < 3; i++) Vect[i] = M[i][0] * V[0] + M[i][1] * V[1] + M[i][2] * V[2];
-  return Vect;
-}
-
-// add to matrices
-function MAdd(M1, M2) {
-  var M = [[],[],[],[]];
-  var i = 0;
-  var j = 0;
-  for (; i < 4; i++) {
-    j = 0;
-    for (; j < 4; j++) M[i][j] = M1[i][j] + M2[i][j];
-  }
-  return M;
-}
-
-function Translate(M, Dx, Dy, Dz) {
-  var T = [
-  [1,0,0,Dx],
-  [0,1,0,Dy],
-  [0,0,1,Dz],
-  [0,0,0,1]
-  ];
-  return MMulti(T, M);
-}
-
-function RotateX(M, Phi) {
-  var a = Phi;
-  a *= Math.PI / 180;
-  var Cos = Math.cos(a);
-  var Sin = Math.sin(a);
-  var R = [
-  [1,0,0,0],
-  [0,Cos,-Sin,0],
-  [0,Sin,Cos,0],
-  [0,0,0,1]
-  ];
-  return MMulti(R, M);
-}
-
-function RotateY(M, Phi) {
-  var a = Phi;
-  a *= Math.PI / 180;
-  var Cos = Math.cos(a);
-  var Sin = Math.sin(a);
-  var R = [
-  [Cos,0,Sin,0],
-  [0,1,0,0],
-  [-Sin,0,Cos,0],
-  [0,0,0,1]
-  ];
-  return MMulti(R, M);
-}
-
-function RotateZ(M, Phi) {
-  var a = Phi;
-  a *= Math.PI / 180;
-  var Cos = Math.cos(a);
-  var Sin = Math.sin(a);
-  var R = [
-  [Cos,-Sin,0,0],
-  [Sin,Cos,0,0],
-  [0,0,1,0],   
-  [0,0,0,1]
-  ];
-  return MMulti(R, M);
-}
-
-function DrawQube() {
-  // calc current normals
-  var CurN = new Array();
-  var i = 5;
-  Q.LastPx = 0;
-  for (; i > -1; i--) CurN[i] = VMulti2(MQube, Q.Normal[i]);
-  if (CurN[0][2] < 0) {
-    if (!Q.Line[0]) { DrawLine(Q[0], Q[1]); Q.Line[0] = true; };
-    if (!Q.Line[1]) { DrawLine(Q[1], Q[2]); Q.Line[1] = true; };
-    if (!Q.Line[2]) { DrawLine(Q[2], Q[3]); Q.Line[2] = true; };
-    if (!Q.Line[3]) { DrawLine(Q[3], Q[0]); Q.Line[3] = true; };
-  }
-  if (CurN[1][2] < 0) {
-    if (!Q.Line[2]) { DrawLine(Q[3], Q[2]); Q.Line[2] = true; };
-    if (!Q.Line[9]) { DrawLine(Q[2], Q[6]); Q.Line[9] = true; };
-    if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
-    if (!Q.Line[10]) { DrawLine(Q[7], Q[3]); Q.Line[10] = true; };
-  }
-  if (CurN[2][2] < 0) {
-    if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
-    if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
-    if (!Q.Line[6]) { DrawLine(Q[6], Q[7]); Q.Line[6] = true; };
-    if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
-  }
-  if (CurN[3][2] < 0) {
-    if (!Q.Line[4]) { DrawLine(Q[4], Q[5]); Q.Line[4] = true; };
-    if (!Q.Line[8]) { DrawLine(Q[5], Q[1]); Q.Line[8] = true; };
-    if (!Q.Line[0]) { DrawLine(Q[1], Q[0]); Q.Line[0] = true; };
-    if (!Q.Line[11]) { DrawLine(Q[0], Q[4]); Q.Line[11] = true; };
-  }
-  if (CurN[4][2] < 0) {
-    if (!Q.Line[11]) { DrawLine(Q[4], Q[0]); Q.Line[11] = true; };
-    if (!Q.Line[3]) { DrawLine(Q[0], Q[3]); Q.Line[3] = true; };
-    if (!Q.Line[10]) { DrawLine(Q[3], Q[7]); Q.Line[10] = true; };
-    if (!Q.Line[7]) { DrawLine(Q[7], Q[4]); Q.Line[7] = true; };
-  }
-  if (CurN[5][2] < 0) {
-    if (!Q.Line[8]) { DrawLine(Q[1], Q[5]); Q.Line[8] = true; };
-    if (!Q.Line[5]) { DrawLine(Q[5], Q[6]); Q.Line[5] = true; };
-    if (!Q.Line[9]) { DrawLine(Q[6], Q[2]); Q.Line[9] = true; };
-    if (!Q.Line[1]) { DrawLine(Q[2], Q[1]); Q.Line[1] = true; };
-  }
-  Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
-  Q.LastPx = 0;
-}
-
-function Loop() {
-  if (Testing.LoopCount > Testing.LoopMax) return;
-  var TestingStr = String(Testing.LoopCount);
-  while (TestingStr.length < 3) TestingStr = "0" + TestingStr;
-  MTrans = Translate(I, -Q[8].V[0], -Q[8].V[1], -Q[8].V[2]);
-  MTrans = RotateX(MTrans, 1);
-  MTrans = RotateY(MTrans, 3);
-  MTrans = RotateZ(MTrans, 5);
-  MTrans = Translate(MTrans, Q[8].V[0], Q[8].V[1], Q[8].V[2]);
-  MQube = MMulti(MTrans, MQube);
-  var i = 8;
-  for (; i > -1; i--) {
-    Q[i].V = VMulti(MTrans, Q[i].V);
-  }
-  DrawQube();
-  Testing.LoopCount++;
-  Loop();
-}
-
-function Init(CubeSize) {
-  // init/reset vars
-  Origin.V = [150,150,20,1];
-  Testing.LoopCount = 0;
-  Testing.LoopMax = 50;
-  Testing.TimeMax = 0;
-  Testing.TimeAvg = 0;
-  Testing.TimeMin = 0;
-  Testing.TimeTemp = 0;
-  Testing.TimeTotal = 0;
-  Testing.Init = false;
-
-  // transformation matrix
-  MTrans = [
-  [1,0,0,0],
-  [0,1,0,0],
-  [0,0,1,0],
-  [0,0,0,1]
-  ];
-  
-  // position information of qube
-  MQube = [
-  [1,0,0,0],
-  [0,1,0,0],
-  [0,0,1,0],
-  [0,0,0,1]
-  ];
-  
-  // entity matrix
-  I = [
-  [1,0,0,0],
-  [0,1,0,0],
-  [0,0,1,0],
-  [0,0,0,1]
-  ];
-  
-  // create qube
-  Q[0] = new CreateP(-CubeSize,-CubeSize, CubeSize);
-  Q[1] = new CreateP(-CubeSize, CubeSize, CubeSize);
-  Q[2] = new CreateP( CubeSize, CubeSize, CubeSize);
-  Q[3] = new CreateP( CubeSize,-CubeSize, CubeSize);
-  Q[4] = new CreateP(-CubeSize,-CubeSize,-CubeSize);
-  Q[5] = new CreateP(-CubeSize, CubeSize,-CubeSize);
-  Q[6] = new CreateP( CubeSize, CubeSize,-CubeSize);
-  Q[7] = new CreateP( CubeSize,-CubeSize,-CubeSize);
-  
-  // center of gravity
-  Q[8] = new CreateP(0, 0, 0);
-  
-  // anti-clockwise edge check
-  Q.Edge = [[0,1,2],[3,2,6],[7,6,5],[4,5,1],[4,0,3],[1,5,6]];
-  
-  // calculate squad normals
-  Q.Normal = new Array();
-  for (var i = 0; i < Q.Edge.length; i++) Q.Normal[i] = CalcNormal(Q[Q.Edge[i][0]].V, Q[Q.Edge[i][1]].V, Q[Q.Edge[i][2]].V);
-  
-  // line drawn ?
-  Q.Line = [false,false,false,false,false,false,false,false,false,false,false,false];
-  
-  // create line pixels
-  Q.NumPx = 9 * 2 * CubeSize;
-  for (var i = 0; i < Q.NumPx; i++) CreateP(0,0,0);
-  
-  MTrans = Translate(MTrans, Origin.V[0], Origin.V[1], Origin.V[2]);
-  MQube = MMulti(MTrans, MQube);
-
-  var i = 0;
-  for (; i < 9; i++) {
-    Q[i].V = VMulti(MTrans, Q[i].V);
-  }
-  DrawQube();
-  Testing.Init = true;
-  Loop();
-}
-
-for ( var i = 20; i <= 160; i *= 2 ) {
-  Init(i);
-}
-
-Q = null;
-MTrans = null;
-MQube = null;
-I = null;
-Origin = null;
-Testing = null;
-LoopTime = null;
-DisplArea = null;
deleted file mode 100644
--- a/js/src/t/3d-morph.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-var loops = 15
-var nx = 120
-var nz = 120
-
-function morph(a, f) {
-    var PI2nx = Math.PI * 8/nx
-    var sin = Math.sin
-    var f30 = -(50 * sin(f*Math.PI*2))
-    
-    for (var i = 0; i < nz; ++i) {
-        for (var j = 0; j < nx; ++j) {
-            a[3*(i*nx+j)+1]    = sin((j-1) * PI2nx ) * -f30
-        }
-    }
-}
-
-    
-var a = Array()
-for (var i=0; i < nx*nz*3; ++i) 
-    a[i] = 0
-
-for (var i = 0; i < loops; ++i) {
-    morph(a, i/loops)
-}
-
-testOutput = 0;
-for (var i = 0; i < nx; i++)
-    testOutput += a[3*(i*nx+i)+1];
-a = null;
deleted file mode 100644
--- a/js/src/t/3d-raytrace.js
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-function createVector(x,y,z) {
-    return new Array(x,y,z);
-}
-
-function sqrLengthVector(self) {
-    return self[0] * self[0] + self[1] * self[1] + self[2] * self[2];
-}
-
-function lengthVector(self) {
-    return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
-}
-
-function addVector(self, v) {
-    self[0] += v[0];
-    self[1] += v[1];
-    self[2] += v[2];
-    return self;
-}
-
-function subVector(self, v) {
-    self[0] -= v[0];
-    self[1] -= v[1];
-    self[2] -= v[2];
-    return self;
-}
-
-function scaleVector(self, scale) {
-    self[0] *= scale;
-    self[1] *= scale;
-    self[2] *= scale;
-    return self;
-}
-
-function normaliseVector(self) {
-    var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
-    self[0] /= len;
-    self[1] /= len;
-    self[2] /= len;
-    return self;
-}
-
-function add(v1, v2) {
-    return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
-}
-
-function sub(v1, v2) {
-    return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
-}
-
-function scalev(v1, v2) {
-    return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);
-}
-
-function dot(v1, v2) {
-    return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
-}
-
-function scale(v, scale) {
-    return [v[0] * scale, v[1] * scale, v[2] * scale];
-}
-
-function cross(v1, v2) {
-    return [v1[1] * v2[2] - v1[2] * v2[1], 
-            v1[2] * v2[0] - v1[0] * v2[2],
-            v1[0] * v2[1] - v1[1] * v2[0]];
-
-}
-
-function normalise(v) {
-    var len = lengthVector(v);
-    return [v[0] / len, v[1] / len, v[2] / len];
-}
-
-function transformMatrix(self, v) {
-    var vals = self;
-    var x  = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3];
-    var y  = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7];
-    var z  = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11];
-    return [x, y, z];
-}
-
-function invertMatrix(self) {
-    var temp = new Array(16);
-    var tx = -self[3];
-    var ty = -self[7];
-    var tz = -self[11];
-    for (h = 0; h < 3; h++) 
-        for (v = 0; v < 3; v++) 
-            temp[h + v * 4] = self[v + h * 4];
-    for (i = 0; i < 11; i++)
-        self[i] = temp[i];
-    self[3] = tx * self[0] + ty * self[1] + tz * self[2];
-    self[7] = tx * self[4] + ty * self[5] + tz * self[6];
-    self[11] = tx * self[8] + ty * self[9] + tz * self[10];
-    return self;
-}
-
-
-// Triangle intersection using barycentric coord method
-function Triangle(p1, p2, p3) {
-    var edge1 = sub(p3, p1);
-    var edge2 = sub(p2, p1);
-    var normal = cross(edge1, edge2);
-    if (Math.abs(normal[0]) > Math.abs(normal[1]))
-        if (Math.abs(normal[0]) > Math.abs(normal[2]))
-            this.axis = 0; 
-        else 
-            this.axis = 2;
-    else
-        if (Math.abs(normal[1]) > Math.abs(normal[2])) 
-            this.axis = 1;
-        else 
-            this.axis = 2;
-    var u = (this.axis + 1) % 3;
-    var v = (this.axis + 2) % 3;
-    var u1 = edge1[u];
-    var v1 = edge1[v];
-    
-    var u2 = edge2[u];
-    var v2 = edge2[v];
-    this.normal = normalise(normal);
-    this.nu = normal[u] / normal[this.axis];
-    this.nv = normal[v] / normal[this.axis];
-    this.nd = dot(normal, p1) / normal[this.axis];
-    var det = u1 * v2 - v1 * u2;
-    this.eu = p1[u];
-    this.ev = p1[v]; 
-    this.nu1 = u1 / det;
-    this.nv1 = -v1 / det;
-    this.nu2 = v2 / det;
-    this.nv2 = -u2 / det; 
-    this.material = [0.7, 0.7, 0.7];
-}
-
-Triangle.prototype.intersect = function(orig, dir, near, far) {
-    var u = (this.axis + 1) % 3;
-    var v = (this.axis + 2) % 3;
-    var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v];
-    var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d;
-    if (t < near || t > far)
-        return null;
-    var Pu = orig[u] + t * dir[u] - this.eu;
-    var Pv = orig[v] + t * dir[v] - this.ev;
-    var a2 = Pv * this.nu1 + Pu * this.nv1;
-    if (a2 < 0) 
-        return null;
-    var a3 = Pu * this.nu2 + Pv * this.nv2;
-    if (a3 < 0) 
-        return null;
-
-    if ((a2 + a3) > 1) 
-        return null;
-    return t;
-}
-
-function Scene(a_triangles) {
-    this.triangles = a_triangles;
-    this.lights = [];
-    this.ambient = [0,0,0];
-    this.background = [0.8,0.8,1];
-}
-var zero = new Array(0,0,0);
-
-Scene.prototype.intersect = function(origin, dir, near, far) {
-    var closest = null;
-    for (i = 0; i < this.triangles.length; i++) {
-        var triangle = this.triangles[i];   
-        var d = triangle.intersect(origin, dir, near, far);
-        if (d == null || d > far || d < near)
-            continue;
-        far = d;
-        closest = triangle;
-    }
-    
-    if (!closest)
-        return [this.background[0],this.background[1],this.background[2]];
-        
-    var normal = closest.normal;
-    var hit = add(origin, scale(dir, far)); 
-    if (dot(dir, normal) > 0)
-        normal = [-normal[0], -normal[1], -normal[2]];
-    
-    var colour = null;
-    if (closest.shader) {
-        colour = closest.shader(closest, hit, dir);
-    } else {
-        colour = closest.material;
-    }
-    
-    // do reflection
-    var reflected = null;
-    if (colour.reflection > 0.001) {
-        var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir);
-        reflected = this.intersect(hit, reflection, 0.0001, 1000000);
-        if (colour.reflection >= 0.999999)
-            return reflected;
-    }
-    
-    var l = [this.ambient[0], this.ambient[1], this.ambient[2]];
-    for (var i = 0; i < this.lights.length; i++) {
-        var light = this.lights[i];
-        var toLight = sub(light, hit);
-        var distance = lengthVector(toLight);
-        scaleVector(toLight, 1.0/distance);
-        distance -= 0.0001;
-        if (this.blocked(hit, toLight, distance))
-            continue;
-        var nl = dot(normal, toLight);
-        if (nl > 0)
-            addVector(l, scale(light.colour, nl));
-    }
-    l = scalev(l, colour);
-    if (reflected) {
-        l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection));
-    }
-    return l;
-}
-
-Scene.prototype.blocked = function(O, D, far) {
-    var near = 0.0001;
-    var closest = null;
-    for (i = 0; i < this.triangles.length; i++) {
-        var triangle = this.triangles[i];   
-        var d = triangle.intersect(O, D, near, far);
-        if (d == null || d > far || d < near)
-            continue;
-        return true;
-    }
-    
-    return false;
-}
-
-
-// this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where
-// that somewhere is
-function Camera(origin, lookat, up) {
-    var zaxis = normaliseVector(subVector(lookat, origin));
-    var xaxis = normaliseVector(cross(up, zaxis));
-    var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis)));
-    var m = new Array(16);
-    m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2];
-    m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2];
-    m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2];
-    invertMatrix(m);
-    m[3] = 0; m[7] = 0; m[11] = 0;
-    this.origin = origin;
-    this.directions = new Array(4);
-    this.directions[0] = normalise([-0.7,  0.7, 1]);
-    this.directions[1] = normalise([ 0.7,  0.7, 1]);
-    this.directions[2] = normalise([ 0.7, -0.7, 1]);
-    this.directions[3] = normalise([-0.7, -0.7, 1]);
-    this.directions[0] = transformMatrix(m, this.directions[0]);
-    this.directions[1] = transformMatrix(m, this.directions[1]);
-    this.directions[2] = transformMatrix(m, this.directions[2]);
-    this.directions[3] = transformMatrix(m, this.directions[3]);
-}
-
-Camera.prototype.generateRayPair = function(y) {
-    rays = new Array(new Object(), new Object());
-    rays[0].origin = this.origin;
-    rays[1].origin = this.origin;
-    rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y));
-    rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y));
-    return rays;
-}
-
-function renderRows(camera, scene, pixels, width, height, starty, stopy) {
-    for (var y = starty; y < stopy; y++) {
-        var rays = camera.generateRayPair(y / height);
-        for (var x = 0; x < width; x++) {
-            var xp = x / width;
-            var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp));
-            var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp)));
-            var l = scene.intersect(origin, dir);
-            pixels[y][x] = l;
-        }
-    }
-}
-
-Camera.prototype.render = function(scene, pixels, width, height) {
-    var cam = this;
-    var row = 0;
-    renderRows(cam, scene, pixels, width, height, 0, height);
-}
-
-
-
-function raytraceScene()
-{
-    var startDate = new Date().getTime();
-    var numTriangles = 2 * 6;
-    var triangles = new Array();//numTriangles);
-    var tfl = createVector(-10,  10, -10);
-    var tfr = createVector( 10,  10, -10);
-    var tbl = createVector(-10,  10,  10);
-    var tbr = createVector( 10,  10,  10);
-    var bfl = createVector(-10, -10, -10);
-    var bfr = createVector( 10, -10, -10);
-    var bbl = createVector(-10, -10,  10);
-    var bbr = createVector( 10, -10,  10);
-    
-    // cube!!!
-    // front
-    var i = 0;
-    
-    triangles[i++] = new Triangle(tfl, tfr, bfr);
-    triangles[i++] = new Triangle(tfl, bfr, bfl);
-    // back
-    triangles[i++] = new Triangle(tbl, tbr, bbr);
-    triangles[i++] = new Triangle(tbl, bbr, bbl);
-    //        triangles[i-1].material = [0.7,0.2,0.2];
-    //            triangles[i-1].material.reflection = 0.8;
-    // left
-    triangles[i++] = new Triangle(tbl, tfl, bbl);
-    //            triangles[i-1].reflection = 0.6;
-    triangles[i++] = new Triangle(tfl, bfl, bbl);
-    //            triangles[i-1].reflection = 0.6;
-    // right
-    triangles[i++] = new Triangle(tbr, tfr, bbr);
-    triangles[i++] = new Triangle(tfr, bfr, bbr);
-    // top
-    triangles[i++] = new Triangle(tbl, tbr, tfr);
-    triangles[i++] = new Triangle(tbl, tfr, tfl);
-    // bottom
-    triangles[i++] = new Triangle(bbl, bbr, bfr);
-    triangles[i++] = new Triangle(bbl, bfr, bfl);
-    
-    //Floor!!!!
-    var green = createVector(0.0, 0.4, 0.0);
-    var grey = createVector(0.4, 0.4, 0.4);
-    grey.reflection = 1.0;
-    var floorShader = function(tri, pos, view) {
-        var x = ((pos[0]/32) % 2 + 2) % 2;
-        var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2;
-        if (x < 1 != z < 1) {
-            //in the real world we use the fresnel term...
-            //    var angle = 1-dot(view, tri.normal);
-            //   angle *= angle;
-            //  angle *= angle;
-            // angle *= angle;
-            //grey.reflection = angle;
-            return grey;
-        } else 
-            return green;
-    }
-    var ffl = createVector(-1000, -30, -1000);
-    var ffr = createVector( 1000, -30, -1000);
-    var fbl = createVector(-1000, -30,  1000);
-    var fbr = createVector( 1000, -30,  1000);
-    triangles[i++] = new Triangle(fbl, fbr, ffr);
-    triangles[i-1].shader = floorShader;
-    triangles[i++] = new Triangle(fbl, ffr, ffl);
-    triangles[i-1].shader = floorShader;
-    
-    var _scene = new Scene(triangles);
-    _scene.lights[0] = createVector(20, 38, -22);
-    _scene.lights[0].colour = createVector(0.7, 0.3, 0.3);
-    _scene.lights[1] = createVector(-23, 40, 17);
-    _scene.lights[1].colour = createVector(0.7, 0.3, 0.3);
-    _scene.lights[2] = createVector(23, 20, 17);
-    _scene.lights[2].colour = createVector(0.7, 0.7, 0.7);
-    _scene.ambient = createVector(0.1, 0.1, 0.1);
-    //  _scene.background = createVector(0.7, 0.7, 1.0);
-    
-    var size = 30;
-    var pixels = new Array();
-    for (var y = 0; y < size; y++) {
-        pixels[y] = new Array();
-        for (var x = 0; x < size; x++) {
-            pixels[y][x] = 0;
-        }
-    }
-
-    var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0));
-    _camera.render(_scene, pixels, size, size);
-
-    return pixels;
-}
-
-function arrayToCanvasCommands(pixels)
-{
-    var s = '<canvas id="renderCanvas" width="30px" height="30px"></canvas><scr' + 'ipt>\nvar pixels = [';
-    var size = 30;
-    for (var y = 0; y < size; y++) {
-        s += "[";
-        for (var x = 0; x < size; x++) {
-            s += "[" + pixels[y][x] + "],";
-        }
-        s+= "],";
-    }
-    s += '];\n    var canvas = document.getElementById("renderCanvas").getContext("2d");\n\
-\n\
-\n\
-    var size = 30;\n\
-    canvas.fillStyle = "red";\n\
-    canvas.fillRect(0, 0, size, size);\n\
-    canvas.scale(1, -1);\n\
-    canvas.translate(0, -size);\n\
-\n\
-    if (!canvas.setFillColor)\n\
-        canvas.setFillColor = function(r, g, b, a) {\n\
-            this.fillStyle = "rgb("+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+")";\n\
-    }\n\
-\n\
-for (var y = 0; y < size; y++) {\n\
-  for (var x = 0; x < size; x++) {\n\
-    var l = pixels[y][x];\n\
-    canvas.setFillColor(l[0], l[1], l[2], 1);\n\
-    canvas.fillRect(x, y, 1, 1);\n\
-  }\n\
-}</scr' + 'ipt>';
-
-    return s;
-}
-
-testOutput = arrayToCanvasCommands(raytraceScene());
deleted file mode 100644
--- a/js/src/t/access-binary-trees.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* The Great Computer Language Shootout
-   http://shootout.alioth.debian.org/
-   contributed by Isaac Gouy */
-
-function TreeNode(left,right,item){
-   this.left = left;
-   this.right = right;
-   this.item = item;
-}
-
-TreeNode.prototype.itemCheck = function(){
-   if (this.left==null) return this.item;
-   else return this.item + this.left.itemCheck() - this.right.itemCheck();
-}
-
-function bottomUpTree(item,depth){
-   if (depth>0){
-      return new TreeNode(
-          bottomUpTree(2*item-1, depth-1)
-         ,bottomUpTree(2*item, depth-1)
-         ,item
-      );
-   }
-   else {
-      return new TreeNode(null,null,item);
-   }
-}
-
-var ret;
-
-for ( var n = 4; n <= 7; n += 1 ) {
-    var minDepth = 4;
-    var maxDepth = Math.max(minDepth + 2, n);
-    var stretchDepth = maxDepth + 1;
-    
-    var check = bottomUpTree(0,stretchDepth).itemCheck();
-    
-    var longLivedTree = bottomUpTree(0,maxDepth);
-    for (var depth=minDepth; depth<=maxDepth; depth+=2){
-        var iterations = 1 << (maxDepth - depth + minDepth);
-
-        check = 0;
-        for (var i=1; i<=iterations; i++){
-            check += bottomUpTree(i,depth).itemCheck();
-            check += bottomUpTree(-i,depth).itemCheck();
-        }
-    }
-
-    ret = longLivedTree.itemCheck();
-}
deleted file mode 100644
--- a/js/src/t/access-fannkuch.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/* The Great Computer Language Shootout
-   http://shootout.alioth.debian.org/
-   contributed by Isaac Gouy */
-
-function fannkuch(n) {
-   var check = 0;
-   var perm = Array(n);
-   var perm1 = Array(n);
-   var count = Array(n);
-   var maxPerm = Array(n);
-   var maxFlipsCount = 0;
-   var m = n - 1;
-
-   for (var i = 0; i < n; i++) perm1[i] = i;
-   var r = n;
-
-   while (true) {
-      // write-out the first 30 permutations
-      if (check < 30){
-         var s = "";
-         for(var i=0; i<n; i++) s += (perm1[i]+1).toString();
-         check++;
-      }
-
-      while (r != 1) { count[r - 1] = r; r--; }
-      if (!(perm1[0] == 0 || perm1[m] == m)) {
-         for (var i = 0; i < n; i++) perm[i] = perm1[i];
-
-         var flipsCount = 0;
-         var k;
-
-         while (!((k = perm[0]) == 0)) {
-            var k2 = (k + 1) >> 1;
-            for (var i = 0; i < k2; i++) {
-               var temp = perm[i]; perm[i] = perm[k - i]; perm[k - i] = temp;
-            }
-            flipsCount++;
-         }
-
-         if (flipsCount > maxFlipsCount) {
-            maxFlipsCount = flipsCount;
-            for (var i = 0; i < n; i++) maxPerm[i] = perm1[i];
-         }
-      }
-
-      while (true) {
-         if (r == n) return maxFlipsCount;
-         var perm0 = perm1[0];
-         var i = 0;
-         while (i < r) {
-            var j = i + 1;
-            perm1[i] = perm1[j];
-            i = j;
-         }
-         perm1[r] = perm0;
-
-         count[r] = count[r] - 1;
-         if (count[r] > 0) break;
-         r++;
-      }
-   }
-}
-
-var n = 8;
-var ret = fannkuch(n);
-
deleted file mode 100644
--- a/js/src/t/access-nbody.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/* The Great Computer Language Shootout
-   http://shootout.alioth.debian.org/
-   contributed by Isaac Gouy */
-
-var PI = 3.141592653589793;
-var SOLAR_MASS = 4 * PI * PI;
-var DAYS_PER_YEAR = 365.24;
-
-function Body(x,y,z,vx,vy,vz,mass){
-   this.x = x;
-   this.y = y;
-   this.z = z;
-   this.vx = vx;
-   this.vy = vy;
-   this.vz = vz;
-   this.mass = mass;
-}
-
-Body.prototype.offsetMomentum = function(px,py,pz) {
-   this.vx = -px / SOLAR_MASS;
-   this.vy = -py / SOLAR_MASS;
-   this.vz = -pz / SOLAR_MASS;
-   return this;
-}
-
-function Jupiter(){
-   return new Body(
-      4.84143144246472090e+00,
-      -1.16032004402742839e+00,
-      -1.03622044471123109e-01,
-      1.66007664274403694e-03 * DAYS_PER_YEAR,
-      7.69901118419740425e-03 * DAYS_PER_YEAR,
-      -6.90460016972063023e-05 * DAYS_PER_YEAR,
-      9.54791938424326609e-04 * SOLAR_MASS
-   );
-}
-
-function Saturn(){
-   return new Body(
-      8.34336671824457987e+00,
-      4.12479856412430479e+00,
-      -4.03523417114321381e-01,
-      -2.76742510726862411e-03 * DAYS_PER_YEAR,
-      4.99852801234917238e-03 * DAYS_PER_YEAR,
-      2.30417297573763929e-05 * DAYS_PER_YEAR,
-      2.85885980666130812e-04 * SOLAR_MASS
-   );
-}
-
-function Uranus(){
-   return new Body(
-      1.28943695621391310e+01,
-      -1.51111514016986312e+01,
-      -2.23307578892655734e-01,
-      2.96460137564761618e-03 * DAYS_PER_YEAR,
-      2.37847173959480950e-03 * DAYS_PER_YEAR,
-      -2.96589568540237556e-05 * DAYS_PER_YEAR,
-      4.36624404335156298e-05 * SOLAR_MASS
-   );
-}
-
-function Neptune(){
-   return new Body(
-      1.53796971148509165e+01,
-      -2.59193146099879641e+01,
-      1.79258772950371181e-01,
-      2.68067772490389322e-03 * DAYS_PER_YEAR,
-      1.62824170038242295e-03 * DAYS_PER_YEAR,
-      -9.51592254519715870e-05 * DAYS_PER_YEAR,
-      5.15138902046611451e-05 * SOLAR_MASS
-   );
-}
-
-function Sun(){
-   return new Body(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, SOLAR_MASS);
-}
-
-
-function NBodySystem(bodies){
-   this.bodies = bodies;
-   var px = 0.0;
-   var py = 0.0;
-   var pz = 0.0;
-   var size = this.bodies.length;
-   for (var i=0; i<size; i++){
-      var b = this.bodies[i];
-      var m = b.mass;
-      px += b.vx * m;
-      py += b.vy * m;
-      pz += b.vz * m;
-   }
-   this.bodies[0].offsetMomentum(px,py,pz);
-}
-
-NBodySystem.prototype.advance = function(dt){
-   var dx, dy, dz, distance, mag;
-   var size = this.bodies.length;
-
-   for (var i=0; i<size; i++) {
-      var bodyi = this.bodies[i];
-      for (var j=i+1; j<size; j++) {
-         var bodyj = this.bodies[j];
-         dx = bodyi.x - bodyj.x;
-         dy = bodyi.y - bodyj.y;
-         dz = bodyi.z - bodyj.z;
-
-         distance = Math.sqrt(dx*dx + dy*dy + dz*dz);
-         mag = dt / (distance * distance * distance);
-
-         bodyi.vx -= dx * bodyj.mass * mag;
-         bodyi.vy -= dy * bodyj.mass * mag;
-         bodyi.vz -= dz * bodyj.mass * mag;
-
-         bodyj.vx += dx * bodyi.mass * mag;
-         bodyj.vy += dy * bodyi.mass * mag;
-         bodyj.vz += dz * bodyi.mass * mag;
-      }
-   }
-
-   for (var i=0; i<size; i++) {
-      var body = this.bodies[i];
-      body.x += dt * body.vx;
-      body.y += dt * body.vy;
-      body.z += dt * body.vz;
-   }
-}
-
-NBodySystem.prototype.energy = function(){
-   var dx, dy, dz, distance;
-   var e = 0.0;
-   var size = this.bodies.length;
-
-   for (var i=0; i<size; i++) {
-      var bodyi = this.bodies[i];
-
-      e += 0.5 * bodyi.mass *
-         ( bodyi.vx * bodyi.vx
-         + bodyi.vy * bodyi.vy
-         + bodyi.vz * bodyi.vz );
-
-      for (var j=i+1; j<size; j++) {
-         var bodyj = this.bodies[j];
-         dx = bodyi.x - bodyj.x;
-         dy = bodyi.y - bodyj.y;
-         dz = bodyi.z - bodyj.z;
-
-         distance = Math.sqrt(dx*dx + dy*dy + dz*dz);
-         e -= (bodyi.mass * bodyj.mass) / distance;
-      }
-   }
-   return e;
-}
-
-var ret;
-
-for ( var n = 3; n <= 24; n *= 2 ) {
-    (function(){
-        var bodies = new NBodySystem( Array(
-           Sun(),Jupiter(),Saturn(),Uranus(),Neptune()
-        ));
-        var max = n * 100;
-        
-        ret = bodies.energy();
-        for (var i=0; i<max; i++){
-            bodies.advance(0.01);
-        }
-        ret = bodies.energy();
-    })();
-}
deleted file mode 100644
--- a/js/src/t/access-nsieve.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// The Great Computer Language Shootout
-// http://shootout.alioth.debian.org/
-//
-// modified by Isaac Gouy
-
-function pad(number,width){
-   var s = number.toString();
-   var prefixWidth = width - s.length;
-   if (prefixWidth>0){
-      for (var i=1; i<=prefixWidth; i++) s = " " + s;
-   }
-   return s;
-}
-
-function nsieve(m, isPrime){
-   var i, k, count;
-
-   for (i=2; i<=m; i++) { isPrime[i] = true; }
-   count = 0;
-
-   for (i=2; i<=m; i++){
-      if (isPrime[i]) {
-         for (k=i+i; k<=m; k+=i) isPrime[k] = false;
-         count++;
-      }
-   }
-   return count;
-}
-
-function sieve() {
-    for (var i = 1; i <= 3; i++ ) {
-        var m = (1<<i)*10000;
-        var flags = Array(m+1);
-        nsieve(m, flags);
-    }
-}
-
-sieve();
deleted file mode 100644
--- a/js/src/t/bitops-3bit-bits-in-byte.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com
-
-// 1 op = 6 ANDs, 3 SHRs, 3 SHLs, 4 assigns, 2 ADDs
-// O(1)
-function fast3bitlookup(b) {
-var c, bi3b = 0xE994; // 0b1110 1001 1001 0100; // 3 2 2 1  2 1 1 0
-c  = 3 & (bi3b >> ((b << 1) & 14));
-c += 3 & (bi3b >> ((b >> 2) & 14));
-c += 3 & (bi3b >> ((b >> 5) & 6));
-return c;
-
-/*
-lir4,0xE994; 9 instructions, no memory access, minimal register dependence, 6 shifts, 2 adds, 1 inline assign
-rlwinmr5,r3,1,28,30
-rlwinmr6,r3,30,28,30
-rlwinmr7,r3,27,29,30
-rlwnmr8,r4,r5,30,31
-rlwnmr9,r4,r6,30,31
-rlwnmr10,r4,r7,30,31
-addr3,r8,r9
-addr3,r3,r10
-*/
-}
-
-
-function TimeFunc(func) {
-var x, y, t;
-for(var x=0; x<500; x++)
-for(var y=0; y<256; y++) func(y);
-}
-
-TimeFunc(fast3bitlookup);
deleted file mode 100644
--- a/js/src/t/bitops-bits-in-byte.js
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2004 by Arthur Langereis (arthur_ext at domain xfinitegames, tld com)
-
-
-// 1 op = 2 assigns, 16 compare/branches, 8 ANDs, (0-8) ADDs, 8 SHLs
-// O(n)
-function bitsinbyte(b) {
-var m = 1, c = 0;
-while(m<0x100) {
-if(b & m) c++;
-m <<= 1;
-}
-return c;
-}
-
-function TimeFunc(func) {
-var x, y, t;
-for(var x=0; x<350; x++)
-for(var y=0; y<256; y++) func(y);
-}
-
-TimeFunc(bitsinbyte);
deleted file mode 100644
--- a/js/src/t/bitops-bitwise-and.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-bitwiseAndValue = 4294967296;
-for (var i = 0; i < 600000; i++)
-    bitwiseAndValue = bitwiseAndValue & i;
deleted file mode 100644
--- a/js/src/t/bitops-nsieve-bits.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// The Great Computer Language Shootout
-//  http://shootout.alioth.debian.org
-//
-//  Contributed by Ian Osgood
-
-function pad(n,width) {
-  var s = n.toString();
-  while (s.length < width) s = ' ' + s;
-  return s;
-}
-
-function primes(isPrime, n) {
-  var i, count = 0, m = 10000<<n, size = m+31>>5;
-
-  for (i=0; i<size; i++) isPrime[i] = 0xffffffff;
-
-  for (i=2; i<m; i++)
-    if (isPrime[i>>5] & 1<<(i&31)) {
-      for (var j=i+i; j<m; j+=i)
-        isPrime[j>>5] &= ~(1<<(j&31));
-      count++;
-    }
-}
-
-function sieve() {
-    for (var i = 4; i <= 4; i++) {
-        var isPrime = new Array((10000<<i)+31>>5);
-        primes(isPrime, i);
-    }
-}
-
-sieve();
deleted file mode 100644
--- a/js/src/t/controlflow-recursive.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// The Computer Language Shootout
-// http://shootout.alioth.debian.org/
-// contributed by Isaac Gouy
-
-function ack(m,n){
-   if (m==0) { return n+1; }
-   if (n==0) { return ack(m-1,1); }
-   return ack(m-1, ack(m,n-1) );
-}
-
-function fib(n) {
-    if (n < 2){ return 1; }
-    return fib(n-2) + fib(n-1);
-}
-
-function tak(x,y,z) {
-    if (y >= x) return z;
-    return tak(tak(x-1,y,z), tak(y-1,z,x), tak(z-1,x,y));
-}
-
-for ( var i = 3; i <= 5; i++ ) {
-    ack(3,i);
-    fib(17.0+i);
-    tak(3*i+3,2*i+2,i+1);
-}
deleted file mode 100644
--- a/js/src/t/crypto-aes.js
+++ /dev/null
@@ -1,422 +0,0 @@
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-/*
- * AES Cipher function: encrypt 'input' with Rijndael algorithm
- *
- *   takes   byte-array 'input' (16 bytes)
- *           2D byte-array key schedule 'w' (Nr+1 x Nb bytes)
- *
- *   applies Nr rounds (10/12/14) using key schedule w for 'add round key' stage
- *
- *   returns byte-array encrypted value (16 bytes)
- */
-function Cipher(input, w) {    // main Cipher function [§5.1]
-  var Nb = 4;               // block size (in words): no of columns in state (fixed at 4 for AES)
-  var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
-
-  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]
-  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
-
-  state = AddRoundKey(state, w, 0, Nb);
-
-  for (var round=1; round<Nr; round++) {
-    state = SubBytes(state, Nb);
-    state = ShiftRows(state, Nb);
-    state = MixColumns(state, Nb);
-    state = AddRoundKey(state, w, round, Nb);
-  }
-
-  state = SubBytes(state, Nb);
-  state = ShiftRows(state, Nb);
-  state = AddRoundKey(state, w, Nr, Nb);
-
-  var output = new Array(4*Nb);  // convert state to 1-d array before returning [§3.4]
-  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
-  return output;
-}
-
-
-function SubBytes(s, Nb) {    // apply SBox to state S [§5.1.1]
-  for (var r=0; r<4; r++) {
-    for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];
-  }
-  return s;
-}
-
-
-function ShiftRows(s, Nb) {    // shift row r of state S left by r bytes [§5.1.2]
-  var t = new Array(4);
-  for (var r=1; r<4; r++) {
-    for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];  // shift into temp copy
-    for (var c=0; c<4; c++) s[r][c] = t[c];         // and copy back
-  }          // note that this will work for Nb=4,5,6, but not 7,8 (always 4 for AES):
-  return s;  // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf 
-}
-
-
-function MixColumns(s, Nb) {   // combine bytes of each col of state S [§5.1.3]
-  for (var c=0; c<4; c++) {
-    var a = new Array(4);  // 'a' is a copy of the current column from 's'
-    var b = new Array(4);  // 'b' is a•{02} in GF(2^8)
-    for (var i=0; i<4; i++) {
-      a[i] = s[i][c];
-      b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;
-    }
-    // a[n] ^ b[n] is a•{03} in GF(2^8)
-    s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
-    s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
-    s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
-    s[3][c] = a[0] ^ b[0] ^ a[1] ^ a[2] ^ b[3]; // 3*a0 + a1 + a2 + 2*a3
-  }
-  return s;
-}
-
-
-function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]
-  for (var r=0; r<4; r++) {
-    for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
-  }
-  return state;
-}
-
-
-function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]
-  var Nb = 4;            // block size (in words): no of columns in state (fixed at 4 for AES)
-  var Nk = key.length/4  // key length (in words): 4/6/8 for 128/192/256-bit keys
-  var Nr = Nk + 6;       // no of rounds: 10/12/14 for 128/192/256-bit keys
-
-  var w = new Array(Nb*(Nr+1));
-  var temp = new Array(4);
-
-  for (var i=0; i<Nk; i++) {
-    var r = [key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]];
-    w[i] = r;
-  }
-
-  for (var i=Nk; i<(Nb*(Nr+1)); i++) {
-    w[i] = new Array(4);
-    for (var t=0; t<4; t++) temp[t] = w[i-1][t];
-    if (i % Nk == 0) {
-      temp = SubWord(RotWord(temp));
-      for (var t=0; t<4; t++) temp[t] ^= Rcon[i/Nk][t];
-    } else if (Nk > 6 && i%Nk == 4) {
-      temp = SubWord(temp);
-    }
-    for (var t=0; t<4; t++) w[i][t] = w[i-Nk][t] ^ temp[t];
-  }
-
-  return w;
-}
-
-function SubWord(w) {    // apply SBox to 4-byte word w
-  for (var i=0; i<4; i++) w[i] = Sbox[w[i]];
-  return w;
-}
-
-function RotWord(w) {    // rotate 4-byte word w left by one byte
-  w[4] = w[0];
-  for (var i=0; i<4; i++) w[i] = w[i+1];
-  return w;
-}
-
-
-// Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [§5.1.1]
-var Sbox =  [0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
-             0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
-             0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
-             0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
-             0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
-             0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
-             0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
-             0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
-             0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
-             0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
-             0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
-             0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
-             0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
-             0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
-             0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
-             0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];
-
-// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
-var Rcon = [ [0x00, 0x00, 0x00, 0x00],
-             [0x01, 0x00, 0x00, 0x00],
-             [0x02, 0x00, 0x00, 0x00],
-             [0x04, 0x00, 0x00, 0x00],
-             [0x08, 0x00, 0x00, 0x00],
-             [0x10, 0x00, 0x00, 0x00],
-             [0x20, 0x00, 0x00, 0x00],
-             [0x40, 0x00, 0x00, 0x00],
-             [0x80, 0x00, 0x00, 0x00],
-             [0x1b, 0x00, 0x00, 0x00],
-             [0x36, 0x00, 0x00, 0x00] ]; 
-
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-/* 
- * Use AES to encrypt 'plaintext' with 'password' using 'nBits' key, in 'Counter' mode of operation
- *                           - see http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
- *   for each block
- *   - outputblock = cipher(counter, key)
- *   - cipherblock = plaintext xor outputblock
- */
-function AESEncryptCtr(plaintext, password, nBits) {
-  if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys
-
-  // for this example script, generate the key by applying Cipher to 1st 16/24/32 chars of password; 
-  // for real-world applications, a more secure approach would be to hash the password e.g. with SHA-1
-  var nBytes = nBits/8;  // no bytes in key
-  var pwBytes = new Array(nBytes);
-  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
-  var key = Cipher(pwBytes, KeyExpansion(pwBytes));
-  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
-
-  // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
-  // block counter in 2nd 8 bytes
-  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
-  var counterBlock = new Array(blockSize);  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
-  var nonce = (new Date()).getTime();  // milliseconds since 1-Jan-1970
-
-  // encode nonce in two stages to cater for JavaScript 32-bit limit on bitwise ops
-  for (var i=0; i<4; i++) counterBlock[i] = (nonce >>> i*8) & 0xff;
-  for (var i=0; i<4; i++) counterBlock[i+4] = (nonce/0x100000000 >>> i*8) & 0xff; 
-
-  // generate key schedule - an expansion of the key into distinct Key Rounds for each round
-  var keySchedule = KeyExpansion(key);
-
-  var blockCount = Math.ceil(plaintext.length/blockSize);
-  var ciphertext = new Array(blockCount);  // ciphertext as array of strings
-  
-  for (var b=0; b<blockCount; b++) {
-    // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
-    // again done in two stages for 32-bit ops
-    for (var c=0; c<4; c++) counterBlock[15-c] = (b >>> c*8) & 0xff;
-    for (var c=0; c<4; c++) counterBlock[15-c-4] = (b/0x100000000 >>> c*8)
-
-    var cipherCntr = Cipher(counterBlock, keySchedule);  // -- encrypt counter block --
-    
-    // calculate length of final block:
-    var blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize+1;
-
-    var ct = '';
-    for (var i=0; i<blockLength; i++) {  // -- xor plaintext with ciphered counter byte-by-byte --
-      var plaintextByte = plaintext.charCodeAt(b*blockSize+i);
-      var cipherByte = plaintextByte ^ cipherCntr[i];
-      ct += String.fromCharCode(cipherByte);
-    }
-    // ct is now ciphertext for this block
-
-    ciphertext[b] = escCtrlChars(ct);  // escape troublesome characters in ciphertext
-  }
-
-  // convert the nonce to a string to go on the front of the ciphertext
-  var ctrTxt = '';
-  for (var i=0; i<8; i++) ctrTxt += String.fromCharCode(counterBlock[i]);
-  ctrTxt = escCtrlChars(ctrTxt);
-
-  // use '-' to separate blocks, use Array.join to concatenate arrays of strings for efficiency
-  return ctrTxt + '-' + ciphertext.join('-');
-}
-
-
-/* 
- * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation
- *
- *   for each block
- *   - outputblock = cipher(counter, key)
- *   - cipherblock = plaintext xor outputblock
- */
-function AESDecryptCtr(ciphertext, password, nBits) {
-  if (!(nBits==128 || nBits==192 || nBits==256)) return '';  // standard allows 128/192/256 bit keys
-
-  var nBytes = nBits/8;  // no bytes in key
-  var pwBytes = new Array(nBytes);
-  for (var i=0; i<nBytes; i++) pwBytes[i] = password.charCodeAt(i) & 0xff;
-  var pwKeySchedule = KeyExpansion(pwBytes);
-  var key = Cipher(pwBytes, pwKeySchedule);
-  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
-
-  var keySchedule = KeyExpansion(key);
-
-  ciphertext = ciphertext.split('-');  // split ciphertext into array of block-length strings 
-
-  // recover nonce from 1st element of ciphertext
-  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
-  var counterBlock = new Array(blockSize);
-  var ctrTxt = unescCtrlChars(ciphertext[0]);
-  for (var i=0; i<8; i++) counterBlock[i] = ctrTxt.charCodeAt(i);
-
-  var plaintext = new Array(ciphertext.length-1);
-
-  for (var b=1; b<ciphertext.length; b++) {
-    // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
-    for (var c=0; c<4; c++) counterBlock[15-c] = ((b-1) >>> c*8) & 0xff;
-    for (var c=0; c<4; c++) counterBlock[15-c-4] = ((b/0x100000000-1) >>> c*8) & 0xff;
-
-    var cipherCntr = Cipher(counterBlock, keySchedule);  // encrypt counter block
-
-    ciphertext[b] = unescCtrlChars(ciphertext[b]);
-
-    var pt = '';
-    for (var i=0; i<ciphertext[b].length; i++) {
-      // -- xor plaintext with ciphered counter byte-by-byte --
-      var ciphertextByte = ciphertext[b].charCodeAt(i);
-      var plaintextByte = ciphertextByte ^ cipherCntr[i];
-      pt += String.fromCharCode(plaintextByte);
-    }
-    // pt is now plaintext for this block
-
-    plaintext[b-1] = pt;  // b-1 'cos no initial nonce block in plaintext
-  }
-
-  return plaintext.join('');
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-function escCtrlChars(str) {  // escape control chars which might cause problems handling ciphertext
-  return str.replace(/[\0\t\n\v\f\r\xa0'"!-]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
-}  // \xa0 to cater for bug in Firefox; include '-' to leave it free for use as a block marker
-
-function unescCtrlChars(str) {  // unescape potentially problematic control characters
-  return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
-}
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-/*
- * if escCtrlChars()/unescCtrlChars() still gives problems, use encodeBase64()/decodeBase64() instead
- */
-var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-
-function encodeBase64(str) {  // http://tools.ietf.org/html/rfc4648
-   var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';
-   
-   str = encodeUTF8(str);  // encode multi-byte chars into UTF-8 for byte-array
-
-   do {  // pack three octets into four hexets
-      o1 = str.charCodeAt(i++);
-      o2 = str.charCodeAt(i++);
-      o3 = str.charCodeAt(i++);
-      
-      bits = o1<<16 | o2<<8 | o3;
-      
-      h1 = bits>>18 & 0x3f;
-      h2 = bits>>12 & 0x3f;
-      h3 = bits>>6 & 0x3f;
-      h4 = bits & 0x3f;
-      
-      // end of string? index to '=' in b64
-      if (isNaN(o3)) h4 = 64;
-      if (isNaN(o2)) h3 = 64;
-      
-      // use hexets to index into b64, and append result to encoded string
-      enc += b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
-   } while (i < str.length);
-   
-   return enc;
-}
-
-function decodeBase64(str) {
-   var o1, o2, o3, h1, h2, h3, h4, bits, i=0, enc='';
-
-   do {  // unpack four hexets into three octets using index points in b64
-      h1 = b64.indexOf(str.charAt(i++));
-      h2 = b64.indexOf(str.charAt(i++));
-      h3 = b64.indexOf(str.charAt(i++));
-      h4 = b64.indexOf(str.charAt(i++));
-      
-      bits = h1<<18 | h2<<12 | h3<<6 | h4;
-      
-      o1 = bits>>16 & 0xff;
-      o2 = bits>>8 & 0xff;
-      o3 = bits & 0xff;
-      
-      if (h3 == 64)      enc += String.fromCharCode(o1);
-      else if (h4 == 64) enc += String.fromCharCode(o1, o2);
-      else               enc += String.fromCharCode(o1, o2, o3);
-   } while (i < str.length);
-
-   return decodeUTF8(enc);  // decode UTF-8 byte-array back to Unicode
-}
-
-function encodeUTF8(str) {  // encode multi-byte string into utf-8 multiple single-byte characters 
-  str = str.replace(
-      /[\u0080-\u07ff]/g,  // U+0080 - U+07FF = 2-byte chars
-      function(c) { 
-        var cc = c.charCodeAt(0);
-        return String.fromCharCode(0xc0 | cc>>6, 0x80 | cc&0x3f); }
-    );
-  str = str.replace(
-      /[\u0800-\uffff]/g,  // U+0800 - U+FFFF = 3-byte chars
-      function(c) { 
-        var cc = c.charCodeAt(0); 
-        return String.fromCharCode(0xe0 | cc>>12, 0x80 | cc>>6&0x3F, 0x80 | cc&0x3f); }
-    );
-  return str;
-}
-
-function decodeUTF8(str) {  // decode utf-8 encoded string back into multi-byte characters
-  str = str.replace(
-      /[\u00c0-\u00df][\u0080-\u00bf]/g,                 // 2-byte chars
-      function(c) { 
-        var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
-        return String.fromCharCode(cc); }
-    );
-  str = str.replace(
-      /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g,  // 3-byte chars
-      function(c) { 
-        var cc = (c.charCodeAt(0)&0x0f)<<12 | (c.charCodeAt(1)&0x3f<<6) | c.charCodeAt(2)&0x3f; 
-        return String.fromCharCode(cc); }
-    );
-  return str;
-}
-
-
-function byteArrayToHexStr(b) {  // convert byte array to hex string for displaying test vectors
-  var s = '';
-  for (var i=0; i<b.length; i++) s += b[i].toString(16) + ' ';
-  return s;
-}
-
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
-
-
-var plainText = "ROMEO: But, soft! what light through yonder window breaks?\n\
-It is the east, and Juliet is the sun.\n\
-Arise, fair sun, and kill the envious moon,\n\
-Who is already sick and pale with grief,\n\
-That thou her maid art far more fair than she:\n\
-Be not her maid, since she is envious;\n\
-Her vestal livery is but sick and green\n\
-And none but fools do wear it; cast it off.\n\
-It is my lady, O, it is my love!\n\
-O, that she knew she were!\n\
-She speaks yet she says nothing: what of that?\n\
-Her eye discourses; I will answer it.\n\
-I am too bold, 'tis not to me she speaks:\n\
-Two of the fairest stars in all the heaven,\n\
-Having some business, do entreat her eyes\n\
-To twinkle in their spheres till they return.\n\
-What if her eyes were there, they in her head?\n\
-The brightness of her cheek would shame those stars,\n\
-As daylight doth a lamp; her eyes in heaven\n\
-Would through the airy region stream so bright\n\
-That birds would sing and think it were not night.\n\
-See, how she leans her cheek upon her hand!\n\
-O, that I were a glove upon that hand,\n\
-That I might touch that cheek!\n\
-JULIET: Ay me!\n\
-ROMEO: She speaks:\n\
-O, speak again, bright angel! for thou art\n\
-As glorious to this night, being o'er my head\n\
-As is a winged messenger of heaven\n\
-Unto the white-upturned wondering eyes\n\
-Of mortals that fall back to gaze on him\n\
-When he bestrides the lazy-pacing clouds\n\
-And sails upon the bosom of the air.";
-
-var password = "O Romeo, Romeo! wherefore art thou Romeo?";
-
-var cipherText = AESEncryptCtr(plainText, password, 256);
-var decryptedText = AESDecryptCtr(cipherText, password, 256);
deleted file mode 100644
--- a/js/src/t/crypto-md5.js
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
-function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
-function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
-function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
-function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
-function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function md5_vm_test()
-{
-  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
-}
-
-/*
- * Calculate the MD5 of an array of little-endian words, and a bit length
- */
-function core_md5(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << ((len) % 32);
-  x[(((len + 64) >>> 9) << 4) + 14] = len;
-
-  var a =  1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d =  271733878;
-
-  for(var i = 0; i < x.length; i += 16)
-  {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-
-    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
-    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
-    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
-    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
-    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
-    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
-    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
-    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
-    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
-    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
-    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
-    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
-    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
-    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
-    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
-    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
-
-    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
-    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
-    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
-    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
-    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
-    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
-    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
-    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
-    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
-    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
-    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
-    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
-    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
-    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
-    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
-    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
-    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
-    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
-    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
-    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
-    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
-    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
-    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
-    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
-    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
-    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
-    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
-    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
-    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
-    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
-    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
-    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
-    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
-    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
-    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
-    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
-    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
-    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
-    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
-    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
-    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
-    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
-    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
-    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
-    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
-    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
-    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
-    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-  }
-  return Array(a, b, c, d);
-
-}
-
-/*
- * These functions implement the four basic operations the algorithm uses.
- */
-function md5_cmn(q, a, b, x, s, t)
-{
-  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
-}
-function md5_ff(a, b, c, d, x, s, t)
-{
-  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
-}
-function md5_gg(a, b, c, d, x, s, t)
-{
-  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
-}
-function md5_hh(a, b, c, d, x, s, t)
-{
-  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
-}
-function md5_ii(a, b, c, d, x, s, t)
-{
-  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
-}
-
-/*
- * Calculate the HMAC-MD5, of a key and some data
- */
-function core_hmac_md5(key, data)
-{
-  var bkey = str2binl(key);
-  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
-  return core_md5(opad.concat(hash), 512 + 128);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
-
-/*
- * Convert a string to an array of little-endian words
- * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
- */
-function str2binl(str)
-{
-  var bin = Array();
-  var mask = (1 << chrsz) - 1;
-  for(var i = 0; i < str.length * chrsz; i += chrsz)
-    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
-  return bin;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2str(bin)
-{
-  var str = "";
-  var mask = (1 << chrsz) - 1;
-  for(var i = 0; i < bin.length * 32; i += chrsz)
-    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
-  return str;
-}
-
-/*
- * Convert an array of little-endian words to a hex string.
- */
-function binl2hex(binarray)
-{
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var str = "";
-  for(var i = 0; i < binarray.length * 4; i++)
-  {
-    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
-           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
-  }
-  return str;
-}
-
-/*
- * Convert an array of little-endian words to a base-64 string
- */
-function binl2b64(binarray)
-{
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var str = "";
-  for(var i = 0; i < binarray.length * 4; i += 3)
-  {
-    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
-                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
-                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
-      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
-    }
-  }
-  return str;
-}
-
-var plainText = "Rebellious subjects, enemies to peace,\n\
-Profaners of this neighbour-stained steel,--\n\
-Will they not hear? What, ho! you men, you beasts,\n\
-That quench the fire of your pernicious rage\n\
-With purple fountains issuing from your veins,\n\
-On pain of torture, from those bloody hands\n\
-Throw your mistemper'd weapons to the ground,\n\
-And hear the sentence of your moved prince.\n\
-Three civil brawls, bred of an airy word,\n\
-By thee, old Capulet, and Montague,\n\
-Have thrice disturb'd the quiet of our streets,\n\
-And made Verona's ancient citizens\n\
-Cast by their grave beseeming ornaments,\n\
-To wield old partisans, in hands as old,\n\
-Canker'd with peace, to part your canker'd hate:\n\
-If ever you disturb our streets again,\n\
-Your lives shall pay the forfeit of the peace.\n\
-For this time, all the rest depart away:\n\
-You Capulet; shall go along with me:\n\
-And, Montague, come you this afternoon,\n\
-To know our further pleasure in this case,\n\
-To old Free-town, our common judgment-place.\n\
-Once more, on pain of death, all men depart."
-
-for (var i = 0; i <4; i++) {
-    plainText += plainText;
-}
-
-var md5Output = hex_md5(plainText);
deleted file mode 100644
--- a/js/src/t/crypto-sha1.js
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS PUB 180-1
- * Version 2.1a Copyright Paul Johnston 2000 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
-function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
-function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
-function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
-function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
-function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test()
-{
-  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
-}
-
-/*
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function core_sha1(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << (24 - len % 32);
-  x[((len + 64 >> 9) << 4) + 15] = len;
-
-  var w = Array(80);
-  var a =  1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d =  271733878;
-  var e = -1009589776;
-
-  for(var i = 0; i < x.length; i += 16)
-  {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-    var olde = e;
-
-    for(var j = 0; j < 80; j++)
-    {
-      if(j < 16) w[j] = x[i + j];
-      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
-      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
-                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
-      e = d;
-      d = c;
-      c = rol(b, 30);
-      b = a;
-      a = t;
-    }
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-    e = safe_add(e, olde);
-  }
-  return Array(a, b, c, d, e);
-
-}
-
-/*
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d)
-{
-  if(t < 20) return (b & c) | ((~b) & d);
-  if(t < 40) return b ^ c ^ d;
-  if(t < 60) return (b & c) | (b & d) | (c & d);
-  return b ^ c ^ d;
-}
-
-/*
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t)
-{
-  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
-         (t < 60) ? -1894007588 : -899497514;
-}
-
-/*
- * Calculate the HMAC-SHA1 of a key and some data
- */
-function core_hmac_sha1(key, data)
-{
-  var bkey = str2binb(key);
-  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
-  return core_sha1(opad.concat(hash), 512 + 160);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
-
-/*
- * Convert an 8-bit or 16-bit string to an array of big-endian words
- * In 8-bit function, characters >255 have their hi-byte silently ignored.
- */
-function str2binb(str)
-{
-  var bin = Array();
-  var mask = (1 << chrsz) - 1;
-  for(var i = 0; i < str.length * chrsz; i += chrsz)
-    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
-  return bin;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2str(bin)
-{
-  var str = "";
-  var mask = (1 << chrsz) - 1;
-  for(var i = 0; i < bin.length * 32; i += chrsz)
-    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
-  return str;
-}
-
-/*
- * Convert an array of big-endian words to a hex string.
- */
-function binb2hex(binarray)
-{
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var str = "";
-  for(var i = 0; i < binarray.length * 4; i++)
-  {
-    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
-           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
-  }
-  return str;
-}
-
-/*
- * Convert an array of big-endian words to a base-64 string
- */
-function binb2b64(binarray)
-{
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var str = "";
-  for(var i = 0; i < binarray.length * 4; i += 3)
-  {
-    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
-                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
-                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
-      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
-    }
-  }
-  return str;
-}
-
-
-var plainText = "Two households, both alike in dignity,\n\
-In fair Verona, where we lay our scene,\n\
-From ancient grudge break to new mutiny,\n\
-Where civil blood makes civil hands unclean.\n\
-From forth the fatal loins of these two foes\n\
-A pair of star-cross'd lovers take their life;\n\
-Whole misadventured piteous overthrows\n\
-Do with their death bury their parents' strife.\n\
-The fearful passage of their death-mark'd love,\n\
-And the continuance of their parents' rage,\n\
-Which, but their children's end, nought could remove,\n\
-Is now the two hours' traffic of our stage;\n\
-The which if you with patient ears attend,\n\
-What here shall miss, our toil shall strive to mend.";
-
-for (var i = 0; i <4; i++) {
-    plainText += plainText;
-}
-
-var sha1Output = hex_sha1(plainText);
deleted file mode 100644
--- a/js/src/t/date-format-tofte.js
+++ /dev/null
@@ -1,299 +0,0 @@
-function arrayExists(array, x) {
-    for (var i = 0; i < array.length; i++) {
-        if (array[i] == x) return true;
-    }
-    return false;
-}
-
-Date.prototype.formatDate = function (input,time) {
-    // formatDate :
-    // a PHP date like function, for formatting date strings
-    // See: http://www.php.net/date
-    //
-    // input : format string
-    // time : epoch time (seconds, and optional)
-    //
-    // if time is not passed, formatting is based on 
-    // the current "this" date object's set time.
-    //
-    // supported:
-    // a, A, B, d, D, F, g, G, h, H, i, j, l (lowercase L), L, 
-    // m, M, n, O, r, s, S, t, U, w, W, y, Y, z
-    //
-    // unsupported:
-    // I (capital i), T, Z    
-
-    var switches =    ["a", "A", "B", "d", "D", "F", "g", "G", "h", "H", 
-                       "i", "j", "l", "L", "m", "M", "n", "O", "r", "s", 
-                       "S", "t", "U", "w", "W", "y", "Y", "z"];
-    var daysLong =    ["Sunday", "Monday", "Tuesday", "Wednesday", 
-                       "Thursday", "Friday", "Saturday"];
-    var daysShort =   ["Sun", "Mon", "Tue", "Wed", 
-                       "Thu", "Fri", "Sat"];
-    var monthsShort = ["Jan", "Feb", "Mar", "Apr",
-                       "May", "Jun", "Jul", "Aug", "Sep",
-                       "Oct", "Nov", "Dec"];
-    var monthsLong =  ["January", "February", "March", "April",
-                       "May", "June", "July", "August", "September",
-                       "October", "November", "December"];
-    var daysSuffix = ["st", "nd", "rd", "th", "th", "th", "th", // 1st - 7th
-                      "th", "th", "th", "th", "th", "th", "th", // 8th - 14th
-                      "th", "th", "th", "th", "th", "th", "st", // 15th - 21st
-                      "nd", "rd", "th", "th", "th", "th", "th", // 22nd - 28th
-                      "th", "th", "st"];                        // 29th - 31st
-
-    function a() {
-        // Lowercase Ante meridiem and Post meridiem
-        return self.getHours() > 11? "pm" : "am";
-    }
-    function A() {
-        // Uppercase Ante meridiem and Post meridiem
-        return self.getHours() > 11? "PM" : "AM";
-    }
-
-    function B(){
-        // Swatch internet time. code simply grabbed from ppk,
-        // since I was feeling lazy:
-        // http://www.xs4all.nl/~ppk/js/beat.html
-        var off = (self.getTimezoneOffset() + 60)*60;
-        var theSeconds = (self.getHours() * 3600) + 
-                         (self.getMinutes() * 60) + 
-                          self.getSeconds() + off;
-        var beat = Math.floor(theSeconds/86.4);
-        if (beat > 1000) beat -= 1000;
-        if (beat < 0) beat += 1000;
-        if ((""+beat).length == 1) beat = "00"+beat;
-        if ((""+beat).length == 2) beat = "0"+beat;
-        return beat;
-    }
-    
-    function d() {
-        // Day of the month, 2 digits with leading zeros
-        return new String(self.getDate()).length == 1?
-        "0"+self.getDate() : self.getDate();
-    }
-    function D() {
-        // A textual representation of a day, three letters
-        return daysShort[self.getDay()];
-    }
-    function F() {
-        // A full textual representation of a month
-        return monthsLong[self.getMonth()];
-    }
-    function g() {
-        // 12-hour format of an hour without leading zeros
-        return self.getHours() > 12? self.getHours()-12 : self.getHours();
-    }
-    function G() {
-        // 24-hour format of an hour without leading zeros
-        return self.getHours();
-    }
-    function h() {
-        // 12-hour format of an hour with leading zeros
-        if (self.getHours() > 12) {
-          var s = new String(self.getHours()-12);
-          return s.length == 1?
-          "0"+ (self.getHours()-12) : self.getHours()-12;
-        } else { 
-          var s = new String(self.getHours());
-          return s.length == 1?
-          "0"+self.getHours() : self.getHours();
-        }  
-    }
-    function H() {
-        // 24-hour format of an hour with leading zeros
-        return new String(self.getHours()).length == 1?
-        "0"+self.getHours() : self.getHours();
-    }
-    function i() {
-        // Minutes with leading zeros
-        return new String(self.getMinutes()).length == 1? 
-        "0"+self.getMinutes() : self.getMinutes(); 
-    }
-    function j() {
-        // Day of the month without leading zeros
-        return self.getDate();
-    }    
-    function l() {
-        // A full textual representation of the day of the week
-        return daysLong[self.getDay()];
-    }
-    function L() {
-        // leap year or not. 1 if leap year, 0 if not.
-        // the logic should match iso's 8601 standard.
-        var y_ = Y();
-        if (         
-            (y_ % 4 == 0 && y_ % 100 != 0) ||
-            (y_ % 4 == 0 && y_ % 100 == 0 && y_ % 400 == 0)
-            ) {
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-    function m() {
-        // Numeric representation of a month, with leading zeros
-        return self.getMonth() < 9?
-        "0"+(self.getMonth()+1) : 
-        self.getMonth()+1;
-    }
-    function M() {
-        // A short textual representation of a month, three letters
-        return monthsShort[self.getMonth()];
-    }
-    function n() {
-        // Numeric representation of a month, without leading zeros
-        return self.getMonth()+1;
-    }
-    function O() {
-        // Difference to Greenwich time (GMT) in hours
-        var os = Math.abs(self.getTimezoneOffset());
-        var h = ""+Math.floor(os/60);
-        var m = ""+(os%60);
-        h.length == 1? h = "0"+h:1;
-        m.length == 1? m = "0"+m:1;
-        return self.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;
-    }
-    function r() {
-        // RFC 822 formatted date
-        var r; // result
-        //  Thu    ,     21          Dec         2000
-        r = D() + ", " + j() + " " + M() + " " + Y() +
-        //        16     :    01     :    07          +0200
-            " " + H() + ":" + i() + ":" + s() + " " + O();
-        return r;
-    }
-    function S() {
-        // English ordinal suffix for the day of the month, 2 characters
-        return daysSuffix[self.getDate()-1];
-    }
-    function s() {
-        // Seconds, with leading zeros
-        return new String(self.getSeconds()).length == 1?
-        "0"+self.getSeconds() : self.getSeconds();
-    }
-    function t() {
-
-        // thanks to Matt Bannon for some much needed code-fixes here!
-        var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31];
-        if (L()==1 && n()==2) return 29; // leap day
-        return daysinmonths[n()];
-    }
-    function U() {
-        // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
-        return Math.round(self.getTime()/1000);
-    }
-    function W() {
-        // Weeknumber, as per ISO specification:
-        // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
-        
-        // if the day is three days before newyears eve,
-        // there's a chance it's "week 1" of next year.
-        // here we check for that.
-        var beforeNY = 364+L() - z();
-        var afterNY  = z();
-        var weekday = w()!=0?w()-1:6; // makes sunday (0), into 6.
-        if (beforeNY <= 2 && weekday <= 2-beforeNY) {
-            return 1;
-        }
-        // similarly, if the day is within threedays of newyears
-        // there's a chance it belongs in the old year.
-        var ny = new Date("January 1 " + Y() + " 00:00:00");
-        var nyDay = ny.getDay()!=0?ny.getDay()-1:6;
-        if (
-            (afterNY <= 2) && 
-            (nyDay >=4)  && 
-            (afterNY >= (6-nyDay))
-            ) {
-            // Since I'm not sure we can just always return 53,
-            // i call the function here again, using the last day
-            // of the previous year, as the date, and then just
-            // return that week.
-            var prevNY = new Date("December 31 " + (Y()-1) + " 00:00:00");
-            return prevNY.formatDate("W");
-        }
-        
-        // week 1, is the week that has the first thursday in it.
-        // note that this value is not zero index.
-        if (nyDay <= 3) {
-            // first day of the year fell on a thursday, or earlier.
-            return 1 + Math.floor( ( z() + nyDay ) / 7 );
-        } else {
-            // first day of the year fell on a friday, or later.
-            return 1 + Math.floor( ( z() - ( 7 - nyDay ) ) / 7 );
-        }
-    }
-    function w() {
-        // Numeric representation of the day of the week
-        return self.getDay();
-    }
-    
-    function Y() {
-        // A full numeric representation of a year, 4 digits
-
-        // we first check, if getFullYear is supported. if it
-        // is, we just use that. ppks code is nice, but wont
-        // work with dates outside 1900-2038, or something like that
-        if (self.getFullYear) {
-            var newDate = new Date("January 1 2001 00:00:00 +0000");
-            var x = newDate .getFullYear();
-            if (x == 2001) {              
-                // i trust the method now
-                return self.getFullYear();
-            }
-        }
-        // else, do this:
-        // codes thanks to ppk:
-        // http://www.xs4all.nl/~ppk/js/introdate.html
-        var x = self.getYear();
-        var y = x % 100;
-        y += (y < 38) ? 2000 : 1900;
-        return y;
-    }
-    function y() {
-        // A two-digit representation of a year
-        var y = Y()+"";
-        return y.substring(y.length-2,y.length);
-    }
-    function z() {
-        // The day of the year, zero indexed! 0 through 366
-        var t = new Date("January 1 " + Y() + " 00:00:00");
-        var diff = self.getTime() - t.getTime();
-        return Math.floor(diff/1000/60/60/24);
-    }
-        
-    var self = this;
-    if (time) {
-        // save time
-        var prevTime = self.getTime();
-        self.setTime(time);
-    }
-    
-    var ia = input.split("");
-    var ij = 0;
-    while (ia[ij]) {
-        if (ia[ij] == "\\") {
-            // this is our way of allowing users to escape stuff
-            ia.splice(ij,1);
-        } else {
-            if (arrayExists(switches,ia[ij])) {
-                ia[ij] = eval(ia[ij] + "()");
-            }
-        }
-        ij++;
-    }
-    // reset time, back to what it was
-    if (prevTime) {
-        self.setTime(prevTime);
-    }
-    return ia.join("");
-}
-
-var date = new Date("1/1/2007 1:11:11");
-
-for (i = 0; i < 500; ++i) {
-    var shortFormat = date.formatDate("Y-m-d");
-    var longFormat = date.formatDate("l, F d, Y g:i:s A");
-    date.setTime(date.getTime() + 84266956);
-}
-
deleted file mode 100644
--- a/js/src/t/date-format-xparb.js
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, version 2.1.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
- * details.
- */
-
-Date.parseFunctions = {count:0};
-Date.parseRegexes = [];
-Date.formatFunctions = {count:0};
-
-Date.prototype.dateFormat = function(format) {
-    if (Date.formatFunctions[format] == null) {
-        Date.createNewFormat(format);
-    }
-    var func = Date.formatFunctions[format];
-    return this[func]();
-}
-
-Date.createNewFormat = function(format) {
-    var funcName = "format" + Date.formatFunctions.count++;
-    Date.formatFunctions[format] = funcName;
-    var code = "Date.prototype." + funcName + " = function(){return ";
-    var special = false;
-    var ch = '';
-    for (var i = 0; i < format.length; ++i) {
-        ch = format.charAt(i);
-        if (!special && ch == "\\") {
-            special = true;
-        }
-        else if (special) {
-            special = false;
-            code += "'" + String.escape(ch) + "' + ";
-        }
-        else {
-            code += Date.getFormatCode(ch);
-        }
-    }
-    eval(code.substring(0, code.length - 3) + ";}");
-}
-
-Date.getFormatCode = function(character) {
-    switch (character) {
-    case "d":
-        return "String.leftPad(this.getDate(), 2, '0') + ";
-    case "D":
-        return "Date.dayNames[this.getDay()].substring(0, 3) + ";
-    case "j":
-        return "this.getDate() + ";
-    case "l":
-        return "Date.dayNames[this.getDay()] + ";
-    case "S":
-        return "this.getSuffix() + ";
-    case "w":
-        return "this.getDay() + ";
-    case "z":
-        return "this.getDayOfYear() + ";
-    case "W":
-        return "this.getWeekOfYear() + ";
-    case "F":
-        return "Date.monthNames[this.getMonth()] + ";
-    case "m":
-        return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
-    case "M":
-        return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
-    case "n":
-        return "(this.getMonth() + 1) + ";
-    case "t":
-        return "this.getDaysInMonth() + ";
-    case "L":
-        return "(this.isLeapYear() ? 1 : 0) + ";
-    case "Y":
-        return "this.getFullYear() + ";
-    case "y":
-        return "('' + this.getFullYear()).substring(2, 4) + ";
-    case "a":
-        return "(this.getHours() < 12 ? 'am' : 'pm') + ";
-    case "A":
-        return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
-    case "g":
-        return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
-    case "G":
-        return "this.getHours() + ";
-    case "h":
-        return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
-    case "H":
-        return "String.leftPad(this.getHours(), 2, '0') + ";
-    case "i":
-        return "String.leftPad(this.getMinutes(), 2, '0') + ";
-    case "s":
-        return "String.leftPad(this.getSeconds(), 2, '0') + ";
-    case "O":
-        return "this.getGMTOffset() + ";
-    case "T":
-        return "this.getTimezone() + ";
-    case "Z":
-        return "(this.getTimezoneOffset() * -60) + ";
-    default:
-        return "'" + String.escape(character) + "' + ";
-    }
-}
-
-Date.parseDate = function(input, format) {
-    if (Date.parseFunctions[format] == null) {
-        Date.createParser(format);
-    }
-    var func = Date.parseFunctions[format];
-    return Date[func](input);
-}
-
-Date.createParser = function(format) {
-    var funcName = "parse" + Date.parseFunctions.count++;
-    var regexNum = Date.parseRegexes.length;
-    var currentGroup = 1;
-    Date.parseFunctions[format] = funcName;
-
-    var code = "Date." + funcName + " = function(input){\n"
-        + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n"
-        + "var d = new Date();\n"
-        + "y = d.getFullYear();\n"
-        + "m = d.getMonth();\n"
-        + "d = d.getDate();\n"
-        + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
-        + "if (results && results.length > 0) {"
-    var regex = "";
-
-    var special = false;
-    var ch = '';
-    for (var i = 0; i < format.length; ++i) {
-        ch = format.charAt(i);
-        if (!special && ch == "\\") {
-            special = true;
-        }
-        else if (special) {
-            special = false;
-            regex += String.escape(ch);
-        }
-        else {
-            obj = Date.formatCodeToRegex(ch, currentGroup);
-            currentGroup += obj.g;
-            regex += obj.s;
-            if (obj.g && obj.c) {
-                code += obj.c;
-            }
-        }
-    }
-
-    code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
-        + "{return new Date(y, m, d, h, i, s);}\n"
-        + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
-        + "{return new Date(y, m, d, h, i);}\n"
-        + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"
-        + "{return new Date(y, m, d, h);}\n"
-        + "else if (y > 0 && m >= 0 && d > 0)\n"
-        + "{return new Date(y, m, d);}\n"
-        + "else if (y > 0 && m >= 0)\n"
-        + "{return new Date(y, m);}\n"
-        + "else if (y > 0)\n"
-        + "{return new Date(y);}\n"
-        + "}return null;}";
-
-    Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
-    eval(code);
-}
-
-Date.formatCodeToRegex = function(character, currentGroup) {
-    switch (character) {
-    case "D":
-        return {g:0,
-        c:null,
-        s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
-    case "j":
-    case "d":
-        return {g:1,
-            c:"d = parseInt(results[" + currentGroup + "], 10);\n",
-            s:"(\\d{1,2})"};
-    case "l":
-        return {g:0,
-            c:null,
-            s:"(?:" + Date.dayNames.join("|") + ")"};
-    case "S":
-        return {g:0,
-            c:null,
-            s:"(?:st|nd|rd|th)"};
-    case "w":
-        return {g:0,
-            c:null,
-            s:"\\d"};
-    case "z":
-        return {g:0,
-            c:null,
-            s:"(?:\\d{1,3})"};
-    case "W":
-        return {g:0,
-            c:null,
-            s:"(?:\\d{2})"};
-    case "F":
-        return {g:1,
-            c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
-            s:"(" + Date.monthNames.join("|") + ")"};
-    case "M":
-        return {g:1,
-            c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
-            s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
-    case "n":
-    case "m":
-        return {g:1,
-            c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
-            s:"(\\d{1,2})"};
-    case "t":
-        return {g:0,
-            c:null,
-            s:"\\d{1,2}"};
-    case "L":
-        return {g:0,
-            c:null,
-            s:"(?:1|0)"};
-    case "Y":
-        return {g:1,
-            c:"y = parseInt(results[" + currentGroup + "], 10);\n",
-            s:"(\\d{4})"};
-    case "y":
-        return {g:1,
-            c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
-                + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
-            s:"(\\d{1,2})"};
-    case "a":
-        return {g:1,
-            c:"if (results[" + currentGroup + "] == 'am') {\n"
-                + "if (h == 12) { h = 0; }\n"
-                + "} else { if (h < 12) { h += 12; }}",
-            s:"(am|pm)"};
-    case "A":
-        return {g:1,
-            c:"if (results[" + currentGroup + "] == 'AM') {\n"
-                + "if (h == 12) { h = 0; }\n"
-                + "} else { if (h < 12) { h += 12; }}",
-            s:"(AM|PM)"};
-    case "g":
-    case "G":
-    case "h":
-    case "H":
-        return {g:1,
-            c:"h = parseInt(results[" + currentGroup + "], 10);\n",
-            s:"(\\d{1,2})"};
-    case "i":
-        return {g:1,
-            c:"i = parseInt(results[" + currentGroup + "], 10);\n",
-            s:"(\\d{2})"};
-    case "s":
-        return {g:1,
-            c:"s = parseInt(results[" + currentGroup + "], 10);\n",
-            s:"(\\d{2})"};
-    case "O":
-        return {g:0,
-            c:null,
-            s:"[+-]\\d{4}"};
-    case "T":
-        return {g:0,
-            c:null,
-            s:"[A-Z]{3}"};
-    case "Z":
-        return {g:0,
-            c:null,
-            s:"[+-]\\d{1,5}"};
-    default:
-        return {g:0,
-            c:null,
-            s:String.escape(character)};
-    }
-}
-
-Date.prototype.getTimezone = function() {
-    return this.toString().replace(
-        /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
-        /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
-}
-
-Date.prototype.getGMTOffset = function() {
-    return (this.getTimezoneOffset() > 0 ? "-" : "+")
-        + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
-        + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
-}
-
-Date.prototype.getDayOfYear = function() {
-    var num = 0;
-    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
-    for (var i = 0; i < this.getMonth(); ++i) {
-        num += Date.daysInMonth[i];
-    }
-    return num + this.getDate() - 1;
-}
-
-Date.prototype.getWeekOfYear = function() {
-    // Skip to Thursday of this week
-    var now = this.getDayOfYear() + (4 - this.getDay());
-    // Find the first Thursday of the year
-    var jan1 = new Date(this.getFullYear(), 0, 1);
-    var then = (7 - jan1.getDay() + 4);
-    document.write(then);
-    return String.leftPad(((now - then) / 7) + 1, 2, "0");
-}
-
-Date.prototype.isLeapYear = function() {
-    var year = this.getFullYear();
-    return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
-}
-
-Date.prototype.getFirstDayOfMonth = function() {
-    var day = (this.getDay() - (this.getDate() - 1)) % 7;
-    return (day < 0) ? (day + 7) : day;
-}
-
-Date.prototype.getLastDayOfMonth = function() {
-    var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
-    return (day < 0) ? (day + 7) : day;
-}
-
-Date.prototype.getDaysInMonth = function() {
-    Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
-    return Date.daysInMonth[this.getMonth()];
-}
-
-Date.prototype.getSuffix = function() {
-    switch (this.getDate()) {
-        case 1:
-        case 21:
-        case 31:
-            return "st";
-        case 2:
-        case 22:
-            return "nd";
-        case 3:
-        case 23:
-            return "rd";
-        default:
-            return "th";
-    }
-}
-
-String.escape = function(string) {
-    return string.replace(/('|\\)/g, "\\$1");
-}
-
-String.leftPad = function (val, size, ch) {
-    var result = new String(val);
-    if (ch == null) {
-        ch = " ";
-    }
-    while (result.length < size) {
-        result = ch + result;
-    }
-    return result;
-}
-
-Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
-Date.monthNames =
-   ["January",
-    "February",
-    "March",
-    "April",
-    "May",
-    "June",
-    "July",
-    "August",
-    "September",
-    "October",
-    "November",
-    "December"];
-Date.dayNames =
-   ["Sunday",
-    "Monday",
-    "Tuesday",
-    "Wednesday",
-    "Thursday",
-    "Friday",
-    "Saturday"];
-Date.y2kYear = 50;
-Date.monthNumbers = {
-    Jan:0,
-    Feb:1,
-    Mar:2,
-    Apr:3,
-    May:4,
-    Jun:5,
-    Jul:6,
-    Aug:7,
-    Sep:8,
-    Oct:9,
-    Nov:10,
-    Dec:11};
-Date.patterns = {
-    ISO8601LongPattern:"Y-m-d H:i:s",
-    ISO8601ShortPattern:"Y-m-d",
-    ShortDatePattern: "n/j/Y",
-    LongDatePattern: "l, F d, Y",
-    FullDateTimePattern: "l, F d, Y g:i:s A",
-    MonthDayPattern: "F d",
-    ShortTimePattern: "g:i A",
-    LongTimePattern: "g:i:s A",
-    SortableDateTimePattern: "Y-m-d\\TH:i:s",
-    UniversalSortableDateTimePattern: "Y-m-d H:i:sO",
-    YearMonthPattern: "F, Y"};
-
-var date = new Date("1/1/2007 1:11:11");
-
-for (i = 0; i < 4000; ++i) {
-    var shortFormat = date.dateFormat("Y-m-d");
-    var longFormat = date.dateFormat("l, F d, Y g:i:s A");
-    date.setTime(date.getTime() + 84266956);
-}
deleted file mode 100644
--- a/js/src/t/math-cordic.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) Rich Moore.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-
-/////. Start CORDIC
-
-var AG_CONST = 0.6072529350;
-
-function FIXED(X)
-{
-  return X * 65536.0;
-}
-
-function FLOAT(X)
-{
-  return X / 65536.0;
-}
-
-function DEG2RAD(X)
-{
-  return 0.017453 * (X);
-}
-
-var Angles = [
-  FIXED(45.0), FIXED(26.565), FIXED(14.0362), FIXED(7.12502),
-  FIXED(3.57633), FIXED(1.78991), FIXED(0.895174), FIXED(0.447614),
-  FIXED(0.223811), FIXED(0.111906), FIXED(0.055953),
-  FIXED(0.027977) 
-              ];
-
-
-function cordicsincos() {
-    var X;
-    var Y;
-    var TargetAngle;
-    var CurrAngle;
-    var Step;
- 
-    X = FIXED(AG_CONST);         /* AG_CONST * cos(0) */
-    Y = 0;                       /* AG_CONST * sin(0) */
-
-    TargetAngle = FIXED(28.027);
-    CurrAngle = 0;
-    for (Step = 0; Step < 12; Step++) {
-        var NewX;
-        if (TargetAngle > CurrAngle) {
-            NewX = X - (Y >> Step);
-            Y = (X >> Step) + Y;
-            X = NewX;
-            CurrAngle += Angles[Step];
-        } else {
-            NewX = X + (Y >> Step);
-            Y = -(X >> Step) + Y;
-            X = NewX;
-            CurrAngle -= Angles[Step];
-        }
-    }
-}
-
-///// End CORDIC
-
-function cordic( runs ) {
-  var start = new Date();
-
-  for ( var i = 0 ; i < runs ; i++ ) {
-      cordicsincos();
-  }
-
-  var end = new Date();
-
-  return end.getTime() - start.getTime();
-}
-
-cordic(25000);
deleted file mode 100644
--- a/js/src/t/math-partial-sums.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// The Computer Language Shootout
-// http://shootout.alioth.debian.org/
-// contributed by Isaac Gouy
-
-function partial(n){
-    var a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = 0.0;
-    var twothirds = 2.0/3.0;
-    var alt = -1.0;
-    var k2 = k3 = sk = ck = 0.0;
-    
-    for (var k = 1; k <= n; k++){
-        k2 = k*k;
-        k3 = k2*k;
-        sk = Math.sin(k);
-        ck = Math.cos(k);
-        alt = -alt;
-        
-        a1 += Math.pow(twothirds,k-1);
-        a2 += Math.pow(k,-0.5);
-        a3 += 1.0/(k*(k+1.0));
-        a4 += 1.0/(k3 * sk*sk);
-        a5 += 1.0/(k3 * ck*ck);
-        a6 += 1.0/k;
-        a7 += 1.0/k2;
-        a8 += alt/k;
-        a9 += alt/(2*k -1);
-    }
-}
-
-for (var i = 1024; i <= 16384; i *= 2) {
-    partial(i);
-}
-
deleted file mode 100644
--- a/js/src/t/math-spectral-norm.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// The Great Computer Language Shootout
-// http://shootout.alioth.debian.org/
-//
-// contributed by Ian Osgood
-
-function A(i,j) {
-  return 1/((i+j)*(i+j+1)/2+i+1);
-}
-
-function Au(u,v) {
-  for (var i=0; i<u.length; ++i) {
-    var t = 0;
-    for (var j=0; j<u.length; ++j)
-      t += A(i,j) * u[j];
-    v[i] = t;
-  }
-}
-
-function Atu(u,v) {
-  for (var i=0; i<u.length; ++i) {
-    var t = 0;
-    for (var j=0; j<u.length; ++j)
-      t += A(j,i) * u[j];
-    v[i] = t;
-  }
-}
-
-function AtAu(u,v,w) {
-  Au(u,w);
-  Atu(w,v);
-}
-
-function spectralnorm(n) {
-  var i, u=[], v=[], w=[], vv=0, vBv=0;
-  for (i=0; i<n; ++i) {
-    u[i] = 1; v[i] = w[i] = 0;
-  }
-  for (i=0; i<10; ++i) {
-    AtAu(u,v,w);
-    AtAu(v,u,w);
-  }
-  for (i=0; i<n; ++i) {
-    vBv += u[i]*v[i];
-    vv  += v[i]*v[i];
-  }
-  return Math.sqrt(vBv/vv);
-}
-
-for (var i = 6; i <= 48; i *= 2) {
-    spectralnorm(i);
-}
deleted file mode 100644
--- a/js/src/t/regexp-dna.js
+++ /dev/null
@@ -1,1712 +0,0 @@
-// The Computer Language Shootout
-// http://shootout.alioth.debian.org/
-//
-// contributed by Jesse Millikan
-// Base on the Ruby version by jose fco. gonzalez
-
-var l;
-var dnaInput = ">ONE Homo sapiens alu\n\
-GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\n\
-TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\n\
-AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\n\
-GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\n\
-CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\n\
-GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\n\
-GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\n\
-TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\n\
-AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\n\
-GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT\n\
-AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC\n\
-AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG\n\
-GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC\n\
-CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG\n\
-AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT\n\
-TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA\n\
-TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT\n\
-GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG\n\
-TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT\n\
-CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG\n\
-CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG\n\
-TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA\n\
-CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG\n\
-AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG\n\
-GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC\n\
-TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA\n\
-TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA\n\
-GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT\n\
-GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC\n\
-ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT\n\
-TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC\n\
-CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG\n\
-CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG\n\
-GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC\n\
-CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT\n\
-GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC\n\
-GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA\n\
-GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA\n\
-GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA\n\
-GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG\n\
-AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\n\
-CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA\n\
-GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA\n\
-AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC\n\
-GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT\n\
-ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG\n\
-GAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATC\n\
-GCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGC\n\
-GGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG\n\
-TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAA\n\
-AAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAG\n\
-GAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACT\n\
-CCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCC\n\
-TGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAG\n\
-ACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGC\n\
-GTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGA\n\
-ACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGA\n\
-CAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCA\n\
-CTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCA\n\
-ACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCG\n\
-CCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG\n\
-AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTC\n\
-CGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCG\n\
-AGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACC\n\
-CCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAG\n\
-CTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAG\n\
-CCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGG\n\
-CCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATC\n\
-ACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAA\n\
-AAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGC\n\
-TGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCC\n\
-ACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGG\n\
-CTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGG\n\
-AGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATT\n\
-AGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAA\n\
-TCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGC\n\
-CTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAA\n\
-TCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAG\n\
-CCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGT\n\
-GGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCG\n\
-GGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAG\n\
-CGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\n\
-GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATG\n\
-GTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGT\n\
-AATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTT\n\
-GCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCT\n\
-CAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCG\n\
-GGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTC\n\
-TCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACT\n\
-CGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAG\n\
-ATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGG\n\
-CGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTG\n\
-AGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATA\n\
-CAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGG\n\
-CAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGC\n\
-ACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCAC\n\
-GCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTC\n\
-GAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCG\n\
-GGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCT\n\
-TGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGG\n\
-CGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCA\n\
-GCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGG\n\
-CCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGC\n\
-GCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGG\n\
-CGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGA\n\
-CTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGG\n\
-CCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAA\n\
-ACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCC\n\
-CAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGT\n\
-GAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAA\n\
-AGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGG\n\
-ATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTAC\n\
-TAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGA\n\
-GGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGC\n\
-GCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGG\n\
-TGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC\n\
-AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAA\n\
-ATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGA\n\
-GAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\n\
-AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTG\n\
-TAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGAC\n\
-CAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGT\n\
-GGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\n\
-CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACA\n\
-GAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACT\n\
-TTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAAC\n\
-ATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCC\n\
-TGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAG\n\
-GTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCG\n\
-TCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAG\n\
-GCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCC\n\
-GTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCT\n\
-ACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCC\n\
-GAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCC\n\
-GGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCAC\n\
-CTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAA\n\
-ATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTG\n\
-AGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCAC\n\
-TGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCT\n\
-CACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAG\n\
-TTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAG\n\
-CCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATC\n\
-GCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCT\n\
-GGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATC\n\
-CCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCC\n\
-TGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGG\n\
-CGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\n\
-AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCG\n\
-AGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGG\n\
-AGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGT\n\
-GAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAA\n\
-TCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGC\n\
-AGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCA\n\
-AAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGG\n\
-CGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTC\n\
-TACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCG\n\
-GGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGAT\n\
-CGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCG\n\
-CGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAG\n\
-GTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACA\n\
-AAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCA\n\
-GGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCAC\n\
-TCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGC\n\
-CTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\n\
-GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG\n\
-CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTG\n\
-AACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCG\n\
-ACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGC\n\
-ACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCC\n\
-AACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGC\n\
-GCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCG\n\
-GAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACT\n\
-CCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCC\n\
-GAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAAC\n\
-CCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\n\
-GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGA\n\
-GCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAG\n\
-GCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGAT\n\
-CACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTA\n\
-AAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGG\n\
-CTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGC\n\
-CACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTG\n\
-GCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAG\n\
-GAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAAT\n\
-TAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGA\n\
-ATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAG\n\
-CCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTA\n\
-ATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCA\n\
-GCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGG\n\
-TGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCC\n\
-GGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGA\n\
-GCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT\n\
-GGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT\n\
-GGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTG\n\
-TAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGT\n\
-TGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTC\n\
-TCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGC\n\
-GGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGT\n\
-CTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTAC\n\
-TCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGA\n\
-GATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGG\n\
-GCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCT\n\
-GAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\n\
-ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAG\n\
-GCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\n\
-CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCA\n\
-CGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTT\n\
-CGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCC\n\
-GGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGC\n\
-TTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGG\n\
-GCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCC\n\
-AGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTG\n\
-GCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCG\n\
-CGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAG\n\
-GCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAG\n\
-ACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAG\n\
-GCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGA\n\
-AACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATC\n\
-CCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAG\n\
-TGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAA\n\
-AAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCG\n\
-GATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTA\n\
-CTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGG\n\
-AGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCG\n\
-CGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCG\n\
-GTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGT\n\
-CAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAA\n\
-AATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGG\n\
-AGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTC\n\
-CAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCT\n\
-GTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\n\
-CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCG\n\
-TGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAA\n\
-CCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGAC\n\
-AGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCAC\n\
-TTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAA\n\
-CATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGC\n\
-CTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGA\n\
-GGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCC\n\
-GTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGA\n\
-GGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCC\n\
-CGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGC\n\
-TACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGC\n\
-CGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGC\n\
-CGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCA\n\
-CCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\n\
-AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCT\n\
-GAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCA\n\
-CTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGC\n\
-TCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGA\n\
-GTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTA\n\
-GCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAAT\n\
-CGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCC\n\
-TGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAAT\n\
-CCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGC\n\
-CTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTG\n\
-GCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGG\n\
-GAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGC\n\
-GAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\n\
-GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGG\n\
-TGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTA\n\
-ATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTG\n\
-CAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTC\n\
-AAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGG\n\
-GCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCT\n\
-CTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTC\n\
-GGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGA\n\
-TCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGC\n\
-GCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGA\n\
-GGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATAC\n\
-AAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGC\n\
-AGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCA\n\
-CTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACG\n\
-CCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCG\n\
-AGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGG\n\
-GCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTT\n\
-GAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGC\n\
-GACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAG\n\
-CACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGC\n\
-CAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCG\n\
-CGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGC\n\
-GGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGAC\n\
-TCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGC\n\
-CGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAA\n\
-CCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCC\n\
-AGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTG\n\
-AGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA\n\
-GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\n\
-TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\n\
-AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\n\
-GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\n\
-CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\n\
-GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\n\
-GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\n\
-TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\n\
-AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\n\
-GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT\n\
-AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC\n\
-AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG\n\
-GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC\n\
-CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG\n\
-AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT\n\
-TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA\n\
-TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT\n\
-GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG\n\
-TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT\n\
-CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG\n\
-CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG\n\
-TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA\n\
-CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG\n\
-AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG\n\
-GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC\n\
-TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA\n\
-TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA\n\
-GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT\n\
-GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC\n\
-ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT\n\
-TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC\n\
-CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG\n\
-CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG\n\
-GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC\n\
-CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT\n\
-GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC\n\
-GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA\n\
-GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA\n\
-GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA\n\
-GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG\n\
-AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\n\
-CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA\n\
-GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA\n\
-AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC\n\
-GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT\n\
-ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG\n\
-GAGGCTGAGGCAGGAGAATC\n\
->TWO IUB ambiguity codes\n\
-cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg\n\
-tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa\n\
-NtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgt\n\
-cattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcaga\n\
-gtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYa\n\
-HgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRca\n\
-tttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactt\n\
-tattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSSt\n\
-acaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaacct\n\
-tacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYt\n\
-gtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWa\n\
-accRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagt\n\
-RDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgt\n\
-tgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacag\n\
-cccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctg\n\
-ttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaat\n\
-actcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKagg\n\
-YtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSa\n\
-KtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttata\n\
-aaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBa\n\
-aNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacg\n\
-gtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgc\n\
-tcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccK\n\
-tcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMt\n\
-ttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacg\n\
-ggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNa\n\
-BKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDtt\n\
-aRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacc\n\
-tttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatc\n\
-cgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcac\n\
-aattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKga\n\
-tacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcga\n\
-aacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaD\n\
-gttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtg\n\
-ttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcV\n\
-taBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaa\n\
-ccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagat\n\
-gaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgg\n\
-gaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaa\n\
-tYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctt\n\
-tYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactt\n\
-taSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatca\n\
-cBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBag\n\
-aHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHt\n\
-cgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctctt\n\
-ttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBW\n\
-attccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatag\n\
-ttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaa\n\
-attBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStc\n\
-tHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHccta\n\
-aagacYRcaggattHaYgtKtaatgcVcaataMYacccatatcacgWDBtgaatcBaata\n\
-cKcttRaRtgatgaBDacggtaattaaYtataStgVHDtDctgactcaaatKtacaatgc\n\
-gYatBtRaDatHaactgtttatatDttttaaaKVccYcaaccNcBcgHaaVcattHctcg\n\
-attaaatBtatgcaaaaatYMctSactHatacgaWacattacMBgHttcgaatVaaaaca\n\
-BatatVtctgaaaaWtctRacgBMaatSgRgtgtcgactatcRtattaScctaStagKga\n\
-DcWgtYtDDWKRgRtHatRtggtcgaHgggcgtattaMgtcagccaBggWVcWctVaaat\n\
-tcgNaatcKWagcNaHtgaaaSaaagctcYctttRVtaaaatNtataaccKtaRgtttaM\n\
-tgtKaBtRtNaggaSattHatatWactcagtgtactaKctatttgRYYatKatgtccgtR\n\
-tttttatttaatatVgKtttgtatgtNtataRatWYNgtRtHggtaaKaYtKSDcatcKg\n\
-taaYatcSRctaVtSMWtVtRWHatttagataDtVggacagVcgKWagBgatBtaaagNc\n\
-aRtagcataBggactaacacRctKgttaatcctHgDgttKHHagttgttaatgHBtatHc\n\
-DaagtVaBaRccctVgtgDtacRHSctaagagcggWYaBtSaKtHBtaaactYacgNKBa\n\
-VYgtaacttagtVttcttaatgtBtatMtMtttaattaatBWccatRtttcatagVgMMt\n\
-agctStKctaMactacDNYgKYHgaWcgaHgagattacVgtttgtRaSttaWaVgataat\n\
-gtgtYtaStattattMtNgWtgttKaccaatagNYttattcgtatHcWtctaaaNVYKKt\n\
-tWtggcDtcgaagtNcagatacgcattaagaccWctgcagcttggNSgaNcHggatgtVt\n\
-catNtRaaBNcHVagagaaBtaaSggDaatWaatRccaVgggStctDaacataKttKatt\n\
-tggacYtattcSatcttagcaatgaVBMcttDattctYaaRgatgcattttNgVHtKcYR\n\
-aatRKctgtaaacRatVSagctgtWacBtKVatctgttttKcgtctaaDcaagtatcSat\n\
-aWVgcKKataWaYttcccSaatgaaaacccWgcRctWatNcWtBRttYaattataaNgac\n\
-acaatagtttVNtataNaYtaatRaVWKtBatKagtaatataDaNaaaaataMtaagaaS\n\
-tccBcaatNgaataWtHaNactgtcDtRcYaaVaaaaaDgtttRatctatgHtgttKtga\n\
-aNSgatactttcgagWaaatctKaaDaRttgtggKKagcDgataaattgSaacWaVtaNM\n\
-acKtcaDaaatttctRaaVcagNacaScRBatatctRatcctaNatWgRtcDcSaWSgtt\n\
-RtKaRtMtKaatgttBHcYaaBtgatSgaSWaScMgatNtctcctatttctYtatMatMt\n\
-RRtSaattaMtagaaaaStcgVgRttSVaScagtgDtttatcatcatacRcatatDctta\n\
-tcatVRtttataaHtattcYtcaaaatactttgVctagtaaYttagatagtSYacKaaac\n\
-gaaKtaaatagataatSatatgaaatSgKtaatVtttatcctgKHaatHattagaaccgt\n\
-YaaHactRcggSBNgtgctaaBagBttgtRttaaattYtVRaaaattgtaatVatttctc\n\
-ttcatgBcVgtgKgaHaaatattYatagWacNctgaaMcgaattStagWaSgtaaKagtt\n\
-ttaagaDgatKcctgtaHtcatggKttVDatcaaggtYcgccagNgtgcVttttagagat\n\
-gctaccacggggtNttttaSHaNtatNcctcatSaaVgtactgBHtagcaYggYVKNgta\n\
-KBcRttgaWatgaatVtagtcgattYgatgtaatttacDacSctgctaaaStttaWMagD\n\
-aaatcaVYctccgggcgaVtaaWtStaKMgDtttcaaMtVgBaatccagNaaatcYRMBg\n\
-gttWtaaScKttMWtYataRaDBMaDataatHBcacDaaKDactaMgagttDattaHatH\n\
-taYatDtattDcRNStgaatattSDttggtattaaNSYacttcDMgYgBatWtaMagact\n\
-VWttctttgYMaYaacRgHWaattgRtaagcattctMKVStatactacHVtatgatcBtV\n\
-NataaBttYtSttacKgggWgYDtgaVtYgatDaacattYgatggtRDaVDttNactaSa\n\
-MtgNttaacaaSaBStcDctaccacagacgcaHatMataWKYtaYattMcaMtgSttDag\n\
-cHacgatcaHttYaKHggagttccgatYcaatgatRaVRcaagatcagtatggScctata\n\
-ttaNtagcgacgtgKaaWaactSgagtMYtcttccaKtStaacggMtaagNttattatcg\n\
-tctaRcactctctDtaacWYtgaYaSaagaWtNtatttRacatgNaatgttattgWDDcN\n\
-aHcctgaaHacSgaataaRaataMHttatMtgaSDSKatatHHaNtacagtccaYatWtc\n\
-actaactatKDacSaStcggataHgYatagKtaatKagStaNgtatactatggRHacttg\n\
-tattatgtDVagDVaRctacMYattDgtttYgtctatggtKaRSttRccRtaaccttaga\n\
-gRatagSaaMaacgcaNtatgaaatcaRaagataatagatactcHaaYKBctccaagaRa\n\
-BaStNagataggcgaatgaMtagaatgtcaKttaaatgtaWcaBttaatRcggtgNcaca\n\
-aKtttScRtWtgcatagtttWYaagBttDKgcctttatMggNttattBtctagVtacata\n\
-aaYttacacaaRttcYtWttgHcaYYtaMgBaBatctNgcDtNttacgacDcgataaSat\n\
-YaSttWtcctatKaatgcagHaVaacgctgcatDtgttaSataaaaYSNttatagtaNYt\n\
-aDaaaNtggggacttaBggcHgcgtNtaaMcctggtVtaKcgNacNtatVaSWctWtgaW\n\
-cggNaBagctctgaYataMgaagatBSttctatacttgtgtKtaattttRagtDtacata\n\
-tatatgatNHVgBMtKtaKaNttDHaagatactHaccHtcatttaaagttVaMcNgHata\n\
-tKtaNtgYMccttatcaaNagctggacStttcNtggcaVtattactHaSttatgNMVatt\n\
-MMDtMactattattgWMSgtHBttStStgatatRaDaagattttctatMtaaaaaggtac\n\
-taaVttaSacNaatactgMttgacHaHRttgMacaaaatagttaatatWKRgacDgaRta\n\
-tatttattatcYttaWtgtBRtWatgHaaattHataagtVaDtWaVaWtgStcgtMSgaS\n\
-RgMKtaaataVacataatgtaSaatttagtcgaaHtaKaatgcacatcggRaggSKctDc\n\
-agtcSttcccStYtccRtctctYtcaaKcgagtaMttttcRaYDttgttatctaatcata\n\
-NctctgctatcaMatactataggDaHaaSttMtaDtcNatataattctMcStaaBYtaNa\n\
-gatgtaatHagagSttgWHVcttatKaYgDctcttggtgttMcRaVgSgggtagacaata\n\
-aDtaattSaDaNaHaBctattgNtaccaaRgaVtKNtaaYggHtaKKgHcatctWtctDt\n\
-ttctttggSDtNtaStagttataaacaattgcaBaBWggHgcaaaBtYgctaatgaaatW\n\
-cDcttHtcMtWWattBHatcatcaaatctKMagtDNatttWaBtHaaaNgMttaaStagt\n\
-tctctaatDtcRVaYttgttMtRtgtcaSaaYVgSWDRtaatagctcagDgcWWaaaBaa\n\
-RaBctgVgggNgDWStNaNBKcBctaaKtttDcttBaaggBttgaccatgaaaNgttttt\n\
-tttatctatgttataccaaDRaaSagtaVtDtcaWatBtacattaWacttaSgtattggD\n\
-gKaaatScaattacgWcagKHaaccaYcRcaRttaDttRtttHgaHVggcttBaRgtccc\n\
-tDatKaVtKtcRgYtaKttacgtatBtStaagcaattaagaRgBagSaattccSWYttta\n\
-ttVaataNctgHgttaaNBgcVYgtRtcccagWNaaaacaDNaBcaaaaRVtcWMgBagM\n\
-tttattacgDacttBtactatcattggaaatVccggttRttcatagttVYcatYaSHaHc\n\
-ttaaagcNWaHataaaRWtctVtRYtagHtaaaYMataHYtNBctNtKaatattStgaMc\n\
-BtRgctaKtgcScSttDgYatcVtggaaKtaagatWccHccgKYctaNNctacaWctttt\n\
-gcRtgtVcgaKttcMRHgctaHtVaataaDtatgKDcttatBtDttggNtacttttMtga\n\
-acRattaaNagaactcaaaBBVtcDtcgaStaDctgaaaSgttMaDtcgttcaccaaaag\n\
-gWtcKcgSMtcDtatgtttStaaBtatagDcatYatWtaaaBacaKgcaDatgRggaaYc\n\
-taRtccagattDaWtttggacBaVcHtHtaacDacYgtaatataMagaatgHMatcttat\n\
-acgtatttttatattacHactgttataMgStYaattYaccaattgagtcaaattaYtgta\n\
-tcatgMcaDcgggtcttDtKgcatgWRtataatatRacacNRBttcHtBgcRttgtgcgt\n\
-catacMtttBctatctBaatcattMttMYgattaaVYatgDaatVagtattDacaacDMa\n\
-tcMtHcccataagatgBggaccattVWtRtSacatgctcaaggggYtttDtaaNgNtaaB\n\
-atggaatgtctRtaBgBtcNYatatNRtagaacMgagSaSDDSaDcctRagtVWSHtVSR\n\
-ggaacaBVaccgtttaStagaacaMtactccagtttVctaaRaaHttNcttagcaattta\n\
-ttaatRtaaaatctaacDaBttggSagagctacHtaaRWgattcaaBtctRtSHaNtgta\n\
-cattVcaHaNaagtataccacaWtaRtaaVKgMYaWgttaKggKMtKcgWatcaDatYtK\n\
-SttgtacgaccNctSaattcDcatcttcaaaDKttacHtggttHggRRaRcaWacaMtBW\n\
-VHSHgaaMcKattgtaRWttScNattBBatYtaNRgcggaagacHSaattRtttcYgacc\n\
-BRccMacccKgatgaacttcgDgHcaaaaaRtatatDtatYVtttttHgSHaSaatagct\n\
-NYtaHYaVYttattNtttgaaaYtaKttWtctaNtgagaaaNctNDctaaHgttagDcRt\n\
-tatagccBaacgcaRBtRctRtggtaMYYttWtgataatcgaataattattataVaaaaa\n\
-ttacNRVYcaaMacNatRttcKatMctgaagactaattataaYgcKcaSYaatMNctcaa\n\
-cgtgatttttBacNtgatDccaattattKWWcattttatatatgatBcDtaaaagttgaa\n\
-VtaHtaHHtBtataRBgtgDtaataMttRtDgDcttattNtggtctatctaaBcatctaR\n\
-atgNacWtaatgaagtcMNaacNgHttatactaWgcNtaStaRgttaaHacccgaYStac\n\
-aaaatWggaYaWgaattattcMaactcBKaaaRVNcaNRDcYcgaBctKaacaaaaaSgc\n\
-tccYBBHYaVagaatagaaaacagYtctVccaMtcgtttVatcaatttDRtgWctagtac\n\
-RttMctgtDctttcKtWttttataaatgVttgBKtgtKWDaWagMtaaagaaattDVtag\n\
-gttacatcatttatgtcgMHaVcttaBtVRtcgtaYgBRHatttHgaBcKaYWaatcNSc\n\
-tagtaaaaatttacaatcactSWacgtaatgKttWattagttttNaggtctcaagtcact\n\
-attcttctaagKggaataMgtttcataagataaaaatagattatDgcBVHWgaBKttDgc\n\
-atRHaagcaYcRaattattatgtMatatattgHDtcaDtcaaaHctStattaatHaccga\n\
-cNattgatatattttgtgtDtRatagSacaMtcRtcattcccgacacSattgttKaWatt\n\
-NHcaacttccgtttSRtgtctgDcgctcaaMagVtBctBMcMcWtgtaacgactctcttR\n\
-ggRKSttgYtYatDccagttDgaKccacgVatWcataVaaagaataMgtgataaKYaaat\n\
-cHDaacgataYctRtcYatcgcaMgtNttaBttttgatttaRtStgcaacaaaataccVg\n\
-aaDgtVgDcStctatatttattaaaaRKDatagaaagaKaaYYcaYSgKStctccSttac\n\
-agtcNactttDVttagaaagMHttRaNcSaRaMgBttattggtttaRMggatggcKDgWR\n\
-tNaataataWKKacttcKWaaagNaBttaBatMHtccattaacttccccYtcBcYRtaga\n\
-ttaagctaaYBDttaNtgaaaccHcaRMtKtaaHMcNBttaNaNcVcgVttWNtDaBatg\n\
-ataaVtcWKcttRggWatcattgaRagHgaattNtatttctctattaattaatgaDaaMa\n\
-tacgttgggcHaYVaaNaDDttHtcaaHtcVVDgBVagcMacgtgttaaBRNtatRtcag\n\
-taagaggtttaagacaVaaggttaWatctccgtVtaDtcDatttccVatgtacNtttccg\n\
-tHttatKgScBatgtVgHtYcWagcaKtaMYaaHgtaattaSaHcgcagtWNaatNccNN\n\
-YcacgVaagaRacttctcattcccRtgtgtaattagcSttaaStWaMtctNNcSMacatt\n\
-ataaactaDgtatWgtagtttaagaaaattgtagtNagtcaataaatttgatMMYactaa\n\
-tatcggBWDtVcYttcDHtVttatacYaRgaMaacaStaatcRttttVtagaDtcacWat\n\
-ttWtgaaaagaaagNRacDtttStVatBaDNtaactatatcBSMcccaSttccggaMatg\n\
-attaaWatKMaBaBatttgataNctgttKtVaagtcagScgaaaDggaWgtgttttKtWt\n\
-atttHaatgtagttcactaaKMagttSYBtKtaYgaactcagagRtatagtVtatcaaaW\n\
-YagcgNtaDagtacNSaaYDgatBgtcgataacYDtaaactacagWDcYKaagtttatta\n\
-gcatcgagttKcatDaattgattatDtcagRtWSKtcgNtMaaaaacaMttKcaWcaaSV\n\
-MaaaccagMVtaMaDtMaHaBgaacataBBVtaatVYaNSWcSgNtDNaaKacacBttta\n\
-tKtgtttcaaHaMctcagtaacgtcgYtactDcgcctaNgagagcYgatattttaaattt\n\
-ccattttacatttDaaRctattttWctttacgtDatYtttcagacgcaaVttagtaaKaa\n\
-aRtgVtccataBggacttatttgtttaWNtgttVWtaWNVDaattgtatttBaagcBtaa\n\
-BttaaVatcHcaVgacattccNggtcgacKttaaaRtagRtctWagaYggtgMtataatM\n\
-tgaaRttattttgWcttNtDRRgMDKacagaaaaggaaaRStcccagtYccVattaNaaK\n\
-StNWtgacaVtagaagcttSaaDtcacaacgDYacWDYtgtttKatcVtgcMaDaSKStV\n\
-cgtagaaWaKaagtttcHaHgMgMtctataagBtKaaaKKcactggagRRttaagaBaaN\n\
-atVVcgRcKSttDaactagtSttSattgttgaaRYatggttVttaataaHttccaagDtg\n\
-atNWtaagHtgcYtaactRgcaatgMgtgtRaatRaNaacHKtagactactggaatttcg\n\
-ccataacgMctRgatgttaccctaHgtgWaYcactcacYaattcttaBtgacttaaacct\n\
-gYgaWatgBttcttVttcgttWttMcNYgtaaaatctYgMgaaattacNgaHgaacDVVM\n\
-tttggtHtctaaRgtacagacgHtVtaBMNBgattagcttaRcttacaHcRctgttcaaD\n\
-BggttKaacatgKtttYataVaNattccgMcgcgtagtRaVVaattaKaatggttRgaMc\n\
-agtatcWBttNtHagctaatctagaaNaaacaYBctatcgcVctBtgcaaagDgttVtga\n\
-HtactSNYtaaNccatgtgDacgaVtDcgKaRtacDcttgctaagggcagMDagggtBWR\n\
-tttSgccttttttaacgtcHctaVtVDtagatcaNMaVtcVacatHctDWNaataRgcgt\n\
-aVHaggtaaaaSgtttMtattDgBtctgatSgtRagagYtctSaKWaataMgattRKtaa\n\
-catttYcgtaacacattRWtBtcggtaaatMtaaacBatttctKagtcDtttgcBtKYYB\n\
-aKttctVttgttaDtgattttcttccacttgSaaacggaaaNDaattcYNNaWcgaaYat\n\
-tttMgcBtcatRtgtaaagatgaWtgaccaYBHgaatagataVVtHtttVgYBtMctaMt\n\
-cctgaDcYttgtccaaaRNtacagcMctKaaaggatttacatgtttaaWSaYaKttBtag\n\
-DacactagctMtttNaKtctttcNcSattNacttggaacaatDagtattRtgSHaataat\n\
-gccVgacccgatactatccctgtRctttgagaSgatcatatcgDcagWaaHSgctYYWta\n\
-tHttggttctttatVattatcgactaagtgtagcatVgtgHMtttgtttcgttaKattcM\n\
-atttgtttWcaaStNatgtHcaaaDtaagBaKBtRgaBgDtSagtatMtaacYaatYtVc\n\
-KatgtgcaacVaaaatactKcRgtaYtgtNgBBNcKtcttaccttKgaRaYcaNKtactt\n\
-tgagSBtgtRagaNgcaaaNcacagtVtttHWatgttaNatBgtttaatNgVtctgaata\n\
-tcaRtattcttttttttRaaKcRStctcggDgKagattaMaaaKtcaHacttaataataK\n\
-taRgDtKVBttttcgtKaggHHcatgttagHggttNctcgtatKKagVagRaaaggaaBt\n\
-NatttVKcRttaHctaHtcaaatgtaggHccaBataNaNaggttgcWaatctgatYcaaa\n\
-HaatWtaVgaaBttagtaagaKKtaaaKtRHatMaDBtBctagcatWtatttgWttVaaa\n\
-ScMNattRactttgtYtttaaaagtaagtMtaMaSttMBtatgaBtttaKtgaatgagYg\n\
-tNNacMtcNRacMMHcttWtgtRtctttaacaacattattcYaMagBaacYttMatcttK\n\
-cRMtgMNccattaRttNatHaHNaSaaHMacacaVaatacaKaSttHatattMtVatWga\n\
-ttttttaYctttKttHgScWaacgHtttcaVaaMgaacagNatcgttaacaaaaagtaca\n\
-HBNaattgttKtcttVttaaBtctgctacgBgcWtttcaggacacatMgacatcccagcg\n\
-gMgaVKaBattgacttaatgacacacaaaaaatRKaaBctacgtRaDcgtagcVBaacDS\n\
-BHaaaaSacatatacagacRNatcttNaaVtaaaataHattagtaaaaSWccgtatWatg\n\
-gDttaactattgcccatcttHaSgYataBttBaactattBtcHtgatcaataSttaBtat\n\
-KSHYttWggtcYtttBttaataccRgVatStaHaKagaatNtagRMNgtcttYaaSaact\n\
-cagDSgagaaYtMttDtMRVgWKWtgMaKtKaDttttgactatacataatcNtatNaHat\n\
-tVagacgYgatatatttttgtStWaaatctWaMgagaRttRatacgStgattcttaagaD\n\
-taWccaaatRcagcagaaNKagtaaDggcgccBtYtagSBMtactaaataMataBSacRM\n\
-gDgattMMgtcHtcaYDtRaDaacggttDaggcMtttatgttaNctaattaVacgaaMMt\n\
-aatDccSgtattgaRtWWaccaccgagtactMcgVNgctDctaMScatagcgtcaactat\n\
-acRacgHRttgctatttaatgaattataYKttgtaagWgtYttgcHgMtaMattWaWVta\n\
-RgcttgYgttBHtYataSccStBtgtagMgtDtggcVaaSBaatagDttgBgtctttctc\n\
-attttaNagtHKtaMWcYactVcgcgtatMVtttRacVagDaatcttgctBBcRDgcaac\n\
-KttgatSKtYtagBMagaRtcgBattHcBWcaactgatttaatttWDccatttatcgagS\n\
-KaWttataHactaHMttaatHtggaHtHagaatgtKtaaRactgtttMatacgatcaagD\n\
-gatKaDctataMggtHDtggHacctttRtatcttYattttgacttgaaSaataaatYcgB\n\
-aaaaccgNatVBttMacHaKaataagtatKgtcaagactcttaHttcggaattgttDtct\n\
-aaccHttttWaaatgaaatataaaWattccYDtKtaaaacggtgaggWVtctattagtga\n\
-ctattaagtMgtttaagcatttgSgaaatatccHaaggMaaaattttcWtatKctagDtY\n\
-tMcctagagHcactttactatacaaacattaacttaHatcVMYattYgVgtMttaaRtga\n\
-aataaDatcaHgtHHatKcDYaatcttMtNcgatYatgSaMaNtcttKcWataScKggta\n\
-tcttacgcttWaaagNatgMgHtctttNtaacVtgttcMaaRatccggggactcMtttaY\n\
-MtcWRgNctgNccKatcttgYDcMgattNYaRagatHaaHgKctcataRDttacatBatc\n\
-cattgDWttatttaWgtcggagaaaaatacaatacSNtgggtttccttacSMaagBatta\n\
-caMaNcactMttatgaRBacYcYtcaaaWtagctSaacttWgDMHgaggatgBVgcHaDt\n\
-ggaactttggtcNatNgtaKaBcccaNtaagttBaacagtatacDYttcctNgWgcgSMc\n\
-acatStctHatgRcNcgtacacaatRttMggaNKKggataaaSaYcMVcMgtaMaHtgat\n\
-tYMatYcggtcttcctHtcDccgtgRatcattgcgccgatatMaaYaataaYSggatagc\n\
-gcBtNtaaaScaKgttBgagVagttaKagagtatVaactaSacWactSaKatWccaKaaa\n\
-atBKgaaKtDMattttgtaaatcRctMatcaaMagMttDgVatggMaaWgttcgaWatga\n\
-aatttgRtYtattaWHKcRgctacatKttctaccaaHttRatctaYattaaWatVNccat\n\
-NgagtcKttKataStRaatatattcctRWatDctVagttYDgSBaatYgttttgtVaatt\n\
-taatagcagMatRaacttBctattgtMagagattaaactaMatVtHtaaatctRgaaaaa\n\
-aaatttWacaacaYccYDSaattMatgaccKtaBKWBattgtcaagcHKaagttMMtaat\n\
-ttcKcMagNaaKagattggMagaggtaatttYacatcWaaDgatMgKHacMacgcVaaca\n\
-DtaDatatYggttBcgtatgWgaSatttgtagaHYRVacaRtctHaaRtatgaactaata\n\
-tctSSBgggaaHMWtcaagatKgagtDaSatagttgattVRatNtctMtcSaagaSHaat\n\
-aNataataRaaRgattctttaataaagWaRHcYgcatgtWRcttgaaggaMcaataBRaa\n\
-ccagStaaacNtttcaatataYtaatatgHaDgcStcWttaacctaRgtYaRtataKtgM\n\
-ttttatgactaaaatttacYatcccRWtttHRtattaaatgtttatatttgttYaatMca\n\
-RcSVaaDatcgtaYMcatgtagacatgaaattgRtcaaYaaYtRBatKacttataccaNa\n\
-aattVaBtctggacaagKaaYaaatatWtMtatcYaaVNtcgHaactBaagKcHgtctac\n\
-aatWtaDtSgtaHcataHtactgataNctRgttMtDcDttatHtcgtacatcccaggStt\n\
-aBgtcacacWtccNMcNatMVaVgtccDYStatMaccDatggYaRKaaagataRatttHK\n\
-tSaaatDgataaacttaHgttgVBtcttVttHgDacgaKatgtatatNYataactctSat\n\
-atatattgcHRRYttStggaactHgttttYtttaWtatMcttttctatctDtagVHYgMR\n\
-BgtHttcctaatYRttKtaagatggaVRataKDctaMtKBNtMtHNtWtttYcVtattMc\n\
-gRaacMcctNSctcatttaaagDcaHtYccSgatgcaatYaaaaDcttcgtaWtaattct\n\
-cgttttScttggtaatctttYgtctaactKataHacctMctcttacHtKataacacagcN\n\
-RatgKatttttSaaatRYcgDttaMRcgaaattactMtgcgtaagcgttatBtttttaat\n\
-taagtNacatHgttcRgacKcBBtVgatKttcgaBaatactDRgtRtgaNacWtcacYtt\n\
-aaKcgttctHaKttaNaMgWgWaggtctRgaKgWttSttBtDcNtgtttacaaatYcDRt\n\
-gVtgcctattcNtctaaaDMNttttNtggctgagaVctDaacVtWccaagtaacacaNct\n\
-gaScattccDHcVBatcgatgtMtaatBgHaatDctMYgagaatgYWKcctaatNaStHa\n\
-aaKccgHgcgtYaaYtattgtStgtgcaaRtattaKatattagaWVtcaMtBagttatta\n\
-gNaWHcVgcaattttDcMtgtaRHVYtHtctgtaaaaHVtMKacatcgNaatttMatatg\n\
-ttgttactagWYtaRacgataKagYNKcattataNaRtgaacKaYgcaaYYacaNccHat\n\
-MatDcNgtHttRaWttagaaDcaaaaaatagggtKDtStaDaRtaVtHWKNtgtattVct\n\
-SVgRgataDaRaWataBgaagaaKtaataaYgDcaStaNgtaDaaggtattHaRaWMYaY\n\
-aWtggttHYgagVtgtgcttttcaaDKcagVcgttagacNaaWtagtaataDttctggtt\n\
-VcatcataaagtgKaaaNaMtaBBaattaatWaattgctHaVKaSgDaaVKaHtatatat\n\
-HatcatSBagNgHtatcHYMHgttDgtaHtBttWatcgtttaRaattgStKgSKNWKatc\n\
-agDtctcagatttctRtYtBatBgHHtKaWtgYBgacVVWaKtacKcDttKMaKaVcggt\n\
-gttataagaataaHaatattagtataatMHgttYgaRttagtaRtcaaVatacggtcMcg\n\
-agtaaRttacWgactKRYataaaagSattYaWgagatYagKagatgSaagKgttaatMgg\n\
-tataatgttWYttatgagaaacctNVataatHcccKtDctcctaatactggctHggaSag\n\
-gRtKHaWaattcgSatMatttagaggcYtctaMcgctcataSatatgRagacNaaDagga\n\
-VBagaYttKtacNaKgtSYtagttggaWcatcWttaatctatgaVtcgtgtMtatcaYcg\n\
-tRccaaYgDctgcMgtgtWgacWtgataacacgcgctBtgttaKtYDtatDcatcagKaV\n\
-MctaatcttgVcaaRgcRMtDcgattaHttcaNatgaatMtactacVgtRgatggaWttt\n\
-actaaKatgagSaaKggtaNtactVaYtaaKRagaacccacaMtaaMtKtatBcttgtaa\n\
-WBtMctaataaVcDaaYtcRHBtcgttNtaaHatttBNgRStVDattBatVtaagttaYa\n\
-tVattaagaBcacggtSgtVtatttaRattgatgtaHDKgcaatattKtggcctatgaWD\n\
-KRYcggattgRctatNgatacaatMNttctgtcRBYRaaaHctNYattcHtaWcaattct\n\
-BtMKtVgYataatMgYtcagcttMDataVtggRtKtgaatgccNcRttcaMtRgattaac\n\
-attRcagcctHtWMtgtDRagaKaBtgDttYaaaaKatKgatctVaaYaacWcgcatagB\n\
-VtaNtRtYRaggBaaBtgKgttacataagagcatgtRattccacttaccatRaaatgWgD\n\
-aMHaYVgVtaSctatcgKaatatattaDgacccYagtgtaYNaaatKcagtBRgagtcca\n\
-tgKgaaaccBgaagBtgSttWtacgatWHaYatcgatttRaaNRgcaNaKVacaNtDgat\n\
-tgHVaatcDaagcgtatgcNttaDataatcSataaKcaataaHWataBtttatBtcaKtK\n\
-tatagttaDgSaYctacaRatNtaWctSaatatttYaKaKtaccWtatcRagacttaYtt\n\
-VcKgSDcgagaagatccHtaattctSttatggtKYgtMaHagVaBRatttctgtRgtcta\n\
-tgggtaHKgtHacHtSYacgtacacHatacKaaBaVaccaDtatcSaataaHaagagaat\n\
-ScagactataaRttagcaaVcaHataKgDacatWccccaagcaBgagWatctaYttgaaa\n\
-tctVNcYtttWagHcgcgcDcVaaatgttKcHtNtcaatagtgtNRaactttttcaatgg\n\
-WgBcgDtgVgtttctacMtaaataaaRggaaacWaHttaRtNtgctaaRRtVBctYtVta\n\
-tDcattDtgaccYatagatYRKatNYKttNgcctagtaWtgaactaMVaacctgaStttc\n\
-tgaKVtaaVaRKDttVtVctaDNtataaaDtccccaagtWtcgatcactDgYaBcatcct\n\
-MtVtacDaaBtYtMaKNatNtcaNacgDatYcatcgcaRatWBgaacWttKttagYtaat\n\
-tcggttgSWttttDWctttacYtatatWtcatDtMgtBttgRtVDggttaacYtacgtac\n\
-atgaattgaaWcttMStaDgtatattgaDtcRBcattSgaaVBRgagccaaKtttcDgcg\n\
-aSMtatgWattaKttWtgDBMaggBBttBaatWttRtgcNtHcgttttHtKtcWtagHSt\n\
-aacagttgatatBtaWSaWggtaataaMttaKacDaatactcBttcaatatHttcBaaSa\n\
-aatYggtaRtatNtHcaatcaHtagVtgtattataNggaMtcttHtNagctaaaggtaga\n\
-YctMattNaMVNtcKtactBKcaHHcBttaSagaKacataYgctaKaYgttYcgacWVtt\n\
-WtSagcaacatcccHaccKtcttaacgaKttcacKtNtacHtatatRtaaatacactaBt\n\
-ttgaHaRttggttWtatYagcatYDatcggagagcWBataagRtacctataRKgtBgatg\n\
-aDatataSttagBaHtaatNtaDWcWtgtaattacagKttcNtMagtattaNgtctcgtc\n\
-ctcttBaHaKcKccgtRcaaYagSattaagtKataDatatatagtcDtaacaWHcaKttD\n\
-gaaRcgtgYttgtcatatNtatttttatggccHtgDtYHtWgttatYaacaattcaWtat\n\
-NgctcaaaSttRgctaatcaaatNatcgtttaBtNNVtgttataagcaaagattBacgtD\n\
-atttNatttaaaDcBgtaSKgacgtagataatttcHMVNttgttBtDtgtaWKaaRMcKM\n\
-tHtaVtagataWctccNNaSWtVaHatctcMgggDgtNHtDaDttatatVWttgttattt\n\
-aacctttcacaaggaSaDcggttttttatatVtctgVtaacaStDVaKactaMtttaSNa\n\
-gtgaaattaNacttSKctattcctctaSagKcaVttaagNaVcttaVaaRNaHaaHttat\n\
-gtHttgtgatMccaggtaDcgaccgtWgtWMtttaHcRtattgScctatttKtaaccaag\n\
-tYagaHgtWcHaatgccKNRtttagtMYSgaDatctgtgaWDtccMNcgHgcaaacNDaa\n\
-aRaStDWtcaaaaHKtaNBctagBtgtattaactaattttVctagaatggcWSatMaccc\n\
-ttHttaSgSgtgMRcatRVKtatctgaaaccDNatYgaaVHNgatMgHRtacttaaaRta\n\
-tStRtDtatDttYatattHggaBcttHgcgattgaKcKtttcRataMtcgaVttWacatN\n\
-catacctRataDDatVaWNcggttgaHtgtMacVtttaBHtgagVttMaataattatgtt\n\
-cttagtttgtgcDtSatttgBtcaacHattaaBagVWcgcaSYttMgcttacYKtVtatc\n\
-aYaKctgBatgcgggcYcaaaaacgNtctagKBtattatctttKtaVttatagtaYtRag\n\
-NtaYataaVtgaatatcHgcaaRataHtacacatgtaNtgtcgYatWMatttgaactacR\n\
-ctaWtWtatacaatctBatatgYtaagtatgtgtatSttactVatcttYtaBcKgRaSgg\n\
-RaaaaatgcagtaaaWgtaRgcgataatcBaataccgtatttttccatcNHtatWYgatH\n\
-SaaaDHttgctgtccHtggggcctaataatttttctatattYWtcattBtgBRcVttaVM\n\
-RSgctaatMagtYtttaaaaatBRtcBttcaaVtaacagctccSaaSttKNtHtKYcagc\n\
-agaaaccccRtttttaaDcDtaStatccaagcgctHtatcttaDRYgatDHtWcaaaBcW\n\
-gKWHttHataagHacgMNKttMKHccaYcatMVaacgttaKgYcaVaaBtacgcaacttt\n\
-MctaaHaatgtBatgagaSatgtatgSRgHgWaVWgataaatatttccKagVgataattW\n\
-aHNcYggaaatgctHtKtaDtctaaagtMaatVDVactWtSaaWaaMtaHtaSKtcBRaN\n\
-cttStggtBttacNagcatagRgtKtgcgaacaacBcgKaatgataagatgaaaattgta\n\
-ctgcgggtccHHWHaaNacaBttNKtKtcaaBatatgctaHNgtKcDWgtttatNgVDHg\n\
-accaacWctKaaggHttgaRgYaatHcaBacaatgagcaaattactgtaVaaYaDtagat\n\
-tgagNKggtggtgKtWKaatacagDRtatRaMRtgattDggtcaaYRtatttNtagaDtc\n\
-acaaSDctDtataatcgtactaHttatacaatYaacaaHttHatHtgcgatRRttNgcat\n\
-SVtacWWgaaggagtatVMaVaaattScDDKNcaYBYaDatHgtctatBagcaacaagaa\n\
-tgagaaRcataaKNaRtBDatcaaacgcattttttaaBtcSgtacaRggatgtMNaattg\n\
-gatatWtgagtattaaaVctgcaYMtatgatttttYgaHtgtcttaagWBttHttgtctt\n\
-attDtcgtatWtataataSgctaHagcDVcNtaatcaagtaBDaWaDgtttagYctaNcc\n\
-DtaKtaHcttaataacccaRKtacaVaatNgcWRaMgaattatgaBaaagattVYaHMDc\n\
-aDHtcRcgYtcttaaaWaaaVKgatacRtttRRKYgaatacaWVacVcRtatMacaBtac\n\
-tggMataaattttHggNagSctacHgtBagcgtcgtgattNtttgatSaaggMttctttc\n\
-ttNtYNagBtaaacaaatttMgaccttacataattgYtcgacBtVMctgStgMDtagtaR\n\
-ctHtatgttcatatVRNWataDKatWcgaaaaagttaaaagcacgHNacgtaatctttMR\n\
-tgacttttDacctataaacgaaatatgattagaactccSYtaBctttaataacWgaaaYa\n\
-tagatgWttcatKtNgatttttcaagHtaYgaaRaDaagtaggagcttatVtagtctttc\n\
-attaaaatcgKtattaRttacagVaDatgcatVgattgggtctttHVtagKaaRBtaHta\n\
-aggccccaaaaKatggtttaMWgtBtaaacttcactttKHtcgatctccctaYaBacMgt\n\
-cttBaBaNgcgaaacaatctagtHccHtKttcRtRVttccVctttcatacYagMVtMcag\n\
-aMaaacaataBctgYtaatRaaagattaaccatVRatHtaRagcgcaBcgDttStttttc\n\
-VtttaDtKgcaaWaaaaatSccMcVatgtKgtaKgcgatatgtagtSaaaDttatacaaa\n\
-catYaRRcVRHctKtcgacKttaaVctaDaatgttMggRcWaacttttHaDaKaDaBctg\n\
-taggcgtttaHBccatccattcNHtDaYtaataMttacggctNVaacDattgatatttta\n\
-cVttSaattacaaRtataNDgacVtgaacataVRttttaDtcaaacataYDBtttaatBa\n\
-DtttYDaDaMccMttNBttatatgagaaMgaNtattHccNataattcaHagtgaaggDga\n\
-tgtatatatgYatgaStcataaBStWacgtcccataRMaaDattggttaaattcMKtctM\n\
-acaBSactcggaatDDgatDgcWctaacaccgggaVcacWKVacggtaNatatacctMta\n\
-tgatagtgcaKagggVaDtgtaacttggagtcKatatcgMcttRaMagcattaBRaStct\n\
-YSggaHYtacaactMBaagDcaBDRaaacMYacaHaattagcattaaaHgcgctaaggSc\n\
-cKtgaaKtNaBtatDDcKBSaVtgatVYaagVtctSgMctacgttaacWaaattctSgtD\n\
-actaaStaaattgcagBBRVctaatatacctNttMcRggctttMttagacRaHcaBaacV\n\
-KgaataHttttMgYgattcYaNRgttMgcVaaacaVVcDHaatttgKtMYgtatBtVVct\n\
-WgVtatHtacaaHttcacgatagcagtaaNattBatatatttcVgaDagcggttMaagtc\n\
-ScHagaaatgcYNggcgtttttMtStggtRatctacttaaatVVtBacttHNttttaRca\n\
-aatcacagHgagagtMgatcSWaNRacagDtatactaaDKaSRtgattctccatSaaRtt\n\
-aaYctacacNtaRtaactggatgaccYtacactttaattaattgattYgttcagDtNKtt\n\
-agDttaaaaaaaBtttaaNaYWKMBaaaacVcBMtatWtgBatatgaacVtattMtYatM\n\
-NYDKNcKgDttDaVtaaaatgggatttctgtaaatWtctcWgtVVagtcgRgacttcccc\n\
-taDcacagcRcagagtgtWSatgtacatgttaaSttgtaaHcgatgggMagtgaacttat\n\
-RtttaVcaccaWaMgtactaatSSaHtcMgaaYtatcgaaggYgggcgtgaNDtgttMNg\n\
-aNDMtaattcgVttttaacatgVatgtWVMatatcaKgaaattcaBcctccWcttgaaWH\n\
-tWgHtcgNWgaRgctcBgSgaattgcaaHtgattgtgNagtDttHHgBttaaWcaaWagc\n\
-aSaHHtaaaVctRaaMagtaDaatHtDMtcVaWMtagSagcttHSattaacaaagtRacM\n\
-tRtctgttagcMtcaBatVKtKtKacgagaSNatSactgtatatcBctgagVtYactgta\n\
-aattaaaggcYgDHgtaacatSRDatMMccHatKgttaacgactKtgKagtcttcaaHRV\n\
-tccttKgtSataatttacaactggatDNgaacttcaRtVaagDcaWatcBctctHYatHa\n\
-DaaatttagYatSatccaWtttagaaatVaacBatHcatcgtacaatatcgcNYRcaata\n\
-YaRaYtgattVttgaatgaVaactcRcaNStgtgtattMtgaggtNttBaDRcgaaaagc\n\
-tNgBcWaWgtSaDcVtgVaatMKBtttcgtttctaaHctaaagYactgMtatBDtcStga\n\
-ccgtSDattYaataHctgggaYYttcggttaWaatctggtRagWMaDagtaacBccacta\n\
-cgHWMKaatgatWatcctgHcaBaSctVtcMtgtDttacctaVgatYcWaDRaaaaRtag\n\
-atcgaMagtggaRaWctctgMgcWttaagKBRtaaDaaWtctgtaagYMttactaHtaat\n\
-cttcataacggcacBtSgcgttNHtgtHccatgttttaaagtatcgaKtMttVcataYBB\n\
-aKtaMVaVgtattNDSataHcagtWMtaggtaSaaKgttgBtVtttgttatcatKcgHac\n\
-acRtctHatNVagSBgatgHtgaRaSgttRcctaacaaattDNttgacctaaYtBgaaaa\n\
-tagttattactcttttgatgtNNtVtgtatMgtcttRttcatttgatgacacttcHSaaa\n\
-ccaWWDtWagtaRDDVNacVaRatgttBccttaatHtgtaaacStcVNtcacaSRttcYa\n\
-gacagaMMttttgMcNttBcgWBtactgVtaRttctccaaYHBtaaagaBattaYacgat\n\
-ttacatctgtaaMKaRYtttttactaaVatWgctBtttDVttctggcDaHaggDaagtcg\n\
-aWcaagtagtWttHtgKtVataStccaMcWcaagataagatcactctHatgtcYgaKcat\n\
-cagatactaagNSStHcctRRNtattgtccttagttagMVgtatagactaactctVcaat\n\
-MctgtttgtgttgccttatWgtaBVtttctggMcaaKgDWtcgtaaYStgSactatttHg\n\
-atctgKagtagBtVacRaagRtMctatgggcaaaKaaaatacttcHctaRtgtDcttDat\n\
-taggaaatttcYHaRaaBttaatggcacKtgctHVcaDcaaaVDaaaVcgMttgtNagcg\n\
-taDWgtcgttaatDgKgagcSatatcSHtagtagttggtgtHaWtaHKtatagctgtVga\n\
-ttaBVaatgaataagtaatVatSttaHctttKtttgtagttaccttaatcgtagtcctgB\n\
-cgactatttVcMacHaaaggaatgDatggKtaHtgStatattaaSagctWcctccRtata\n\
-BaDYcgttgcNaagaggatRaaaYtaWgNtSMcaatttactaacatttaaWttHtatBat\n\
-tgtcgacaatNgattgcNgtMaaaKaBDattHacttggtRtttaYaacgVactBtaBaKt\n\
-gBttatgVttgtVttcaatcWcNctDBaaBgaDHacBttattNtgtDtatttVSaaacag\n\
-gatgcRatSgtaSaNtgBatagttcHBgcBBaaattaHgtDattatDaKaatBaaYaaMa\n\
-ataaataKtttYtagtBgMatNcatgtttgaNagtgttgtgKaNaSagtttgaSMaYBca\n\
-aaacDStagttVacaaaaactaaWttBaagtctgtgcgtMgtaattctcctacctcaNtt\n\
-taaccaaaaVtBcacataacaccccBcWMtatVtggaatgaWtcaaWaaaaaaaaWtDta\n\
-atatRcctDWtcctaccMtVVatKttaWaaKaaatataaagScHBagaggBaSMtaWaVt\n\
-atattactSaaaKNaactatNatccttgaYctattcaaaVgatttYHcRagattttaSat\n\
-aggttattcVtaaagaKgtattattKtRttNcggcRgtgtgtWYtaacHgKatKgatYta\n\
-cYagDtWcHBDctctgRaYKaYagcactKcacSaRtBttttBHKcMtNtcBatttatttt\n\
-tgSatVgaaagaWtcDtagDatatgMacaacRgatatatgtttgtKtNRaatatNatgYc\n\
-aHtgHataacKtgagtagtaacYttaNccaaatHcacaacaVDtagtaYtccagcattNt\n\
-acKtBtactaaagaBatVtKaaHBctgStgtBgtatgaSNtgDataaccctgtagcaBgt\n\
-gatcttaDataStgaMaccaSBBgWagtacKcgattgaDgNNaaaacacagtSatBacKD\n\
-gcgtataBKcatacactaSaatYtYcDaactHttcatRtttaatcaattataRtttgtaa\n\
-gMcgNttcatcBtYBagtNWNMtSHcattcRctttttRWgaKacKttgggagBcgttcgc\n\
-MaWHtaatactgtctctatttataVgtttaBScttttaBMaNaatMacactYtBMggtHa\n\
-cMagtaRtctgcatttaHtcaaaatttgagKtgNtactBacaHtcgtatttctMaSRagc\n\
-agttaatgtNtaaattgagagWcKtaNttagVtacgatttgaatttcgRtgtWcVatcgt\n\
-taaDVctgtttBWgaccagaaagtcSgtVtatagaBccttttcctaaattgHtatcggRa\n\
-ttttcaaggcYSKaagWaWtRactaaaacccBatMtttBaatYtaagaactSttcgaaSc\n\
-aatagtattgaccaagtgttttctaacatgtttNVaatcaaagagaaaNattaaRtttta\n\
-VaaaccgcaggNMtatattVctcaagaggaacgBgtttaacaagttcKcYaatatactaa\n\
-ccBaaaSggttcNtattctagttRtBacgScVctcaatttaatYtaaaaaaatgSaatga\n\
-tagaMBRatgRcMcgttgaWHtcaVYgaatYtaatctttYttatRaWtctgBtDcgatNa\n\
-tcKaBaDgatgtaNatWKctccgatattaacattNaaacDatgBgttctgtDtaaaMggt\n\
-gaBaSHataacgccSctaBtttaRBtcNHcDatcDcctagagtcRtaBgWttDRVHagat\n\
-tYatgtatcWtaHtttYcattWtaaagtctNgtStggRNcgcggagSSaaagaaaatYcH\n\
-DtcgctttaatgYcKBVSgtattRaYBaDaaatBgtatgaHtaaRaRgcaSWNtagatHa\n\
-acttNctBtcaccatctMcatattccaSatttgcgaDagDgtatYtaaaVDtaagtttWV\n\
-aagtagYatRttaagDcNgacKBcScagHtattatcDaDactaaaaaYgHttBcgaDttg\n\
-gataaaKSRcBMaBcgaBSttcWtgNBatRaccgattcatttataacggHVtaattcaca\n\
-agagVttaaRaatVVRKcgWtVgacctgDgYaaHaWtctttcacMagggatVgactagMa\n\
-aataKaaNWagKatagNaaWtaaaatttgaattttatttgctaaVgaHatBatcaaBWcB\n\
-gttcMatcgBaaNgttcgSNaggSaRtttgHtRtattaNttcDcatSaVttttcgaaaaa\n\
-ttgHatctaRaggSaNatMDaaatDcacgattttagaHgHaWtYgattaatHNSttatMS\n\
-gggNtcKtYatRggtttgtMWVtttaYtagcagBagHaYagttatatggtBacYcattaR\n\
-SataBatMtttaaatctHcaaaSaaaagttNSaaWcWRccRtKaagtBWtcaaattSttM\n\
-tattggaaaccttaacgttBtWatttatatWcDaatagattcctScacctaagggRaaYt\n\
-aNaatgVtBcttaaBaacaMVaaattatStYgRcctgtactatcMcVKatttcgSgatRH\n\
-MaaaHtagtaaHtVgcaaataatatcgKKtgccaatBNgaaWcVttgagttaKatagttc\n\
-aggKDatDtattgaKaVcaKtaataDataataHSaHcattagttaatRVYcNaHtaRcaa\n\
-ggtNHcgtcaaccaBaaagYtHWaaaRcKgaYaaDttgcWYtataRgaatatgtYtgcKt\n\
-aNttWacatYHctRaDtYtattcBttttatcSataYaYgttWaRagcacHMgtttHtYtt\n\
-YaatcggtatStttcgtRSattaaDaKMaatatactaNBaWgctacacYtgaYVgtgHta\n\
-aaRaaRgHtagtWattataaaSDaaWtgMattatcgaaaagtaYRSaWtSgNtBgagcRY\n\
-aMDtactaacttaWgtatctagacaagNtattHggataatYttYatcataDcgHgttBtt\n\
-ctttVttgccgaaWtaaaacgKgtatctaaaaaNtccDtaDatBMaMggaatNKtatBaa\n\
-atVtccRaHtaSacataHattgtttKVYattcataVaattWtcgtgMttcttKtgtctaa\n\
-cVtatctatatBRataactcgKatStatattcatHHRttKtccaacgtgggtgRgtgaMt\n\
-attattggctatcgtgacMtRcBDtcttgtactaatRHttttaagatcgVMDStattatY\n\
-BtttDttgtBtNttgRcMtYtgBacHaWaBaatDKctaagtgaaactaatgRaaKgatcc\n\
-aagNaaaatattaggWNtaagtatacttttKcgtcggSYtcttgRctataYcttatataa\n\
-agtatattaatttataVaacacaDHatctatttttKYVatHRactttaBHccaWagtact\n\
-BtcacgaVgcgttRtttttttSVgtSagtBaaattctgaHgactcttgMcattttagVta\n\
-agaattHctHtcaDaaNtaacRggWatagttcgtSttgaDatcNgNagctagDgatcNtt\n\
-KgttgtaDtctttRaaYStRatDtgMggactSttaDtagSaVtBDttgtDgccatcacaM\n\
-attaaaMtNacaVcgSWcVaaDatcaHaatgaattaMtatccVtctBtaattgtWattat\n\
-BRcWcaatgNNtactWYtDaKttaaatcactcagtRaaRgatggtKgcgccaaHgaggat\n\
-StattYcaNMtcaBttacttatgagDaNtaMgaaWtgtttcttctaHtMNgttatctaWW\n\
-atMtBtaaatagDVatgtBYtatcggcttaagacMRtaHScgatatYgRDtcattatSDa\n\
-HggaaataNgaWSRRaaaBaatagBattaDctttgHWNttacaataaaaaaatacggttt\n\
-gHgVtaHtWMttNtBtctagtMcgKMgHgYtataHaNagWtcaacYattaataYRgtaWK\n\
-gaBctataaccgatttaHaNBRaRaMtccggtNgacMtctcatttgcaattcWgMactta\n\
-caaDaaNtactWatVtttagccttMaatcagVaagtctVaaDaBtattaattaYtNaYtg\n\
-gattaKtaKctYaMtattYgatattataatKtVgDcttatatNBtcgttgtStttttMag\n\
-aggttaHYSttcKgtcKtDNtataagttataagSgttatDtRttattgttttSNggRtca\n\
-aKMNatgaatattgtBWtaMacctgggYgaSgaagYataagattacgagaatBtggtRcV\n\
-HtgYggaDgaYaKagWagctatagacgaaHgtWaNgacttHRatVaWacKYtgRVNgVcS\n\
-gRWctacatcKSactctgWYtBggtataagcttNRttVtgRcaWaaatDMatYattaact\n\
-ttcgaagRatSctgccttgcRKaccHtttSNVagtagHagBagttagaccaRtataBcca\n\
-taatSHatRtcHagacBWatagcaMtacaRtgtgaaBatctKRtScttccaNaatcNgta\n\
-atatWtcaMgactctBtWtaaNactHaaaaRctcgcatggctMcaaNtcagaaaaacaca\n\
-gtggggWttRttagtaagaVctVMtcgaatcttcMaaaHcaHBttcgattatgtcaDagc\n\
-YRtBtYcgacMgtDcagcgaNgttaataatagcagKYYtcgtaBtYctMaRtaRtDagaa\n\
-aacacatgYaBttgattattcgaaNttBctSataaMataWRgaHtttccgtDgaYtatgg\n\
-tDgHKgMtatttVtMtVagttaRatMattRagataaccctKctMtSttgaHagtcStcta\n\
-tttccSagatgttccacgaggYNttHRacgattcDatatDcataaaatBBttatcgaHtN\n\
-HaaatatDNaggctgaNcaaggagttBttMgRagVatBcRtaWgatgBtSgaKtcgHttt\n\
-gaatcaaDaHttcSBgHcagtVaaSttDcagccgttNBtgttHagYtattctttRWaaVt\n\
-SttcatatKaaRaaaNacaVtVctMtSDtDtRHRcgtaatgctcttaaatSacacaatcg\n\
-HattcaWcttaaaatHaaatcNctWttaNMcMtaKctVtcctaagYgatgatcYaaaRac\n\
-tctaRDaYagtaacgtDgaggaaatctcaaacatcaScttcKttNtaccatNtaNataca\n\
-tttHaaDHgcaDatMWaaBttcRggctMaagctVYcacgatcaDttatYtaatcKatWat\n\
-caatVYtNagatttgattgaYttttYgacttVtcKaRagaaaHVgDtaMatKYagagttN\n\
-atWttaccNtYtcDWgSatgaRgtMatgKtcgacaagWtacttaagtcgKtgatccttNc\n\
-ttatagMatHVggtagcgHctatagccctYttggtaattKNaacgaaYatatVctaataM\n\
-aaaYtgVtcKaYtaataacagaatHcacVagatYWHttagaaSMaatWtYtgtaaagNaa\n\
-acaVgaWtcacNWgataNttcaSagctMDaRttgNactaccgataMaaatgtttattDtc\n\
-aagacgctDHYYatggttcaagccNctccttcMctttagacBtaaWtaWVHggaaaaNat\n\
-ttaDtDtgctaaHHtMtatNtMtagtcatttgcaaaRatacagRHtatDNtgtDgaatVg\n\
-tVNtcaaatYBMaaaagcaKgtgatgatMgWWMaHttttMgMagatDtataaattaacca\n\
-actMtacataaattgRataatacgBtKtaataattRgtatDagDtcRDacctatRcagag\n\
-cSHatNtcaScNtttggacNtaaggaccgtgKNttgttNcttgaaRgYgRtNtcagttBc\n\
-ttttcHtKtgcttYaaNgYagtaaatgaatggWaMattBHtatctatSgtcYtgcHtaat\n\
-tHgaaMtHcagaaSatggtatgccaHBtYtcNattWtgtNgctttaggtttgtWatNtgH\n\
-tgcDttactttttttgcNtactKtWRaVcttcatagtgSNKaNccgaataaBttataata\n\
-YtSagctttaaatSttggctaaKSaatRccgWHgagDttaaatcatgagMtcgagtVtaD\n\
-ggaBtatttgDacataaacgtagYRagBWtgDStKDgatgaagttcattatttaKWcata\n\
-aatWRgatataRgttRacaaNKttNtKagaaYaStaactScattattaacgatttaaatg\n\
-DtaattagatHgaYataaactatggggatVHtgccgtNgatNYcaStRtagaccacWcaM\n\
-tatRagHgVactYtWHtcttcatgatWgagaKggagtatgaWtDtVtNaNtcgYYgtaaa\n\
-ctttaDtBactagtaDctatagtaatatttatatataacgHaaaRagKattSagttYtSt\n\
->THREE Homo sapiens frequency\n\
-agagagacgatgaaaattaatcgtcaatacgctggcgaacactgagggggacccaatgct\n\
-cttctcggtctaaaaaggaatgtgtcagaaattggtcagttcaaaagtagaccggatctt\n\
-tgcggagaacaattcacggaacgtagcgttgggaaatatcctttctaccacacatcggat\n\
-tttcgccctctcccattatttattgtgttctcacatagaattattgtttagacatccctc\n\
-gttgtatggagagttgcccgagcgtaaaggcataatccatataccgccgggtgagtgacc\n\
-tgaaattgtttttagttgggatttcgctatggattagcttacacgaagagattctaatgg\n\
-tactataggataattataatgctgcgtggcgcagtacaccgttacaaacgtcgttcgcat\n\
-atgtggctaacacggtgaaaatacctacatcgtatttgcaatttcggtcgtttcatagag\n\
-cgcattgaattactcaaaaattatatatgttgattatttgattagactgcgtggaaagaa\n\
-ggggtactcaagccatttgtaaaagctgcatctcgcttaagtttgagagcttacattagt\n\
-ctatttcagtcttctaggaaatgtctgtgtgagtggttgtcgtccataggtcactggcat\n\
-atgcgattcatgacatgctaaactaagaaagtagattactattaccggcatgcctaatgc\n\
-gattgcactgctatgaaggtgcggacgtcgcgcccatgtagccctgataataccaatact\n\
-tacatttggtcagcaattctgacattatacctagcacccataaatttactcagacttgag\n\
-gacaggctcttggagtcgatcttctgtttgtatgcatgtgatcatatagatgaataagcg\n\
-atgcgactagttagggcatagtatagatctgtgtatacagttcagctgaacgtccgcgag\n\
-tggaagtacagctgagatctatcctaaaatgcaaccatatcgttcacacatgatatgaac\n\
-ccagggggaaacattgagttcagttaaattggcagcgaatcccccaagaagaaggcggag\n\
-tgacgttgaacgggcttatggtttttcagtacttcctccgtataagttgagcgaaatgta\n\
-aacagaataatcgttgtgttaacaacattaaaatcgcggaatatgatgagaatacacagt\n\
-gtgagcatttcacttgtaaaatatctttggtagaacttactttgctttaaatatgttaaa\n\
-ccgatctaataatctacaaaacggtagattttgcctagcacattgcgtccttctctattc\n\
-agatagaggcaatactcagaaggttttatccaaagcactgtgttgactaacctaagtttt\n\
-agtctaataatcatgattgattataggtgccgtggactacatgactcgtccacaaataat\n\
-acttagcagatcagcaattggccaagcacccgacttttatttaatggttgtgcaatagtc\n\
-cagattcgtattcgggactctttcaaataatagtttcctggcatctaagtaagaaaagct\n\
-cataaggaagcgatattatgacacgctcttccgccgctgttttgaaacttgagtattgct\n\
-cgtccgaaattgagggtcacttcaaaatttactgagaagacgaagatcgactaaagttaa\n\
-aatgctagtccacagttggtcaagttgaattcatccacgagttatatagctattttaatt\n\
-tatagtcgagtgtacaaaaaacatccacaataagatttatcttagaataacaacccccgt\n\
-atcatcgaaatcctccgttatggcctgactcctcgagcttatagcatttgtgctggcgct\n\
-cttgccaggaacttgctcgcgaggtggtgacgagtgagatgatcagtttcattatgatga\n\
-tacgattttatcgcgactagttaatcatcatagcaagtaaaatttgaattatgtcattat\n\
-catgctccattaacaggttatttaattgatactgacgaaattttttcacaatgggttttc\n\
-tagaatttaatatcagtaattgaagccttcataggggtcctactagtatcctacacgacg\n\
-caggtccgcagtatcctggagggacgtgttactgattaaaagggtcaaaggaatgaaggc\n\
-tcacaatgttacctgcttcaccatagtgagccgatgagttttacattagtactaaatccc\n\
-aaatcatactttacgatgaggcttgctagcgctaaagagaatacatacaccaccacatag\n\
-aattgttagcgatgatatcaaatagactcctggaagtgtcagggggaaactgttcaatat\n\
-ttcgtccacaggactgaccaggcatggaaaagactgacgttggaaactataccatctcac\n\
-gcccgacgcttcactaattgatgatccaaaaaatatagcccggattcctgattagcaaag\n\
-ggttcacagagaaagatattatcgacgtatatcccaaaaaacagacgtaatgtgcatctt\n\
-cgaatcgggatgaatacttgtatcataaaaatgtgacctctagtatacaggttaatgtta\n\
-gtgatacacaatactcgtgggccatgggttctcaaataaaatgtaatattgcgtcgatca\n\
-ctcacccacgtatttggtctaattatgttttatttagtgacaatccaatagataaccggt\n\
-cctattaagggctatatttttagcgaccacgcgtttaaacaaaggattgtatgtagatgg\n\
-taccagtttaattgccagtgggcaatcctaagcaaaatgagattctatcctaaagtttgg\n\
-gcttgatataagatttcggatgtatgggttttataatcgttggagagctcaatcatgagc\n\
-taatacatggatttcgctacctcaccgagagaccttgcatgaagaattctaaccaaaagt\n\
-ttaataggccggattggattgagttaattaagaccttgttcagtcatagtaaaaaccctt\n\
-aaattttaccgattgacaaagtgagcagtcgcaataccctatgcgaaacgcctcgatagt\n\
-gactaggtatacaaggtttttgagttcctttgaaatagttaactaatttaaaattaatta\n\
-acgacatggaaatcacagaacctaatgctttgtaggagttatttatgctgtttactgcct\n\
-ctacaaccctaataaagcagtcctaagaatgaaacgcatcttttagttcagaaagtggta\n\
-tccagggtggtcaatttaataaattcaacatcgggtctcaggatattcggtcatataatt\n\
-tattaagggctcttcgagtcttactctgagtgaaattggaaacagtcatccttttcgttg\n\
-tgaggcatcttacaccgctatcgatatacaatgcattccaccgcggtgtcccgtacacaa\n\
-ggaaacttgttaccttggggatataagaaaactcacacgtctcattattaaactgagtac\n\
-aatttttgcacgagaaagtaatgcaatacaatatgatgaaagccagctaatgaaaaggga\n\
-tggaacgcacctcggatctgttgcactggattaaaatccgattatttttaaaaatattca\n\
-gtgctagagcatatcaggtctacttttttatctggtatgtaaagcccacggagcgatagt\n\
-gagatccttacgactcaacgaaaagttataacataactcccgttagccaaagcccaatcc\n\
-cgattactgccctaccctaacgtctgccatctaaatatcgaacttgttatgatcaatgtg\n\
-actacctcccaccctttccccttcatttgttccactggggataagctagcgttttcagaa\n\
-tcaatgcaataagaatagccaattgtctcacttcatcagagctcttggcaattccaggcg\n\
-ctacgtggttctggaatatattcatttttcaaatagtaatacgtttagtgttgctattgt\n\
-ctacacgtttggatattacgttatgtgagcggacatcaatagttgtctaactctttagta\n\
-agccagagatagcactcttagcgaatggataccatcttccataagtttagttaatagtcc\n\
-gaaacaactgcttcgagcatatttgaacctccttgtaggcaaatagcctcttcaaagcaa\n\
-tcttactaatagatagagtttgttttaagggactactagaaatgggacaatcttaatagt\n\
-atgacctaaactgacatttaaagatatatccaggtggcaagcataaagatcattgcgcca\n\
-cctccaccgtgggattacttatcagtcgatatcctatatgctaagtttgcgacggcagaa\n\
-tacaaactaagctgagttgatgctaaccttacctatgataccccattggaccggttaaca\n\
-gccctacttattccaaataaaagaacttttatgctgtagaagctattatagtgatgcctg\n\
-gtaacttcagtatattaaaatgacacacatacgccatatagagctcctggaactttgaat\n\
-aatgagcgaacttcgaagttgaagagcaagaaaccatatgtcacggttgcctaaagcccg\n\
-gtaaccagacatgtgctatcattgatcattatcgaggttttcataaccttgacccattat\n\
-cggctgtgcgcggacaagtacttaaatcactagtttcttcacctgcttatcggtaagaaa\n\
-taaggttggcaaagaatcgcataagacggacgtagagccgcagcgttgtgcgagtccagg\n\
-tgcatgcgcagcaataggattttaaattttgttccatttttaatttagccgtaaggatgt\n\
-ccgtaaatgattgaaaattggattcaatctttgggcctatgctactggaacctgatcgac\n\
-aaaatttcaaacatacgttaactccgaaagaccgtatttttgcggctagaatagtcagtc\n\
-gcttggagccatataccttaccacttaaacgacgtgctcctgtagttgaaatataaacag\n\
-aacacaaagactaccgatcatatcaactgaagatctttgtaactttgaggcgaagcaccc\n\
-tcttcgagacaactaagagtaaagtaccgggcgccgcaaggagtcgattgggaccctaaa\n\
-tcttgacgaattgctaagaggctcagagctaccactgtaatttctctagagcccataata\n\
-aatgaacgatacatccgtaggtagcacctaagggattataatggaagccaaatgcagtta\n\
-ataatattatatactggcgtacacgattcgacggatctctcacatagtgattcacgaccc\n\
-ccccctttgattgacacagcgtcagcattttgcaagaacgatcttctgcatagggtgcgc\n\
-caccgtaaggatgacgtcgaagctacaactgggtataatttaccatgcttccctgatgct\n\
-gagtgcaatacactaagaatgagtttttaccccatatcaccagtatttgttctgttattg\n\
-cgaagaaatggctatgctgagttggcgactaaagtcacccatcctttttattaggtaacc\n\
-ccctcccttaaactaactgatttgctggagctgccctgcatacatatactttatcattta\n\
-tggacgtccgtgacgcttattatccaccatagtcgatatgctacacggattcattaatgg\n\
-atcgtaggagtttaagttatatttactaagatcggtctcggctactatcccgccttaccc\n\
-ggcgctatttacggccatttttaatatattgacggtaattattcctatggtttcgaccgc\n\
-acgtccttggacaagaaagaatggcaaaaaaaatgtaaaagaaaaaaaatattgagtccc\n\
-taccatcatataaaaaatatgtgatgagtaacttgacgaaatgttagtggttattaaaga\n\
-ctatctattacaccttttgttttctgtcgtagtatattaaagtctagaagccttacagga\n\
-aaatcagggttatacagccgatactccgcagcatgaatcatcgaggaggtgtcctaccat\n\
-cgcgccttgtaatcttgtctgtgtatactgtatttagaccttttatacaaagtaaatatc\n\
-tcggctttatgtgattgggaggggcctactcaaacatgatgacttgacctaataatcact\n\
-gtgcgggcgtcttatgactagctattccttgaaatccaccaccaaatggttaatatgtaa\n\
-aaactttgacgatgaaacaaggtgaatgtgtagttactttgtgtaattagctgcgtcgag\n\
-cattgcttgtaaaaccgtcaatcgcacacgttacttccataaaatttctacgaatacacc\n\
-cttcttaaaaaaaacgtaggaattcacgagtttaacaaacgataactgtataaagtggaa\n\
-gtccgaagaaagcagatgcccgaactactcgaagatgtttcgttttcttaaccatagggg\n\
-cttcttaatggcccactacgcacattttgttcaagcccgagagggacatccccattacgg\n\
-gagtattactaaaactgttccgtaatacgttcagcaagggatgaaaaaggccactgctca\n\
-agttattgacgtgggagtattacatcggaagcctgaatcccacactatgatggtctgtac\n\
-aggcctagggactgcgtctagacggtattaccggcttctaatcatacgatcgtgagtctt\n\
-aacgggaagtaaggctcacacctaccccaaaccatttatctatgtaagtataaaattgtg\n\
-cgtaagtgttcaaagtggacaataaagacgtggcaaaaacccccgcacataagccgcttt\n\
-agatttcacaaataccaatgcggttaaaaacatccttgagtcgtacatacaccatactcg\n\
-cgttaaacggatataacagaagataataaatccggatgtggagtcggtgtaactatagaa\n\
-agccaagtgaaataatgcttaccagtcatttagctatacggctttcatttcatgtcaaga\n\
-gggtggagtttgacctgtacagttgatatatcaccgatacttagaactcacctaaagcta\n\
-aaattgctcgcagcgtgtaatccgcatattacaaacaatagatgggattcattatacata\n\
-agacacgatgatctgctttttcaggttgcgagatgttgcctatcgtcaatcgagtcctgc\n\
-cttacaccacttaaacaaaagtattgacagggaacctattttcgaggtattatatagtcc\n\
-agcttgaatatcaatttgacagttaacctagtgaaaatcagtaagaggaaatacgccaca\n\
-ttctccagtgaaattctacgggttatcgtctagtccaactatcaattataactcacgaga\n\
-tataagtaaattctcgtacttggcctgatttttattatactttggatccttagtaaacag\n\
-gaagggagaaaccttcaacgaaaaacactggattttgttttactctcaaagctcttatat\n\
-gacggaaataccctgtcaagtcttaactttattactagactaatgaaatgggcttggggt\n\
-ggccagaatcatagtacaatttagcggatacactattcggactttcctatcggctgtctg\n\
-gttggataagtatggggactaataggctagacatacctatacttaaactatacaggcgtc\n\
-atctatctctgcaactttggagttccctgatgttctcccgccctttgggttcacatcttc\n\
-tataccgacacccctaataacgattagtttgtgggttagagtaaattaatacggttaata\n\
-ttaatgtatcgttgaaaagctggtgtcgccaataaggtaaccggctaggcagagtatatg\n\
-tcacgaagtataactaccctaatgataagctgtaggaataaaattaatgctgtctctaag\n\
-cgaagagatatttccgactctgttttaatgacgaatctcattacttctgacttgcaaatg\n\
-ttcaatatggcacggtttcacggcacctttgtgacgcatataatgaacttagaagattat\n\
-aacgacggaactttatatgataatccgttacgattaaagaatctgttaaatatcataatg\n\
-gcattcagttctagaccgtgcatcatggtaaacttactttctctgcatggcgacatacat\n\
-ttcgctattcaaattcgcgtgtggttacacccactcgcacctttggaatattaagagaag\n\
-atgatcagaaaatccattcgctcaatttttctgacgtacgtctaatttatcctaggagac\n\
-aaatcgttttatgtctctcacatttttgaagaaaggttcgagagacaatactcaggtcct\n\
-gaactgctagaagatactcggtggagcgtggcaacaatgaaaaactcgtgacataaatga\n\
-atgatacttttccaagttcagttaagtgaatatgtttaacatacccggcttttcgatctt\n\
-aagctgacgctggacgtgcgagtaatgtcagtctcttacatacactagtgactccaagtt\n\
-tcgtcaaaaacgccccctcccttctcgagcccactcacgctatgtattgacgcgaacttg\n\
-ttcgggatcagacttttcaggagttcggtcgcgtgtccctatgtgctaatatataagtta\n\
-gatcgcattagatgctaatctgaatacttatagacgaccttcaacgagaacgggtaccac\n\
-cttgaggctagagttaggtgtgaaacgacaggtagggacatataaaatttgagtgcggct\n\
-ttagttaagggtttaattacctactcaaacatcacgctcgcgcccttcgtacgtaatcga\n\
-ccatctagaggctaaggggactgtactaggtagtgattaatgatatcctagacgcacgtg\n\
-ccttagatcttcagactctgatggtccgcgatcaccgtaattgtagtcctccaactcgat\n\
-cactttgttggcgtcaaagaaattacgatatctaaatacttataatacaataaccaagga\n\
-tgagaatgactcatcgcgttggagttatattgcttgaagttctatggaatgaaagcacgt\n\
-tatctgccgtcccaatatctccagtgagctaattcattggacggtccactttgatcaatc\n\
-cccgaggagatgttcggacactttagtctgtaacacttagcgttgagaccacgaacaatt\n\
-gattactcagtcttgaaggtgttttccaaagttcattttaaataagactacgataggcct\n\
-ttcctattgatataaactacccggctctgttgttcgtgtgagtcgtacttctctgtgttt\n\
-ttctgattatagcaagattcgattcttagtgtaaacagcgatttttatttgacccgtcaa\n\
-tgagaagcgcataggatctaagcaaaattatcaagttgtgccacaaggtaagatctttcc\n\
-agttattgcaggtaggatgtatcccacgttgatagtatgaggtctgacgtcaactgtcta\n\
-ggagagttgaccgcgtgcgggtacaccggatttgcatcgatgttgagaacgcagaactcc\n\
-cactgtcgtggcggcgttcctgatatttagcaagaggcgttgataaagccctcatcatct\n\
-agatctcgacctcatctgccctcttgctccatcattttctacacagactactttcctatc\n\
-tacgttagtataattgctttctatcttagtatcatttagagcttctccgtcaacaggttc\n\
-gtgctattaaagttagtacgaaagggacaacttgtagcaacgcatttaatcggttttcga\n\
-ctacttcgcacaaaatcagataaagaagtttgtcattctattagacattgaattgcgcaa\n\
-ttgacttgtaccacttatgatcgaacactgaatcaagactgtgattaactaaaatagaca\n\
-agccactatatcaactaataaaaacgcccctggtggtcgaacatagttgactacaggata\n\
-attaattggactggagccattacattctctacaatcgtatcacttcccaagtagacaact\n\
-ttgaccttgtagtttcatgtacaaaaaaatgctttcgcaggagcacattggtagttcaat\n\
-agtttcatgggaacctcttgagccgtcttctgtgggtgtgttcggatagtaggtactgat\n\
-aaagtcgtgtcgctttcgatgagagggaattcaccggaaaacaccttggttaacaggata\n\
-gtctatgtaaacttcgagacatgtttaagagttaccagcttaatccacggtgctctacta\n\
-gtatcatcagctgtcttgcctcgcctagaaatatgcattctatcgttatcctatcaacgg\n\
-ttgccgtactgagcagccttattgtggaagagtaatatataaatgtagtcttgtctttac\n\
-gaagcagacgtaagtaataatgacttggaataccaaaactaaacatagtggattatcata\n\
-ctcaagaactctccagataaataacagtttttacgatacgtcaccaatgagcttaaagat\n\
-taggatcctcaaaactgatacaaacgctaattcatttgttattggatccagtatcagtta\n\
-aactgaatggagtgaagattgtagaatgttgttctggcctcgcatggggtctaggtgata\n\
-tacaatttctcatacttacacggtagtggaaatctgattctagcttcgtagctgactata\n\
-ctcaaggaaccactgctcaaggtaggagactagttccgaccctacagtcaaagtggccga\n\
-agcttaaactatagactagttgttaaatgctgatttcaagatatcatctatatacagttt\n\
-ggacaattatgtgtgcgaaactaaaattcatgctattcagatggatttcacttatgcctt\n\
-agaaacagatattgcccgagctcaatcaacagttttagccggaaacaatcgaagcatagg\n\
-gacaatgtatcttttcctaaattgccatgtgcagatttctgagtgtcacgaagcgcataa\n\
-tagaatcttgtgttgcctcaactcgttgaaaagtttaaaacaatcgcagcagtctttttg\n\
-gggtctactgtgtgtttgcaaaataactgaaagaaacgcttgaacaactctgaagtagct\n\
-cgagtactcattaaagtgtaacacattagtgaatatcggccaatgaaccaaacgcttccc\n\
-ggtacgctatctctctcatcgggaggcgatgtgcaggttatctacgaaagcatcccttta\n\
-cgttgagagtgtcgatgcatgaacctcattgtaacaatagcccagcaaattctcatacgt\n\
-gcctcagggtccgggcgtactcctccatggaagggcgcgcatctagtgttataccaactc\n\
-gctttttaactactatgctgtagttctacaggcatagtggccagtattttctaacttctc\n\
-tggatagatgctctcactcctcatccatcacggcttcagtttacgtcttacttgcttgtt\n\
-cagcaacggatggaggcattaagtatcttcactgttccctaaaattgctgttcaatatca\n\
-aagtaaggacgatacagggaaagctcaagcacactcattgaatactgccccagttgcaac\n\
-ctcacttaatctgacaaaaataatgactactctaagtgttgcggaagcagtctcttccac\n\
-gagcttgtctgtatcacttcgtataggcatgtaactcgatagacacgaacaccgagtgag\n\
-aaactatattcttgcttccgtgtgtgtgacaccaggtaattgatgcggatataagctgga\n\
-gatcactcacgcccacacaaggcgctgctacctctttattccaatgtgtaagaatttgct\n\
-aacttcatttctagaccgcagctttgcggtcataatttcacggtacggacccttgggtta\n\
-gagacttgataacacacttcgcagtttccaccgcgcacatgttttagtggcttctaacat\n\
-agaatttttgttgtgacataaagagtgcgtgggagacttgcccgaccgttaagccataat\n\
-caattgaaagccccgtgagtcacatctaattggttgtactgcgcatttagctatccttta\n\
-gctgactcgaagagattcgattcctaatataggttaattagatggctgccgcgcgaagta\n\
-aaacgtgaaaaacgtagtgcgcagatctgcataactcgcgcttaattacttatgagtagt\n\
-tccaagttcgctacgttatgagagagattggaattaagcaaatatgttttatggtgattt\n\
-tgggatgagaaggactgctaagtacggctactaaacaaatttctaaaaccgccatctacc\n\
-ttatcttggagacatttaagttgtatatgtcactagtctagcttttgtctgtgggacgcg\n\
-ttctcggaatgagggaaatgcaagagccgattcatcaaatgcttatctaagaaagtagtg\n\
-gactattacaccaagcacgaatgccagggaactgctttcttgctcaggacctcgcgacaa\n\
-ggtaccccgcataagtcctagaattacatttggtcagcaatgctgacatttgaccgtgaa\n\
-aacataattttaatcagaaggcagctcacccgcttgctctagatcttatctttgtatgaa\n\
-tgtcagaatttactgcaatatccgttccgaatagtgagggcttagtatagttctctgtat\n\
-acaggtcacatcaaactccccctgtcctagtacagctctgagctttaattaattgcatac\n\
-atttccttcaatcatcagatgaaaacaccgcgaatcatgctcttctcgtatagggcaaga\n\
-gaagcaacaaacaactagcccgactcacgttcatccgccgtatccttgttcagttcttac\n\
-tccgtattaggtcagcgaaatctaatcagaataatcggtcgcgtatcaaaattaaaatcc\n\
-cgcttgaggttgacaattaaaacgctgagcagttatcggctattagatagtggggtgaaa\n\
-gtaattggctggaattatgttaaaacgtgatattaagctaaaatacgctacttgttgccg\n\
-acctaattcagtcattcgatattcagttagagccaagaataacaagcttgtataaattga\n\
-acggggtgcactaaacgatgtgttactctaatattcagcttggagtatacctgaaggcga\n\
-attcatgtatcggccaataataagacgttgaagatcacaatttggactagcaaaagaagg\n\
-tgatttatgcgtggggattgagtccactgtacgagtacggtctctggaaaattataggtt\n\
-cagggaatataaggaagtaaagataattaccaagagatttttggtatcgctatgacccag\n\
-aggtgttctaacgtctgttttgatccgcagaatttctgcctcaatgcatatttgacggac\n\
-ttgaactagagcctctaaagttaaatggcgacgcaactgttcctaaacttcaattattac\n\
-tactctttttttcctagggtattgtagaggccagtggacaaaataaatcaaatttaagat\n\
-gtttcggacattaacatcccccgtagcatagaaatcatcagttatccaatctctcatcga\n\
-gcttttacaatttctgctggcgctatggacagcatatgccgcgagacctccgcaagactc\n\
-acttgatcactgtaagtatcttcattagaggttagagcctatagttaagctgctgaccta\n\
-gtaaaattggtattttctaattttattgctcaagttaaaggttagtgaagggataatgac\n\
-gttatttttgaacaatgggttgtattcaattttatatcacgaatggaacccttcattccc\n\
-ggcataatactagacgacacgaacaagctccgatctatcagccaggcacgtgttaaggtt\n\
-taattccggcaaaccaatgaagcatcaaaaggtgacctgatgcaacttagggtcacgatg\n\
-agtttttcaggactacttattacctattaataagttaacatgagccttcataccccgtaa\n\
-gacaatacatactccaccaattagaattctgagccatcttatctttttgtatcatcgaag\n\
-ggtatggccgaataggttaattagttactcctaacgtctctacaggcatgcatttgacgc\n\
-accttcgaaaatagtcaatctctcgccacacgcgtctagtatgcagcatcaaaaatatag\n\
-tccacggtttccggattaccaaacgcggcaaagagaaacattgtatcgacggagataact\n\
-taatacagaaggaaggggcatcttcgaatacggatgaataattctatctgtttattctga\n\
-catcttgttttcaggttaatcttacgcattcaaatgacgcctgccccatgcgtgcgcaat\n\
-tattttctaatattgacgagagcaatctcactccttttgggtctatttatgttttattga\n\
-ggcacaagcctatacagaacaggtactattaaggccgtgagtgtgagactcaaaccgtgg\n\
-aaacaaaggatgggttgttcttggtacaagttttagtgcatgtgggcaatccttaccaaa\n\
-atcagatgctatccttaactttgggctgcatttaagatggcggttggaggcctgtgagaa\n\
-tcctgcgtgtcatctttaatgaccgaattcatccatgtagattcagatcacacactcatt\n\
-ccttgatgttgtctaaacaaaagttgttgtggacgcattggagggagttaagtaacaact\n\
-tgggatcgcatacttataaaaattatatgttaaactttcacaaacgctgaagtccaaagt\n\
-aactagcccaaacgcctcgagagtcactaggtattaatggtgtttgagttcctgtgaaat\n\
-agtgttcgaaggtaaaatttatgtaccaaatcgaaagaacacttaataaggcttgcttgc\n\
-acggaggtatgatgtttactgactctacaaccctaattttccagtacgtacattcattcc\n\
-aataggttagttctcaaagtgctatacaggctcctcaattgatgatatgcttcagccgct\n\
-ctatggatattagctcattttatttaggaagcccgcttagaggcttactatgagggaaat\n\
-gccaaaatgtcatacttttcggtgtgtcccatatgacaccgctttacatagaatttgaat\n\
-taaaacgcgctctcccgttcactaccatacttggtaccgtgcgcatattacatatagata\n\
-taggatcattttttaaagctgtactaggtttgatcgacaatcttatgctatactatatga\n\
-tgtaaccctcataatcaataccgatcgtacgatcctagcataggtggcaagcgattttat\n\
-gccgattattgtgttaaatagtctgtgagtgtgattatcagggctacgttggtagagggg\n\
-ttgtatagacctcgcacacattgtgacatacttaacaatatacgaaaactgatataataa\n\
-atccccttacccaaacaccaatcccgttgaatcaactaccataacgtctcccatataaat\n\
-tgcctacttgtttgcataaatctgaatacataacaccattgcaccttcttgtgttccaat\n\
-cccgttaagattgccttgtcagatgatatgcaagaacaatagcatttgctagcaattatt\n\
-aacagctcttcgaattgcctccacataacgcgggagggtatattttaatttggcaaatac\n\
-taagtactgttggcgtcatatgctattaacggttggatattaagttatgtcagccgtaag\n\
-caagagtgggcgaaatattttgttacccagtgagagcactcttagagtttggatacaata\n\
-ggccatatgttgacttaagaggacgtaactacgccgtacaccattgttcaaccgacttct\n\
-tggcaaatagaatcgtattagcaatcttaagaatagagacacgttcgtgttagggtatac\n\
-tacaaatccgaaaatcttaagaggatcacctaaactgaaatttatacatatttcaacgtg\n\
-gatagatttaacataattcagccacctccaacctgggagtaattttcagtagatttacta\n\
-gatgattagtggcccaacgcacttgactatataagatctggggatcctaacctgacctat\n\
-gagacaaaattggaaacgttaacagcccttatgtgtacaaagaaaagtaagttgttgctg\n\
-ttcaacagatgatagtcatgacgcgtaacttcactatagtaaattgaaacaaatacgcaa\n\
-tttagacagaatggtacggtcatgaatgacagtaattcgaagtgctagaccaacttaaaa\n\
-taggtaaacgtgcccgaaaccccccttaacagaaagctgctatcatggtgcagtatcgac\n\
-gtgttcagaaacttgtaacttttgagcaggtccgagcacatggaagtatatcacgtgttt\n\
-ctgaaccggcttatccctaagatatatccgtcgcaaactttcgatttagtcccacgtaga\n\
-gcccaagcgttgtgcgactccacgtgcatgcccagaaatacgagtttaaatttggttaca\n\
-tggttaattttgaccgaagcatcgcactttatgattgataattggattcaatatgtcgcc\n\
-ctatgcgaatgcaacatgatccacaatttggctataagacgtttaatccgtatcacactt\n\
-tgtttgcggctagtatagtaacgcccgtgcaccaagagtcagtaacaattataagtactc\n\
-cgcaggtacttcaaatataaaaactaatcaaacacgacccatatgatcatctgaagatat\n\
-ttggaactttctcgacaaccaccctcgtactcaatacttacactaatcgacaggcacacg\n\
-caacgtgtacagtcgcaccatattgagtcaagatttgcttagtggcgatgagcgtacacg\n\
-cttatttctctagtcacaattagttatctacgagacatcacgagggagcaaataagcgat\n\
-gttatggctacacataggcacgtatgaatatgatataagccagttaaacagtcgaaccat\n\
-cgagcaaattctcatgcaccaacccacacgttgaggcacaaagagtaagctgtttgaatg\n\
-taacttcttctgctgagcgggccccaacgtaaggatcaactagaagagaaaactcggtat\n\
-tagtttaaatgcgtcacggagcatgagtgcatttcactaagaatgtctgtgtaaccaata\n\
-taacatctatttgttatctgattgcctacttatggctttgcggtcgtggcgactaatgtc\n\
-tccaatccttttgaggtcggtaccaactccctttaaattacgctgtgcaggctcatgcac\n\
-tgcatacatatacggtagcaggtagggacctcacgcacccttattataatcaatagtagt\n\
-tatcagtcaacgaggcaggaatgctgaggtcgaggtgttggtatattttctatgtgccgt\n\
-ctaggcgactatcacgcattaccaggcgagatttaagccaattttgaatatagtcaacgt\n\
-aatttttactatgggttccaccgaaacgccttgcacaactaagaatcccataaaatatcg\n\
-atatcaaataaaagattgtgtcaataccttcatatatattttttcggttgactaacgtga\n\
-actaaggttaggggttttgtatgtctatataggaaacagtttcttttctgtcctacttta\n\
-gtaaagtcttcaagccttactccaaaatcacggtgattaagccgttactcagcagcatga\n\
-ttctgcctgctcgggtcctaaaatccagccttgtaagagtcgctgtgtattagctaggga\n\
-gacctttgttaaaaaggatatatcgcggcgggatgtgagtgcgtggcgcatactcaatct\n\
-tcagctcgtgtcattataatatctctcccccacgcttttcactagatatgccgtgtaagc\n\
-aaacaccttatgcttaatttcgaaaatattggtacttgaaaaaagctgtaggggtactta\n\
-atgtctggtaggagatcaggagagaattgagtgtaaaaccgtaaagccctcacctgactt\n\
-catgtaaatggcttagaagactccatgatttaataaatactacgaaggaaagactggatc\n\
-taaagataactctagtaaggccaactcccttcaatgctgttgccagttataatccaagag\n\
-ctgtccttttctgaaccatagcggcttctgaagcgaactagaagcaaagttggttctagc\n\
-cagacagccacataccctgtacgggtgtattactaaaactggtccggtattagttcacca\n\
-agggaggaattaggcaaaggatctaggtatgcaagtcggagtattacatccctaccctga\n\
-atccatcaataggttcctctgtactggccttcgcaatgagtattcaaggttgtacagccg\n\
-tataataataagatagtgactatgaacgggaagtaacccgctcaccttccccaaaacatt\n\
-gttatatctaagtattaaagtctgccgtagtgttaatactcgaaaataaacaactggcaa\n\
-attacaccgcacttaagccgcttttgatttatatttttccaatgcgcttttaaaaataat\n\
-tcagtcctacatactaattaagacccttaaacggagatatcacaagttaagttttaacca\n\
-tctcgactaggtggaactatagatacccaactcaatttatcattacctgtaatgttccta\n\
-gaaggattgcatttcatgtcaagacggtggagtttcacagcgaaacttcagtgtgaacag\n\
-attctgagaaatcacctaaacctattagtcagagcacccggttagaaccagttgtcaaaa\n\
-aatagagcggttgcatgagacagaagtaacgatgagatccgttgtaacgttgagacatct\n\
-ggcctatcgtcaatacagtcctcccttaaaaatatttttaaatactaggcaaacccaaca\n\
-taggttagtcctatgtgatacgccacatggtatatcattttgtaacgttacctagggata\n\
-atcaggaagtggaattacgcaaaagtagacagtgaaatgcttagggttatagtctagtcc\n\
-aaagataaaggataaagcacgtcagagaactatattagccgaatgggaatcattgttagg\n\
-agactgtggatcatgtctaaaaagcaacgcagaaacagtcatcgaaaaaatctcgttttt\n\
-gtttgaatctaaaagagctttgatgaccgatagtacctgtatactagttactgtattacg\n\
-tgtctaatgatttcggattggggtccccagaatcagacgtcattgtagacgattcaagtt\n\
-taccaatttaatttcccagctctccttggagaactatcgccaataattgcagtcactttc\n\
-cttttctgaaacgataaagccgtcagagttctctgcaacgttggacttacctgaggttct\n\
-aacccactttcggttctaatagtagttaacgacacaacgaataacctttactgtggggct\n\
-ttcacgatattttttcgcttattattaatggttacgtcataagctggtgtccaaattaag\n\
-gttaccggcttcgcagagtagttgtatccaagtataacttccctaatcataagatcgagg\n\
-tagaaaattaatgctgtctctaaccgaacagatatgtcccactatgtggtatggacgttg\n\
-ctaattacttctgaagggaaattggtcattatggatacgtgtctaccatcaggtcggacg\n\
-cagatatggttctgtcttcagttgatccaccgttctttataggataataactgacgatta\n\
-aagattatggtaaatagattaagccaattctcttcttgtcagtgaagcatccttaactga\n\
-cttgctctgcagcccctcatacatttagctattcaaagtaccggctcgtttcaaactctc\n\
-ccacctttggaagaggttgtcaacttgataagtatatcatttacagcattttttcggacg\n\
-tacctctaatgtttcattgcagaaaattagttttttctatcgcacattttgcaagtaacg\n\
-ttagagacacaattatctgcgaatgaactgctagatctgacgaccgggagcctcgcaaat\n\
-atcaaaaaagactgacatatatcaaggagtcgttgacaagtgctggtaagtcaattggtt\n\
-tatctgtcccggcgtttcgatcttaagctgaccatgcacggcagagtaatgtcactctcg\n\
-ttcttacaagtctgtctccaagggtcggcaaaaaagacccctccattctcgagcccactc\n\
-acgatatgtagggacgacaacttgtgcggcttatgaattgtctggactgcgggcgagggt\n\
-ccatatctccgaagttagaagggacatacctttagatgataagatcaattcttattgacg\n\
-aaattcatccacaacggggaacaacttcaccctagacttacgtctgaaaagacacctagc\n\
-gtcttataaaaggtcagtgccccgtttcgtaaggctggaattacctacgcaaacttaaac\n\
-ctcgcgcccttccttacgtatcgacaagatagaggctatcgcgaatgtactacggaggca\n\
-tgaatcatatactagaaccaagtgcctgtgatattaacaagatgatccgacgcgagcacc\n\
-gtaattctaggcataaaactccagcaatttgggggccgaaaacaaatgacgttagctaat\n\
-taattatatgacatgatcaaaggaggtcaatcacgcatcgagttcgacgtatattcattg\n\
-aacttcgtgcgtttgaaagaaacttttatgaaggcaaaattgatcctgtctcctatttca\n\
-tgcgtacctcctagttgataattccccgagcagtggttaggacacttttgtcggtatcaa\n\
-gttccggtctcaaaacgtaaaattctgtaatctgtatggatggtctgtgaattagttaat\n\
-ttttatgaagtcgtcgagacgcagttcctattgatttattctaaacggagatgtgcttcg\n\
-tgggactcggaagtagatctgtgtttatgattattgctactttagatgctgactgttaac\n\
-tccgtgttgtttttcaaccgtatatcacaaccgaattggatagaacctatagtttcaagt\n\
-tctgccacaaggtatcatatttacagttagtgctggttgcttctttcaaacgtggtgagt\n\
-ttgtgctatcacgtcaacggtagagctcagtggaccgagtgcgcgttcaaccctgttcca\n\
-gagagggtgtgatagcacatataccacgctcgtcgaggcgttcatgatagtttgcaagag\n\
-ccggtgttaaacacatattattattgttatccaactaatcggacctatgcataaagcatt\n\
-gtctaaacagaataattgcctatatacggtagttttagtgatttatatcttagtatcagt\n\
-tagagcttcgaactcttcaggttcctcatatttaacgttcttcgaaagcgaaaacttcta\n\
-caaacgaatgtaagcggttttccaagtagtacctataaatcacagaaagatctgtctcag\n\
-tatagttgaaatggtattcagctagtgacgtgtaccaattatcatagttcactcaagcaa\n\
-gacgctcattaacgaatatagacaagacactatatcatataataaaaaagaacatggtgc\n\
-tcgaacatagttgaattcaccatattgaaggggaatgctgacatgtaattcgctactaga\n\
-cgatcaattccctacttgtcaaagttgaactggtacgttcttggaattaaatatgattgc\n\
-gctggaccaaattgcgacttcttgagtttcagggcaaacgattgagccggaggatgtccg\n\
-tctcttacctttcttgcttatgataaacgacggtccctgtacatcactgggaattctcag\n\
-caaaaataattgggtaaatcgagactcgatgtattcggccacaaaggtgttagacgttaa\n\
-agattattcaacggggcgataataggatcataaccggtatgcaagcgcattgaaagagcc\n\
-atgagatccttatccgataaacgctgcacggtatgtgcagccttattgtcgatcacgaat\n\
-ttataaatgtagtctgggctgtaagttgaagacctaagttataatgaagtgcaataccaa\n\
-atcgattcatagtggattatcagactcaagatatctcctgataaattacagttgttaaga\n\
-tacggataaaatgagatttaagattagcagcctctaatctgtttcaatcccgttggaatg\n\
-tggtatgcgatcaaggttaagttaaaatcaagcctgtcttcagtcttgattcttgttctg\n\
-ccatcgcatgcggtctacgtgagttaatatgtagcttacgttctagcttgtgctaatctg\n\
-agtatagattcgtagaggaatattatcaagcttccacgcctcaacgtacgtgtattggtc\n\
-acacaagacactaaaagtggaagtagcgtaaactatagtctagttgttaaatgctcagtt\n\
-cttgttatattcgatatactcttggctaatttatgtctgagtatataaaattaatgatat\n\
-taacttgcatttcacggatcccttagaaaaagattttgaccgagcgcattataaacggtt\n\
-acaccgaatcaatagaagcatacccaatagctttctttgaatttattgcctgcgcaactt\n\
-ggctgactctctagatccgaataattctatatggtcgtgacgaaactagttcattactgt\n\
-ttaaaatgccaacatgtcttttgggccgataatggctctttgcaaaattactcaatgata\n\
-cgattgatcaaagcggtagttgctagtggtagcatgtaagtctatcaaatgtctgattat\n\
-ccgaaaatcttccaaaagagtccacgtaccatatctatctcatagcgacgcgaggggaac\n\
-cttatctaactatcattccatttaccgggtgactctcgatgcaggatccgattgggataa\n\
-attgcccagaaatggctcattcctgactaagggtaaggccgttctcagcaagggaacccc\n\
-gcgaatctaggcttataccatctagattgttaactacttgcctgtagttctacagccata\n\
-ctggacagttgtttctaaatgatcgggattcatgctagcactcctctgaatgcaccgcgt\n\
-aagtttaactattacgtccgtgggcagataaggatggaggctgtatgtatcttaactgtt\n\
-acctaatatggctggtaattatcaaagtaaggaccttaatgccatagcgctagcaatcgc\n\
-tttgtatactgaccatgtgccaacctctcttaatctgtaaaatataatgtcttagctaac\n\
-tgtggacgatcatgtctctgcctagagcttcgctgtatcaattcctatagccagcgtact\n\
-agtgacacaacaacaccgtgtgagaaaagatattagtccttacgtctgtctctctacagc\n\
-ttattgatgaggattgaacatggacatatagctccccctcaaaagcagatgctacctctt\n\
-tattccattctcgaacatttgccgaacttaatttcgacaaacctgaggtcacgtcttaat\n\
-ttatcggtaacgtcacgtccctttgagactggataaatatattaccaggggccaacgagc\n\
-aattgttggaggcgcttctataatacaaggtgtcttgtcaaagaaagacggcgtgcgtct\n\
-cgtgcaactcacttaaccaatattaatgtgaaacccccctctctcacatcttatgcggtg\n\
-tactgccctggtacatttcctgtacaggactccaacagtgtagattcctaagatagctgt\n\
-tggagttgcctcacgccagatcgaaaaactgaataaactagtgagctgagctgcagaaat\n\
-accgcttaattacttatgactagttcaaagggacctacgtgatgtcagacattgcaagga\n\
-agaaattaggtttgtgcgtcattttggctggactagcactccttacttcccctactattc\n\
-aaatgtcgtaaacagcatgagacaggatcgtgctgacatttaaggtctattgggaacgag\n\
-gctacctttggtcgcgcgctcgcgttctccgaatgaccgaaatgcatgagcacagtatgc\n\
-aattgcttatagatctaaggtctggtcgttgaaaccaagcacgtaggcctgggaaatcag\n\
-ttcttcctcagcaactacacaaaagcgtccaagcattagtacttgtagtaaatgtccgaa\n\
-cctatgcgctcatttgaaagtcaaaaaatatttttaagcagtaggcacctaacccgattc\n\
-ctctacttagtagctttctttgattctcagaattgactgcaatatcactgcacaattctg\n\
-tgccattactagacttctctgtattaacgtctcatcttactaacactcgcctaggacaca\n\
-tctgagagtgaagtatttcaatacatttactgaaatcttcagttctaaaatccccgaata\n\
-aggctcttatcggtttggccaacacaagaaaaaaacttcttgcaccactcaccttcatac\n\
-gcaggagcctggggaacttagtaataactatttcggcagacaaagcttataacaagttgc\n\
-cggcgcgtataatatttaaaagaccccttgagctgctcaattaaaacgctcacctggtat\n\
-aggctattagatagtgccgtcttagtaaggggcgggaattatcggataaactgatatttt\n\
-gataaaataaccgacttgttcacgacataagtcactaaggagattttatctttctccaaa\n\
-gtatatcttccttggataatttcaaagcgctgcaatttaagttctgttactagtttatgc\n\
-tgctgggaggtgaccggaaggcgtagtaatctagaggcaaattataagaagttcatcata\n\
-tcattttcgactacaaaaacaaggtgttgtatgccggcgcattgtgtaaactggacgagt\n\
-accctagatggaaaattatacgttaagccaagatttcgatgtaatgataattacctacac\n\
-atttttgctatccataggaacaagagctgttctataggctcgtggcatacgaacatttgc\n\
-tgccgctatgaatattggaagctcttcaactacagactctattcttaattgccgtcgaaa\n\
-atgggccgaatcggctattattaatactcggtttttccgaggggattgttgtcgacagtc\n\
-gtaattattattaatattgatgttggtgaggtcatttaaatacaaccttgcagacaatga\n\
-ataagggatccaatctctcatactccttttacaattgctcatgcccctatgcaaacctta\n\
-tgccgccacacctccgcaactctctcttctgaactgtaagtagcttcattactggtttga\n\
-gactatactgaagctgatgacattctaaaatggctattttcgaatgtgattcataatgtt\n\
-tatcgtttgggatggcagaatcacgttatttttgatatagcccgggtattctattgtata\n\
-gaacgtatgctacaagtcattccccgaagaagactagaagtaaacaacatgcgaccatcg\n\
-ttaagccacgcaaggctgtagctttatttcccgataacctatcttccataaatagcggac\n\
-agcaggatactgacgctcaacatcagtggttatggtctaatttttaacttttaataaggt\n\
-aacttcagcaggcatacacagtaactctttaatttataatcaaattagaagtctgacact\n\
-tcttatatttttctatcatccaacgcgatcgcccattagcttattgtgttactaataacg\n\
-tatctaaaccaatccttttcaagctactgcctatattgtcaatatatacaaacaacagga\n\
-tagtaggctgcttaaaaaatattgtcaaccgtgtacgctttacaatacccggaaatcaca\n\
-aactttgtagacaacgagtgaaatttatacactacgaagggccagcgtacaagacccatg\n\
-aattaggcgatatgtttattctgacatattggtttatccttaatctgtcgctgtaaaatg\n\
-aagccgcccccatccctgcgaattttttttcgaagattcacgactgaaatataaatacgt\n\
-ttggctatatttatgttggagggaggcaatagcctttactgttaaccgaagatttagcca\n\
-gtgagtgtgacactaaaacactggaataaatgcaggcgttcttctgggtaaaaggtttag\n\
-tcaatctcgcctataagttcatatagctctggatataattatctggcccatgcatttatc\n\
-atggcgcttggtgccctgtgtgaagccggcctctcatattgaaggtccgaagtattccat\n\
-gtacattaagatcactctctcattcatgcatcttggcttaacaaatctggttgtccaagc\n\
-tttccaggcacgtatggtacaaattcggatcgaatacttataaaaatgatatgttaaact\n\
-gtctaaaacgctcatctacaaagtaaagtgcactaaccaatagagtctcaagaccgtgta\n\
-atgctggtgcactgaatgtgtaatacggttagaagggattagttatgttacaaatccatt\n\
-gaaaacttaagaagcattgcgtgctcggagggtgcatcttttatcaagagactaacatta\n\
-ttttcaacgacgtacatgctttacaatagggtacttatcaaacgccgagaaacgcgccta\n\
-tagtgatgttatgattatgacccgatatccattggaccgaattttatgtaggttcccagc\n\
-gtactcgcgtaatatctcggtattgccataatgtaatacttgtcggtctctcccagatga\n\
-aaaagcgttacagagtatttcaatgaaaaacagcgcgcaacgtcaatacctttaggggta\n\
-acggccgctgatttcatatagatatacgataagttggtatagctctactaggtggcatcc\n\
-acaatcgttgcatttactatagctggttacaatcataatctataccgttccttacatact\n\
-accatagcgggatagcgtttttttgccgttgattgggtttaagaggatgtcagtctcatt\n\
-atatccgattcggtgggagagccgttgttttcaaatcgcacactttgtgacataatgtac\n\
-aagataacaaaactgatataagatataaactgtcaatatcaccttgacacttgaatcaaa\n\
-gtaaattaactcgcaaatataatttgactaattgggtgcagatttctcaattaataaaaa\n\
-aatggcaccggatgggcttacaagccccttatcattcacttgtatcatgatttccaagaa\n\
-caatagaatttgctagcaagtatgaacagagattcgaattgcatccacagtacgccggag\n\
-cgtttattttaatgtggatatgacgatgtactgttggcggcatttgctagtaaccggtcc\n\
-ttatttacgtagcgcacacgtaagcatgtctgggagaaatatggtggtacaatctcagag\n\
-aaagattacagtttggtttaaataggacttatcgggtcggaagtggaacttaataagcag\n\
-tacacaattgggcaacagacgtcttgcctattacaataggattacaatgcgttagatttc\n\
-agacacgttcgtgtttggctattcgtcaattccctaaatagttagacgatcaactattat\n\
-caaagtgattctttgttcatcctccattcatgtaacagatggcacactacgcataacgcc\n\
-gaggaattttaacgagatttaagagagcagttcgggcacaacccacttgactttataaca\n\
-gctcggcagcataaacggtaatatgtgacaaatttccaaacgttataagaacgtatgtgt\n\
-acttagaaaactaagtggttcatgttcaacagatgtgacgcagcaagcctaacttatcta\n\
-ttggttttgctataaaagaacaaagttacacagaatcctaagggcttgtttcacacttat\n\
-gcctagtgcttcaccatcttaaaatagcgaaaccggcacgaatcaaaccttaaaacaatg\n\
-cgcagatattggtgatggtgactccgggtatgataatggtaactgttgaccagcgcccac\n\
-ctcatcgaagtatagaaagtggttaggataaggatgagaccgaacttatttccggccata\n\
-actttagattttctacctagtacacaacatcagggcggacacgaaaccgccatcacatca\n\
-tataccaggtttaatttgcttaatgggggaagtgtcaacgaaccttcgaactttagcagg\n\
-catatggccattatatatggccccagagcagaatgctacagcagacaaaatttggattta\n\
-tgtagtttaatacctatcaaacttggtgtgaccatacttgtctaacgacagtgcacaaag\n\
-tgtaagttacaattattactactcagcagcttctgcaatgataaaatcttatcatacacg\n\
-tcacatatgataatatctacttagggggaacgggctccacaacctacatagtactcaata\n\
-cttacactattcgacaggcacaccaaacctgtacagtcccaaaagattgagtcaactttg\n\
-cagtactgcagatcacagtaatagcttagttagcgagtcaaaattagttttctacgagac\n\
-tgcacgaccgtgcaaatttccgatgtgttggctacaaatagcaacgtatgaatttgtttg\n\
-aagccacgtaaactgtacaaccttagagataagtctcaggctactaaaaacacgttgtgg\n\
-cactaacaggatcatggttgattcttacttattcggctgaccggcccaataagtaacctt\n\
-caactagaacagaataatcgggagtagtttaattcagtcaaggtgcaggtctcattgtaa\n\
-ctaacaagctctgtgtaaccaagttaaaatcgttttcttagcggattccctacttatgga\n\
-tttgagctcgtccacaatattcgatacaagaagtttgtggtccgtaacaacgaaatttta\n\
-attacgctgtgcagcctcatccaaggaattaatagaaggttgatggtaggctccgaacgc\n\
-tccatgattataatcaagtggactgtgcagtaaacgaggaaggtatcctgacgtcgtggt\n\
-gttcgtttttgttatttgtgccctatacgagtagataaaccatgaacagcacagtgtgaa\n\
-cccatggttgattttaggctaccttatttttaatttccgttacacagaaacgaattccac\n\
-aactaacatgccattaatttttcgatatcttataaaagatggtcgaaattcattcattta\n\
-ttttttttcggttctcgaaagtcaactaagctgtcgcgttttgtttctctttagaggtaa\n\
-aagtggctttgatctcctacgtttggatactagtcaaccattactccatttgatccgtga\n\
-gtatcacctgtctaacatccagcattatgactcctcggcgaagaaaagacacacttctta\n\
-gagtcgatgtgtattagctagggacacagttgtttaatacgatagtgagcccagggaggg\n\
-cagtgcgtcccccagtagatttattcagctagtgtaagtataagatatctcacccacgag\n\
-gttcaagtgatatgcagtcttagaataatacttatcctgaatttcgatattatgggtact\n\
-tcaataatccgctagcgctactttatgtctcgttggacagcaggacacatggcagtctta\n\
-aacactaaagacatcacctgaatgaatgtaatgggattacaagaatcaatgaggtattat\n\
-atacgacgtaggaaactctggatatatacagtaatctagttacgccatcgcacttcattc\n\
-ctctggaaacttagaagacatcagctgtacgtggaggaaccagacccccgtatgtagcca\n\
-aatagaaccaaagttgcttatacaaacacacccaatgacaatggaccgctggagttcgta\n\
-aactcggaacgtagtactgcacaaacccagcatttagcaataggagctacgtatgcaact\n\
-cccacgtggtaataccttcaagctatcaatatataggtgcctagctaatcgcattcgcaa\n\
-gcagtattcaagcttgtaaaccagtataataattacagaggctctatgaaacccaacttt\n\
-ccagctaaaagtcccaattaaatggttatttcgtacttttaaagtcgcccgttctgttat\n\
-tacgcgaattgattctactccaaaattaaacacaaattatcaaccgtttcatttatattt\n\
-gtcaatgcagctgtttaaaataaggctctactaaattataattaagacacttattaccag\n\
-atttctctagttaagtttgaaccagctcgactaccgcgaaagatacattcccttctctat\n\
-ttttcagttcatctatgggtcagagaagcattgaatttattctattcaccctcgtcgttc\n\
-acagcgaatcgtcagtgtgatcagtgtatgagaaatatcctaaaccgtttagtcagacca\n\
-cacgcttagaacaagtggtctaaaaagactgccctggaaggagtaagaagtatacagctg\n\
-atccggtgtatccttcagtcatctgccctatactaattacacgacgcaaggaaaaatagg\n\
-tttattttctaggcaaacccttcataggtgactccgatgtgttacgaatcatgcttgaga\n\
-atgtgctatcgttaccgacggataataacgatctccaatgaaccaaatgtagaatgtcta\n\
-ttgattacccttttactattcgacttagagataggagatagaacctcagtgtactttttt\n\
-agccgaatgggaatctttgggaggtgaatggccataaggtcgtaaatccaaccctcttaa\n\
-agtcttccatattatatcgttgttcgtggaatcgataacagatttgttgacccatagtaa\n\
-atgtatactagtttatgttgtaagtgtagattgttttccgattgccgtccaaactttatg\n\
-tcgtaattgtagaccagtaaagttgaccaaggtaagtgcccagcgatcctgcgagatcga\n\
-tcgccaatttttccagtcactgtaagtgtaggtttagataaagccgtatgagttatatca\n\
-taagggcctcggaaagcagcttcgaaccaaagttcccttataatagtagtttaactataa\n\
-aagtatatactggtctgtcgccctttcacgatttgttttaccggtttatgaagcgttacg\n\
-tcattagagcggctccaatttaaggttaacggcttccatgtgtagttgtatacaaggata\n\
-acttaaagtatctgttcagcgagctagttaagttatcctcgatagaacacaactcagagg\n\
-tcccaagatcgggtttgcaacttgctaatttattctcaaggcaaattgggaattatcgat\n\
-acctgtataccataaggtcgctcgatgtgatgcttatgtcttctggtgatcctaccttag\n\
-ttagtgctgattaacggaacattaatgtttatcgttttgagatttagccaattctctgat\n\
-tctaactcaagatgccttatctgacgtgctatgcagcccctaagtattttacattgtaat\n\
-aggacacgctcctttaaaactcgccaaaaggtcgttgtggttctctactggttaactata\n\
-taatttacagctttgttgagctagttcctctttggtttaagtcctcaatattagttggtt\n\
-cgagcgataagttggctagttaccttagtcactatattagatccgaatgttatgcttcat\n\
-ctgaagaccgccaccctccaaaatttcttttaagactcacttattgcaaggtgtaggtga\n\
-attcggctcgtttctcaagtggtgtatctgtacacgagtttccatattttcatcaacagc\n\
-caccgcacacttatgtcactctaggtattaaaagtcgctctacaaggggacgcaattaag\n\
-aaacagacatgctagtcaaaaataaacatagcgaggcaccactaattcggccgcttatca\n\
-atgggatgctctgcgcgagacgcgccagagctcagtagttagttcggacatacatttact\n\
-tcagatgatcaattagttttctacaaatgcttactctaccccgaaaaaagtcaccagact\n\
-cttacgtctctttagtatccttccgtcttatataaggtcagtcccccgtttcggtaccct\n\
-ggaatttactaagaataatgaaacagcccccaaggacgtacgtttacaaatgatagacca\n\
-gatcgcctagcttattccgacgcatgttgcatagaattgaaccaacggaatgtgagagta\n\
-actagatgagccgaccacagcacccgtttgcgtcgcagaatacgcctgatagttcggcca\n\
-cgaaatcatatgtcctttgagtattaagtatttgtaatgatcaatcgagctcaagcaagc\n\
-ttacacttcctcggatattcagggaacttagtgcctttgaaagatacgttgatcaacgaa\n\
-aaattgataatggctcatatggaatgcctacctcatagtgctgaattaacacagcactgc\n\
-ggacctaacttttcgaggtttcaagttcacgtctcaaaacctaataggctggaatatgta\n\
-gggatcctcggtgaatttgtgattgggtttgttgtagtactgaccaagtgaatattcttt\n\
-ttttctaaaagcagatctgctgccgggcactacgaaggagatctctgtgtatcattattg\n\
-cttcttgacatgatgactcttaaatcactgtgggtgtgcaaaacgatagcacaacccaat\n\
-tcgatagtacatattgttgatacttcgcactaaaccgttcatatttaaaggttgtgctcc\n\
-ttccttcgttaaatactggtgacttggtcctatctactattagctagacctctggggaac\n\
-cacgcccccgtaaaacctgtgcaagagagggggtcatacatcttagacatcgcgcctcca\n\
-ccagggaagcattgggtgattgaccaggtgtgtaacaaatatgattattcttatactaat\n\
-attagcaaagatgcataatgatttgtattaaatgtataattgaattgataagggtctttt\n\
-agtcagtgatagagtagtataaggtagacattagaactcttaaccggacgcagatttttc\n\
-ggtcttagtaagccaattagtcgacaaaacaaggtaagagcggttactagtagtacctat\n\
-aatgcactgaatcttcggtcgaagtatagttctaatgctatgcagattgtgacggcgaca\n\
-aatgttcagacttatatcatgaaacaagctcttgtaagtattgacaaatgaaaagattga\n\
-atatttttaaatacaaaatgcgcctacttattaggggaattaaccagattgaaggccaat\n\
-cctcacatgtaatgagataatagacgataaatgaaattcttgtaatagttgaactgctac\n\
-gtgatgggtattatatatgattgagatcctccaattgccgacgtcttgtcttgatgccca\n\
-aaagattgtcaacgaggagctccctcgcgtacctgtcgtccgtatcataaacgacgcgac\n\
-atgtacagcactccgaagtataagcaataataatgcgggtaatccagactagatcttttc\n\
-ggactcaatgcggtttcacggtaaacatgattaataccggagagtagtcgagcttatcag\n\
-cgatgcaagcgaattcattgtgccaggagatacgttgcagataaaaccggcaacgtatgt\n\
-caacaagttttggcgatctcgttgtttgtattcgacgaggcgcgggaacttcaagaacta\n\
-tcgtatattcaagtccattaccttttagtttcagactggtggagctgactaaagttatat\n\
-catcattttgtacactggtttagttaacgataatttcagatttaacatgaccagacgata\n\
-atcgctgtatatccagttggaatgtggtttgccagaaaggttaacttataatcaagcctc\n\
-tcttcagtcttgattcgtcgtatcccatccattgcgctatacctcagtgtatttggagct\n\
-gtagttataccgtgtgctaagatcagtagacatgacgagagcaatattatctaccttaca\n\
-agcatcaacggacgtctagtcggaacaaaagactctaaaactcgaacttcaggttaatat\n\
-actatagttctgtattcagcagttattcttatattcgatattatcttgcctattggatgt\n\
-ctgactttagtatattaatcatagtatctgccatgtaaaggtgccagtactaaatctgtt\n\
-tcacagtgcgaattataaacggttacaaccattaaagacaacaagaccctatagctttat\n\
-ttgaattttgtcaatgcgcaacttggagctcgcgatacatcccaattagtctatagggtc\n\
-gggacgattctacggcatttctggttataatgacaacatggattgtggcccgagaatcgc\n\
-tctttcattaattaagcaatcattacagtcttataagcgctacttccgagtggtagcagg\n\
-taactcgatataaggtcgcatgagccgaatagcttaaaaaacaggccaccgaacattgat\n\
-agagaataccgaccacagcgcaacctttgattactttcattaaattgtacggctcactcg\n\
-acatcaagcttaagattgcgataatgtgaactcaaatggatcagtactgaagaaccgtaa\n\
-cccacttcgcagaaagcgtacccagagaagatacgctgttacaatatacagggtgaaatt\n\
-attgcctgttcttcgtaaccatttcgccaaacttggttagaaatgatagccattcatgat\n\
-agaaataagctgaatgataccagtatctttaactatgtagtcagggggaagataacgatg\n\
-gtccatgtatgtttctgatatgtgacagtattggccgcgtaatttgctaacgaagctact\n\
-taatgcctttgagcttcatatagatttctttaatcaaaatcggcaaaaagatagtatgag\n\
-ctataatatatgctagtagagaactctggaccatcatctatatgaatactgattcgagcg\n\
-tgcaattactttagcctgcgtactactgactctacaaaacactctgagataagtttgtag\n\
-tcagtaagtcgctctctataaaccttttggatgaccattgtacagccacttatagatccc\n\
-aataaatagcacaggagacagagtttttcaatgctcgatcatttgccgatagtattttcg\n\
-tctaacctcagggcacctattatttgatacctaacctaacggccctttcacaatggagaa\n\
-atatatgacatcgggacaaacacaaatggtgggtggccaggagatatgacatggtggcgt\n\
-ctctaagaaacacggactccctctaggcaaactcacgtaaccaattttaatgtcaaacaa\n\
-aacgctcgaaaagattttgccgtgtaatgacctggtacattgactggtcaggaatacatc\n\
-actgtagttgccgtagtgtcctgttggtgttccatcaagacacatcgtataacgcaattt\n\
-acgacggacatcagatcaagttatacagattatttaagtatcacgtgtgcattgggacat\n\
-aagggatctcacacatgccttggaacatttttgctttgtgccgctttttcgctgcactac\n\
-caatccttacttaccagtatattcaaaggtcgttaacagaatgagaaaggttagggctct\n\
-aagttatcgtcgattgggatagacgagacatttgcgagcgccctccacggatacgaatct\n\
-cccatatcaatgtgaactggatgctatgcagtttagttcttacgtctcctagtggtaaaa\n\
-atcaaagtagcactcgcatagcagttattcagaacctaatacacaaaaccgtcaaacatt\n\
-ttctaattctaggtatgggccgatcataggagctaaggtgaaactcataaatgttttgtt\n\
-agatctagcatcctaaaaagatgcatatactgagtagctggcgtgcattctctcaattgt\n\
-atcctttttaactgaactagtcggtcccatttcgtgactgagatctattaaccgataaga\n\
-ttaataacactcgcattcgtatcagctcagagtgaagtttttcaataatttgactgatat\n\
-attaacttctaaaataaccctttaagcctcggatccgtttcccaatcacatcaaaaattc\n\
-ttattccaactatctacggattaacaacgtgcatggggatcgtagtaagaacttgttccg\n\
-atcactttgagtatatcaagttgacggcccggttattattgaatagaaacattcacctgc\n\
-taaattaaataccgcacatcggatacccgatttcagagggccgtcttactaagggcaggc\n\
-tttgttcggtttaactgagatgttcattattttacagtatgcttcaactaatatgtaacg\n\
-aaggacagtggatctgtctccatagtagatcttcagtcgtgaatttcataccgctcctat\n\
-ttaagttcgcgttcgagttgttgatcatggcacgtgaaagcaacccctagtattctagac\n\
-gaaaattttttctagttcatctgataatttgccaattcaaaaacaaccgctggtttcccg\n\
-gcgcattctctaaaatggaagtcgaacctagagccattatttgtcggtaacccatgagtt\n\
-ccttcttttcagaagttaatacactgtggtcctatacagaggaaaaacagcggttatata\n\
-cgatcgtggcataacaacattggatcaagatagcaatttggctacctattctaattctca\n\
-ctagattcggtattccactacaatatcggcagattaggattggatgaataatcggtgttt\n\
-aagtccggttgcgtctccaatctcctaatttttattaatattgatcttggtgacctattg\n\
-taaataaaaacttcaagactttgaataacggtgaaaagatagaagactcatttgaaaatg\n\
-gatcatccacagatccaaacattagcaagacactaatccccaactagctattctgatcgc\n\
-gatcgtgctgcagtactcctgtcacaatagtctgttcatgatctaattctttttgggctt\n\
-tgttcgatggtgattcagaatctttatccggtcgcttccctgtagctactttgtggggat\n\
-attgcccggggattatagggttgagatcgtttcctaaaagtatttaaaccaagtagactt\n\
-caactaaactacatcagaacatcgtgaagacaccatacgcggtacctttatttaccgata\n\
-acatttcttcaagaaataccggtaagcagcataatgaccctaaacagctcggggtatcgt\n\
-cgtagttttaaattttatttaggttactgctcaaggaataaaaactaactatttaattta\n\
-taataatattacaaggctcacactgattagatttgtctataagacttcgcgatcccccat\n\
-taccggattgtcttaagaataaactagataaaccatgcattttctagataaggcctttag\n\
-tctaattagatacaaaaaacacgatagttgcatccttaatttattgtgtcaaacctggaa\n\
-ccttttaattacccgcaaatcactttatgtcgagactacctctgaaatttattatctacc\n\
-taccgcatgaggacttgaaccatcttgtaggagttatgtttattagctaagattcgttta\n\
-tcctgtagcggtccatgtatattcaacaagcaaaaagcactcagaattgtttttagttga\n\
-gtcaagactgatatataaataagtttccctagttttttcgtggtgggacgatattgaatt\n\
-gaatcttaaccgaagagtttcccactctgtcgcacaataatacacgccaatatttccagc\n\
-cctgcttatgccttaatcggttactcaatctcccattgaagttcattttgatctgcatag\n\
-aagtttcgggcccagccttttttctgccaccttcctccaagctctgtagacgcactctaa\n\
-gattgatgctcacatgtattaattctacattaacataaatatataagtcatgcatcttcg\n\
-agtaaaatatctggttctccaacatgtcctggcacgtatcgttataatgcccatacatgt\n\
-agtattaaaatgattgggttaactggatattaagatcatcgaaattgtaaagtcaaatta\n\
-acaatactgtctcaagaccgtgtattcctcgtgctcggaagggctattacgcttacttcc\n\
-gttttggtatcttaatatgactttcaaaaattaagttgcagtgagtcctacctgcgtgca\n\
-tcggttagcaagagtataaaagttgtttaaacgaactacttgctttacaataccggtcgt\n\
-atatatcgccgtgaatccagaagattgtcttctttggattatcaaccgagatcctgtgga\n\
-ccgatgttttgggaccttcacagaggactccaggtagagctcgcttttgcattaatctaa\n\
-gaattgtacctctctaaaagatctaaaacagtgaatgtgtatttcatggaaaaacacaga\n\
-gaaacgtaaattactttaggccgaaaggcacatgagttattatacatatacgagatggtg\n\
-gtatacatcgaattcggggcatacactatagttgcattgtatttagctgctttaaataat\n\
-atgatattaccttccttacataagacattaccggcataccctggttttcaacttgtgggg\n\
-ctttttgacgatcgcactctcatttgatccgagtagggcggtgacccctgcttttcaaat\n\
-acaaaaatttcgctatgaaggtaatagattacttttcgctgttatg