Bug 1341102 - Revendor rust dependencies on a CLOSED TREE.
authorXidorn Quan <me@upsuper.org>
Thu, 01 Jun 2017 09:12:44 +1000
changeset 361688 591656964cf4ed767950565bb9b351cbe5a5954d
parent 361687 898a81f1f62b302044656d67f8b8c60c67e7b733
child 361689 ed1a152dba74778327420a572576d68a47821469
push id31939
push usercbook@mozilla.com
push dateThu, 01 Jun 2017 11:49:28 +0000
treeherdermozilla-central@d96110d76619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1341102
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1341102 - Revendor rust dependencies on a CLOSED TREE. MozReview-Commit-ID: 6MPTaW3uQN
third_party/rust/bitflags/.cargo-checksum.json
third_party/rust/bitflags/.travis.yml
third_party/rust/bitflags/Cargo.toml
third_party/rust/bitflags/README.md
third_party/rust/bitflags/src/lib.rs
third_party/rust/bitflags/tests/i128_bitflags.rs
third_party/rust/rayon-core/.cargo-checksum.json
third_party/rust/rayon-core/Cargo.toml
third_party/rust/rayon-core/src/sleep/mod.rs
third_party/rust/rayon/.cargo-checksum.json
third_party/rust/rayon/Cargo.toml
third_party/rust/rayon/RELEASES.md
third_party/rust/unicode-bidi/.cargo-checksum.json
third_party/rust/unicode-bidi/.gitignore
third_party/rust/unicode-bidi/.rustfmt.toml
third_party/rust/unicode-bidi/.travis.yml
third_party/rust/unicode-bidi/AUTHORS
third_party/rust/unicode-bidi/Cargo.toml
third_party/rust/unicode-bidi/benches/udhr.rs
third_party/rust/unicode-bidi/benches/udhr_data/README.md
third_party/rust/unicode-bidi/src/char_data/mod.rs
third_party/rust/unicode-bidi/src/char_data/tables.rs
third_party/rust/unicode-bidi/src/deprecated.rs
third_party/rust/unicode-bidi/src/explicit.rs
third_party/rust/unicode-bidi/src/format_chars.rs
third_party/rust/unicode-bidi/src/implicit.rs
third_party/rust/unicode-bidi/src/level.rs
third_party/rust/unicode-bidi/src/lib.rs
third_party/rust/unicode-bidi/src/prepare.rs
third_party/rust/unicode-bidi/src/tables.rs
third_party/rust/unicode-bidi/tests/conformance_tests.rs
third_party/rust/unicode-bidi/tools/generate.py
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/third_party/rust/bitflags/.cargo-checksum.json
+++ b/third_party/rust/bitflags/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"793de473e858941a0d41e0c4e114373bca6b822737cdcf5ff8f36238a9b51837","Cargo.toml":"98d1298b1d79ccc587957062cf1c56712f68ee2796bed5f39c8d334133d9c562","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"1cce1c9c1fe2cf40ec1c6a0384f8cc2f0c5c40ece4acfedd64330ed95ef74e44","src/lib.rs":"006a631d800f713e2ffc74e33f65fd47505eec1b047c109e180905a9dcb7e973","tests/external.rs":"546e549ec831876a5dc272bd0537adc9e9886c6da54656c825e7bffc079e2c74","tests/external_no_std.rs":"48929f5109aabc156442d5ae2ab07b4bce5d648488bf49dba725f6ab23bcb48a","tests/i128_bitflags.rs":"fb1bf9e01f528478539c52de94e82a96b2639dc271ea242fea6ebb32dcb0f99e"},"package":"1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"2b615144d3f4b2e63ba6ec435cc18df7d76354aa07c2a02d6c707028cc448784","Cargo.toml":"db8c2e9ea912c5f3d2d89cf4cf936c448300e356b0fb533db8875923cb135256","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"8cfbc986af45867d9e620188af2392320fe6e0d9536753ba415c94ab522f5fb5","src/lib.rs":"618ce383bb219725363fba174fc66beb4874d9682e5da953f9e3e9cb3f786d5f","tests/external.rs":"546e549ec831876a5dc272bd0537adc9e9886c6da54656c825e7bffc079e2c74","tests/external_no_std.rs":"48929f5109aabc156442d5ae2ab07b4bce5d648488bf49dba725f6ab23bcb48a"},"package":"aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"}
\ No newline at end of file
--- a/third_party/rust/bitflags/.travis.yml
+++ b/third_party/rust/bitflags/.travis.yml
@@ -1,24 +1,24 @@
 language: rust
 rust:
   - stable
   - beta
   - nightly
 sudo: false
-before_script:
-  - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
 script:
   - cargo build --verbose
   - cargo test --verbose
-  - travis-cargo --only nightly test
-  - cargo doc --no-deps
-after_success:
-  - travis-cargo --only nightly doc-upload
+  - cargo doc
+after_success: |
+  [ $TRAVIS_BRANCH = master ] &&
+  [ $TRAVIS_PULL_REQUEST = false ] &&
+  [ $TRAVIS_RUST_VERSION = nightly ] &&
+  echo '<meta http-equiv=refresh content=0;url=bitflags/index.html>' > target/doc/index.html &&
+  pip install ghp-import --user $USER &&
+  $HOME/.local/bin/ghp-import -n target/doc &&
+  git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
 env:
   global:
-    secure: "DoZ8g8iPs+X3xEEucke0Ae02JbkQ1qd1SSv/L2aQqxULmREtRcbzRauhiT+ToQO5Ft1Lul8uck14nPfs4gMr/O3jFFBhEBVpSlbkJx7eNL3kwUdp95UNroA8I43xPN/nccJaHDN6TMTD3+uajTQTje2SyzOQP+1gvdKg17kguvE="
-
-
-
+    secure: d+l63TtlF6cfFVDGauYRexgx4lBww4ORqqK4Vt75nWbiCbjZYsKXbcTUdhAr193nIVGiNW50A8SekM01F3EngHwHwr6u5kFleOggm+HA0kkBVeX+k2A4WCVVfYI+gth+zk99WaF8h46MA0evhx6FYDoqeyl9oqmVifI4kaqhMwc=
 notifications:
   email:
     on_success: never
--- a/third_party/rust/bitflags/Cargo.toml
+++ b/third_party/rust/bitflags/Cargo.toml
@@ -1,17 +1,13 @@
 [package]
 
 name = "bitflags"
-version = "0.8.2"
+version = "0.7.0"
 authors = ["The Rust Project Developers"]
 license = "MIT/Apache-2.0"
 readme = "README.md"
 repository = "https://github.com/rust-lang/bitflags"
 homepage = "https://github.com/rust-lang/bitflags"
 documentation = "https://doc.rust-lang.org/bitflags"
 description = """
 A macro to generate structures which behave like bitflags.
 """
-
-[features]
-i128 = []
-unstable = ["i128"]
--- a/third_party/rust/bitflags/README.md
+++ b/third_party/rust/bitflags/README.md
@@ -8,36 +8,17 @@ A Rust macro to generate structures whic
 [Documentation](https://doc.rust-lang.org/bitflags)
 
 ## Usage
 
 Add this to your `Cargo.toml`:
 
 ```toml
 [dependencies]
-bitflags = "0.7"
+bitflags = "0.6"
 ```
 
 and this to your crate root:
 
 ```rust
 #[macro_use]
 extern crate bitflags;
 ```
-
-## 128-bit integer bitflags (nightly only)
-
-Add this to your `Cargo.toml`:
-
-```toml
-[dependencies.bitflags]
-version = "0.7"
-features = ["i128"]
-```
-
-and this to your crate root:
-
-```rust
-#![feature(i128_type)]
-
-#[macro_use]
-extern crate bitflags;
-```
--- a/third_party/rust/bitflags/src/lib.rs
+++ b/third_party/rust/bitflags/src/lib.rs
@@ -7,38 +7,26 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 //! A typesafe bitmask flag generator.
 
 #![no_std]
 
-#![cfg_attr(feature = "i128", feature(i128_type))]
-
-// When compiled for the rustc compiler itself we want to make sure that this is
-// an unstable crate.
-#![cfg_attr(rustbuild, feature(staged_api))]
-#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))]
-
 #[cfg(test)]
 #[macro_use]
 extern crate std;
 
 // Re-export libstd/libcore using an alias so that the macros can work in no_std
 // crates while remaining compatible with normal crates.
 #[allow(private_in_public)]
 #[doc(hidden)]
 pub use core as __core;
 
-#[cfg(feature = "i128")]
-pub type __BitFlagsWidth = u128;
-#[cfg(not(feature = "i128"))]
-pub type __BitFlagsWidth = u64;
-
 /// The `bitflags!` macro generates a `struct` that holds a set of C-style
 /// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
 ///
 /// The flags should only be defined for integer types, otherwise unexpected
 /// type errors may occur at compile time.
 ///
 /// # Example
 ///
@@ -238,53 +226,52 @@ macro_rules! bitflags {
                 // bit value of 0.
                 #[allow(dead_code)]
                 #[allow(unused_assignments)]
                 mod dummy {
                     // We can't use the real $BitFlags struct because it may be
                     // private, which prevents us from using it to define
                     // public constants.
                     pub struct $BitFlags {
-                        bits: $crate::__BitFlagsWidth,
+                        bits: u64,
                     }
                     mod real_flags {
                         use super::$BitFlags;
                         $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags {
-                            bits: super::super::$Flag.bits as $crate::__BitFlagsWidth
+                            bits: super::super::$Flag.bits as u64
                         };)+
                     }
                     // Now we define the "undefined" versions of the flags.
                     // This way, all the names exist, even if some are #[cfg]ed
                     // out.
                     $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
 
                     #[inline]
-                    pub fn fmt(self_: $crate::__BitFlagsWidth,
+                    pub fn fmt(self_: u64,
                                f: &mut $crate::__core::fmt::Formatter)
                                -> $crate::__core::fmt::Result {
                         // Now we import the real values for the flags.
                         // Only ones that are #[cfg]ed out will be 0.
                         use self::real_flags::*;
 
                         let mut first = true;
                         $(
                             // $Flag.bits == 0 means that $Flag doesn't exist
-                            if $Flag.bits != 0 && self_ & $Flag.bits as $crate::__BitFlagsWidth ==
-                                $Flag.bits as $crate::__BitFlagsWidth {
+                            if $Flag.bits != 0 && self_ & $Flag.bits as u64 == $Flag.bits as u64 {
                                 if !first {
                                     try!(f.write_str(" | "));
                                 }
                                 first = false;
                                 try!(f.write_str(stringify!($Flag)));
                             }
                         )+
                         Ok(())
                     }
                 }
-                dummy::fmt(self.bits as $crate::__BitFlagsWidth, f)
+                dummy::fmt(self.bits as u64, f)
             }
         }
 
         #[allow(dead_code)]
         impl $BitFlags {
             /// Returns an empty set of flags.
             #[inline]
             pub fn empty() -> $BitFlags {
@@ -293,28 +280,28 @@ macro_rules! bitflags {
 
             /// Returns the set containing all flags.
             #[inline]
             pub fn all() -> $BitFlags {
                 // See above `dummy` module for why this approach is taken.
                 #[allow(dead_code)]
                 mod dummy {
                     pub struct $BitFlags {
-                        bits: $crate::__BitFlagsWidth,
+                        bits: u64,
                     }
                     mod real_flags {
                         use super::$BitFlags;
                         $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags {
-                            bits: super::super::$Flag.bits as $crate::__BitFlagsWidth
+                            bits: super::super::$Flag.bits as u64
                         };)+
                     }
                     $(const $Flag: $BitFlags = $BitFlags { bits: 0 };)+
 
                     #[inline]
-                    pub fn all() -> $crate::__BitFlagsWidth {
+                    pub fn all() -> u64 {
                         use self::real_flags::*;
                         $($Flag.bits)|+
                     }
                 }
                 $BitFlags { bits: dummy::all() as $T }
             }
 
             /// Returns the raw value of the flags currently stored.
@@ -377,26 +364,16 @@ macro_rules! bitflags {
                 self.bits &= !other.bits;
             }
 
             /// Toggles the specified flags in-place.
             #[inline]
             pub fn toggle(&mut self, other: $BitFlags) {
                 self.bits ^= other.bits;
             }
-
-            /// Inserts or removes the specified flags depending on the passed value.
-            #[inline]
-            pub fn set(&mut self, other: $BitFlags, value: bool) {
-                if value {
-                    self.insert(other);
-                } else {
-                    self.remove(other);
-                }
-            }
         }
 
         impl $crate::__core::ops::BitOr for $BitFlags {
             type Output = $BitFlags;
 
             /// Returns the union of the two sets of flags.
             #[inline]
             fn bitor(self, other: $BitFlags) -> $BitFlags {
@@ -689,25 +666,16 @@ mod tests {
         assert_eq!(e3, FlagA | FlagB);
 
         let mut m4 = AnotherSetOfFlags::empty();
         m4.toggle(AnotherSetOfFlags::empty());
         assert_eq!(m4, AnotherSetOfFlags::empty());
     }
 
     #[test]
-    fn test_set() {
-        let mut e1 = FlagA | FlagC;
-        e1.set(FlagB, true);
-        e1.set(FlagC, false);
-
-        assert_eq!(e1, FlagA | FlagB);
-    }
-
-    #[test]
     fn test_assignment_operators() {
         let mut m1 = Flags::empty();
         let e1 = FlagA | FlagC;
         // union
         m1 |= FlagA;
         assert_eq!(m1, FlagA);
         // intersection
         m1 &= e1;
deleted file mode 100644
--- a/third_party/rust/bitflags/tests/i128_bitflags.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-#![allow(dead_code, unused_imports)]
-#![cfg_attr(feature = "i128", feature(i128_type))]
-
-#[macro_use]
-extern crate bitflags;
-
-#[cfg(feature = "i128")]
-bitflags! {
-    /// baz
-    flags Flags128: u128 {
-        const A       = 0x0000_0000_0000_0000_0000_0000_0000_0001,
-        const B       = 0x0000_0000_0000_1000_0000_0000_0000_0000,
-        const C       = 0x8000_0000_0000_0000_0000_0000_0000_0000,
-        const ABC     = A.bits | B.bits | C.bits,
-    }
-}
-
-#[cfg(feature = "i128")]
-#[test]
-fn test_i128_bitflags() {
-    assert_eq!(ABC, A | B | C);
-    assert_eq!(A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
-    assert_eq!(B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
-    assert_eq!(C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
-    assert_eq!(ABC.bits, 0x8000_0000_0000_1000_0000_0000_0000_0001);
-    assert_eq!(format!("{:?}", A), "A");
-    assert_eq!(format!("{:?}", B), "B");
-    assert_eq!(format!("{:?}", C), "C");
-    assert_eq!(format!("{:?}", ABC), "A | B | C | ABC");
-}
--- a/third_party/rust/rayon-core/.cargo-checksum.json
+++ b/third_party/rust/rayon-core/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"19740ff7a9baf34f7e6c20292344c4afbb095b8df157ef977dd79c6155bcbf37","build.rs":"fa31cb198b772600d100a7c403ddedccef637d2e6b2da431fa7f02ca41307fc6","src/future/README.md":"c2371a6a7a6cba3ef2c12b4789d6cfc02c5925bca9bf0e15967c8c8e63b18a1b","src/future/mod.rs":"fc503a81b78786443613a3516c407eaeffb77808b7d249d3a629e34e05169e06","src/future/test.rs":"fd193f77134a235a42338b94e31b4dea76ac6c8f2a22e6a52735a8f6689de0fb","src/job.rs":"bc456ec252d0cd8878e96a5bf602997440957c6bc5ea59d049e4fe0a6bbfb2cd","src/join/mod.rs":"96ec2c8f4bda0e8f32881ff3c6f6b81623d4c2c58c845212f2793872a788bd26","src/join/test.rs":"d9abcdb857915ee9c863d2f7f877be7bc969f08661566df405257e9f403432bf","src/latch.rs":"37117e2bdfd657107c8c91805d43bbed0916fd3eba2336cd081000eafbb398f4","src/lib.rs":"c88b72f0c8811b3cc4815bdd59dfb21b58f6bfaf5c00dfe203a272814ad31586","src/log.rs":"1f4a3418177a188a4e1eb95c027851c38f5fa2dcb87e35e7f0b2c67b9f09f16f","src/registry.rs":"6e8f5329f40a74eeaddb711dfe34e47b6126c3d5920fcf7d8b66f1709efef2b2","src/scope/mod.rs":"0094812560dd1aabb1db17f1141641f6ff84fcbd068a8194eec0e0156a91faf8","src/scope/test.rs":"c6bbb63a07b9883b252cf1abe0eb5f7289bfe3bab35d7f2751b829521bcd71c0","src/sleep/README.md":"34a83cd8a0f84e58472af5c40744794139fbfe22a392f0dc6eb90cfdf9389119","src/sleep/mod.rs":"e88cfdf47f1b74318296a91928807c8e8a527f8aae2089da1fa7f8ae942773b4","src/spawn_async/mod.rs":"226b2042193382ba4fa59f7b88df96850f72970aee9e65cced083770d487118b","src/spawn_async/test.rs":"e7fe38cef25f79fe3ac7e5ee623f3db9354aa857839494b13160fc37f78b6954","src/test.rs":"a6b7e8aaddba6e864b6654616f14e0a62c10bdf5766c2dada8a2fd3fb85278ea","src/thread_pool/mod.rs":"095442c7446bd8f6c77f893559e68b0f1d842ff16b4e354e7967cdf0116850ad","src/thread_pool/test.rs":"71a6319752d5b88a7cecb11ba272bb05ed42bedc3bc84d5dbced836e3bd746b6","src/unwind.rs":"52a4b26d51bbcbac9e22776cdff8c6cadfe79f7fa20ed507bb987b168f9afe77","src/util.rs":"63ec7e1c75ea3871593d7fa5fc46689de7a2a86aa080b587880181dafd5e9838"},"package":"767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"0b0f43ae64596e3577a241d6e405706bb39b06c40c25c60922e28eb9478d8327","Cargo.toml.orig":"23d1969277dd451114d259082e0c4ecf1ee261c5d36efff071c5a8976b85fa6a","build.rs":"fa31cb198b772600d100a7c403ddedccef637d2e6b2da431fa7f02ca41307fc6","src/future/README.md":"c2371a6a7a6cba3ef2c12b4789d6cfc02c5925bca9bf0e15967c8c8e63b18a1b","src/future/mod.rs":"fc503a81b78786443613a3516c407eaeffb77808b7d249d3a629e34e05169e06","src/future/test.rs":"fd193f77134a235a42338b94e31b4dea76ac6c8f2a22e6a52735a8f6689de0fb","src/job.rs":"bc456ec252d0cd8878e96a5bf602997440957c6bc5ea59d049e4fe0a6bbfb2cd","src/join/mod.rs":"96ec2c8f4bda0e8f32881ff3c6f6b81623d4c2c58c845212f2793872a788bd26","src/join/test.rs":"d9abcdb857915ee9c863d2f7f877be7bc969f08661566df405257e9f403432bf","src/latch.rs":"37117e2bdfd657107c8c91805d43bbed0916fd3eba2336cd081000eafbb398f4","src/lib.rs":"c88b72f0c8811b3cc4815bdd59dfb21b58f6bfaf5c00dfe203a272814ad31586","src/log.rs":"1f4a3418177a188a4e1eb95c027851c38f5fa2dcb87e35e7f0b2c67b9f09f16f","src/registry.rs":"6e8f5329f40a74eeaddb711dfe34e47b6126c3d5920fcf7d8b66f1709efef2b2","src/scope/mod.rs":"0094812560dd1aabb1db17f1141641f6ff84fcbd068a8194eec0e0156a91faf8","src/scope/test.rs":"c6bbb63a07b9883b252cf1abe0eb5f7289bfe3bab35d7f2751b829521bcd71c0","src/sleep/README.md":"34a83cd8a0f84e58472af5c40744794139fbfe22a392f0dc6eb90cfdf9389119","src/sleep/mod.rs":"f5e5caf619a23da6534d69fff7beb7f4c361bd5b8d86e81e6326eab300e1507c","src/spawn_async/mod.rs":"226b2042193382ba4fa59f7b88df96850f72970aee9e65cced083770d487118b","src/spawn_async/test.rs":"e7fe38cef25f79fe3ac7e5ee623f3db9354aa857839494b13160fc37f78b6954","src/test.rs":"a6b7e8aaddba6e864b6654616f14e0a62c10bdf5766c2dada8a2fd3fb85278ea","src/thread_pool/mod.rs":"095442c7446bd8f6c77f893559e68b0f1d842ff16b4e354e7967cdf0116850ad","src/thread_pool/test.rs":"71a6319752d5b88a7cecb11ba272bb05ed42bedc3bc84d5dbced836e3bd746b6","src/unwind.rs":"52a4b26d51bbcbac9e22776cdff8c6cadfe79f7fa20ed507bb987b168f9afe77","src/util.rs":"63ec7e1c75ea3871593d7fa5fc46689de7a2a86aa080b587880181dafd5e9838"},"package":"bd1e76f8ee0322fbbeb0c43a07e1757fcf8ff06bb0ff92da017625882ddc04dd"}
\ No newline at end of file
--- a/third_party/rust/rayon-core/Cargo.toml
+++ b/third_party/rust/rayon-core/Cargo.toml
@@ -1,25 +1,45 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
 [package]
 name = "rayon-core"
-version = "1.0.0"
+version = "1.0.2"
 authors = ["Niko Matsakis <niko@alum.mit.edu>"]
+build = "build.rs"
+links = "rayon-core"
 description = "Core APIs for Rayon"
+documentation = "https://docs.rs/rayon/"
 license = "Apache-2.0/MIT"
 repository = "https://github.com/nikomatsakis/rayon"
-documentation = "https://docs.rs/rayon/"
-links = "rayon-core"
-build = "build.rs"
+[dependencies.lazy_static]
+version = "0.2.2"
+
+[dependencies.deque]
+version = "0.3.1"
+
+[dependencies.libc]
+version = "0.2.16"
 
-[dependencies]
-rand = "0.3"
-num_cpus = "1.2"
-deque = "0.3.1"
-libc = "0.2.16"
-lazy_static = "0.2.2"
-futures = { version = "0.1.7", optional = true }
+[dependencies.rand]
+version = "0.3"
+
+[dependencies.num_cpus]
+version = "1.2"
+
+[dependencies.futures]
+version = "0.1.7"
+optional = true
 
 [dev-dependencies]
 
 [features]
-# Unstable APIs that have not yet
-# proven their utility.
 unstable = ["futures"]
--- a/third_party/rust/rayon-core/src/sleep/mod.rs
+++ b/third_party/rust/rayon-core/src/sleep/mod.rs
@@ -65,16 +65,17 @@ impl Sleep {
         log!(DidNotFindWork {
             worker: worker_index,
             yields: yields,
         });
         if yields < ROUNDS_UNTIL_SLEEPY {
             thread::yield_now();
             yields + 1
         } else if yields == ROUNDS_UNTIL_SLEEPY {
+            thread::yield_now();
             if self.get_sleepy(worker_index) {
                 yields + 1
             } else {
                 yields
             }
         } else if yields < ROUNDS_UNTIL_ASLEEP {
             thread::yield_now();
             if self.still_sleepy(worker_index) {
--- a/third_party/rust/rayon/.cargo-checksum.json
+++ b/third_party/rust/rayon/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"27a47461f4d718958efb16375ae789d48f7d6dbb5c0f1745cd550cf574b41be7",".travis.yml":"b0310836f3e6b227536a934cc728b8e597caad05b76a72b07d53844b2f351035","Cargo.toml":"3bd77e82386fd042fca31381b46c14b90a61cd79b7a508fce7ab577467def17a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"319c3ee487d97e3f4aed43f15e3c0faff6d8a23f16d196100dabaeb8849b6068","RELEASES.md":"6532140e020052400aa6d98d45a1cc0a41c1ae2285876f0b815f1be8aaeb00a2","ci/highlander.sh":"68b1e5c3be188a4c503d0e6b12e8409459947f560dcf92ec0658b27e136d44f2","examples/README.md":"537e6fe9cf696fd4ada9c08bf31055ed6e366ed65668a523e7c5fde77f97c8d3","examples/cpu_monitor.rs":"5edb7b0f0a83492700ff2780b61893e2b69560b5feaad4239c7ad27f52b9554f","scripts/analyze.sh":"35214a036d8d0ead5400562cd72b131376849f65d63d04122c21886a57049934","src/collections/binary_heap.rs":"c9b77ba76e03f73ce192bdd9ff10e5bf1becbac51b229d2edcf215b360020c7a","src/collections/btree_map.rs":"e04e373c37266a65d880f8f7449aec4ae380de77e6e7705344e90ab45b81e336","src/collections/btree_set.rs":"1f2e75b0c1bd8fbf4405a57fb735fe071acb68b988fd58f1f3cd06e678ae4da4","src/collections/hash_map.rs":"c53e4157e07a21d49e011ab1fb3d80d54790059a81827ec8b6ead063438c4ecc","src/collections/hash_set.rs":"2341e7193a156030cc59f6b88984056ed31cef8bdaf36e76f2bebe7f29f1e954","src/collections/linked_list.rs":"675ee631db311a360424125e8b0d2fd6cf156b836d9874a7a06149fac82b51d5","src/collections/mod.rs":"24bbbe85c6e9c65ce7a3906595a68048bfe4c94c790563e1526920104dfb1906","src/collections/vec_deque.rs":"b152b6119ac543adfef92f852e3795322887cb5b252412991c685891f3152b20","src/delegate.rs":"fd2481d75da8fa55da9d8f45a1d30300ad4761ebdcdff41f13a50fce968119b5","src/iter/README.md":"a60607db06fd8da132df425372022a60492d5b5b9e814ecb110fc92b7bf4d27d","src/iter/chain.rs":"deaa35aee910a54e05885fa48eeb7100ab72ad88a970d1a797eaef1ffa2b766e","src/iter/collect/consumer.rs":"628d1f758395463aa754e83d20b82eeb545c765964d3d28c47fbdd5f53a337db","src/iter/collect/mod.rs":"49e1801670e3e29ad21489493dbed8e4cf2052fb98862491eae04b3748171702","src/iter/collect/test.rs":"3305b01a4f7526b89bda7c15578678849b512706baa9ef78fdd3ada7cefc2212","src/iter/enumerate.rs":"55f4a24186b109c4591b9568849aca42777092a9b736ad2896008c086041bccb","src/iter/filter.rs":"3257d2101632fcf54f023847875cee1d0f3f9f247f7f89f1d6b538d6d35fe619","src/iter/filter_map.rs":"a7c09cfdaad129c442510fcad22cda723baef8e691bca3d90e7065669d08996d","src/iter/find.rs":"f52f482947bde2717e9eb8163a8993fbaf19ddd561c3b320f878953e3ff18bbe","src/iter/find_first_last/mod.rs":"017d2ed50d02eee16ef6d5d434d8ec9f78ce4b56b6dd19316378efb839ede26c","src/iter/find_first_last/test.rs":"6b7e25af53bfee8361cb71dce561e50366087938bd8f40bb26129ed7a0f40a1b","src/iter/flat_map.rs":"bd21f6b9fe590a461ead3a6e9a78350ac95a85acc509f3e104d371902d5e4f18","src/iter/fold.rs":"bd7dbe33c3645f25fdc9cfb6b9c2dd5e6f2f837518dbe49fc83c71c2585f5fe5","src/iter/for_each.rs":"85f1f279ec9895c5db7fab0515fad621234466b2c9de29fb1de071cda9502de8","src/iter/from_par_iter.rs":"c0eb8bb8021ab3b0c7276971a48236b2ee1357f9f9204fd88e3d69650071ad17","src/iter/internal.rs":"ec976560ec6fbedfab53d20892c03a31149f75f723f1913054ef47879ed8d787","src/iter/len.rs":"f664fb9d5eb4dfebf78d3e38e14d97fa4753e8624734d4cb33cec21a2fd8bcd8","src/iter/map.rs":"917e6689123ec0500f488357bbea8c029aae3c56e678bbf54327868bc598c404","src/iter/mod.rs":"8096008f8c3428d7b9ffa7a45cf0f47f1f57bb0362ec0ef7b249c4f3dce7b250","src/iter/noop.rs":"11327d59d3574a735ba63832adeef6c763cd0a823ca3fca473b552b8d622b0c2","src/iter/product.rs":"3c8788c2874c8fd094e1e8f3e3a02cf86be76137a114377e6df27df9e93059d2","src/iter/reduce.rs":"99168b4d096741ecaa7aadbe61363b71e64d15cba2c51aaea9fd5fc63f3ae12e","src/iter/rev.rs":"2d8d93c3b60b145e06c24b75f39a48ea82e3df361fe8d7ac17a7b8fa685fe4ee","src/iter/skip.rs":"2ea784ddc47cc276d8a1821bd879327eee9bd08b1358e3b51805c8d6dc7c0d8a","src/iter/splitter.rs":"0b99b3bd64198d6eba83b3f28ce8b7a39774b156924ef84b65dd5a3e2c7cce11","src/iter/sum.rs":"a5cbac4d0b9e10e51fc61af77914eea4e028c5951c03ce218d46c77a53eb99d1","src/iter/take.rs":"dce16c333224e50b3fb649dd6a031d894f747999b89662d9577dc034383c411c","src/iter/test.rs":"eb21d71e47ead2aee9d19155c4b7377181dfd42e06674c8e7ad1199e25cf5ee0","src/iter/weight.rs":"d14dc82adb4fa6eef9f7b63ac50c6efca6accbf51877404baf28f3cf1ef55069","src/iter/zip.rs":"19759013d0df678c3574e232429ae6bbb87e7852e0cae41e9faefd1bb55cc4ea","src/lib.rs":"daa1401795f99a25a3a5e2a24f481df8ef31890dc3b05e976aa9df40d120c45b","src/option.rs":"eabeec0f142571a03a2b2efb96ab4754f49d86513041c742004229dd4e6a4769","src/prelude.rs":"3e3053e5c1751628f39d223038353232096a59bab9e4f53d557763082e786408","src/private.rs":"951f15fc1e9446cc47a7a932cdd9f858aa5df7da7fa070d196cd05de190e6952","src/range.rs":"ba28c99ae3ca57d4bfc133c2d33720bc57470eadfddfb485c42a0e66c088401d","src/result.rs":"0bcf5b2c9c71e0d6c22fdc69ed45c9876d4946d0376301c3d56ca2d935b5ced9","src/slice.rs":"c543a652f0bbf3392893d0305292ae35680da7f30c6abde0eb5564adaeb8aef3","src/str.rs":"99007c4174e63551c26396e61f76de08e72251943f5875f19a0ddb11a84e40fe","src/test.rs":"9df94a8995ce8ad22efc5ec5b805edd54560b179220b7c9e8f3e1a3d1af65b3e","src/vec.rs":"65c78a08e5138f45fb7851eb99e8d9e22f9d6283b2be9827bd99fb229385767a","tests/compile-fail-unstable/README.md":"53e7fb9aa143094c4ad8a4f3f954b125559d3f09e40d3cb4ab43dd06fc22e35b","tests/compile-fail-unstable/future_escape.rs":"f876eceb4c7ff26fd538c1e5d4cae6c424516563face45842cb2d0fa3bff5131","tests/compile-fail/README.md":"3a7477331161672cf83c67a2f38aeb989cb35a9bcb00c3ddf0cc123315f5cd00","tests/compile-fail/cannot_collect_filtermap_data.rs":"730a597fc86b79edf0921999f343d376c80f369e65f9109760be8b81037d4033","tests/compile-fail/cannot_zip_filtered_data.rs":"9271f21d2d1146e9e588936a15b7c54507b050039c04d902f09516ed1bcf2728","tests/compile-fail/cell_par_iter.rs":"3a20e18d488b0769f7b7679387cfe05f383b657dd07d155f3d4391676e36e857","tests/compile-fail/no_send_par_iter.rs":"95349df06cd40d1c8e94aa7b32cea240caa6500969d7d879576cb37b2dd91f19","tests/compile-fail/quicksort_race1.rs":"983cb334de39ef9fc6d3bdf40497d6cba9db50d6ea7932b0fbd628e8ba6f82df","tests/compile-fail/quicksort_race2.rs":"7e9d4477e6b34d075405e86fbb617c5e60ccf1729f81ef04907282106257fc64","tests/compile-fail/quicksort_race3.rs":"8ae1b5285acb75097358d8d424bf2c08a6044937edb57aa647ca521f30240d16","tests/compile-fail/rc_par_iter.rs":"2518f55a035db28c446faedfc07e2cede9d18f6bb5d53a69e0a533538b1b22c3","tests/compile-fail/rc_return.rs":"2db7865b885b6b51abfd52ec88e876347e7827865905489702f10ac4e485af7c","tests/compile-fail/rc_upvar.rs":"200c4583e17eb09547cabcf1b2f3ab02d2176f58e11f6ae9fff864ff9a6c9655","tests/compile-fail/scope_join_bad.rs":"2ad7d09f2273860a0e7c6d9b65356141339b96b189b7c8403aeccdcb1c0c9060","tests/run-fail-unstable/README.md":"448cd23346a2a71d581c5afbb61daa0349892ec5ad78d18730190127d2d11487","tests/run-fail/README.md":"2b9a7abb977671af7123478f9c4d2f596cd446869a7adaaf306656a2767bb80a","tests/run-fail/iter_panic.rs":"a897798038b89125d13883a7040341c0666bbde9f71a2bebed96ead8839bfaa3","tests/run-fail/simple_panic.rs":"b9d1cd0bedb6b22e4fd3df5ae948e804c1119d5e7a98e9eb4fdcf6281fd504ed","tests/run-pass-unstable/README.md":"2f996550ba5946cf6721b0ee6420f77555fc9a796ce0543fab7931b7a5e4ef5b","tests/run-pass/README.md":"324816facdb78da40a1539cdae8c4bc9d4d027451c167b5f087abc3239b199bf","tests/run-pass/double_init_fail.rs":"841735a15b819bf3ea5e50e758e0825575b00652897cb0fecf25d723a537f1b9","tests/run-pass/init_zero_threads.rs":"42ff55d2396a9feb0be67aaad18252a0a92f778b9f5e9564f35634488228e37c","tests/run-pass/named-threads.rs":"511a75feed739de04033efe4bb2986fd1549bd03a086db8e12ec3b9751d27771","tests/run-pass/scope_join.rs":"65894d7bfde3d2ad7f18a54dbc786bcd756e1d00ce4d7cef503b3c74938e06d7","tests/run-pass/stack_overflow_crash.rs":"a76489f74f2b9a308f3e56317e87d6566708b0b8c635ffec9a46305da4d48f77"},"package":"8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"27a47461f4d718958efb16375ae789d48f7d6dbb5c0f1745cd550cf574b41be7",".travis.yml":"b0310836f3e6b227536a934cc728b8e597caad05b76a72b07d53844b2f351035","Cargo.toml":"bd78801ad2eff379fe3be704ab207e10953ac4b0e6777e52bc434a1ed266e21c","Cargo.toml.orig":"21c374d0295643874bbcbd1395f97dcc14ea745e10f9dda4e65fcf9a1b77c5fb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0621878e61f0d0fda054bcbe02df75192c28bde1ecc8289cbd86aeba2dd72720","README.md":"319c3ee487d97e3f4aed43f15e3c0faff6d8a23f16d196100dabaeb8849b6068","RELEASES.md":"1a52e4b0228ae06f11af2fc3d4629fe025c2128a009a0a27b422271ff3c06f58","ci/highlander.sh":"68b1e5c3be188a4c503d0e6b12e8409459947f560dcf92ec0658b27e136d44f2","examples/README.md":"537e6fe9cf696fd4ada9c08bf31055ed6e366ed65668a523e7c5fde77f97c8d3","examples/cpu_monitor.rs":"5edb7b0f0a83492700ff2780b61893e2b69560b5feaad4239c7ad27f52b9554f","scripts/analyze.sh":"35214a036d8d0ead5400562cd72b131376849f65d63d04122c21886a57049934","src/collections/binary_heap.rs":"c9b77ba76e03f73ce192bdd9ff10e5bf1becbac51b229d2edcf215b360020c7a","src/collections/btree_map.rs":"e04e373c37266a65d880f8f7449aec4ae380de77e6e7705344e90ab45b81e336","src/collections/btree_set.rs":"1f2e75b0c1bd8fbf4405a57fb735fe071acb68b988fd58f1f3cd06e678ae4da4","src/collections/hash_map.rs":"c53e4157e07a21d49e011ab1fb3d80d54790059a81827ec8b6ead063438c4ecc","src/collections/hash_set.rs":"2341e7193a156030cc59f6b88984056ed31cef8bdaf36e76f2bebe7f29f1e954","src/collections/linked_list.rs":"675ee631db311a360424125e8b0d2fd6cf156b836d9874a7a06149fac82b51d5","src/collections/mod.rs":"24bbbe85c6e9c65ce7a3906595a68048bfe4c94c790563e1526920104dfb1906","src/collections/vec_deque.rs":"b152b6119ac543adfef92f852e3795322887cb5b252412991c685891f3152b20","src/delegate.rs":"fd2481d75da8fa55da9d8f45a1d30300ad4761ebdcdff41f13a50fce968119b5","src/iter/README.md":"a60607db06fd8da132df425372022a60492d5b5b9e814ecb110fc92b7bf4d27d","src/iter/chain.rs":"deaa35aee910a54e05885fa48eeb7100ab72ad88a970d1a797eaef1ffa2b766e","src/iter/collect/consumer.rs":"628d1f758395463aa754e83d20b82eeb545c765964d3d28c47fbdd5f53a337db","src/iter/collect/mod.rs":"49e1801670e3e29ad21489493dbed8e4cf2052fb98862491eae04b3748171702","src/iter/collect/test.rs":"3305b01a4f7526b89bda7c15578678849b512706baa9ef78fdd3ada7cefc2212","src/iter/enumerate.rs":"55f4a24186b109c4591b9568849aca42777092a9b736ad2896008c086041bccb","src/iter/filter.rs":"3257d2101632fcf54f023847875cee1d0f3f9f247f7f89f1d6b538d6d35fe619","src/iter/filter_map.rs":"a7c09cfdaad129c442510fcad22cda723baef8e691bca3d90e7065669d08996d","src/iter/find.rs":"f52f482947bde2717e9eb8163a8993fbaf19ddd561c3b320f878953e3ff18bbe","src/iter/find_first_last/mod.rs":"017d2ed50d02eee16ef6d5d434d8ec9f78ce4b56b6dd19316378efb839ede26c","src/iter/find_first_last/test.rs":"6b7e25af53bfee8361cb71dce561e50366087938bd8f40bb26129ed7a0f40a1b","src/iter/flat_map.rs":"bd21f6b9fe590a461ead3a6e9a78350ac95a85acc509f3e104d371902d5e4f18","src/iter/fold.rs":"bd7dbe33c3645f25fdc9cfb6b9c2dd5e6f2f837518dbe49fc83c71c2585f5fe5","src/iter/for_each.rs":"85f1f279ec9895c5db7fab0515fad621234466b2c9de29fb1de071cda9502de8","src/iter/from_par_iter.rs":"c0eb8bb8021ab3b0c7276971a48236b2ee1357f9f9204fd88e3d69650071ad17","src/iter/internal.rs":"ec976560ec6fbedfab53d20892c03a31149f75f723f1913054ef47879ed8d787","src/iter/len.rs":"f664fb9d5eb4dfebf78d3e38e14d97fa4753e8624734d4cb33cec21a2fd8bcd8","src/iter/map.rs":"917e6689123ec0500f488357bbea8c029aae3c56e678bbf54327868bc598c404","src/iter/mod.rs":"8096008f8c3428d7b9ffa7a45cf0f47f1f57bb0362ec0ef7b249c4f3dce7b250","src/iter/noop.rs":"11327d59d3574a735ba63832adeef6c763cd0a823ca3fca473b552b8d622b0c2","src/iter/product.rs":"3c8788c2874c8fd094e1e8f3e3a02cf86be76137a114377e6df27df9e93059d2","src/iter/reduce.rs":"99168b4d096741ecaa7aadbe61363b71e64d15cba2c51aaea9fd5fc63f3ae12e","src/iter/rev.rs":"2d8d93c3b60b145e06c24b75f39a48ea82e3df361fe8d7ac17a7b8fa685fe4ee","src/iter/skip.rs":"2ea784ddc47cc276d8a1821bd879327eee9bd08b1358e3b51805c8d6dc7c0d8a","src/iter/splitter.rs":"0b99b3bd64198d6eba83b3f28ce8b7a39774b156924ef84b65dd5a3e2c7cce11","src/iter/sum.rs":"a5cbac4d0b9e10e51fc61af77914eea4e028c5951c03ce218d46c77a53eb99d1","src/iter/take.rs":"dce16c333224e50b3fb649dd6a031d894f747999b89662d9577dc034383c411c","src/iter/test.rs":"eb21d71e47ead2aee9d19155c4b7377181dfd42e06674c8e7ad1199e25cf5ee0","src/iter/weight.rs":"d14dc82adb4fa6eef9f7b63ac50c6efca6accbf51877404baf28f3cf1ef55069","src/iter/zip.rs":"19759013d0df678c3574e232429ae6bbb87e7852e0cae41e9faefd1bb55cc4ea","src/lib.rs":"daa1401795f99a25a3a5e2a24f481df8ef31890dc3b05e976aa9df40d120c45b","src/option.rs":"eabeec0f142571a03a2b2efb96ab4754f49d86513041c742004229dd4e6a4769","src/prelude.rs":"3e3053e5c1751628f39d223038353232096a59bab9e4f53d557763082e786408","src/private.rs":"951f15fc1e9446cc47a7a932cdd9f858aa5df7da7fa070d196cd05de190e6952","src/range.rs":"ba28c99ae3ca57d4bfc133c2d33720bc57470eadfddfb485c42a0e66c088401d","src/result.rs":"0bcf5b2c9c71e0d6c22fdc69ed45c9876d4946d0376301c3d56ca2d935b5ced9","src/slice.rs":"c543a652f0bbf3392893d0305292ae35680da7f30c6abde0eb5564adaeb8aef3","src/str.rs":"99007c4174e63551c26396e61f76de08e72251943f5875f19a0ddb11a84e40fe","src/test.rs":"9df94a8995ce8ad22efc5ec5b805edd54560b179220b7c9e8f3e1a3d1af65b3e","src/vec.rs":"65c78a08e5138f45fb7851eb99e8d9e22f9d6283b2be9827bd99fb229385767a","tests/compile-fail-unstable/README.md":"53e7fb9aa143094c4ad8a4f3f954b125559d3f09e40d3cb4ab43dd06fc22e35b","tests/compile-fail-unstable/future_escape.rs":"f876eceb4c7ff26fd538c1e5d4cae6c424516563face45842cb2d0fa3bff5131","tests/compile-fail/README.md":"3a7477331161672cf83c67a2f38aeb989cb35a9bcb00c3ddf0cc123315f5cd00","tests/compile-fail/cannot_collect_filtermap_data.rs":"730a597fc86b79edf0921999f343d376c80f369e65f9109760be8b81037d4033","tests/compile-fail/cannot_zip_filtered_data.rs":"9271f21d2d1146e9e588936a15b7c54507b050039c04d902f09516ed1bcf2728","tests/compile-fail/cell_par_iter.rs":"3a20e18d488b0769f7b7679387cfe05f383b657dd07d155f3d4391676e36e857","tests/compile-fail/no_send_par_iter.rs":"95349df06cd40d1c8e94aa7b32cea240caa6500969d7d879576cb37b2dd91f19","tests/compile-fail/quicksort_race1.rs":"983cb334de39ef9fc6d3bdf40497d6cba9db50d6ea7932b0fbd628e8ba6f82df","tests/compile-fail/quicksort_race2.rs":"7e9d4477e6b34d075405e86fbb617c5e60ccf1729f81ef04907282106257fc64","tests/compile-fail/quicksort_race3.rs":"8ae1b5285acb75097358d8d424bf2c08a6044937edb57aa647ca521f30240d16","tests/compile-fail/rc_par_iter.rs":"2518f55a035db28c446faedfc07e2cede9d18f6bb5d53a69e0a533538b1b22c3","tests/compile-fail/rc_return.rs":"2db7865b885b6b51abfd52ec88e876347e7827865905489702f10ac4e485af7c","tests/compile-fail/rc_upvar.rs":"200c4583e17eb09547cabcf1b2f3ab02d2176f58e11f6ae9fff864ff9a6c9655","tests/compile-fail/scope_join_bad.rs":"2ad7d09f2273860a0e7c6d9b65356141339b96b189b7c8403aeccdcb1c0c9060","tests/run-fail-unstable/README.md":"448cd23346a2a71d581c5afbb61daa0349892ec5ad78d18730190127d2d11487","tests/run-fail/README.md":"2b9a7abb977671af7123478f9c4d2f596cd446869a7adaaf306656a2767bb80a","tests/run-fail/iter_panic.rs":"a897798038b89125d13883a7040341c0666bbde9f71a2bebed96ead8839bfaa3","tests/run-fail/simple_panic.rs":"b9d1cd0bedb6b22e4fd3df5ae948e804c1119d5e7a98e9eb4fdcf6281fd504ed","tests/run-pass-unstable/README.md":"2f996550ba5946cf6721b0ee6420f77555fc9a796ce0543fab7931b7a5e4ef5b","tests/run-pass/README.md":"324816facdb78da40a1539cdae8c4bc9d4d027451c167b5f087abc3239b199bf","tests/run-pass/double_init_fail.rs":"841735a15b819bf3ea5e50e758e0825575b00652897cb0fecf25d723a537f1b9","tests/run-pass/init_zero_threads.rs":"42ff55d2396a9feb0be67aaad18252a0a92f778b9f5e9564f35634488228e37c","tests/run-pass/named-threads.rs":"511a75feed739de04033efe4bb2986fd1549bd03a086db8e12ec3b9751d27771","tests/run-pass/scope_join.rs":"65894d7bfde3d2ad7f18a54dbc786bcd756e1d00ce4d7cef503b3c74938e06d7","tests/run-pass/stack_overflow_crash.rs":"a76489f74f2b9a308f3e56317e87d6566708b0b8c635ffec9a46305da4d48f77"},"package":"a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"}
\ No newline at end of file
--- a/third_party/rust/rayon/Cargo.toml
+++ b/third_party/rust/rayon/Cargo.toml
@@ -1,27 +1,39 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
 [package]
 name = "rayon"
-version = "0.7.0"
+version = "0.7.1"
 authors = ["Niko Matsakis <niko@alum.mit.edu>"]
 description = "Simple work-stealing parallelism for Rust"
+documentation = "https://docs.rs/rayon/"
 license = "Apache-2.0/MIT"
 repository = "https://github.com/nikomatsakis/rayon"
-documentation = "https://docs.rs/rayon/"
+[dependencies.rayon-core]
+version = "1.0.2"
+[dev-dependencies.rustc-serialize]
+version = "0.3"
 
-[workspace]
-members = ["rayon-demo", "rayon-core"]
-exclude = ["ci"]
+[dev-dependencies.futures]
+version = "0.1.7"
 
-[dependencies]
-rayon-core = { version = "1.0", path = "rayon-core" }
+[dev-dependencies.docopt]
+version = "0.7"
 
-[dev-dependencies]
-compiletest_rs = "0.2.1"
-docopt = "0.7"
-futures = "0.1.7"
-rand = "0.3"
-rustc-serialize = "0.3"
+[dev-dependencies.rand]
+version = "0.3"
+
+[dev-dependencies.compiletest_rs]
+version = "0.2.1"
 
 [features]
-# Unstable APIs that have not yet
-# proven their utility.
 unstable = ["rayon-core/unstable"]
--- a/third_party/rust/rayon/RELEASES.md
+++ b/third_party/rust/rayon/RELEASES.md
@@ -1,8 +1,14 @@
+# Release rayon 0.7.1 / rayon-core 1.0.2
+
+This release is a targeted performance fix for #343, an issue where
+rayon threads could sometimes enter into a spin loop where they would
+be unable to make progress until they are pre-empted.
+
 # Release rayon 0.7 / rayon-core 1.0
 
 This release marks the first step towards Rayon 1.0. **For best
 performance, it is important that all Rayon users update to at least
 Rayon 0.7.** This is because, as of Rayon 0.7, we have taken steps to
 ensure that, no matter how many versions of rayon are actively in use,
 there will only be a single global scheduler. This is achieved via the
 `rayon-core` crate, which is being released at version 1.0, and which
--- a/third_party/rust/unicode-bidi/.cargo-checksum.json
+++ b/third_party/rust/unicode-bidi/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c4efd1043636b9b8f207ead7488fca41f56871884df3c1f51bafdd80daa60f24",".rustfmt.toml":"4587a30e695dc4afdd3b5d33370cf712c90a716de06ab0c5a2c023b0f269ab1a",".travis.yml":"e340419604a35e795fc3afdab237eb0ea3a31e71c98fb98fa88626d61b8a50f7","AUTHORS":"1ff3a7c8519b29544bb28ba9b1e7502df0cb764051fb9a1172e60006aa2b8dcc","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.toml":"2da98c00ffb4e0f2977eefab077329e9b544cde3bb495432d4bb933b558c5b59","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"e764abd9a6abbe9517dd9dedc003dd64594351282437a509fec9362ef136686d","benches/udhr.rs":"a4ada9ef6953e25d794ea8338356a8717d0f8ef32997cf5ee6a4e3db9d6eb369","benches/udhr_data/README.md":"103dd98f2777082f73dd90ce441245370169a6e889b329da81ee4b9c236c0e05","src/char_data/mod.rs":"3ae73b97dfbcea927a0dde160a8e328e550d270ef82bfc3137b8bfba5d13174c","src/char_data/tables.rs":"3742ed00360d3955b10ba690b1446e69ddf04f2cee13e86dd185ba6641bc6198","src/deprecated.rs":"ce1b62ac47d0d7ea547a1e03d17cd86b6b850e4e095642ba2e9c29130f13fa72","src/explicit.rs":"9ebe900dd42cba45de5348d52d60118fe880ed154b63b388536acb67e045bd7f","src/format_chars.rs":"ce14652d83a2227df31152cbabff30585b3ab2890ee290da8c46950c03969dc0","src/implicit.rs":"e28f215c821b601216872858c81c654c1812c5ce676d59e23eb2a7981bc2cadf","src/level.rs":"b8739d4dd84d9270140047972167d9e72db8637c769228eec17d12e07c5ab55f","src/lib.rs":"683409b531874e752b9233c6cb1650c14db7305030ce9c5aed803bce3af2dcb1","src/prepare.rs":"3d48eabc78cce98ca23957e3d24da817aad4fcd2fb8311d355be1858a4dead72","tests/conformance_tests.rs":"9f17d470806704faedac83ec4c4b11cb40a548b56f17dfa623d91a673b227f70","tools/generate.py":"12f94bdf2226f306d993fe2a0fa623b8dc9b1db1ac038a17ab44892ccdc8feeb"},"package":"c44d4e7ce691e2538b886bf33669fd6da1653a12d741b9390f351955c0949c03"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"ca9e613b65aadd1e89ff6bc5f76a1cd7989ca7441b4debfe1bde8c35cc165b59",".travis.yml":"5c3f9b92ab6ca79a98400b8c344f3a06fcc096b5df6f49fbae1a83dceb540170","AUTHORS":"6029da5a270f7047db642cfdaa521acdfd93dcae9f9cd02dc1bd43dfa526fc18","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.toml":"4b649e28df32ff0d08dd5ab0dfffb62d96f2f81e85370f2112ecd4d7f800910a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"e764abd9a6abbe9517dd9dedc003dd64594351282437a509fec9362ef136686d","src/lib.rs":"ef549431c0da99908df0a91deaee977d658c54449ed4abe935d3b0ef01c0eb51","src/tables.rs":"a2bb982b051a0ce7b85ade1f755c5b89e7f0415cfa1cbb62beb118d7b29da587","tools/generate.py":"a7b4a0c097bea5e0c626a6d33cb862bf4c542e36ac837b99455535c4ab83da6d"},"package":"d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032"}
\ No newline at end of file
--- a/third_party/rust/unicode-bidi/.gitignore
+++ b/third_party/rust/unicode-bidi/.gitignore
@@ -1,3 +1,4 @@
 Cargo.lock
-/data/
-/target/
+target
+src/ReadMe.txt
+*.txt
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/.rustfmt.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-array_layout = "Block"
-array_width = 80
-fn_args_layout = "Block"
-fn_brace_style = "SameLineWhere"
-fn_call_style = "Block"
-generics_indent = "Block"
--- a/third_party/rust/unicode-bidi/.travis.yml
+++ b/third_party/rust/unicode-bidi/.travis.yml
@@ -1,24 +1,9 @@
 sudo: false
 language: rust
-
 rust:
   - nightly
   - beta
   - stable
-  - 1.15.0
-
-matrix:
-  fast_finish: true
 
 notifications:
   webhooks: http://build.servo.org:54856/travis
-
-before_script:
-    - pip install git+https://github.com/euclio/travis-cargo@kcov --user && export PATH=$HOME/.local/bin:$PATH
-
-script:
-  - cargo build --verbose
-  - cargo test  --verbose
-  - cargo test  --verbose --features with_serde
-  - cargo doc   --verbose --no-deps
-  - travis-cargo bench
--- a/third_party/rust/unicode-bidi/AUTHORS
+++ b/third_party/rust/unicode-bidi/AUTHORS
@@ -1,4 +1,3 @@
 This software was written by the following people:
 
 Matt Brubeck <mbrubeck@limpet.net>
-Behnam Esfahbod <behnam@zwnj.org>
--- a/third_party/rust/unicode-bidi/Cargo.toml
+++ b/third_party/rust/unicode-bidi/Cargo.toml
@@ -1,25 +1,17 @@
 [package]
 name = "unicode-bidi"
-version = "0.3.1"
+version = "0.2.5"
 authors = ["The Servo Project Developers"]
 license = "MIT / Apache-2.0"
 description = "Implementation of the Unicode Bidirectional Algorithm"
 repository = "https://github.com/servo/unicode-bidi"
 documentation = "http://doc.servo.org/unicode_bidi/"
 keywords = ["rtl", "unicode", "text", "layout", "bidi"]
 
 exclude = ["*.txt"]
 
 [lib]
 name = "unicode_bidi"
 
 [dependencies]
 matches = "0.1"
-serde = {version = ">=0.8, <2.0", optional = true}
-serde_test = {version = ">=0.8, <2.0", optional = true}
-serde_derive = {version = ">=0.8, <2.0", optional = true}
-
-[features]
-default = []
-unstable = []  # Use in benches/
-with_serde = ["serde", "serde_test", "serde_derive"]
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/benches/udhr.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 The html5ever Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(all(test, feature = "unstable"))]
-#![feature(test)]
-
-extern crate test;
-extern crate unicode_bidi;
-
-use test::Bencher;
-
-use unicode_bidi::BidiInfo;
-
-const LTR_TEXTS: &[&str] = &[
-    include_str!("udhr_data/ltr/udhr_acu_1.txt"),
-    include_str!("udhr_data/ltr/udhr_auc.txt"),
-    include_str!("udhr_data/ltr/udhr_knc.txt"),
-    include_str!("udhr_data/ltr/udhr_krl.txt"),
-    include_str!("udhr_data/ltr/udhr_kwi.txt"),
-    include_str!("udhr_data/ltr/udhr_lot.txt"),
-    include_str!("udhr_data/ltr/udhr_piu.txt"),
-    include_str!("udhr_data/ltr/udhr_qug.txt"),
-    include_str!("udhr_data/ltr/udhr_snn.txt"),
-    include_str!("udhr_data/ltr/udhr_tiv.txt"),
-];
-
-const BIDI_TEXTS: &[&str] = &[
-    include_str!("udhr_data/bidi/udhr_aii.txt"),
-    include_str!("udhr_data/bidi/udhr_arb.txt"),
-    include_str!("udhr_data/bidi/udhr_mly_arab.txt"),
-    include_str!("udhr_data/bidi/udhr_pes_1.txt"),
-    include_str!("udhr_data/bidi/udhr_skr.txt"),
-    include_str!("udhr_data/bidi/udhr_urd.txt"),
-    include_str!("udhr_data/bidi/udhr_eng.txt"),
-    include_str!("udhr_data/bidi/udhr_mly_latn.txt"),
-    include_str!("udhr_data/bidi/udhr_pes_2.txt"),
-    include_str!("udhr_data/bidi/udhr_uig_arab.txt"),
-    include_str!("udhr_data/bidi/udhr_urd_2.txt"),
-    include_str!("udhr_data/bidi/udhr_heb.txt"),
-    include_str!("udhr_data/bidi/udhr_pbu.txt"),
-    include_str!("udhr_data/bidi/udhr_pnb.txt"),
-    include_str!("udhr_data/bidi/udhr_uig_latn.txt"),
-    include_str!("udhr_data/bidi/udhr_ydd.txt"),
-];
-
-#[bench]
-fn bench_bidi_info_new_for_ltr_texts(b: &mut Bencher) {
-    b.iter(
-        || for text in LTR_TEXTS {
-            BidiInfo::new(text, None);
-        },
-    );
-}
-
-#[bench]
-fn bench_bidi_info_new_for_bidi_texts(b: &mut Bencher) {
-    b.iter(
-        || for text in BIDI_TEXTS {
-            BidiInfo::new(text, None);
-        },
-    );
-}
-
-#[bench]
-fn bench_bidi_info_new_and_reordered_for_ltr_texts(b: &mut Bencher) {
-    b.iter(
-        || for text in LTR_TEXTS {
-            let bidi_info = BidiInfo::new(text, None);
-            let para = &bidi_info.paragraphs[0];
-            let line = para.range.clone();
-            bidi_info.reordered_levels(para, line);
-        },
-    );
-}
-
-#[bench]
-fn bench_bidi_info_new_and_reordered_for_bidi_texts(b: &mut Bencher) {
-    b.iter(
-        || for text in BIDI_TEXTS {
-            let bidi_info = BidiInfo::new(text, None);
-            let para = &bidi_info.paragraphs[0];
-            let line = para.range.clone();
-            bidi_info.reordered_levels(para, line);
-        },
-    );
-}
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/benches/udhr_data/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# A collection of UDHR in Unicode text files
-
-Source: http://unicode.org/udhr/
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/char_data/mod.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2015 The Servo Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Accessor for `Bidi_Class` property from Unicode Character Database (UCD)
-
-mod tables;
-
-pub use self::tables::{BidiClass, UNICODE_VERSION};
-
-use std::cmp::Ordering::{Equal, Less, Greater};
-use std::char;
-
-use self::tables::bidi_class_table;
-use BidiClass::*;
-
-/// Find the BidiClass of a single char.
-pub fn bidi_class(c: char) -> BidiClass {
-    bsearch_range_value_table(c, bidi_class_table)
-}
-
-pub fn is_rtl(bidi_class: BidiClass) -> bool {
-    match bidi_class {
-        RLE | RLO | RLI => true,
-        _ => false,
-    }
-}
-
-fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
-    match r.binary_search_by(
-        |&(lo, hi, _)| if lo <= c && c <= hi {
-            Equal
-        } else if hi < c {
-            Less
-        } else {
-            Greater
-        },
-    ) {
-        Ok(idx) => {
-            let (_, _, cat) = r[idx];
-            cat
-        }
-        // UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
-        // for Bidi_Class have the value Left_To_Right (L)."
-        Err(_) => L,
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_bidi_class() {
-        for (input, expected) in
-            vec![
-                (0x0000, BN),
-                (0x0040, ON),
-                (0x0041, L),
-                (0x0062, L),
-                (0x007F, BN),
-
-                // Hebrew
-                (0x0590, R),
-                (0x05D0, R),
-                (0x05D1, R),
-                (0x05FF, R),
-
-                // Arabic
-                (0x0600, AN),
-                (0x0627, AL),
-                (0x07BF, AL),
-
-                // Default R + Arabic Extras
-                (0x07C0, R),
-                (0x085F, R),
-                (0x0860, R),
-                (0x089F, R),
-                (0x08A0, AL),
-                (0x089F, R),
-                (0x08FF, NSM),
-
-                // Default ET
-                (0x20A0, ET),
-                (0x20CF, ET),
-
-                // Arabic Presentation Forms
-                (0xFB1D, R),
-                (0xFB4F, R),
-                (0xFB50, AL),
-                (0xFDCF, AL),
-                (0xFDF0, AL),
-                (0xFDFF, AL),
-                (0xFE70, AL),
-                (0xFEFE, AL),
-                (0xFEFF, BN),
-
-                // Default AL + R
-                (0x10800, R),
-                (0x10FFF, R),
-                (0x1E800, R),
-                (0x1EDFF, R),
-                (0x1EE00, AL),
-                (0x1EEFF, AL),
-                (0x1EF00, R),
-                (0x1EFFF, R),
-            ] {
-            assert_eq!(bidi_class(char::from_u32(input).unwrap()), expected);
-        }
-    }
-}
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/char_data/tables.rs
+++ /dev/null
@@ -1,452 +0,0 @@
-// NOTE:
-// The following code was generated by "tools/generate.py". do not edit directly
-
-#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
-#![cfg_attr(rustfmt, rustfmt_skip)]
-
-/// The [Unicode version](http://www.unicode.org/versions/) of data
-pub const UNICODE_VERSION: (u64, u64, u64) = (9, 0, 0);
-
-#[allow(non_camel_case_types)]
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-/// Represents values of the Unicode character property
-/// [Bidi_Class](http://www.unicode.org/reports/tr44/#Bidi_Class), also
-/// known as the *bidirectional character type*.
-///
-/// * http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
-/// * http://www.unicode.org/reports/tr44/#Bidi_Class_Values
-pub enum BidiClass {
-    AL,
-    AN,
-    B,
-    BN,
-    CS,
-    EN,
-    ES,
-    ET,
-    FSI,
-    L,
-    LRE,
-    LRI,
-    LRO,
-    NSM,
-    ON,
-    PDF,
-    PDI,
-    R,
-    RLE,
-    RLI,
-    RLO,
-    S,
-    WS,
-}
-
-use self::BidiClass::*;
-pub const bidi_class_table: &'static [(char, char, BidiClass)] = &[
-    ('\u{0}', '\u{8}', BN), ('\u{9}', '\u{9}', S), ('\u{a}', '\u{a}', B), ('\u{b}', '\u{b}', S),
-    ('\u{c}', '\u{c}', WS), ('\u{d}', '\u{d}', B), ('\u{e}', '\u{1b}', BN), ('\u{1c}', '\u{1e}', B),
-    ('\u{1f}', '\u{1f}', S), ('\u{20}', '\u{20}', WS), ('\u{21}', '\u{22}', ON), ('\u{23}',
-    '\u{25}', ET), ('\u{26}', '\u{2a}', ON), ('\u{2b}', '\u{2b}', ES), ('\u{2c}', '\u{2c}', CS),
-    ('\u{2d}', '\u{2d}', ES), ('\u{2e}', '\u{2f}', CS), ('\u{30}', '\u{39}', EN), ('\u{3a}',
-    '\u{3a}', CS), ('\u{3b}', '\u{40}', ON), ('\u{41}', '\u{5a}', L), ('\u{5b}', '\u{60}', ON),
-    ('\u{61}', '\u{7a}', L), ('\u{7b}', '\u{7e}', ON), ('\u{7f}', '\u{84}', BN), ('\u{85}',
-    '\u{85}', B), ('\u{86}', '\u{9f}', BN), ('\u{a0}', '\u{a0}', CS), ('\u{a1}', '\u{a1}', ON),
-    ('\u{a2}', '\u{a5}', ET), ('\u{a6}', '\u{a9}', ON), ('\u{aa}', '\u{aa}', L), ('\u{ab}',
-    '\u{ac}', ON), ('\u{ad}', '\u{ad}', BN), ('\u{ae}', '\u{af}', ON), ('\u{b0}', '\u{b1}', ET),
-    ('\u{b2}', '\u{b3}', EN), ('\u{b4}', '\u{b4}', ON), ('\u{b5}', '\u{b5}', L), ('\u{b6}',
-    '\u{b8}', ON), ('\u{b9}', '\u{b9}', EN), ('\u{ba}', '\u{ba}', L), ('\u{bb}', '\u{bf}', ON),
-    ('\u{c0}', '\u{d6}', L), ('\u{d7}', '\u{d7}', ON), ('\u{d8}', '\u{f6}', L), ('\u{f7}', '\u{f7}',
-    ON), ('\u{f8}', '\u{2b8}', L), ('\u{2b9}', '\u{2ba}', ON), ('\u{2bb}', '\u{2c1}', L),
-    ('\u{2c2}', '\u{2cf}', ON), ('\u{2d0}', '\u{2d1}', L), ('\u{2d2}', '\u{2df}', ON), ('\u{2e0}',
-    '\u{2e4}', L), ('\u{2e5}', '\u{2ed}', ON), ('\u{2ee}', '\u{2ee}', L), ('\u{2ef}', '\u{2ff}',
-    ON), ('\u{300}', '\u{36f}', NSM), ('\u{370}', '\u{373}', L), ('\u{374}', '\u{375}', ON),
-    ('\u{376}', '\u{377}', L), ('\u{37a}', '\u{37d}', L), ('\u{37e}', '\u{37e}', ON), ('\u{37f}',
-    '\u{37f}', L), ('\u{384}', '\u{385}', ON), ('\u{386}', '\u{386}', L), ('\u{387}', '\u{387}',
-    ON), ('\u{388}', '\u{38a}', L), ('\u{38c}', '\u{38c}', L), ('\u{38e}', '\u{3a1}', L),
-    ('\u{3a3}', '\u{3f5}', L), ('\u{3f6}', '\u{3f6}', ON), ('\u{3f7}', '\u{482}', L), ('\u{483}',
-    '\u{489}', NSM), ('\u{48a}', '\u{52f}', L), ('\u{531}', '\u{556}', L), ('\u{559}', '\u{55f}',
-    L), ('\u{561}', '\u{587}', L), ('\u{589}', '\u{589}', L), ('\u{58a}', '\u{58a}', ON),
-    ('\u{58d}', '\u{58e}', ON), ('\u{58f}', '\u{58f}', ET), ('\u{590}', '\u{590}', R), ('\u{591}',
-    '\u{5bd}', NSM), ('\u{5be}', '\u{5be}', R), ('\u{5bf}', '\u{5bf}', NSM), ('\u{5c0}', '\u{5c0}',
-    R), ('\u{5c1}', '\u{5c2}', NSM), ('\u{5c3}', '\u{5c3}', R), ('\u{5c4}', '\u{5c5}', NSM),
-    ('\u{5c6}', '\u{5c6}', R), ('\u{5c7}', '\u{5c7}', NSM), ('\u{5c8}', '\u{5ff}', R), ('\u{600}',
-    '\u{605}', AN), ('\u{606}', '\u{607}', ON), ('\u{608}', '\u{608}', AL), ('\u{609}', '\u{60a}',
-    ET), ('\u{60b}', '\u{60b}', AL), ('\u{60c}', '\u{60c}', CS), ('\u{60d}', '\u{60d}', AL),
-    ('\u{60e}', '\u{60f}', ON), ('\u{610}', '\u{61a}', NSM), ('\u{61b}', '\u{64a}', AL), ('\u{64b}',
-    '\u{65f}', NSM), ('\u{660}', '\u{669}', AN), ('\u{66a}', '\u{66a}', ET), ('\u{66b}', '\u{66c}',
-    AN), ('\u{66d}', '\u{66f}', AL), ('\u{670}', '\u{670}', NSM), ('\u{671}', '\u{6d5}', AL),
-    ('\u{6d6}', '\u{6dc}', NSM), ('\u{6dd}', '\u{6dd}', AN), ('\u{6de}', '\u{6de}', ON), ('\u{6df}',
-    '\u{6e4}', NSM), ('\u{6e5}', '\u{6e6}', AL), ('\u{6e7}', '\u{6e8}', NSM), ('\u{6e9}', '\u{6e9}',
-    ON), ('\u{6ea}', '\u{6ed}', NSM), ('\u{6ee}', '\u{6ef}', AL), ('\u{6f0}', '\u{6f9}', EN),
-    ('\u{6fa}', '\u{710}', AL), ('\u{711}', '\u{711}', NSM), ('\u{712}', '\u{72f}', AL), ('\u{730}',
-    '\u{74a}', NSM), ('\u{74b}', '\u{7a5}', AL), ('\u{7a6}', '\u{7b0}', NSM), ('\u{7b1}', '\u{7bf}',
-    AL), ('\u{7c0}', '\u{7ea}', R), ('\u{7eb}', '\u{7f3}', NSM), ('\u{7f4}', '\u{7f5}', R),
-    ('\u{7f6}', '\u{7f9}', ON), ('\u{7fa}', '\u{815}', R), ('\u{816}', '\u{819}', NSM), ('\u{81a}',
-    '\u{81a}', R), ('\u{81b}', '\u{823}', NSM), ('\u{824}', '\u{824}', R), ('\u{825}', '\u{827}',
-    NSM), ('\u{828}', '\u{828}', R), ('\u{829}', '\u{82d}', NSM), ('\u{82e}', '\u{858}', R),
-    ('\u{859}', '\u{85b}', NSM), ('\u{85c}', '\u{89f}', R), ('\u{8a0}', '\u{8d3}', AL), ('\u{8d4}',
-    '\u{8e1}', NSM), ('\u{8e2}', '\u{8e2}', AN), ('\u{8e3}', '\u{902}', NSM), ('\u{903}', '\u{939}',
-    L), ('\u{93a}', '\u{93a}', NSM), ('\u{93b}', '\u{93b}', L), ('\u{93c}', '\u{93c}', NSM),
-    ('\u{93d}', '\u{940}', L), ('\u{941}', '\u{948}', NSM), ('\u{949}', '\u{94c}', L), ('\u{94d}',
-    '\u{94d}', NSM), ('\u{94e}', '\u{950}', L), ('\u{951}', '\u{957}', NSM), ('\u{958}', '\u{961}',
-    L), ('\u{962}', '\u{963}', NSM), ('\u{964}', '\u{980}', L), ('\u{981}', '\u{981}', NSM),
-    ('\u{982}', '\u{983}', L), ('\u{985}', '\u{98c}', L), ('\u{98f}', '\u{990}', L), ('\u{993}',
-    '\u{9a8}', L), ('\u{9aa}', '\u{9b0}', L), ('\u{9b2}', '\u{9b2}', L), ('\u{9b6}', '\u{9b9}', L),
-    ('\u{9bc}', '\u{9bc}', NSM), ('\u{9bd}', '\u{9c0}', L), ('\u{9c1}', '\u{9c4}', NSM), ('\u{9c7}',
-    '\u{9c8}', L), ('\u{9cb}', '\u{9cc}', L), ('\u{9cd}', '\u{9cd}', NSM), ('\u{9ce}', '\u{9ce}',
-    L), ('\u{9d7}', '\u{9d7}', L), ('\u{9dc}', '\u{9dd}', L), ('\u{9df}', '\u{9e1}', L), ('\u{9e2}',
-    '\u{9e3}', NSM), ('\u{9e6}', '\u{9f1}', L), ('\u{9f2}', '\u{9f3}', ET), ('\u{9f4}', '\u{9fa}',
-    L), ('\u{9fb}', '\u{9fb}', ET), ('\u{a01}', '\u{a02}', NSM), ('\u{a03}', '\u{a03}', L),
-    ('\u{a05}', '\u{a0a}', L), ('\u{a0f}', '\u{a10}', L), ('\u{a13}', '\u{a28}', L), ('\u{a2a}',
-    '\u{a30}', L), ('\u{a32}', '\u{a33}', L), ('\u{a35}', '\u{a36}', L), ('\u{a38}', '\u{a39}', L),
-    ('\u{a3c}', '\u{a3c}', NSM), ('\u{a3e}', '\u{a40}', L), ('\u{a41}', '\u{a42}', NSM), ('\u{a47}',
-    '\u{a48}', NSM), ('\u{a4b}', '\u{a4d}', NSM), ('\u{a51}', '\u{a51}', NSM), ('\u{a59}',
-    '\u{a5c}', L), ('\u{a5e}', '\u{a5e}', L), ('\u{a66}', '\u{a6f}', L), ('\u{a70}', '\u{a71}',
-    NSM), ('\u{a72}', '\u{a74}', L), ('\u{a75}', '\u{a75}', NSM), ('\u{a81}', '\u{a82}', NSM),
-    ('\u{a83}', '\u{a83}', L), ('\u{a85}', '\u{a8d}', L), ('\u{a8f}', '\u{a91}', L), ('\u{a93}',
-    '\u{aa8}', L), ('\u{aaa}', '\u{ab0}', L), ('\u{ab2}', '\u{ab3}', L), ('\u{ab5}', '\u{ab9}', L),
-    ('\u{abc}', '\u{abc}', NSM), ('\u{abd}', '\u{ac0}', L), ('\u{ac1}', '\u{ac5}', NSM), ('\u{ac7}',
-    '\u{ac8}', NSM), ('\u{ac9}', '\u{ac9}', L), ('\u{acb}', '\u{acc}', L), ('\u{acd}', '\u{acd}',
-    NSM), ('\u{ad0}', '\u{ad0}', L), ('\u{ae0}', '\u{ae1}', L), ('\u{ae2}', '\u{ae3}', NSM),
-    ('\u{ae6}', '\u{af0}', L), ('\u{af1}', '\u{af1}', ET), ('\u{af9}', '\u{af9}', L), ('\u{b01}',
-    '\u{b01}', NSM), ('\u{b02}', '\u{b03}', L), ('\u{b05}', '\u{b0c}', L), ('\u{b0f}', '\u{b10}',
-    L), ('\u{b13}', '\u{b28}', L), ('\u{b2a}', '\u{b30}', L), ('\u{b32}', '\u{b33}', L), ('\u{b35}',
-    '\u{b39}', L), ('\u{b3c}', '\u{b3c}', NSM), ('\u{b3d}', '\u{b3e}', L), ('\u{b3f}', '\u{b3f}',
-    NSM), ('\u{b40}', '\u{b40}', L), ('\u{b41}', '\u{b44}', NSM), ('\u{b47}', '\u{b48}', L),
-    ('\u{b4b}', '\u{b4c}', L), ('\u{b4d}', '\u{b4d}', NSM), ('\u{b56}', '\u{b56}', NSM), ('\u{b57}',
-    '\u{b57}', L), ('\u{b5c}', '\u{b5d}', L), ('\u{b5f}', '\u{b61}', L), ('\u{b62}', '\u{b63}',
-    NSM), ('\u{b66}', '\u{b77}', L), ('\u{b82}', '\u{b82}', NSM), ('\u{b83}', '\u{b83}', L),
-    ('\u{b85}', '\u{b8a}', L), ('\u{b8e}', '\u{b90}', L), ('\u{b92}', '\u{b95}', L), ('\u{b99}',
-    '\u{b9a}', L), ('\u{b9c}', '\u{b9c}', L), ('\u{b9e}', '\u{b9f}', L), ('\u{ba3}', '\u{ba4}', L),
-    ('\u{ba8}', '\u{baa}', L), ('\u{bae}', '\u{bb9}', L), ('\u{bbe}', '\u{bbf}', L), ('\u{bc0}',
-    '\u{bc0}', NSM), ('\u{bc1}', '\u{bc2}', L), ('\u{bc6}', '\u{bc8}', L), ('\u{bca}', '\u{bcc}',
-    L), ('\u{bcd}', '\u{bcd}', NSM), ('\u{bd0}', '\u{bd0}', L), ('\u{bd7}', '\u{bd7}', L),
-    ('\u{be6}', '\u{bf2}', L), ('\u{bf3}', '\u{bf8}', ON), ('\u{bf9}', '\u{bf9}', ET), ('\u{bfa}',
-    '\u{bfa}', ON), ('\u{c00}', '\u{c00}', NSM), ('\u{c01}', '\u{c03}', L), ('\u{c05}', '\u{c0c}',
-    L), ('\u{c0e}', '\u{c10}', L), ('\u{c12}', '\u{c28}', L), ('\u{c2a}', '\u{c39}', L), ('\u{c3d}',
-    '\u{c3d}', L), ('\u{c3e}', '\u{c40}', NSM), ('\u{c41}', '\u{c44}', L), ('\u{c46}', '\u{c48}',
-    NSM), ('\u{c4a}', '\u{c4d}', NSM), ('\u{c55}', '\u{c56}', NSM), ('\u{c58}', '\u{c5a}', L),
-    ('\u{c60}', '\u{c61}', L), ('\u{c62}', '\u{c63}', NSM), ('\u{c66}', '\u{c6f}', L), ('\u{c78}',
-    '\u{c7e}', ON), ('\u{c7f}', '\u{c80}', L), ('\u{c81}', '\u{c81}', NSM), ('\u{c82}', '\u{c83}',
-    L), ('\u{c85}', '\u{c8c}', L), ('\u{c8e}', '\u{c90}', L), ('\u{c92}', '\u{ca8}', L), ('\u{caa}',
-    '\u{cb3}', L), ('\u{cb5}', '\u{cb9}', L), ('\u{cbc}', '\u{cbc}', NSM), ('\u{cbd}', '\u{cc4}',
-    L), ('\u{cc6}', '\u{cc8}', L), ('\u{cca}', '\u{ccb}', L), ('\u{ccc}', '\u{ccd}', NSM),
-    ('\u{cd5}', '\u{cd6}', L), ('\u{cde}', '\u{cde}', L), ('\u{ce0}', '\u{ce1}', L), ('\u{ce2}',
-    '\u{ce3}', NSM), ('\u{ce6}', '\u{cef}', L), ('\u{cf1}', '\u{cf2}', L), ('\u{d01}', '\u{d01}',
-    NSM), ('\u{d02}', '\u{d03}', L), ('\u{d05}', '\u{d0c}', L), ('\u{d0e}', '\u{d10}', L),
-    ('\u{d12}', '\u{d3a}', L), ('\u{d3d}', '\u{d40}', L), ('\u{d41}', '\u{d44}', NSM), ('\u{d46}',
-    '\u{d48}', L), ('\u{d4a}', '\u{d4c}', L), ('\u{d4d}', '\u{d4d}', NSM), ('\u{d4e}', '\u{d4f}',
-    L), ('\u{d54}', '\u{d61}', L), ('\u{d62}', '\u{d63}', NSM), ('\u{d66}', '\u{d7f}', L),
-    ('\u{d82}', '\u{d83}', L), ('\u{d85}', '\u{d96}', L), ('\u{d9a}', '\u{db1}', L), ('\u{db3}',
-    '\u{dbb}', L), ('\u{dbd}', '\u{dbd}', L), ('\u{dc0}', '\u{dc6}', L), ('\u{dca}', '\u{dca}',
-    NSM), ('\u{dcf}', '\u{dd1}', L), ('\u{dd2}', '\u{dd4}', NSM), ('\u{dd6}', '\u{dd6}', NSM),
-    ('\u{dd8}', '\u{ddf}', L), ('\u{de6}', '\u{def}', L), ('\u{df2}', '\u{df4}', L), ('\u{e01}',
-    '\u{e30}', L), ('\u{e31}', '\u{e31}', NSM), ('\u{e32}', '\u{e33}', L), ('\u{e34}', '\u{e3a}',
-    NSM), ('\u{e3f}', '\u{e3f}', ET), ('\u{e40}', '\u{e46}', L), ('\u{e47}', '\u{e4e}', NSM),
-    ('\u{e4f}', '\u{e5b}', L), ('\u{e81}', '\u{e82}', L), ('\u{e84}', '\u{e84}', L), ('\u{e87}',
-    '\u{e88}', L), ('\u{e8a}', '\u{e8a}', L), ('\u{e8d}', '\u{e8d}', L), ('\u{e94}', '\u{e97}', L),
-    ('\u{e99}', '\u{e9f}', L), ('\u{ea1}', '\u{ea3}', L), ('\u{ea5}', '\u{ea5}', L), ('\u{ea7}',
-    '\u{ea7}', L), ('\u{eaa}', '\u{eab}', L), ('\u{ead}', '\u{eb0}', L), ('\u{eb1}', '\u{eb1}',
-    NSM), ('\u{eb2}', '\u{eb3}', L), ('\u{eb4}', '\u{eb9}', NSM), ('\u{ebb}', '\u{ebc}', NSM),
-    ('\u{ebd}', '\u{ebd}', L), ('\u{ec0}', '\u{ec4}', L), ('\u{ec6}', '\u{ec6}', L), ('\u{ec8}',
-    '\u{ecd}', NSM), ('\u{ed0}', '\u{ed9}', L), ('\u{edc}', '\u{edf}', L), ('\u{f00}', '\u{f17}',
-    L), ('\u{f18}', '\u{f19}', NSM), ('\u{f1a}', '\u{f34}', L), ('\u{f35}', '\u{f35}', NSM),
-    ('\u{f36}', '\u{f36}', L), ('\u{f37}', '\u{f37}', NSM), ('\u{f38}', '\u{f38}', L), ('\u{f39}',
-    '\u{f39}', NSM), ('\u{f3a}', '\u{f3d}', ON), ('\u{f3e}', '\u{f47}', L), ('\u{f49}', '\u{f6c}',
-    L), ('\u{f71}', '\u{f7e}', NSM), ('\u{f7f}', '\u{f7f}', L), ('\u{f80}', '\u{f84}', NSM),
-    ('\u{f85}', '\u{f85}', L), ('\u{f86}', '\u{f87}', NSM), ('\u{f88}', '\u{f8c}', L), ('\u{f8d}',
-    '\u{f97}', NSM), ('\u{f99}', '\u{fbc}', NSM), ('\u{fbe}', '\u{fc5}', L), ('\u{fc6}', '\u{fc6}',
-    NSM), ('\u{fc7}', '\u{fcc}', L), ('\u{fce}', '\u{fda}', L), ('\u{1000}', '\u{102c}', L),
-    ('\u{102d}', '\u{1030}', NSM), ('\u{1031}', '\u{1031}', L), ('\u{1032}', '\u{1037}', NSM),
-    ('\u{1038}', '\u{1038}', L), ('\u{1039}', '\u{103a}', NSM), ('\u{103b}', '\u{103c}', L),
-    ('\u{103d}', '\u{103e}', NSM), ('\u{103f}', '\u{1057}', L), ('\u{1058}', '\u{1059}', NSM),
-    ('\u{105a}', '\u{105d}', L), ('\u{105e}', '\u{1060}', NSM), ('\u{1061}', '\u{1070}', L),
-    ('\u{1071}', '\u{1074}', NSM), ('\u{1075}', '\u{1081}', L), ('\u{1082}', '\u{1082}', NSM),
-    ('\u{1083}', '\u{1084}', L), ('\u{1085}', '\u{1086}', NSM), ('\u{1087}', '\u{108c}', L),
-    ('\u{108d}', '\u{108d}', NSM), ('\u{108e}', '\u{109c}', L), ('\u{109d}', '\u{109d}', NSM),
-    ('\u{109e}', '\u{10c5}', L), ('\u{10c7}', '\u{10c7}', L), ('\u{10cd}', '\u{10cd}', L),
-    ('\u{10d0}', '\u{1248}', L), ('\u{124a}', '\u{124d}', L), ('\u{1250}', '\u{1256}', L),
-    ('\u{1258}', '\u{1258}', L), ('\u{125a}', '\u{125d}', L), ('\u{1260}', '\u{1288}', L),
-    ('\u{128a}', '\u{128d}', L), ('\u{1290}', '\u{12b0}', L), ('\u{12b2}', '\u{12b5}', L),
-    ('\u{12b8}', '\u{12be}', L), ('\u{12c0}', '\u{12c0}', L), ('\u{12c2}', '\u{12c5}', L),
-    ('\u{12c8}', '\u{12d6}', L), ('\u{12d8}', '\u{1310}', L), ('\u{1312}', '\u{1315}', L),
-    ('\u{1318}', '\u{135a}', L), ('\u{135d}', '\u{135f}', NSM), ('\u{1360}', '\u{137c}', L),
-    ('\u{1380}', '\u{138f}', L), ('\u{1390}', '\u{1399}', ON), ('\u{13a0}', '\u{13f5}', L),
-    ('\u{13f8}', '\u{13fd}', L), ('\u{1400}', '\u{1400}', ON), ('\u{1401}', '\u{167f}', L),
-    ('\u{1680}', '\u{1680}', WS), ('\u{1681}', '\u{169a}', L), ('\u{169b}', '\u{169c}', ON),
-    ('\u{16a0}', '\u{16f8}', L), ('\u{1700}', '\u{170c}', L), ('\u{170e}', '\u{1711}', L),
-    ('\u{1712}', '\u{1714}', NSM), ('\u{1720}', '\u{1731}', L), ('\u{1732}', '\u{1734}', NSM),
-    ('\u{1735}', '\u{1736}', L), ('\u{1740}', '\u{1751}', L), ('\u{1752}', '\u{1753}', NSM),
-    ('\u{1760}', '\u{176c}', L), ('\u{176e}', '\u{1770}', L), ('\u{1772}', '\u{1773}', NSM),
-    ('\u{1780}', '\u{17b3}', L), ('\u{17b4}', '\u{17b5}', NSM), ('\u{17b6}', '\u{17b6}', L),
-    ('\u{17b7}', '\u{17bd}', NSM), ('\u{17be}', '\u{17c5}', L), ('\u{17c6}', '\u{17c6}', NSM),
-    ('\u{17c7}', '\u{17c8}', L), ('\u{17c9}', '\u{17d3}', NSM), ('\u{17d4}', '\u{17da}', L),
-    ('\u{17db}', '\u{17db}', ET), ('\u{17dc}', '\u{17dc}', L), ('\u{17dd}', '\u{17dd}', NSM),
-    ('\u{17e0}', '\u{17e9}', L), ('\u{17f0}', '\u{17f9}', ON), ('\u{1800}', '\u{180a}', ON),
-    ('\u{180b}', '\u{180d}', NSM), ('\u{180e}', '\u{180e}', BN), ('\u{1810}', '\u{1819}', L),
-    ('\u{1820}', '\u{1877}', L), ('\u{1880}', '\u{1884}', L), ('\u{1885}', '\u{1886}', NSM),
-    ('\u{1887}', '\u{18a8}', L), ('\u{18a9}', '\u{18a9}', NSM), ('\u{18aa}', '\u{18aa}', L),
-    ('\u{18b0}', '\u{18f5}', L), ('\u{1900}', '\u{191e}', L), ('\u{1920}', '\u{1922}', NSM),
-    ('\u{1923}', '\u{1926}', L), ('\u{1927}', '\u{1928}', NSM), ('\u{1929}', '\u{192b}', L),
-    ('\u{1930}', '\u{1931}', L), ('\u{1932}', '\u{1932}', NSM), ('\u{1933}', '\u{1938}', L),
-    ('\u{1939}', '\u{193b}', NSM), ('\u{1940}', '\u{1940}', ON), ('\u{1944}', '\u{1945}', ON),
-    ('\u{1946}', '\u{196d}', L), ('\u{1970}', '\u{1974}', L), ('\u{1980}', '\u{19ab}', L),
-    ('\u{19b0}', '\u{19c9}', L), ('\u{19d0}', '\u{19da}', L), ('\u{19de}', '\u{19ff}', ON),
-    ('\u{1a00}', '\u{1a16}', L), ('\u{1a17}', '\u{1a18}', NSM), ('\u{1a19}', '\u{1a1a}', L),
-    ('\u{1a1b}', '\u{1a1b}', NSM), ('\u{1a1e}', '\u{1a55}', L), ('\u{1a56}', '\u{1a56}', NSM),
-    ('\u{1a57}', '\u{1a57}', L), ('\u{1a58}', '\u{1a5e}', NSM), ('\u{1a60}', '\u{1a60}', NSM),
-    ('\u{1a61}', '\u{1a61}', L), ('\u{1a62}', '\u{1a62}', NSM), ('\u{1a63}', '\u{1a64}', L),
-    ('\u{1a65}', '\u{1a6c}', NSM), ('\u{1a6d}', '\u{1a72}', L), ('\u{1a73}', '\u{1a7c}', NSM),
-    ('\u{1a7f}', '\u{1a7f}', NSM), ('\u{1a80}', '\u{1a89}', L), ('\u{1a90}', '\u{1a99}', L),
-    ('\u{1aa0}', '\u{1aad}', L), ('\u{1ab0}', '\u{1abe}', NSM), ('\u{1b00}', '\u{1b03}', NSM),
-    ('\u{1b04}', '\u{1b33}', L), ('\u{1b34}', '\u{1b34}', NSM), ('\u{1b35}', '\u{1b35}', L),
-    ('\u{1b36}', '\u{1b3a}', NSM), ('\u{1b3b}', '\u{1b3b}', L), ('\u{1b3c}', '\u{1b3c}', NSM),
-    ('\u{1b3d}', '\u{1b41}', L), ('\u{1b42}', '\u{1b42}', NSM), ('\u{1b43}', '\u{1b4b}', L),
-    ('\u{1b50}', '\u{1b6a}', L), ('\u{1b6b}', '\u{1b73}', NSM), ('\u{1b74}', '\u{1b7c}', L),
-    ('\u{1b80}', '\u{1b81}', NSM), ('\u{1b82}', '\u{1ba1}', L), ('\u{1ba2}', '\u{1ba5}', NSM),
-    ('\u{1ba6}', '\u{1ba7}', L), ('\u{1ba8}', '\u{1ba9}', NSM), ('\u{1baa}', '\u{1baa}', L),
-    ('\u{1bab}', '\u{1bad}', NSM), ('\u{1bae}', '\u{1be5}', L), ('\u{1be6}', '\u{1be6}', NSM),
-    ('\u{1be7}', '\u{1be7}', L), ('\u{1be8}', '\u{1be9}', NSM), ('\u{1bea}', '\u{1bec}', L),
-    ('\u{1bed}', '\u{1bed}', NSM), ('\u{1bee}', '\u{1bee}', L), ('\u{1bef}', '\u{1bf1}', NSM),
-    ('\u{1bf2}', '\u{1bf3}', L), ('\u{1bfc}', '\u{1c2b}', L), ('\u{1c2c}', '\u{1c33}', NSM),
-    ('\u{1c34}', '\u{1c35}', L), ('\u{1c36}', '\u{1c37}', NSM), ('\u{1c3b}', '\u{1c49}', L),
-    ('\u{1c4d}', '\u{1c88}', L), ('\u{1cc0}', '\u{1cc7}', L), ('\u{1cd0}', '\u{1cd2}', NSM),
-    ('\u{1cd3}', '\u{1cd3}', L), ('\u{1cd4}', '\u{1ce0}', NSM), ('\u{1ce1}', '\u{1ce1}', L),
-    ('\u{1ce2}', '\u{1ce8}', NSM), ('\u{1ce9}', '\u{1cec}', L), ('\u{1ced}', '\u{1ced}', NSM),
-    ('\u{1cee}', '\u{1cf3}', L), ('\u{1cf4}', '\u{1cf4}', NSM), ('\u{1cf5}', '\u{1cf6}', L),
-    ('\u{1cf8}', '\u{1cf9}', NSM), ('\u{1d00}', '\u{1dbf}', L), ('\u{1dc0}', '\u{1df5}', NSM),
-    ('\u{1dfb}', '\u{1dff}', NSM), ('\u{1e00}', '\u{1f15}', L), ('\u{1f18}', '\u{1f1d}', L),
-    ('\u{1f20}', '\u{1f45}', L), ('\u{1f48}', '\u{1f4d}', L), ('\u{1f50}', '\u{1f57}', L),
-    ('\u{1f59}', '\u{1f59}', L), ('\u{1f5b}', '\u{1f5b}', L), ('\u{1f5d}', '\u{1f5d}', L),
-    ('\u{1f5f}', '\u{1f7d}', L), ('\u{1f80}', '\u{1fb4}', L), ('\u{1fb6}', '\u{1fbc}', L),
-    ('\u{1fbd}', '\u{1fbd}', ON), ('\u{1fbe}', '\u{1fbe}', L), ('\u{1fbf}', '\u{1fc1}', ON),
-    ('\u{1fc2}', '\u{1fc4}', L), ('\u{1fc6}', '\u{1fcc}', L), ('\u{1fcd}', '\u{1fcf}', ON),
-    ('\u{1fd0}', '\u{1fd3}', L), ('\u{1fd6}', '\u{1fdb}', L), ('\u{1fdd}', '\u{1fdf}', ON),
-    ('\u{1fe0}', '\u{1fec}', L), ('\u{1fed}', '\u{1fef}', ON), ('\u{1ff2}', '\u{1ff4}', L),
-    ('\u{1ff6}', '\u{1ffc}', L), ('\u{1ffd}', '\u{1ffe}', ON), ('\u{2000}', '\u{200a}', WS),
-    ('\u{200b}', '\u{200d}', BN), ('\u{200e}', '\u{200e}', L), ('\u{200f}', '\u{200f}', R),
-    ('\u{2010}', '\u{2027}', ON), ('\u{2028}', '\u{2028}', WS), ('\u{2029}', '\u{2029}', B),
-    ('\u{202a}', '\u{202a}', LRE), ('\u{202b}', '\u{202b}', RLE), ('\u{202c}', '\u{202c}', PDF),
-    ('\u{202d}', '\u{202d}', LRO), ('\u{202e}', '\u{202e}', RLO), ('\u{202f}', '\u{202f}', CS),
-    ('\u{2030}', '\u{2034}', ET), ('\u{2035}', '\u{2043}', ON), ('\u{2044}', '\u{2044}', CS),
-    ('\u{2045}', '\u{205e}', ON), ('\u{205f}', '\u{205f}', WS), ('\u{2060}', '\u{2064}', BN),
-    ('\u{2066}', '\u{2066}', LRI), ('\u{2067}', '\u{2067}', RLI), ('\u{2068}', '\u{2068}', FSI),
-    ('\u{2069}', '\u{2069}', PDI), ('\u{206a}', '\u{206f}', BN), ('\u{2070}', '\u{2070}', EN),
-    ('\u{2071}', '\u{2071}', L), ('\u{2074}', '\u{2079}', EN), ('\u{207a}', '\u{207b}', ES),
-    ('\u{207c}', '\u{207e}', ON), ('\u{207f}', '\u{207f}', L), ('\u{2080}', '\u{2089}', EN),
-    ('\u{208a}', '\u{208b}', ES), ('\u{208c}', '\u{208e}', ON), ('\u{2090}', '\u{209c}', L),
-    ('\u{20a0}', '\u{20cf}', ET), ('\u{20d0}', '\u{20f0}', NSM), ('\u{2100}', '\u{2101}', ON),
-    ('\u{2102}', '\u{2102}', L), ('\u{2103}', '\u{2106}', ON), ('\u{2107}', '\u{2107}', L),
-    ('\u{2108}', '\u{2109}', ON), ('\u{210a}', '\u{2113}', L), ('\u{2114}', '\u{2114}', ON),
-    ('\u{2115}', '\u{2115}', L), ('\u{2116}', '\u{2118}', ON), ('\u{2119}', '\u{211d}', L),
-    ('\u{211e}', '\u{2123}', ON), ('\u{2124}', '\u{2124}', L), ('\u{2125}', '\u{2125}', ON),
-    ('\u{2126}', '\u{2126}', L), ('\u{2127}', '\u{2127}', ON), ('\u{2128}', '\u{2128}', L),
-    ('\u{2129}', '\u{2129}', ON), ('\u{212a}', '\u{212d}', L), ('\u{212e}', '\u{212e}', ET),
-    ('\u{212f}', '\u{2139}', L), ('\u{213a}', '\u{213b}', ON), ('\u{213c}', '\u{213f}', L),
-    ('\u{2140}', '\u{2144}', ON), ('\u{2145}', '\u{2149}', L), ('\u{214a}', '\u{214d}', ON),
-    ('\u{214e}', '\u{214f}', L), ('\u{2150}', '\u{215f}', ON), ('\u{2160}', '\u{2188}', L),
-    ('\u{2189}', '\u{218b}', ON), ('\u{2190}', '\u{2211}', ON), ('\u{2212}', '\u{2212}', ES),
-    ('\u{2213}', '\u{2213}', ET), ('\u{2214}', '\u{2335}', ON), ('\u{2336}', '\u{237a}', L),
-    ('\u{237b}', '\u{2394}', ON), ('\u{2395}', '\u{2395}', L), ('\u{2396}', '\u{23fe}', ON),
-    ('\u{2400}', '\u{2426}', ON), ('\u{2440}', '\u{244a}', ON), ('\u{2460}', '\u{2487}', ON),
-    ('\u{2488}', '\u{249b}', EN), ('\u{249c}', '\u{24e9}', L), ('\u{24ea}', '\u{26ab}', ON),
-    ('\u{26ac}', '\u{26ac}', L), ('\u{26ad}', '\u{27ff}', ON), ('\u{2800}', '\u{28ff}', L),
-    ('\u{2900}', '\u{2b73}', ON), ('\u{2b76}', '\u{2b95}', ON), ('\u{2b98}', '\u{2bb9}', ON),
-    ('\u{2bbd}', '\u{2bc8}', ON), ('\u{2bca}', '\u{2bd1}', ON), ('\u{2bec}', '\u{2bef}', ON),
-    ('\u{2c00}', '\u{2c2e}', L), ('\u{2c30}', '\u{2c5e}', L), ('\u{2c60}', '\u{2ce4}', L),
-    ('\u{2ce5}', '\u{2cea}', ON), ('\u{2ceb}', '\u{2cee}', L), ('\u{2cef}', '\u{2cf1}', NSM),
-    ('\u{2cf2}', '\u{2cf3}', L), ('\u{2cf9}', '\u{2cff}', ON), ('\u{2d00}', '\u{2d25}', L),
-    ('\u{2d27}', '\u{2d27}', L), ('\u{2d2d}', '\u{2d2d}', L), ('\u{2d30}', '\u{2d67}', L),
-    ('\u{2d6f}', '\u{2d70}', L), ('\u{2d7f}', '\u{2d7f}', NSM), ('\u{2d80}', '\u{2d96}', L),
-    ('\u{2da0}', '\u{2da6}', L), ('\u{2da8}', '\u{2dae}', L), ('\u{2db0}', '\u{2db6}', L),
-    ('\u{2db8}', '\u{2dbe}', L), ('\u{2dc0}', '\u{2dc6}', L), ('\u{2dc8}', '\u{2dce}', L),
-    ('\u{2dd0}', '\u{2dd6}', L), ('\u{2dd8}', '\u{2dde}', L), ('\u{2de0}', '\u{2dff}', NSM),
-    ('\u{2e00}', '\u{2e44}', ON), ('\u{2e80}', '\u{2e99}', ON), ('\u{2e9b}', '\u{2ef3}', ON),
-    ('\u{2f00}', '\u{2fd5}', ON), ('\u{2ff0}', '\u{2ffb}', ON), ('\u{3000}', '\u{3000}', WS),
-    ('\u{3001}', '\u{3004}', ON), ('\u{3005}', '\u{3007}', L), ('\u{3008}', '\u{3020}', ON),
-    ('\u{3021}', '\u{3029}', L), ('\u{302a}', '\u{302d}', NSM), ('\u{302e}', '\u{302f}', L),
-    ('\u{3030}', '\u{3030}', ON), ('\u{3031}', '\u{3035}', L), ('\u{3036}', '\u{3037}', ON),
-    ('\u{3038}', '\u{303c}', L), ('\u{303d}', '\u{303f}', ON), ('\u{3041}', '\u{3096}', L),
-    ('\u{3099}', '\u{309a}', NSM), ('\u{309b}', '\u{309c}', ON), ('\u{309d}', '\u{309f}', L),
-    ('\u{30a0}', '\u{30a0}', ON), ('\u{30a1}', '\u{30fa}', L), ('\u{30fb}', '\u{30fb}', ON),
-    ('\u{30fc}', '\u{30ff}', L), ('\u{3105}', '\u{312d}', L), ('\u{3131}', '\u{318e}', L),
-    ('\u{3190}', '\u{31ba}', L), ('\u{31c0}', '\u{31e3}', ON), ('\u{31f0}', '\u{321c}', L),
-    ('\u{321d}', '\u{321e}', ON), ('\u{3220}', '\u{324f}', L), ('\u{3250}', '\u{325f}', ON),
-    ('\u{3260}', '\u{327b}', L), ('\u{327c}', '\u{327e}', ON), ('\u{327f}', '\u{32b0}', L),
-    ('\u{32b1}', '\u{32bf}', ON), ('\u{32c0}', '\u{32cb}', L), ('\u{32cc}', '\u{32cf}', ON),
-    ('\u{32d0}', '\u{32fe}', L), ('\u{3300}', '\u{3376}', L), ('\u{3377}', '\u{337a}', ON),
-    ('\u{337b}', '\u{33dd}', L), ('\u{33de}', '\u{33df}', ON), ('\u{33e0}', '\u{33fe}', L),
-    ('\u{33ff}', '\u{33ff}', ON), ('\u{3400}', '\u{4db5}', L), ('\u{4dc0}', '\u{4dff}', ON),
-    ('\u{4e00}', '\u{9fd5}', L), ('\u{a000}', '\u{a48c}', L), ('\u{a490}', '\u{a4c6}', ON),
-    ('\u{a4d0}', '\u{a60c}', L), ('\u{a60d}', '\u{a60f}', ON), ('\u{a610}', '\u{a62b}', L),
-    ('\u{a640}', '\u{a66e}', L), ('\u{a66f}', '\u{a672}', NSM), ('\u{a673}', '\u{a673}', ON),
-    ('\u{a674}', '\u{a67d}', NSM), ('\u{a67e}', '\u{a67f}', ON), ('\u{a680}', '\u{a69d}', L),
-    ('\u{a69e}', '\u{a69f}', NSM), ('\u{a6a0}', '\u{a6ef}', L), ('\u{a6f0}', '\u{a6f1}', NSM),
-    ('\u{a6f2}', '\u{a6f7}', L), ('\u{a700}', '\u{a721}', ON), ('\u{a722}', '\u{a787}', L),
-    ('\u{a788}', '\u{a788}', ON), ('\u{a789}', '\u{a7ae}', L), ('\u{a7b0}', '\u{a7b7}', L),
-    ('\u{a7f7}', '\u{a801}', L), ('\u{a802}', '\u{a802}', NSM), ('\u{a803}', '\u{a805}', L),
-    ('\u{a806}', '\u{a806}', NSM), ('\u{a807}', '\u{a80a}', L), ('\u{a80b}', '\u{a80b}', NSM),
-    ('\u{a80c}', '\u{a824}', L), ('\u{a825}', '\u{a826}', NSM), ('\u{a827}', '\u{a827}', L),
-    ('\u{a828}', '\u{a82b}', ON), ('\u{a830}', '\u{a837}', L), ('\u{a838}', '\u{a839}', ET),
-    ('\u{a840}', '\u{a873}', L), ('\u{a874}', '\u{a877}', ON), ('\u{a880}', '\u{a8c3}', L),
-    ('\u{a8c4}', '\u{a8c5}', NSM), ('\u{a8ce}', '\u{a8d9}', L), ('\u{a8e0}', '\u{a8f1}', NSM),
-    ('\u{a8f2}', '\u{a8fd}', L), ('\u{a900}', '\u{a925}', L), ('\u{a926}', '\u{a92d}', NSM),
-    ('\u{a92e}', '\u{a946}', L), ('\u{a947}', '\u{a951}', NSM), ('\u{a952}', '\u{a953}', L),
-    ('\u{a95f}', '\u{a97c}', L), ('\u{a980}', '\u{a982}', NSM), ('\u{a983}', '\u{a9b2}', L),
-    ('\u{a9b3}', '\u{a9b3}', NSM), ('\u{a9b4}', '\u{a9b5}', L), ('\u{a9b6}', '\u{a9b9}', NSM),
-    ('\u{a9ba}', '\u{a9bb}', L), ('\u{a9bc}', '\u{a9bc}', NSM), ('\u{a9bd}', '\u{a9cd}', L),
-    ('\u{a9cf}', '\u{a9d9}', L), ('\u{a9de}', '\u{a9e4}', L), ('\u{a9e5}', '\u{a9e5}', NSM),
-    ('\u{a9e6}', '\u{a9fe}', L), ('\u{aa00}', '\u{aa28}', L), ('\u{aa29}', '\u{aa2e}', NSM),
-    ('\u{aa2f}', '\u{aa30}', L), ('\u{aa31}', '\u{aa32}', NSM), ('\u{aa33}', '\u{aa34}', L),
-    ('\u{aa35}', '\u{aa36}', NSM), ('\u{aa40}', '\u{aa42}', L), ('\u{aa43}', '\u{aa43}', NSM),
-    ('\u{aa44}', '\u{aa4b}', L), ('\u{aa4c}', '\u{aa4c}', NSM), ('\u{aa4d}', '\u{aa4d}', L),
-    ('\u{aa50}', '\u{aa59}', L), ('\u{aa5c}', '\u{aa7b}', L), ('\u{aa7c}', '\u{aa7c}', NSM),
-    ('\u{aa7d}', '\u{aaaf}', L), ('\u{aab0}', '\u{aab0}', NSM), ('\u{aab1}', '\u{aab1}', L),
-    ('\u{aab2}', '\u{aab4}', NSM), ('\u{aab5}', '\u{aab6}', L), ('\u{aab7}', '\u{aab8}', NSM),
-    ('\u{aab9}', '\u{aabd}', L), ('\u{aabe}', '\u{aabf}', NSM), ('\u{aac0}', '\u{aac0}', L),
-    ('\u{aac1}', '\u{aac1}', NSM), ('\u{aac2}', '\u{aac2}', L), ('\u{aadb}', '\u{aaeb}', L),
-    ('\u{aaec}', '\u{aaed}', NSM), ('\u{aaee}', '\u{aaf5}', L), ('\u{aaf6}', '\u{aaf6}', NSM),
-    ('\u{ab01}', '\u{ab06}', L), ('\u{ab09}', '\u{ab0e}', L), ('\u{ab11}', '\u{ab16}', L),
-    ('\u{ab20}', '\u{ab26}', L), ('\u{ab28}', '\u{ab2e}', L), ('\u{ab30}', '\u{ab65}', L),
-    ('\u{ab70}', '\u{abe4}', L), ('\u{abe5}', '\u{abe5}', NSM), ('\u{abe6}', '\u{abe7}', L),
-    ('\u{abe8}', '\u{abe8}', NSM), ('\u{abe9}', '\u{abec}', L), ('\u{abed}', '\u{abed}', NSM),
-    ('\u{abf0}', '\u{abf9}', L), ('\u{ac00}', '\u{d7a3}', L), ('\u{d7b0}', '\u{d7c6}', L),
-    ('\u{d7cb}', '\u{d7fb}', L), ('\u{e000}', '\u{fa6d}', L), ('\u{fa70}', '\u{fad9}', L),
-    ('\u{fb00}', '\u{fb06}', L), ('\u{fb13}', '\u{fb17}', L), ('\u{fb1d}', '\u{fb1d}', R),
-    ('\u{fb1e}', '\u{fb1e}', NSM), ('\u{fb1f}', '\u{fb28}', R), ('\u{fb29}', '\u{fb29}', ES),
-    ('\u{fb2a}', '\u{fb4f}', R), ('\u{fb50}', '\u{fd3d}', AL), ('\u{fd3e}', '\u{fd3f}', ON),
-    ('\u{fd40}', '\u{fdcf}', AL), ('\u{fdf0}', '\u{fdfc}', AL), ('\u{fdfd}', '\u{fdfd}', ON),
-    ('\u{fdfe}', '\u{fdff}', AL), ('\u{fe00}', '\u{fe0f}', NSM), ('\u{fe10}', '\u{fe19}', ON),
-    ('\u{fe20}', '\u{fe2f}', NSM), ('\u{fe30}', '\u{fe4f}', ON), ('\u{fe50}', '\u{fe50}', CS),
-    ('\u{fe51}', '\u{fe51}', ON), ('\u{fe52}', '\u{fe52}', CS), ('\u{fe54}', '\u{fe54}', ON),
-    ('\u{fe55}', '\u{fe55}', CS), ('\u{fe56}', '\u{fe5e}', ON), ('\u{fe5f}', '\u{fe5f}', ET),
-    ('\u{fe60}', '\u{fe61}', ON), ('\u{fe62}', '\u{fe63}', ES), ('\u{fe64}', '\u{fe66}', ON),
-    ('\u{fe68}', '\u{fe68}', ON), ('\u{fe69}', '\u{fe6a}', ET), ('\u{fe6b}', '\u{fe6b}', ON),
-    ('\u{fe70}', '\u{fefe}', AL), ('\u{feff}', '\u{feff}', BN), ('\u{ff01}', '\u{ff02}', ON),
-    ('\u{ff03}', '\u{ff05}', ET), ('\u{ff06}', '\u{ff0a}', ON), ('\u{ff0b}', '\u{ff0b}', ES),
-    ('\u{ff0c}', '\u{ff0c}', CS), ('\u{ff0d}', '\u{ff0d}', ES), ('\u{ff0e}', '\u{ff0f}', CS),
-    ('\u{ff10}', '\u{ff19}', EN), ('\u{ff1a}', '\u{ff1a}', CS), ('\u{ff1b}', '\u{ff20}', ON),
-    ('\u{ff21}', '\u{ff3a}', L), ('\u{ff3b}', '\u{ff40}', ON), ('\u{ff41}', '\u{ff5a}', L),
-    ('\u{ff5b}', '\u{ff65}', ON), ('\u{ff66}', '\u{ffbe}', L), ('\u{ffc2}', '\u{ffc7}', L),
-    ('\u{ffca}', '\u{ffcf}', L), ('\u{ffd2}', '\u{ffd7}', L), ('\u{ffda}', '\u{ffdc}', L),
-    ('\u{ffe0}', '\u{ffe1}', ET), ('\u{ffe2}', '\u{ffe4}', ON), ('\u{ffe5}', '\u{ffe6}', ET),
-    ('\u{ffe8}', '\u{ffee}', ON), ('\u{fff9}', '\u{fffd}', ON), ('\u{10000}', '\u{1000b}', L),
-    ('\u{1000d}', '\u{10026}', L), ('\u{10028}', '\u{1003a}', L), ('\u{1003c}', '\u{1003d}', L),
-    ('\u{1003f}', '\u{1004d}', L), ('\u{10050}', '\u{1005d}', L), ('\u{10080}', '\u{100fa}', L),
-    ('\u{10100}', '\u{10100}', L), ('\u{10101}', '\u{10101}', ON), ('\u{10102}', '\u{10102}', L),
-    ('\u{10107}', '\u{10133}', L), ('\u{10137}', '\u{1013f}', L), ('\u{10140}', '\u{1018c}', ON),
-    ('\u{1018d}', '\u{1018e}', L), ('\u{10190}', '\u{1019b}', ON), ('\u{101a0}', '\u{101a0}', ON),
-    ('\u{101d0}', '\u{101fc}', L), ('\u{101fd}', '\u{101fd}', NSM), ('\u{10280}', '\u{1029c}', L),
-    ('\u{102a0}', '\u{102d0}', L), ('\u{102e0}', '\u{102e0}', NSM), ('\u{102e1}', '\u{102fb}', EN),
-    ('\u{10300}', '\u{10323}', L), ('\u{10330}', '\u{1034a}', L), ('\u{10350}', '\u{10375}', L),
-    ('\u{10376}', '\u{1037a}', NSM), ('\u{10380}', '\u{1039d}', L), ('\u{1039f}', '\u{103c3}', L),
-    ('\u{103c8}', '\u{103d5}', L), ('\u{10400}', '\u{1049d}', L), ('\u{104a0}', '\u{104a9}', L),
-    ('\u{104b0}', '\u{104d3}', L), ('\u{104d8}', '\u{104fb}', L), ('\u{10500}', '\u{10527}', L),
-    ('\u{10530}', '\u{10563}', L), ('\u{1056f}', '\u{1056f}', L), ('\u{10600}', '\u{10736}', L),
-    ('\u{10740}', '\u{10755}', L), ('\u{10760}', '\u{10767}', L), ('\u{10800}', '\u{1091e}', R),
-    ('\u{1091f}', '\u{1091f}', ON), ('\u{10920}', '\u{10a00}', R), ('\u{10a01}', '\u{10a03}', NSM),
-    ('\u{10a04}', '\u{10a04}', R), ('\u{10a05}', '\u{10a06}', NSM), ('\u{10a07}', '\u{10a0b}', R),
-    ('\u{10a0c}', '\u{10a0f}', NSM), ('\u{10a10}', '\u{10a37}', R), ('\u{10a38}', '\u{10a3a}', NSM),
-    ('\u{10a3b}', '\u{10a3e}', R), ('\u{10a3f}', '\u{10a3f}', NSM), ('\u{10a40}', '\u{10ae4}', R),
-    ('\u{10ae5}', '\u{10ae6}', NSM), ('\u{10ae7}', '\u{10b38}', R), ('\u{10b39}', '\u{10b3f}', ON),
-    ('\u{10b40}', '\u{10e5f}', R), ('\u{10e60}', '\u{10e7e}', AN), ('\u{10e7f}', '\u{10fff}', R),
-    ('\u{11000}', '\u{11000}', L), ('\u{11001}', '\u{11001}', NSM), ('\u{11002}', '\u{11037}', L),
-    ('\u{11038}', '\u{11046}', NSM), ('\u{11047}', '\u{1104d}', L), ('\u{11052}', '\u{11065}', ON),
-    ('\u{11066}', '\u{1106f}', L), ('\u{1107f}', '\u{11081}', NSM), ('\u{11082}', '\u{110b2}', L),
-    ('\u{110b3}', '\u{110b6}', NSM), ('\u{110b7}', '\u{110b8}', L), ('\u{110b9}', '\u{110ba}', NSM),
-    ('\u{110bb}', '\u{110c1}', L), ('\u{110d0}', '\u{110e8}', L), ('\u{110f0}', '\u{110f9}', L),
-    ('\u{11100}', '\u{11102}', NSM), ('\u{11103}', '\u{11126}', L), ('\u{11127}', '\u{1112b}', NSM),
-    ('\u{1112c}', '\u{1112c}', L), ('\u{1112d}', '\u{11134}', NSM), ('\u{11136}', '\u{11143}', L),
-    ('\u{11150}', '\u{11172}', L), ('\u{11173}', '\u{11173}', NSM), ('\u{11174}', '\u{11176}', L),
-    ('\u{11180}', '\u{11181}', NSM), ('\u{11182}', '\u{111b5}', L), ('\u{111b6}', '\u{111be}', NSM),
-    ('\u{111bf}', '\u{111c9}', L), ('\u{111ca}', '\u{111cc}', NSM), ('\u{111cd}', '\u{111cd}', L),
-    ('\u{111d0}', '\u{111df}', L), ('\u{111e1}', '\u{111f4}', L), ('\u{11200}', '\u{11211}', L),
-    ('\u{11213}', '\u{1122e}', L), ('\u{1122f}', '\u{11231}', NSM), ('\u{11232}', '\u{11233}', L),
-    ('\u{11234}', '\u{11234}', NSM), ('\u{11235}', '\u{11235}', L), ('\u{11236}', '\u{11237}', NSM),
-    ('\u{11238}', '\u{1123d}', L), ('\u{1123e}', '\u{1123e}', NSM), ('\u{11280}', '\u{11286}', L),
-    ('\u{11288}', '\u{11288}', L), ('\u{1128a}', '\u{1128d}', L), ('\u{1128f}', '\u{1129d}', L),
-    ('\u{1129f}', '\u{112a9}', L), ('\u{112b0}', '\u{112de}', L), ('\u{112df}', '\u{112df}', NSM),
-    ('\u{112e0}', '\u{112e2}', L), ('\u{112e3}', '\u{112ea}', NSM), ('\u{112f0}', '\u{112f9}', L),
-    ('\u{11300}', '\u{11301}', NSM), ('\u{11302}', '\u{11303}', L), ('\u{11305}', '\u{1130c}', L),
-    ('\u{1130f}', '\u{11310}', L), ('\u{11313}', '\u{11328}', L), ('\u{1132a}', '\u{11330}', L),
-    ('\u{11332}', '\u{11333}', L), ('\u{11335}', '\u{11339}', L), ('\u{1133c}', '\u{1133c}', NSM),
-    ('\u{1133d}', '\u{1133f}', L), ('\u{11340}', '\u{11340}', NSM), ('\u{11341}', '\u{11344}', L),
-    ('\u{11347}', '\u{11348}', L), ('\u{1134b}', '\u{1134d}', L), ('\u{11350}', '\u{11350}', L),
-    ('\u{11357}', '\u{11357}', L), ('\u{1135d}', '\u{11363}', L), ('\u{11366}', '\u{1136c}', NSM),
-    ('\u{11370}', '\u{11374}', NSM), ('\u{11400}', '\u{11437}', L), ('\u{11438}', '\u{1143f}', NSM),
-    ('\u{11440}', '\u{11441}', L), ('\u{11442}', '\u{11444}', NSM), ('\u{11445}', '\u{11445}', L),
-    ('\u{11446}', '\u{11446}', NSM), ('\u{11447}', '\u{11459}', L), ('\u{1145b}', '\u{1145b}', L),
-    ('\u{1145d}', '\u{1145d}', L), ('\u{11480}', '\u{114b2}', L), ('\u{114b3}', '\u{114b8}', NSM),
-    ('\u{114b9}', '\u{114b9}', L), ('\u{114ba}', '\u{114ba}', NSM), ('\u{114bb}', '\u{114be}', L),
-    ('\u{114bf}', '\u{114c0}', NSM), ('\u{114c1}', '\u{114c1}', L), ('\u{114c2}', '\u{114c3}', NSM),
-    ('\u{114c4}', '\u{114c7}', L), ('\u{114d0}', '\u{114d9}', L), ('\u{11580}', '\u{115b1}', L),
-    ('\u{115b2}', '\u{115b5}', NSM), ('\u{115b8}', '\u{115bb}', L), ('\u{115bc}', '\u{115bd}', NSM),
-    ('\u{115be}', '\u{115be}', L), ('\u{115bf}', '\u{115c0}', NSM), ('\u{115c1}', '\u{115db}', L),
-    ('\u{115dc}', '\u{115dd}', NSM), ('\u{11600}', '\u{11632}', L), ('\u{11633}', '\u{1163a}', NSM),
-    ('\u{1163b}', '\u{1163c}', L), ('\u{1163d}', '\u{1163d}', NSM), ('\u{1163e}', '\u{1163e}', L),
-    ('\u{1163f}', '\u{11640}', NSM), ('\u{11641}', '\u{11644}', L), ('\u{11650}', '\u{11659}', L),
-    ('\u{11660}', '\u{1166c}', ON), ('\u{11680}', '\u{116aa}', L), ('\u{116ab}', '\u{116ab}', NSM),
-    ('\u{116ac}', '\u{116ac}', L), ('\u{116ad}', '\u{116ad}', NSM), ('\u{116ae}', '\u{116af}', L),
-    ('\u{116b0}', '\u{116b5}', NSM), ('\u{116b6}', '\u{116b6}', L), ('\u{116b7}', '\u{116b7}', NSM),
-    ('\u{116c0}', '\u{116c9}', L), ('\u{11700}', '\u{11719}', L), ('\u{1171d}', '\u{1171f}', NSM),
-    ('\u{11720}', '\u{11721}', L), ('\u{11722}', '\u{11725}', NSM), ('\u{11726}', '\u{11726}', L),
-    ('\u{11727}', '\u{1172b}', NSM), ('\u{11730}', '\u{1173f}', L), ('\u{118a0}', '\u{118f2}', L),
-    ('\u{118ff}', '\u{118ff}', L), ('\u{11ac0}', '\u{11af8}', L), ('\u{11c00}', '\u{11c08}', L),
-    ('\u{11c0a}', '\u{11c2f}', L), ('\u{11c30}', '\u{11c36}', NSM), ('\u{11c38}', '\u{11c3d}', NSM),
-    ('\u{11c3e}', '\u{11c45}', L), ('\u{11c50}', '\u{11c6c}', L), ('\u{11c70}', '\u{11c8f}', L),
-    ('\u{11c92}', '\u{11ca7}', NSM), ('\u{11ca9}', '\u{11ca9}', L), ('\u{11caa}', '\u{11cb0}', NSM),
-    ('\u{11cb1}', '\u{11cb1}', L), ('\u{11cb2}', '\u{11cb3}', NSM), ('\u{11cb4}', '\u{11cb4}', L),
-    ('\u{11cb5}', '\u{11cb6}', NSM), ('\u{12000}', '\u{12399}', L), ('\u{12400}', '\u{1246e}', L),
-    ('\u{12470}', '\u{12474}', L), ('\u{12480}', '\u{12543}', L), ('\u{13000}', '\u{1342e}', L),
-    ('\u{14400}', '\u{14646}', L), ('\u{16800}', '\u{16a38}', L), ('\u{16a40}', '\u{16a5e}', L),
-    ('\u{16a60}', '\u{16a69}', L), ('\u{16a6e}', '\u{16a6f}', L), ('\u{16ad0}', '\u{16aed}', L),
-    ('\u{16af0}', '\u{16af4}', NSM), ('\u{16af5}', '\u{16af5}', L), ('\u{16b00}', '\u{16b2f}', L),
-    ('\u{16b30}', '\u{16b36}', NSM), ('\u{16b37}', '\u{16b45}', L), ('\u{16b50}', '\u{16b59}', L),
-    ('\u{16b5b}', '\u{16b61}', L), ('\u{16b63}', '\u{16b77}', L), ('\u{16b7d}', '\u{16b8f}', L),
-    ('\u{16f00}', '\u{16f44}', L), ('\u{16f50}', '\u{16f7e}', L), ('\u{16f8f}', '\u{16f92}', NSM),
-    ('\u{16f93}', '\u{16f9f}', L), ('\u{16fe0}', '\u{16fe0}', L), ('\u{17000}', '\u{187ec}', L),
-    ('\u{18800}', '\u{18af2}', L), ('\u{1b000}', '\u{1b001}', L), ('\u{1bc00}', '\u{1bc6a}', L),
-    ('\u{1bc70}', '\u{1bc7c}', L), ('\u{1bc80}', '\u{1bc88}', L), ('\u{1bc90}', '\u{1bc99}', L),
-    ('\u{1bc9c}', '\u{1bc9c}', L), ('\u{1bc9d}', '\u{1bc9e}', NSM), ('\u{1bc9f}', '\u{1bc9f}', L),
-    ('\u{1bca0}', '\u{1bca3}', BN), ('\u{1d000}', '\u{1d0f5}', L), ('\u{1d100}', '\u{1d126}', L),
-    ('\u{1d129}', '\u{1d166}', L), ('\u{1d167}', '\u{1d169}', NSM), ('\u{1d16a}', '\u{1d172}', L),
-    ('\u{1d173}', '\u{1d17a}', BN), ('\u{1d17b}', '\u{1d182}', NSM), ('\u{1d183}', '\u{1d184}', L),
-    ('\u{1d185}', '\u{1d18b}', NSM), ('\u{1d18c}', '\u{1d1a9}', L), ('\u{1d1aa}', '\u{1d1ad}', NSM),
-    ('\u{1d1ae}', '\u{1d1e8}', L), ('\u{1d200}', '\u{1d241}', ON), ('\u{1d242}', '\u{1d244}', NSM),
-    ('\u{1d245}', '\u{1d245}', ON), ('\u{1d300}', '\u{1d356}', ON), ('\u{1d360}', '\u{1d371}', L),
-    ('\u{1d400}', '\u{1d454}', L), ('\u{1d456}', '\u{1d49c}', L), ('\u{1d49e}', '\u{1d49f}', L),
-    ('\u{1d4a2}', '\u{1d4a2}', L), ('\u{1d4a5}', '\u{1d4a6}', L), ('\u{1d4a9}', '\u{1d4ac}', L),
-    ('\u{1d4ae}', '\u{1d4b9}', L), ('\u{1d4bb}', '\u{1d4bb}', L), ('\u{1d4bd}', '\u{1d4c3}', L),
-    ('\u{1d4c5}', '\u{1d505}', L), ('\u{1d507}', '\u{1d50a}', L), ('\u{1d50d}', '\u{1d514}', L),
-    ('\u{1d516}', '\u{1d51c}', L), ('\u{1d51e}', '\u{1d539}', L), ('\u{1d53b}', '\u{1d53e}', L),
-    ('\u{1d540}', '\u{1d544}', L), ('\u{1d546}', '\u{1d546}', L), ('\u{1d54a}', '\u{1d550}', L),
-    ('\u{1d552}', '\u{1d6a5}', L), ('\u{1d6a8}', '\u{1d6da}', L), ('\u{1d6db}', '\u{1d6db}', ON),
-    ('\u{1d6dc}', '\u{1d714}', L), ('\u{1d715}', '\u{1d715}', ON), ('\u{1d716}', '\u{1d74e}', L),
-    ('\u{1d74f}', '\u{1d74f}', ON), ('\u{1d750}', '\u{1d788}', L), ('\u{1d789}', '\u{1d789}', ON),
-    ('\u{1d78a}', '\u{1d7c2}', L), ('\u{1d7c3}', '\u{1d7c3}', ON), ('\u{1d7c4}', '\u{1d7cb}', L),
-    ('\u{1d7ce}', '\u{1d7ff}', EN), ('\u{1d800}', '\u{1d9ff}', L), ('\u{1da00}', '\u{1da36}', NSM),
-    ('\u{1da37}', '\u{1da3a}', L), ('\u{1da3b}', '\u{1da6c}', NSM), ('\u{1da6d}', '\u{1da74}', L),
-    ('\u{1da75}', '\u{1da75}', NSM), ('\u{1da76}', '\u{1da83}', L), ('\u{1da84}', '\u{1da84}', NSM),
-    ('\u{1da85}', '\u{1da8b}', L), ('\u{1da9b}', '\u{1da9f}', NSM), ('\u{1daa1}', '\u{1daaf}', NSM),
-    ('\u{1e000}', '\u{1e006}', NSM), ('\u{1e008}', '\u{1e018}', NSM), ('\u{1e01b}', '\u{1e021}',
-    NSM), ('\u{1e023}', '\u{1e024}', NSM), ('\u{1e026}', '\u{1e02a}', NSM), ('\u{1e800}',
-    '\u{1e8cf}', R), ('\u{1e8d0}', '\u{1e8d6}', NSM), ('\u{1e8d7}', '\u{1e943}', R), ('\u{1e944}',
-    '\u{1e94a}', NSM), ('\u{1e94b}', '\u{1edff}', R), ('\u{1ee00}', '\u{1eeef}', AL), ('\u{1eef0}',
-    '\u{1eef1}', ON), ('\u{1eef2}', '\u{1eeff}', AL), ('\u{1ef00}', '\u{1efff}', R), ('\u{1f000}',
-    '\u{1f02b}', ON), ('\u{1f030}', '\u{1f093}', ON), ('\u{1f0a0}', '\u{1f0ae}', ON), ('\u{1f0b1}',
-    '\u{1f0bf}', ON), ('\u{1f0c1}', '\u{1f0cf}', ON), ('\u{1f0d1}', '\u{1f0f5}', ON), ('\u{1f100}',
-    '\u{1f10a}', EN), ('\u{1f10b}', '\u{1f10c}', ON), ('\u{1f110}', '\u{1f12e}', L), ('\u{1f130}',
-    '\u{1f169}', L), ('\u{1f16a}', '\u{1f16b}', ON), ('\u{1f170}', '\u{1f1ac}', L), ('\u{1f1e6}',
-    '\u{1f202}', L), ('\u{1f210}', '\u{1f23b}', L), ('\u{1f240}', '\u{1f248}', L), ('\u{1f250}',
-    '\u{1f251}', L), ('\u{1f300}', '\u{1f6d2}', ON), ('\u{1f6e0}', '\u{1f6ec}', ON), ('\u{1f6f0}',
-    '\u{1f6f6}', ON), ('\u{1f700}', '\u{1f773}', ON), ('\u{1f780}', '\u{1f7d4}', ON), ('\u{1f800}',
-    '\u{1f80b}', ON), ('\u{1f810}', '\u{1f847}', ON), ('\u{1f850}', '\u{1f859}', ON), ('\u{1f860}',
-    '\u{1f887}', ON), ('\u{1f890}', '\u{1f8ad}', ON), ('\u{1f910}', '\u{1f91e}', ON), ('\u{1f920}',
-    '\u{1f927}', ON), ('\u{1f930}', '\u{1f930}', ON), ('\u{1f933}', '\u{1f93e}', ON), ('\u{1f940}',
-    '\u{1f94b}', ON), ('\u{1f950}', '\u{1f95e}', ON), ('\u{1f980}', '\u{1f991}', ON), ('\u{1f9c0}',
-    '\u{1f9c0}', ON), ('\u{20000}', '\u{2a6d6}', L), ('\u{2a700}', '\u{2b734}', L), ('\u{2b740}',
-    '\u{2b81d}', L), ('\u{2b820}', '\u{2cea1}', L), ('\u{2f800}', '\u{2fa1d}', L), ('\u{e0001}',
-    '\u{e0001}', BN), ('\u{e0020}', '\u{e007f}', BN), ('\u{e0100}', '\u{e01ef}', NSM), ('\u{f0000}',
-    '\u{ffffd}', L), ('\u{100000}', '\u{10fffd}', L)
-];
-
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/deprecated.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2015 The Servo Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! This module holds deprecated assets only.
-
-use super::*;
-
-/// Find the level runs within a line and return them in visual order.
-///
-/// NOTE: This implementation is incomplete. The algorithm needs information about the text,
-/// including original BidiClass property of each character, to be able to perform correctly.
-/// Please see [`BidiInfo::visual_runs()`](../struct.BidiInfo.html#method.visual_runs) for the
-/// improved implementation.
-///
-/// `line` is a range of bytes indices within `levels`.
-///
-/// http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
-#[deprecated(since="0.3.0", note="please use `BidiInfo::visual_runs()` instead.")]
-pub fn visual_runs(line: Range<usize>, levels: &[Level]) -> Vec<LevelRun> {
-    assert!(line.start <= levels.len());
-    assert!(line.end <= levels.len());
-
-    let mut runs = Vec::new();
-
-    // Find consecutive level runs.
-    let mut start = line.start;
-    let mut level = levels[start];
-    let mut min_level = level;
-    let mut max_level = level;
-
-    for i in (start + 1)..line.end {
-        let new_level = levels[i];
-        if new_level != level {
-            // End of the previous run, start of a new one.
-            runs.push(start..i);
-            start = i;
-            level = new_level;
-
-            min_level = min(level, min_level);
-            max_level = max(level, max_level);
-        }
-    }
-    runs.push(start..line.end);
-
-    let run_count = runs.len();
-
-    // Re-order the odd runs.
-    // http://www.unicode.org/reports/tr9/#L2
-
-    // Stop at the lowest *odd* level.
-    min_level = min_level.new_lowest_ge_rtl().expect("Level error");
-
-    while max_level >= min_level {
-        // Look for the start of a sequence of consecutive runs of max_level or higher.
-        let mut seq_start = 0;
-        while seq_start < run_count {
-            if levels[runs[seq_start].start] < max_level {
-                seq_start += 1;
-                continue;
-            }
-
-            // Found the start of a sequence. Now find the end.
-            let mut seq_end = seq_start + 1;
-            while seq_end < run_count {
-                if levels[runs[seq_end].start] < max_level {
-                    break;
-                }
-                seq_end += 1;
-            }
-
-            // Reverse the runs within this sequence.
-            runs[seq_start..seq_end].reverse();
-
-            seq_start = seq_end;
-        }
-        max_level
-            .lower(1)
-            .expect("Lowering embedding level below zero");
-    }
-
-    runs
-}
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/explicit.rs
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2015 The Servo Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! 3.3.2 Explicit Levels and Directions
-//!
-//! http://www.unicode.org/reports/tr9/#Explicit_Levels_and_Directions
-
-use super::char_data::{BidiClass, is_rtl};
-use super::level::Level;
-
-use BidiClass::*;
-
-/// Compute explicit embedding levels for one paragraph of text (X1-X8).
-///
-/// `processing_classes[i]` must contain the BidiClass of the char at byte index `i`,
-/// for each char in `text`.
-pub fn compute(
-    text: &str,
-    para_level: Level,
-    initial_classes: &[BidiClass],
-    levels: &mut [Level],
-    processing_classes: &mut [BidiClass],
-) {
-    assert!(text.len() == initial_classes.len());
-
-    // http://www.unicode.org/reports/tr9/#X1
-    let mut stack = DirectionalStatusStack::new();
-    stack.push(para_level, OverrideStatus::Neutral);
-
-    let mut overflow_isolate_count = 0u32;
-    let mut overflow_embedding_count = 0u32;
-    let mut valid_isolate_count = 0u32;
-
-    for (i, c) in text.char_indices() {
-        match initial_classes[i] {
-
-            // Rules X2-X5c
-            RLE | LRE | RLO | LRO | RLI | LRI | FSI => {
-                let last_level = stack.last().level;
-
-                // X5a-X5c: Isolate initiators get the level of the last entry on the stack.
-                let is_isolate = matches!(initial_classes[i], RLI | LRI | FSI);
-                if is_isolate {
-                    levels[i] = last_level;
-                    match stack.last().status {
-                        OverrideStatus::RTL => processing_classes[i] = R,
-                        OverrideStatus::LTR => processing_classes[i] = L,
-                        _ => {}
-                    }
-                }
-
-                let new_level = if is_rtl(initial_classes[i]) {
-                    last_level.new_explicit_next_rtl()
-                } else {
-                    last_level.new_explicit_next_ltr()
-                };
-                if new_level.is_ok() && overflow_isolate_count == 0 &&
-                   overflow_embedding_count == 0 {
-                    let new_level = new_level.unwrap();
-                    stack.push(
-                        new_level,
-                        match initial_classes[i] {
-                            RLO => OverrideStatus::RTL,
-                            LRO => OverrideStatus::LTR,
-                            RLI | LRI | FSI => OverrideStatus::Isolate,
-                            _ => OverrideStatus::Neutral,
-                        },
-                    );
-                    if is_isolate {
-                        valid_isolate_count += 1;
-                    } else {
-                        // The spec doesn't explicitly mention this step, but it is necessary.
-                        // See the reference implementations for comparison.
-                        levels[i] = new_level;
-                    }
-                } else if is_isolate {
-                    overflow_isolate_count += 1;
-                } else if overflow_isolate_count == 0 {
-                    overflow_embedding_count += 1;
-                }
-            }
-
-            // http://www.unicode.org/reports/tr9/#X6a
-            PDI => {
-                if overflow_isolate_count > 0 {
-                    overflow_isolate_count -= 1;
-                } else if valid_isolate_count > 0 {
-                    overflow_embedding_count = 0;
-                    loop {
-                        // Pop everything up to and including the last Isolate status.
-                        match stack.vec.pop() {
-                            Some(Status { status: OverrideStatus::Isolate, .. }) => break,
-                            None => break,
-                            _ => continue,
-                        }
-                    }
-                    valid_isolate_count -= 1;
-                }
-                let last = stack.last();
-                levels[i] = last.level;
-                match last.status {
-                    OverrideStatus::RTL => processing_classes[i] = R,
-                    OverrideStatus::LTR => processing_classes[i] = L,
-                    _ => {}
-                }
-            }
-
-            // http://www.unicode.org/reports/tr9/#X7
-            PDF => {
-                if overflow_isolate_count > 0 {
-                    continue;
-                }
-                if overflow_embedding_count > 0 {
-                    overflow_embedding_count -= 1;
-                    continue;
-                }
-                if stack.last().status != OverrideStatus::Isolate && stack.vec.len() >= 2 {
-                    stack.vec.pop();
-                }
-                // The spec doesn't explicitly mention this step, but it is necessary.
-                // See the reference implementations for comparison.
-                levels[i] = stack.last().level;
-            }
-
-            // Nothing
-            B | BN => {}
-
-            // http://www.unicode.org/reports/tr9/#X6
-            _ => {
-                let last = stack.last();
-                levels[i] = last.level;
-                match last.status {
-                    OverrideStatus::RTL => processing_classes[i] = R,
-                    OverrideStatus::LTR => processing_classes[i] = L,
-                    _ => {}
-                }
-            }
-        }
-
-        // Handle multi-byte characters.
-        for j in 1..c.len_utf8() {
-            levels[i + j] = levels[i];
-            processing_classes[i + j] = processing_classes[i];
-        }
-    }
-}
-
-/// Entries in the directional status stack:
-struct Status {
-    level: Level,
-    status: OverrideStatus,
-}
-
-#[derive(PartialEq)]
-enum OverrideStatus {
-    Neutral,
-    RTL,
-    LTR,
-    Isolate,
-}
-
-struct DirectionalStatusStack {
-    vec: Vec<Status>,
-}
-
-impl DirectionalStatusStack {
-    fn new() -> Self {
-        DirectionalStatusStack { vec: Vec::with_capacity(Level::max_explicit_depth() as usize + 2) }
-    }
-
-    fn push(&mut self, level: Level, status: OverrideStatus) {
-        self.vec
-            .push(
-                Status {
-                    level: level,
-                    status: status,
-                },
-            );
-    }
-
-    fn last(&self) -> &Status {
-        self.vec.last().unwrap()
-    }
-}
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/format_chars.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The html5ever Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Directional Formatting Characters
-//!
-//! http://www.unicode.org/reports/tr9/#Directional_Formatting_Characters
-
-// == Implicit ==
-/// ARABIC LETTER MARK
-pub const ALM: char = '\u{061C}';
-/// LEFT-TO-RIGHT MARK
-pub const LRM: char = '\u{200E}';
-/// RIGHT-TO-LEFT MARK
-pub const RLM: char = '\u{200F}';
-
-// == Explicit Isolates ==
-/// LEFT‑TO‑RIGHT ISOLATE
-pub const LRI: char = '\u{2066}';
-/// RIGHT‑TO‑LEFT ISOLATE
-pub const RLI: char = '\u{2067}';
-/// FIRST STRONG ISOLATE
-pub const FSI: char = '\u{2068}';
-/// POP DIRECTIONAL ISOLATE
-pub const PDI: char = '\u{2069}';
-
-// == Explicit Embeddings and Overrides ==
-/// LEFT-TO-RIGHT EMBEDDING
-pub const LRE: char = '\u{202A}';
-/// RIGHT-TO-LEFT EMBEDDING
-pub const RLE: char = '\u{202B}';
-/// LEFT-TO-RIGHT OVERRIDE
-pub const LRO: char = '\u{202D}';
-/// RIGHT-TO-LEFT OVERRIDE
-pub const RLO: char = '\u{202E}';
-/// POP DIRECTIONAL FORMATTING
-pub const PDF: char = '\u{202C}';
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/implicit.rs
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright 2015 The Servo Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! 3.3.4 - 3.3.6. Resolve implicit levels and types.
-
-use std::cmp::max;
-
-use super::char_data::BidiClass;
-use super::prepare::{IsolatingRunSequence, LevelRun, not_removed_by_x9, removed_by_x9};
-use super::level::Level;
-
-use BidiClass::*;
-
-/// 3.3.4 Resolving Weak Types
-///
-/// http://www.unicode.org/reports/tr9/#Resolving_Weak_Types
-pub fn resolve_weak(sequence: &IsolatingRunSequence, processing_classes: &mut [BidiClass]) {
-    // FIXME (#8): This function applies steps W1-W6 in a single pass.  This can produce
-    // incorrect results in cases where a "later" rule changes the value of `prev_class` seen
-    // by an "earlier" rule.  We should either split this into separate passes, or preserve
-    // extra state so each rule can see the correct previous class.
-
-    let mut prev_class = sequence.sos;
-    let mut last_strong_is_al = false;
-    let mut et_run_indices = Vec::new(); // for W5
-
-    // Like sequence.runs.iter().flat_map(Clone::clone), but make indices itself clonable.
-    fn id(x: LevelRun) -> LevelRun {
-        x
-    }
-    let mut indices = sequence
-        .runs
-        .iter()
-        .cloned()
-        .flat_map(id as fn(LevelRun) -> LevelRun);
-
-    while let Some(i) = indices.next() {
-        match processing_classes[i] {
-            // http://www.unicode.org/reports/tr9/#W1
-            NSM => {
-                processing_classes[i] = match prev_class {
-                    RLI | LRI | FSI | PDI => ON,
-                    _ => prev_class,
-                };
-            }
-            EN => {
-                if last_strong_is_al {
-                    // W2. If previous strong char was AL, change EN to AN.
-                    processing_classes[i] = AN;
-                } else {
-                    // W5. If a run of ETs is adjacent to an EN, change the ETs to EN.
-                    for j in &et_run_indices {
-                        processing_classes[*j] = EN;
-                    }
-                    et_run_indices.clear();
-                }
-            }
-            // http://www.unicode.org/reports/tr9/#W3
-            AL => processing_classes[i] = R,
-
-            // http://www.unicode.org/reports/tr9/#W4
-            ES | CS => {
-                let next_class = indices
-                    .clone()
-                    .map(|j| processing_classes[j])
-                    .filter(not_removed_by_x9)
-                    .next()
-                    .unwrap_or(sequence.eos);
-                processing_classes[i] = match (prev_class, processing_classes[i], next_class) {
-                    (EN, ES, EN) | (EN, CS, EN) => EN,
-                    (AN, CS, AN) => AN,
-                    (_, _, _) => ON,
-                }
-            }
-            // http://www.unicode.org/reports/tr9/#W5
-            ET => {
-                match prev_class {
-                    EN => processing_classes[i] = EN,
-                    _ => et_run_indices.push(i), // In case this is followed by an EN.
-                }
-            }
-            class => {
-                if removed_by_x9(class) {
-                    continue;
-                }
-            }
-        }
-
-        prev_class = processing_classes[i];
-        match prev_class {
-            L | R => {
-                last_strong_is_al = false;
-            }
-            AL => {
-                last_strong_is_al = true;
-            }
-            _ => {}
-        }
-        if prev_class != ET {
-            // W6. If we didn't find an adjacent EN, turn any ETs into ON instead.
-            for j in &et_run_indices {
-                processing_classes[*j] = ON;
-            }
-            et_run_indices.clear();
-        }
-    }
-
-    // W7. If the previous strong char was L, change EN to L.
-    let mut last_strong_is_l = sequence.sos == L;
-    for run in &sequence.runs {
-        for i in run.clone() {
-            match processing_classes[i] {
-                EN if last_strong_is_l => {
-                    processing_classes[i] = L;
-                }
-                L => {
-                    last_strong_is_l = true;
-                }
-                R | AL => {
-                    last_strong_is_l = false;
-                }
-                _ => {}
-            }
-        }
-    }
-}
-
-/// 3.3.5 Resolving Neutral Types
-///
-/// http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types
-pub fn resolve_neutral(
-    sequence: &IsolatingRunSequence,
-    levels: &[Level],
-    processing_classes: &mut [BidiClass],
-) {
-    let mut indices = sequence.runs.iter().flat_map(Clone::clone);
-    let mut prev_class = sequence.sos;
-
-    // Neutral or Isolate formatting characters (NI).
-    // http://www.unicode.org/reports/tr9/#NI
-    fn ni(class: BidiClass) -> bool {
-        matches!(class, B | S | WS | ON | FSI | LRI | RLI | PDI)
-    }
-
-    while let Some(mut i) = indices.next() {
-        // N0. Process bracket pairs.
-        // TODO
-
-        // Process sequences of NI characters.
-        let mut ni_run = Vec::new();
-        if ni(processing_classes[i]) {
-            // Consume a run of consecutive NI characters.
-            ni_run.push(i);
-            let mut next_class;
-            loop {
-                match indices.next() {
-                    Some(j) => {
-                        i = j;
-                        if removed_by_x9(processing_classes[i]) {
-                            continue;
-                        }
-                        next_class = processing_classes[j];
-                        if ni(next_class) {
-                            ni_run.push(i);
-                        } else {
-                            break;
-                        }
-                    }
-                    None => {
-                        next_class = sequence.eos;
-                        break;
-                    }
-                };
-            }
-
-            // N1-N2.
-            let new_class = match (prev_class, next_class) {
-                (L, L) => L,
-                (R, R) | (R, AN) | (R, EN) | (AN, R) | (AN, AN) | (AN, EN) | (EN, R) |
-                (EN, AN) | (EN, EN) => R,
-                (_, _) => levels[i].bidi_class(),
-            };
-            for j in &ni_run {
-                processing_classes[*j] = new_class;
-            }
-            ni_run.clear();
-        }
-        prev_class = processing_classes[i];
-    }
-}
-
-/// 3.3.6 Resolving Implicit Levels
-///
-/// Returns the maximum embedding level in the paragraph.
-///
-/// http://www.unicode.org/reports/tr9/#Resolving_Implicit_Levels
-pub fn resolve_levels(original_classes: &[BidiClass], levels: &mut [Level]) -> Level {
-    let mut max_level = Level::ltr();
-
-    assert!(original_classes.len() == levels.len());
-    for i in 0..levels.len() {
-        match (levels[i].is_rtl(), original_classes[i]) {
-            // http://www.unicode.org/reports/tr9/#I1
-            (false, R) => levels[i].raise(1).expect("Level number error"),
-            (false, AN) | (false, EN) => levels[i].raise(2).expect("Level number error"),
-            // http://www.unicode.org/reports/tr9/#I2
-            (true, L) | (true, EN) | (true, AN) => levels[i].raise(1).expect("Level number error"),
-            (_, _) => {}
-        }
-        max_level = max(max_level, levels[i]);
-    }
-
-    max_level
-}
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/level.rs
+++ /dev/null
@@ -1,382 +0,0 @@
-// Copyright 2017 The Servo Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Bidi Embedding Level
-//!
-//! See [`Level`](struct.Level.html) for more details.
-//!
-//! http://www.unicode.org/reports/tr9/#BD2
-
-use std::convert::{From, Into};
-
-use super::char_data::BidiClass;
-
-/// Embedding Level
-///
-/// Embedding Levels are numbers between 0 and 126 (inclusive), where even values denote a
-/// left-to-right (LTR) direction and odd values a right-to-left (RTL) direction.
-///
-/// This struct maintains a *valid* status for level numbers, meaning that creating a new level, or
-/// mutating an existing level, with the value smaller than `0` (before conversion to `u8`) or
-/// larger than 125 results in an `Error`.
-///
-/// http://www.unicode.org/reports/tr9/#BD2
-#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
-#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
-pub struct Level(u8);
-
-pub const LTR_LEVEL: Level = Level(0);
-pub const RTL_LEVEL: Level = Level(1);
-
-const MAX_DEPTH: u8 = 125;
-/// During explicit level resolution, embedding level can go as high as `max_depth`.
-pub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;
-/// During implicit level resolution, embedding level can go as high as `max_depth + 1`.
-pub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;
-
-/// Errors that can occur on Level creation or mutation
-#[derive(Debug, PartialEq)]
-pub enum Error {
-    /// Out-of-range (invalid) embedding level number.
-    OutOfRangeNumber,
-}
-
-impl Level {
-    /// New LTR level with smallest number value (0).
-    #[inline]
-    pub fn ltr() -> Level {
-        LTR_LEVEL
-    }
-
-    /// New RTL level with smallest number value (1).
-    #[inline]
-    pub fn rtl() -> Level {
-        RTL_LEVEL
-    }
-
-    /// Maximum depth of the directional status stack during implicit resolutions.
-    pub fn max_implicit_depth() -> u8 {
-        MAX_IMPLICIT_DEPTH
-    }
-
-    /// Maximum depth of the directional status stack during explicit resolutions.
-    pub fn max_explicit_depth() -> u8 {
-        MAX_EXPLICIT_DEPTH
-    }
-
-    // == Inquiries ==
-
-    /// Create new level, fail if number is larger than `max_depth + 1`.
-    #[inline]
-    pub fn new(number: u8) -> Result<Level, Error> {
-        if number <= MAX_IMPLICIT_DEPTH {
-            Ok(Level(number))
-        } else {
-            Err(Error::OutOfRangeNumber)
-        }
-    }
-
-    /// Create new level, fail if number is larger than `max_depth`.
-    #[inline]
-    pub fn new_explicit(number: u8) -> Result<Level, Error> {
-        if number <= MAX_EXPLICIT_DEPTH {
-            Ok(Level(number))
-        } else {
-            Err(Error::OutOfRangeNumber)
-        }
-    }
-
-    // == Inquiries ==
-
-    /// The level number.
-    #[inline]
-    pub fn number(&self) -> u8 {
-        self.0
-    }
-
-    /// If this level is left-to-right.
-    #[inline]
-    pub fn is_ltr(&self) -> bool {
-        self.0 % 2 == 0
-    }
-
-    /// If this level is right-to-left.
-    #[inline]
-    pub fn is_rtl(&self) -> bool {
-        self.0 % 2 == 1
-    }
-
-    // == Mutators ==
-
-    /// Raise level by `amount`, fail if number is larger than `max_depth + 1`.
-    #[inline]
-    pub fn raise(&mut self, amount: u8) -> Result<(), Error> {
-        match self.0.checked_add(amount) {
-            Some(number) => {
-                if number <= MAX_IMPLICIT_DEPTH {
-                    self.0 = number;
-                    Ok(())
-                } else {
-                    Err(Error::OutOfRangeNumber)
-                }
-            }
-            None => Err(Error::OutOfRangeNumber),
-        }
-    }
-
-    /// Raise level by `amount`, fail if number is larger than `max_depth`.
-    #[inline]
-    pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {
-        match self.0.checked_add(amount) {
-            Some(number) => {
-                if number <= MAX_EXPLICIT_DEPTH {
-                    self.0 = number;
-                    Ok(())
-                } else {
-                    Err(Error::OutOfRangeNumber)
-                }
-            }
-            None => Err(Error::OutOfRangeNumber),
-        }
-    }
-
-    /// Lower level by `amount`, fail if number goes below zero.
-    #[inline]
-    pub fn lower(&mut self, amount: u8) -> Result<(), Error> {
-        match self.0.checked_sub(amount) {
-            Some(number) => {
-                self.0 = number;
-                Ok(())
-            }
-            None => Err(Error::OutOfRangeNumber),
-        }
-    }
-
-    // == Helpers ==
-
-    /// The next LTR (even) level greater than this, or fail if number is larger than `max_depth`.
-    #[inline]
-    pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {
-        Level::new_explicit(self.0 + 2 & !1)
-    }
-
-    /// The next RTL (odd) level greater than this, or fail if number is larger than `max_depth`.
-    #[inline]
-    pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {
-        Level::new_explicit((self.0 + 1) | 1)
-    }
-
-    /// The lowest RTL (odd) level greater than or equal to this, or fail if number is larger than
-    /// `max_depth + 1`.
-    #[inline]
-    pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {
-        Level::new(self.0 | 1)
-    }
-
-    /// Generate a character type based on a level (as specified in steps X10 and N2).
-    #[inline]
-    pub fn bidi_class(&self) -> BidiClass {
-        if self.is_rtl() {
-            BidiClass::R
-        } else {
-            BidiClass::L
-        }
-    }
-
-    pub fn vec(v: &[u8]) -> Vec<Level> {
-        v.iter().map(|&x| x.into()).collect()
-    }
-}
-
-/// If levels has any RTL (odd) level
-///
-/// This information is usually used to skip re-ordering of text when no RTL level is present
-#[inline]
-pub fn has_rtl(levels: &[Level]) -> bool {
-    levels.iter().any(|&lvl| lvl.is_rtl())
-}
-
-impl Into<u8> for Level {
-    /// Convert to the level number
-    #[inline]
-    fn into(self) -> u8 {
-        self.number()
-    }
-}
-
-impl From<u8> for Level {
-    /// Create level by number
-    #[inline]
-    fn from(number: u8) -> Level {
-        Level::new(number).expect("Level number error")
-    }
-}
-
-/// Used for matching levels in conformance tests
-impl<'a> PartialEq<&'a str> for Level {
-    #[inline]
-    fn eq(&self, s: &&'a str) -> bool {
-        *s == "x" || *s == self.0.to_string()
-    }
-}
-
-/// Used for matching levels in conformance tests
-impl<'a> PartialEq<String> for Level {
-    #[inline]
-    fn eq(&self, s: &String) -> bool {
-        self == &s.as_str()
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_new() {
-        assert_eq!(Level::new(0), Ok(Level(0)));
-        assert_eq!(Level::new(1), Ok(Level(1)));
-        assert_eq!(Level::new(10), Ok(Level(10)));
-        assert_eq!(Level::new(125), Ok(Level(125)));
-        assert_eq!(Level::new(126), Ok(Level(126)));
-        assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));
-        assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));
-    }
-
-    #[test]
-    fn test_new_explicit() {
-        assert_eq!(Level::new_explicit(0), Ok(Level(0)));
-        assert_eq!(Level::new_explicit(1), Ok(Level(1)));
-        assert_eq!(Level::new_explicit(10), Ok(Level(10)));
-        assert_eq!(Level::new_explicit(125), Ok(Level(125)));
-        assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));
-        assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));
-    }
-
-    #[test]
-    fn test_is_ltr() {
-        assert_eq!(Level(0).is_ltr(), true);
-        assert_eq!(Level(1).is_ltr(), false);
-        assert_eq!(Level(10).is_ltr(), true);
-        assert_eq!(Level(11).is_ltr(), false);
-        assert_eq!(Level(124).is_ltr(), true);
-        assert_eq!(Level(125).is_ltr(), false);
-    }
-
-    #[test]
-    fn test_is_rtl() {
-        assert_eq!(Level(0).is_rtl(), false);
-        assert_eq!(Level(1).is_rtl(), true);
-        assert_eq!(Level(10).is_rtl(), false);
-        assert_eq!(Level(11).is_rtl(), true);
-        assert_eq!(Level(124).is_rtl(), false);
-        assert_eq!(Level(125).is_rtl(), true);
-    }
-
-    #[test]
-    fn test_raise() {
-        let mut level = Level::ltr();
-        assert_eq!(level.number(), 0);
-        assert!(level.raise(100).is_ok());
-        assert_eq!(level.number(), 100);
-        assert!(level.raise(26).is_ok());
-        assert_eq!(level.number(), 126);
-        assert!(level.raise(1).is_err()); // invalid!
-        assert!(level.raise(250).is_err()); // overflow!
-        assert_eq!(level.number(), 126);
-    }
-
-    #[test]
-    fn test_raise_explicit() {
-        let mut level = Level::ltr();
-        assert_eq!(level.number(), 0);
-        assert!(level.raise_explicit(100).is_ok());
-        assert_eq!(level.number(), 100);
-        assert!(level.raise_explicit(25).is_ok());
-        assert_eq!(level.number(), 125);
-        assert!(level.raise_explicit(1).is_err()); // invalid!
-        assert!(level.raise_explicit(250).is_err()); // overflow!
-        assert_eq!(level.number(), 125);
-    }
-
-    #[test]
-    fn test_lower() {
-        let mut level = Level::rtl();
-        assert_eq!(level.number(), 1);
-        assert!(level.lower(1).is_ok());
-        assert_eq!(level.number(), 0);
-        assert!(level.lower(1).is_err()); // underflow!
-        assert!(level.lower(250).is_err()); // underflow!
-        assert_eq!(level.number(), 0);
-    }
-
-    #[test]
-    fn test_has_rtl() {
-        assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);
-        assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);
-        assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);
-        assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);
-        assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);
-    }
-
-    #[test]
-    fn test_into() {
-        let level = Level::rtl();
-        assert_eq!(1u8, level.into());
-    }
-
-    #[test]
-    fn test_vec() {
-        assert_eq!(
-            Level::vec(&[0, 1, 125]),
-            vec![Level(0), Level(1), Level(125)]
-        );
-    }
-
-    #[test]
-    fn test_str_eq() {
-        assert_eq!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "x", "125"]);
-        assert_ne!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "5", "125"]);
-    }
-
-    #[test]
-    fn test_string_eq() {
-        assert_eq!(
-            Level::vec(&[0, 1, 4, 125]),
-            vec!["0".to_string(), "1".to_string(), "x".to_string(), "125".to_string()]
-        );
-    }
-}
-
-#[cfg(all(feature = "with_serde", test))]
-mod serde_tests {
-    use serde_test::{Token, assert_tokens};
-    use super::*;
-
-    #[test]
-    fn test_statics() {
-        assert_tokens(
-            &Level::ltr(),
-            &[Token::NewtypeStruct { name: "Level" }, Token::U8(0)],
-        );
-        assert_tokens(
-            &Level::rtl(),
-            &[Token::NewtypeStruct { name: "Level" }, Token::U8(1)],
-        );
-    }
-
-    #[test]
-    fn test_new() {
-        let level = Level::new(42).unwrap();
-        assert_tokens(
-            &level,
-            &[Token::NewtypeStruct { name: "Level" }, Token::U8(42)],
-        );
-    }
-}
--- a/third_party/rust/unicode-bidi/src/lib.rs
+++ b/third_party/rust/unicode-bidi/src/lib.rs
@@ -1,755 +1,1027 @@
-// Copyright 2015 The Servo Project Developers. See the
+// Copyright 2014 The html5ever Project Developers. See the
 // COPYRIGHT file at the top-level directory of this distribution.
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 //! This crate implements the [Unicode Bidirectional Algorithm][tr9] for display of mixed
 //! right-to-left and left-to-right text.  It is written in safe Rust, compatible with the
 //! current stable release.
 //!
 //! ## Example
 //!
 //! ```rust
-//! use unicode_bidi::BidiInfo;
+//! use unicode_bidi::{process_text, reorder_line};
 //!
 //! // This example text is defined using `concat!` because some browsers
 //! // and text editors have trouble displaying bidi strings.
-//! let text = concat![
-//!   "א",
-//!   "ב",
-//!   "ג",
-//!   "a",
-//!   "b",
-//!   "c",
-//! ];
+//! let text = concat!["א",
+//!                    "ב",
+//!                    "ג",
+//!                    "a",
+//!                    "b",
+//!                    "c"];
 //!
 //! // Resolve embedding levels within the text.  Pass `None` to detect the
 //! // paragraph level automatically.
-//! let bidi_info = BidiInfo::new(&text, None);
+//! let info = process_text(&text, None);
 //!
 //! // This paragraph has embedding level 1 because its first strong character is RTL.
-//! assert_eq!(bidi_info.paragraphs.len(), 1);
-//! let para = &bidi_info.paragraphs[0];
-//! assert_eq!(para.level.number(), 1);
-//! assert_eq!(para.level.is_rtl(), true);
+//! assert_eq!(info.paragraphs.len(), 1);
+//! let paragraph_info = &info.paragraphs[0];
+//! assert_eq!(paragraph_info.level, 1);
 //!
 //! // Re-ordering is done after wrapping each paragraph into a sequence of
 //! // lines. For this example, I'll just use a single line that spans the
 //! // entire paragraph.
-//! let line = para.range.clone();
+//! let line = paragraph_info.range.clone();
 //!
-//! let display = bidi_info.reorder_line(para, line);
-//! assert_eq!(display, concat![
-//!   "a",
-//!   "b",
-//!   "c",
-//!   "ג",
-//!   "ב",
-//!   "א",
-//! ]);
+//! let display = reorder_line(&text, line, &info.levels);
+//! assert_eq!(display, concat!["a",
+//!                             "b",
+//!                             "c",
+//!                             "ג",
+//!                             "ב",
+//!                             "א"]);
 //! ```
 //!
 //! [tr9]: http://www.unicode.org/reports/tr9/
 
 #![forbid(unsafe_code)]
 
-#[macro_use]
-extern crate matches;
-
-#[cfg(feature = "with_serde")]
-#[macro_use]
-extern crate serde_derive;
-
-#[cfg(all(feature = "with_serde", test))]
-extern crate serde_test;
+#[macro_use] extern crate matches;
 
-pub mod deprecated;
-pub mod format_chars;
-pub mod level;
+pub mod tables;
 
-mod char_data;
-mod explicit;
-mod implicit;
-mod prepare;
-
-pub use char_data::{BidiClass, bidi_class, UNICODE_VERSION};
-pub use level::Level;
-pub use prepare::LevelRun;
+pub use tables::{BidiClass, bidi_class, UNICODE_VERSION};
+use BidiClass::*;
 
 use std::borrow::Cow;
 use std::cmp::{max, min};
 use std::iter::repeat;
 use std::ops::Range;
 
-use BidiClass::*;
-use format_chars as chars;
-
-
-/// Bidi information about a single paragraph
+/// Output of `process_text`
+///
+/// The `classes` and `levels` vectors are indexed by byte offsets into the text.  If a character
+/// is multiple bytes wide, then its class and level will appear multiple times in these vectors.
 #[derive(Debug, PartialEq)]
-pub struct ParagraphInfo {
-    /// The paragraphs boundaries within the text, as byte indices.
-    ///
-    /// TODO: Shrink this to only include the starting index?
-    pub range: Range<usize>,
-
-    /// The paragraph embedding level.
-    ///
-    /// http://www.unicode.org/reports/tr9/#BD4
-    pub level: Level,
-}
-
-/// Initial bidi information of the text
-///
-/// Contains the paragraphs and BidiClasses in a string of text.
-#[derive(PartialEq, Debug)]
-pub struct InitialInfo<'text> {
-    /// The text
-    pub text: &'text str,
-
+pub struct BidiInfo {
     /// The BidiClass of the character at each byte in the text.
-    /// If a character is multiple bytes, its class will appear multiple times in the vector.
-    pub original_classes: Vec<BidiClass>,
-
-    /// The boundaries and level of each paragraph within the text.
-    pub paragraphs: Vec<ParagraphInfo>,
-}
-
-impl<'text> InitialInfo<'text> {
-    /// Find the paragraphs and BidiClasses in a string of text.
-    ///
-    /// http://www.unicode.org/reports/tr9/#The_Paragraph_Level
-    ///
-    /// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong
-    /// character is found before the matching PDI.  If no strong character is found, the class will
-    /// remain FSI, and it's up to later stages to treat these as LRI when needed.
-    pub fn new(text: &str, default_para_level: Option<Level>) -> InitialInfo {
-        let mut original_classes = Vec::with_capacity(text.len());
-
-        // The stack contains the starting byte index for each nested isolate we're inside.
-        let mut isolate_stack = Vec::new();
-        let mut paragraphs = Vec::new();
-
-        let mut para_start = 0;
-        let mut para_level = default_para_level;
-
-        for (i, c) in text.char_indices() {
-            let class = bidi_class(c);
-            original_classes.extend(repeat(class).take(c.len_utf8()));
-            match class {
-                B => {
-                    // P1. Split the text into separate paragraphs. The paragraph separator is kept
-                    // with the previous paragraph.
-                    let para_end = i + c.len_utf8();
-                    paragraphs.push(
-                        ParagraphInfo {
-                            range: para_start..para_end,
-                            // P3. If no character is found in p2, set the paragraph level to zero.
-                            level: para_level.unwrap_or(Level::ltr()),
-                        },
-                    );
-                    // Reset state for the start of the next paragraph.
-                    para_start = para_end;
-                    // TODO: Support defaulting to direction of previous paragraph
-                    //
-                    // http://www.unicode.org/reports/tr9/#HL1
-                    para_level = default_para_level;
-                    isolate_stack.clear();
-                }
-                L | R | AL => {
-                    match isolate_stack.last() {
-                        Some(&start) => {
-                            if original_classes[start] == FSI {
-                                // X5c. If the first strong character between FSI and its matching
-                                // PDI is R or AL, treat it as RLI. Otherwise, treat it as LRI.
-                                for j in 0..chars::FSI.len_utf8() {
-                                    original_classes[start + j] =
-                                        if class == L { LRI } else { RLI };
-                                }
-                            }
-                        }
-                        None => {
-                            if para_level.is_none() {
-                                // P2. Find the first character of type L, AL, or R, while skipping
-                                // any characters between an isolate initiator and its matching
-                                // PDI.
-                                para_level = Some(
-                                    if class != L {
-                                        Level::rtl()
-                                    } else {
-                                        Level::ltr()
-                                    },
-                                );
-                            }
-                        }
-                    }
-                }
-                RLI | LRI | FSI => {
-                    isolate_stack.push(i);
-                }
-                PDI => {
-                    isolate_stack.pop();
-                }
-                _ => {}
-            }
-        }
-        if para_start < text.len() {
-            paragraphs.push(
-                ParagraphInfo {
-                    range: para_start..text.len(),
-                    level: para_level.unwrap_or(Level::ltr()),
-                },
-            );
-        }
-        assert!(original_classes.len() == text.len());
-
-        InitialInfo {
-            text: text,
-            original_classes: original_classes,
-            paragraphs: paragraphs,
-        }
-    }
-}
-
-/// Bidi information of the text
-///
-/// The `original_classes` and `levels` vectors are indexed by byte offsets into the text.  If a
-/// character is multiple bytes wide, then its class and level will appear multiple times in these
-/// vectors.
-// TODO: Impl `struct StringProperty<T> { values: Vec<T> }` and use instead of Vec<T>
-#[derive(Debug, PartialEq)]
-pub struct BidiInfo<'text> {
-    /// The text
-    pub text: &'text str,
-
-    /// The BidiClass of the character at each byte in the text.
-    pub original_classes: Vec<BidiClass>,
+    pub classes: Vec<BidiClass>,
 
     /// The directional embedding level of each byte in the text.
-    pub levels: Vec<Level>,
+    pub levels: Vec<u8>,
 
     /// The boundaries and paragraph embedding level of each paragraph within the text.
     ///
     /// TODO: Use SmallVec or similar to avoid overhead when there are only one or two paragraphs?
     /// Or just don't include the first paragraph, which always starts at 0?
     pub paragraphs: Vec<ParagraphInfo>,
 }
 
-impl<'text> BidiInfo<'text> {
-    /// Split the text into paragraphs and determine the bidi embedding levels for each paragraph.
-    ///
-    /// TODO: In early steps, check for special cases that allow later steps to be skipped. like
-    /// text that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.
+/// Info about a single paragraph 
+#[derive(Debug, PartialEq)]
+pub struct ParagraphInfo {
+    /// The paragraphs boundaries within the text, as byte indices.
     ///
-    /// TODO: Support auto-RTL base direction
-    pub fn new(text: &str, default_para_level: Option<Level>) -> BidiInfo {
-        let InitialInfo {
-            text: _,
-            original_classes,
-            paragraphs,
-        } = InitialInfo::new(text, default_para_level);
-
-        let mut levels = Vec::<Level>::with_capacity(text.len());
-        let mut processing_classes = original_classes.clone();
+    /// TODO: Shrink this to only include the starting index?
+    pub range: Range<usize>,
 
-        for para in &paragraphs {
-            let text = &text[para.range.clone()];
-            let original_classes = &original_classes[para.range.clone()];
-            let processing_classes = &mut processing_classes[para.range.clone()];
+    /// The paragraph embedding level. http://www.unicode.org/reports/tr9/#BD4
+    pub level: u8,
+}
 
-            let new_len = levels.len() + para.range.len();
-            levels.resize(new_len, para.level);
-            let levels = &mut levels[para.range.clone()];
-
-            explicit::compute(
-                text,
-                para.level,
-                &original_classes,
-                levels,
-                processing_classes,
-            );
+/// Determine the bidirectional embedding levels for a single paragraph.
+///
+/// TODO: In early steps, check for special cases that allow later steps to be skipped. like text
+/// that is entirely LTR.  See the `nsBidi` class from Gecko for comparison.
+pub fn process_text(text: &str, level: Option<u8>) -> BidiInfo {
+    let InitialProperties { initial_classes, paragraphs } = initial_scan(text, level);
 
-            let sequences = prepare::isolating_run_sequences(para.level, &original_classes, levels);
-            for sequence in &sequences {
-                implicit::resolve_weak(sequence, processing_classes);
-                implicit::resolve_neutral(sequence, levels, processing_classes);
-            }
-            implicit::resolve_levels(processing_classes, levels);
+    let mut levels = Vec::with_capacity(text.len());
+    let mut classes = initial_classes.clone();
 
-            assign_levels_to_removed_chars(para.level, &original_classes, levels);
-        }
-
-        BidiInfo {
-            text: text,
-            original_classes: original_classes,
-            paragraphs: paragraphs,
-            levels: levels,
-        }
-    }
+    for para in &paragraphs {
+        let text = &text[para.range.clone()];
+        let classes = &mut classes[para.range.clone()];
+        let initial_classes = &initial_classes[para.range.clone()];
 
-    /// Re-order a line based on resolved levels and return only the embedding levels.
-    pub fn reordered_levels(&self, para: &ParagraphInfo, line: Range<usize>) -> Vec<Level> {
-        let (levels, _) = self.visual_runs(para, line.clone());
-        levels
-    }
+        // FIXME: Use `levels.resize(...)` when it becomes stable.
+        levels.extend(repeat(para.level).take(para.range.len()));
+        let levels = &mut levels[para.range.clone()];
+
+        explicit::compute(text, para.level, &initial_classes, levels, classes);
 
-    /// Re-order a line based on resolved levels and return the line in display order.
-    pub fn reorder_line(&self, para: &ParagraphInfo, line: Range<usize>) -> Cow<'text, str> {
-        let (levels, runs) = self.visual_runs(para, line.clone());
-        if runs.len() == 1 && levels[runs[0].start].is_ltr() {
-            return self.text.into();
+        let sequences = prepare::isolating_run_sequences(para.level, &initial_classes, levels);
+        for sequence in &sequences {
+            implicit::resolve_weak(sequence, classes);
+            implicit::resolve_neutral(sequence, levels, classes);
         }
-        let mut result = String::with_capacity(line.len());
-        for run in runs {
-            if levels[run.start].is_rtl() {
-                result.extend(self.text[run].chars().rev());
-            } else {
-                result.push_str(&self.text[run]);
-            }
-        }
-        result.into()
+        implicit::resolve_levels(classes, levels);
+        assign_levels_to_removed_chars(para.level, &initial_classes, levels);
     }
 
-    /// Find the level runs within a line and return them in visual order.
-    ///
-    /// `line` is a range of bytes indices within `levels`.
-    ///
-    /// http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
-    pub fn visual_runs(
-        &self,
-        para: &ParagraphInfo,
-        line: Range<usize>,
-    ) -> (Vec<Level>, Vec<LevelRun>) {
-        assert!(line.start <= self.levels.len());
-        assert!(line.end <= self.levels.len());
+    BidiInfo {
+        levels: levels,
+        classes: initial_classes,
+        paragraphs: paragraphs,
+    }
+}
 
-        let mut levels = self.levels.clone();
+#[inline]
+/// Even embedding levels are left-to-right.
+///
+/// http://www.unicode.org/reports/tr9/#BD2
+pub fn is_ltr(level: u8) -> bool { level % 2 == 0 }
+
+#[inline]
+/// Odd levels are right-to-left.
+///
+/// http://www.unicode.org/reports/tr9/#BD2
+pub fn is_rtl(level: u8) -> bool { level % 2 == 1 }
+
+/// Generate a character type based on a level (as specified in steps X10 and N2).
+fn class_for_level(level: u8) -> BidiClass {
+    if is_rtl(level) { R } else { L }
+}
 
-        // Reset some whitespace chars to paragraph level.
-        // http://www.unicode.org/reports/tr9/#L1
-        let line_str: &str = &self.text[line.clone()];
-        let mut reset_from: Option<usize> = None;
-        let mut reset_to: Option<usize> = None;
-        for (i, c) in line_str.char_indices() {
-            match self.original_classes[i] {
-                // Segment separator, Paragraph separator
-                B | S => {
-                    assert!(reset_to == None);
-                    reset_to = Some(i + c.len_utf8());
-                    if reset_from == None {
-                        reset_from = Some(i);
-                    }
-                }
-                // Whitespace, isolate formatting
-                WS | FSI | LRI | RLI | PDI => {
-                    if reset_from == None {
-                        reset_from = Some(i);
-                    }
-                }
-                _ => {
-                    reset_from = None;
-                }
-            }
-            if let (Some(from), Some(to)) = (reset_from, reset_to) {
-                for j in from..to {
-                    levels[j] = para.level;
-                }
-                reset_from = None;
-                reset_to = None;
-            }
+/// Re-order a line based on resolved levels.
+///
+/// `levels` are the embedding levels returned by `process_text`.
+/// `line` is a range of bytes indices within `text`.
+///
+/// Returns the line in display order.
+pub fn reorder_line<'a>(text: &'a str, line: Range<usize>, levels: &[u8])
+    -> Cow<'a, str>
+{
+    let runs = visual_runs(line.clone(), &levels);
+    if runs.len() == 1 && !is_rtl(levels[runs[0].start]) {
+        return text.into()
+    }
+    let mut result = String::with_capacity(line.len());
+    for run in runs {
+        if is_rtl(levels[run.start]) {
+            result.extend(text[run].chars().rev());
+        } else {
+            result.push_str(&text[run]);
         }
-        if let Some(from) = reset_from {
-            for j in from..line_str.len() {
-                levels[j] = para.level;
-            }
-        }
+    }
+    result.into()
+}
+
+/// A maximal substring of characters with the same embedding level.
+///
+/// Represented as a range of byte indices.
+pub type LevelRun = Range<usize>;
 
-        // Find consecutive level runs.
-        let mut runs = Vec::new();
-        let mut start = line.start;
-        let mut level = levels[start];
-        let mut min_level = level;
-        let mut max_level = level;
+/// Find the level runs within a line and return them in visual order.
+///
+/// `line` is a range of bytes indices within `levels`.
+///
+/// http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
+pub fn visual_runs(line: Range<usize>, levels: &[u8]) -> Vec<LevelRun> {
+    assert!(line.start <= levels.len());
+    assert!(line.end <= levels.len());
+
+    // TODO: Whitespace handling.
+    // http://www.unicode.org/reports/tr9/#L1
+
+    let mut runs = Vec::new();
 
-        for i in (start + 1)..line.end {
-            let new_level = levels[i];
-            if new_level != level {
-                // End of the previous run, start of a new one.
-                runs.push(start..i);
-                start = i;
-                level = new_level;
+    // Find consecutive level runs.
+    let mut start = line.start;
+    let mut level = levels[start];
+    let mut min_level = level;
+    let mut max_level = level;
 
-                min_level = min(level, min_level);
-                max_level = max(level, max_level);
-            }
-        }
-        runs.push(start..line.end);
-
-        let run_count = runs.len();
-
-        // Re-order the odd runs.
-        // http://www.unicode.org/reports/tr9/#L2
-
-        // Stop at the lowest *odd* level.
-        min_level = min_level.new_lowest_ge_rtl().expect("Level error");
+    for i in (start + 1)..line.end {
+        let new_level = levels[i];
+        if new_level != level {
+            // End of the previous run, start of a new one.
+            runs.push(start..i);
+            start = i;
+            level = new_level;
 
-        while max_level >= min_level {
-            // Look for the start of a sequence of consecutive runs of max_level or higher.
-            let mut seq_start = 0;
-            while seq_start < run_count {
-                if self.levels[runs[seq_start].start] < max_level {
-                    seq_start += 1;
-                    continue;
-                }
+            min_level = min(level, min_level);
+            max_level = max(level, max_level);
+        }
+    }
+    runs.push(start..line.end);
+
+    let run_count = runs.len();
+
+    // Re-order the odd runs.
+    // http://www.unicode.org/reports/tr9/#L2
+
+    // Stop at the lowest *odd* level.
+    min_level |= 1;
 
-                // Found the start of a sequence. Now find the end.
-                let mut seq_end = seq_start + 1;
-                while seq_end < run_count {
-                    if self.levels[runs[seq_end].start] < max_level {
-                        break;
-                    }
-                    seq_end += 1;
-                }
+    while max_level >= min_level {
+        // Look for the start of a sequence of consecutive runs of max_level or higher.
+        let mut seq_start = 0;
+        while seq_start < run_count {
+            if levels[runs[seq_start].start] < max_level {
+                seq_start += 1;
+                continue
+            }
 
-                // Reverse the runs within this sequence.
-                runs[seq_start..seq_end].reverse();
-
-                seq_start = seq_end;
+            // Found the start of a sequence. Now find the end.
+            let mut seq_end = seq_start + 1;
+            while seq_end < run_count {
+                if levels[runs[seq_end].start] < max_level {
+                    break
+                }
+                seq_end += 1;
             }
-            max_level
-                .lower(1)
-                .expect("Lowering embedding level below zero");
+
+            // Reverse the runs within this sequence.
+            runs[seq_start..seq_end].reverse();
+
+            seq_start = seq_end;
         }
-
-        (levels, runs)
+        max_level -= 1;
     }
 
-    /// If processed text has any computed RTL levels
-    ///
-    /// This information is usually used to skip re-ordering of text when no RTL level is present
-    #[inline]
-    pub fn has_rtl(&self) -> bool {
-        level::has_rtl(&self.levels)
+    runs
+}
+
+/// Output of `initial_scan`
+#[derive(PartialEq, Debug)]
+pub struct InitialProperties {
+    /// The BidiClass of the character at each byte in the text.
+    /// If a character is multiple bytes, its class will appear multiple times in the vector.
+    pub initial_classes: Vec<BidiClass>,
+
+    /// The boundaries and level of each paragraph within the text.
+    pub paragraphs: Vec<ParagraphInfo>,
+}
+
+/// Find the paragraphs and BidiClasses in a string of text.
+///
+/// http://www.unicode.org/reports/tr9/#The_Paragraph_Level
+///
+/// Also sets the class for each First Strong Isolate initiator (FSI) to LRI or RLI if a strong
+/// character is found before the matching PDI.  If no strong character is found, the class will
+/// remain FSI, and it's up to later stages to treat these as LRI when needed.
+pub fn initial_scan(text: &str, default_para_level: Option<u8>) -> InitialProperties {
+    let mut classes = Vec::with_capacity(text.len());
+
+    // The stack contains the starting byte index for each nested isolate we're inside.
+    let mut isolate_stack = Vec::new();
+    let mut paragraphs = Vec::new();
+
+    let mut para_start = 0;
+    let mut para_level = default_para_level;
+
+    const FSI_CHAR: char = '\u{2069}';
+
+    for (i, c) in text.char_indices() {
+        let class = bidi_class(c);
+        classes.extend(repeat(class).take(c.len_utf8()));
+        match class {
+            B => {
+                // P1. Split the text into separate paragraphs. The paragraph separator is kept
+                // with the previous paragraph.
+                let para_end = i + c.len_utf8();
+                paragraphs.push(ParagraphInfo {
+                    range: para_start..para_end,
+                    // P3. If no character is found in p2, set the paragraph level to zero.
+                    level: para_level.unwrap_or(0)
+                });
+                // Reset state for the start of the next paragraph.
+                para_start = para_end;
+                para_level = default_para_level;
+                isolate_stack.clear();
+            }
+            L | R | AL => match isolate_stack.last() {
+                Some(&start) => if classes[start] == FSI {
+                    // X5c. If the first strong character between FSI and its matching PDI is R
+                    // or AL, treat it as RLI. Otherwise, treat it as LRI.
+                    for j in 0..FSI_CHAR.len_utf8() {
+                        classes[start+j] = if class == L { LRI } else { RLI };
+                    }
+                },
+                None => if para_level.is_none() {
+                    // P2. Find the first character of type L, AL, or R, while skipping any
+                    // characters between an isolate initiator and its matching PDI.
+                    para_level = Some(if class == L { 0 } else { 1 });
+                }
+            },
+            RLI | LRI | FSI => {
+                isolate_stack.push(i);
+            }
+            PDI => {
+                isolate_stack.pop();
+            }
+            _ => {}
+        }
+    }
+    if para_start < text.len() {
+        paragraphs.push(ParagraphInfo {
+            range: para_start..text.len(),
+            level: para_level.unwrap_or(0)
+        });
+    }
+    assert!(classes.len() == text.len());
+
+    InitialProperties {
+        initial_classes: classes,
+        paragraphs: paragraphs,
     }
 }
 
 /// Assign levels to characters removed by rule X9.
 ///
 /// The levels assigned to these characters are not specified by the algorithm.  This function
 /// assigns each one the level of the previous character, to avoid breaking level runs.
-fn assign_levels_to_removed_chars(para_level: Level, classes: &[BidiClass], levels: &mut [Level]) {
+fn assign_levels_to_removed_chars(para_level: u8, classes: &[BidiClass], levels: &mut [u8]) {
     for i in 0..levels.len() {
         if prepare::removed_by_x9(classes[i]) {
-            levels[i] = if i > 0 { levels[i - 1] } else { para_level };
+            levels[i] = if i > 0 { levels[i-1] } else { para_level };
+        }
+    }
+}
+
+/// 3.3.2 Explicit Levels and Directions
+///
+/// http://www.unicode.org/reports/tr9/#Explicit_Levels_and_Directions
+mod explicit {
+    use super::{BidiClass, is_rtl};
+    use super::BidiClass::*;
+
+    /// Compute explicit embedding levels for one paragraph of text (X1-X8).
+    ///
+    /// `classes[i]` must contain the BidiClass of the char at byte index `i`,
+    /// for each char in `text`.
+    pub fn compute(text: &str, para_level: u8, initial_classes: &[BidiClass],
+                   levels: &mut [u8], classes: &mut [BidiClass]) {
+        assert!(text.len() == initial_classes.len());
+
+        // http://www.unicode.org/reports/tr9/#X1
+        let mut stack = DirectionalStatusStack::new();
+        stack.push(para_level, OverrideStatus::Neutral);
+
+        let mut overflow_isolate_count = 0u32;
+        let mut overflow_embedding_count = 0u32;
+        let mut valid_isolate_count = 0u32;
+
+        for (i, c) in text.char_indices() {
+            match initial_classes[i] {
+                // Rules X2-X5c
+                RLE | LRE | RLO | LRO | RLI | LRI | FSI => {
+                    let is_rtl = match initial_classes[i] {
+                        RLE | RLO | RLI => true,
+                        _ => false
+                    };
+
+                    let last_level = stack.last().level;
+                    let new_level = match is_rtl {
+                        true  => next_rtl_level(last_level),
+                        false => next_ltr_level(last_level)
+                    };
+
+                    // X5a-X5c: Isolate initiators get the level of the last entry on the stack.
+                    let is_isolate = matches!(initial_classes[i], RLI | LRI | FSI);
+                    if is_isolate {
+                        levels[i] = last_level;
+                        match stack.last().status {
+                            OverrideStatus::RTL => classes[i] = R,
+                            OverrideStatus::LTR => classes[i] = L,
+                            _ => {}
+                        }
+                    }
+
+                    if valid(new_level) && overflow_isolate_count == 0 && overflow_embedding_count == 0 {
+                        stack.push(new_level, match initial_classes[i] {
+                            RLO => OverrideStatus::RTL,
+                            LRO => OverrideStatus::LTR,
+                            RLI | LRI | FSI => OverrideStatus::Isolate,
+                            _ => OverrideStatus::Neutral
+                        });
+                        if is_isolate {
+                            valid_isolate_count += 1;
+                        } else {
+                            // The spec doesn't explicitly mention this step, but it is necessary.
+                            // See the reference implementations for comparison.
+                            levels[i] = new_level;
+                        }
+                    } else if is_isolate {
+                        overflow_isolate_count += 1;
+                    } else if overflow_isolate_count == 0 {
+                        overflow_embedding_count += 1;
+                    }
+                }
+                // http://www.unicode.org/reports/tr9/#X6a
+                PDI => {
+                    if overflow_isolate_count > 0 {
+                        overflow_isolate_count -= 1;
+                    } else if valid_isolate_count > 0 {
+                        overflow_embedding_count = 0;
+                        loop {
+                            // Pop everything up to and including the last Isolate status.
+                            match stack.vec.pop() {
+                                Some(Status { status: OverrideStatus::Isolate, .. }) => break,
+                                None => break,
+                                _ => continue
+                            }
+                        }
+                        valid_isolate_count -= 1;
+                    }
+                    let last = stack.last();
+                    levels[i] = last.level;
+                    match last.status {
+                        OverrideStatus::RTL => classes[i] = R,
+                        OverrideStatus::LTR => classes[i] = L,
+                        _ => {}
+                    }
+                }
+                // http://www.unicode.org/reports/tr9/#X7
+                PDF => {
+                    if overflow_isolate_count > 0 {
+                        continue
+                    }
+                    if overflow_embedding_count > 0 {
+                        overflow_embedding_count -= 1;
+                        continue
+                    }
+                    if stack.last().status != OverrideStatus::Isolate && stack.vec.len() >= 2 {
+                        stack.vec.pop();
+                    }
+                    // The spec doesn't explicitly mention this step, but it is necessary.
+                    // See the reference implementations for comparison.
+                    levels[i] = stack.last().level;
+                }
+                // http://www.unicode.org/reports/tr9/#X6
+                B | BN => {}
+                _ => {
+                    let last = stack.last();
+                    levels[i] = last.level;
+                    match last.status {
+                        OverrideStatus::RTL => classes[i] = R,
+                        OverrideStatus::LTR => classes[i] = L,
+                        _ => {}
+                    }
+                }
+            }
+            // Handle multi-byte characters.
+            for j in 1..c.len_utf8() {
+                levels[i+j] = levels[i];
+                classes[i+j] = classes[i];
+            }
+        }
+    }
+
+    /// Maximum depth of the directional status stack.
+    pub const MAX_DEPTH: u8 = 125;
+
+    /// Levels from 0 through max_depth are valid at this stage.
+    /// http://www.unicode.org/reports/tr9/#X1
+    fn valid(level: u8) -> bool { level <= MAX_DEPTH }
+
+    /// The next odd level greater than `level`.
+    fn next_rtl_level(level: u8) -> u8 { (level + 1) |  1 }
+
+    /// The next even level greater than `level`.
+    fn next_ltr_level(level: u8) -> u8 { (level + 2) & !1 }
+
+    /// Entries in the directional status stack:
+    struct Status {
+        level: u8,
+        status: OverrideStatus,
+    }
+
+    #[derive(PartialEq)]
+    enum OverrideStatus { Neutral, RTL, LTR, Isolate }
+
+    struct DirectionalStatusStack {
+        vec: Vec<Status>,
+    }
+
+    impl DirectionalStatusStack {
+        fn new() -> Self {
+            DirectionalStatusStack {
+                vec: Vec::with_capacity(MAX_DEPTH as usize + 2)
+            }
+        }
+        fn push(&mut self, level: u8, status: OverrideStatus) {
+            self.vec.push(Status { level: level, status: status });
+        }
+        fn last(&self) -> &Status {
+            self.vec.last().unwrap()
         }
     }
 }
 
+/// 3.3.3 Preparations for Implicit Processing
+///
+/// http://www.unicode.org/reports/tr9/#Preparations_for_Implicit_Processing
+mod prepare {
+    use super::{BidiClass, class_for_level, LevelRun};
+    use super::BidiClass::*;
+    use std::cmp::max;
+
+    /// Output of `isolating_run_sequences` (steps X9-X10)
+    pub struct IsolatingRunSequence {
+        pub runs: Vec<LevelRun>,
+        pub sos: BidiClass, // Start-of-sequence type.
+        pub eos: BidiClass, // End-of-sequence type.
+    }
+
+    /// Compute the set of isolating run sequences.
+    ///
+    /// An isolating run sequence is a maximal sequence of level runs such that for all level runs
+    /// except the last one in the sequence, the last character of the run is an isolate initiator
+    /// whose matching PDI is the first character of the next level run in the sequence.
+    ///
+    /// Note: This function does *not* return the sequences in order by their first characters.
+    pub fn isolating_run_sequences(para_level: u8, initial_classes: &[BidiClass], levels: &[u8])
+        -> Vec<IsolatingRunSequence>
+    {
+        let runs = level_runs(levels, initial_classes);
+
+        // Compute the set of isolating run sequences.
+        // http://www.unicode.org/reports/tr9/#BD13
+
+        let mut sequences = Vec::with_capacity(runs.len());
+
+        // When we encounter an isolate initiator, we push the current sequence onto the
+        // stack so we can resume it after the matching PDI.
+        let mut stack = vec![Vec::new()];
+
+        for run in runs {
+            assert!(run.len() > 0);
+            assert!(stack.len() > 0);
+
+            let start_class = initial_classes[run.start];
+            let end_class = initial_classes[run.end - 1];
+
+            let mut sequence = if start_class == PDI && stack.len() > 1 {
+                // Continue a previous sequence interrupted by an isolate.
+                stack.pop().unwrap()
+            } else {
+                // Start a new sequence.
+                Vec::new()
+            };
+
+            sequence.push(run);
+
+            if matches!(end_class, RLI | LRI | FSI) {
+                // Resume this sequence after the isolate.
+                stack.push(sequence);
+            } else {
+                // This sequence is finished.
+                sequences.push(sequence);
+            }
+        }
+        // Pop any remaning sequences off the stack.
+        sequences.extend(stack.into_iter().rev().filter(|seq| seq.len() > 0));
+
+        // Determine the `sos` and `eos` class for each sequence.
+        // http://www.unicode.org/reports/tr9/#X10
+        return sequences.into_iter().map(|sequence| {
+            assert!(!sequence.len() > 0);
+            let start = sequence[0].start;
+            let end = sequence[sequence.len() - 1].end;
+
+            // Get the level inside these level runs.
+            let level = levels[start];
+
+            // Get the level of the last non-removed char before the runs.
+            let pred_level = match initial_classes[..start].iter().rposition(not_removed_by_x9) {
+                Some(idx) => levels[idx],
+                None => para_level
+            };
+
+            // Get the level of the next non-removed char after the runs.
+            let succ_level = if matches!(initial_classes[end - 1], RLI|LRI|FSI) {
+                para_level
+            } else {
+                match initial_classes[end..].iter().position(not_removed_by_x9) {
+                    Some(idx) => levels[idx],
+                    None => para_level
+                }
+            };
+
+            IsolatingRunSequence {
+                runs: sequence,
+                sos: class_for_level(max(level, pred_level)),
+                eos: class_for_level(max(level, succ_level)),
+            }
+        }).collect()
+    }
+
+    /// Finds the level runs in a paragraph.
+    ///
+    /// http://www.unicode.org/reports/tr9/#BD7
+    fn level_runs(levels: &[u8], classes: &[BidiClass]) -> Vec<LevelRun> {
+        assert!(levels.len() == classes.len());
+
+        let mut runs = Vec::new();
+        if levels.len() == 0 {
+            return runs
+        }
+
+        let mut current_run_level = levels[0];
+        let mut current_run_start = 0;
+
+        for i in 1..levels.len() {
+            if !removed_by_x9(classes[i]) {
+                if levels[i] != current_run_level {
+                    // End the last run and start a new one.
+                    runs.push(current_run_start..i);
+                    current_run_level = levels[i];
+                    current_run_start = i;
+                }
+            }
+        }
+        runs.push(current_run_start..levels.len());
+        runs
+    }
+
+    /// Should this character be ignored in steps after X9?
+    ///
+    /// http://www.unicode.org/reports/tr9/#X9
+    pub fn removed_by_x9(class: BidiClass) -> bool {
+        matches!(class, RLE | LRE | RLO | LRO | PDF | BN)
+    }
+
+    // For use as a predicate for `position` / `rposition`
+    pub fn not_removed_by_x9(class: &BidiClass) -> bool {
+        !removed_by_x9(*class)
+    }
+
+    #[cfg(test)] #[test]
+    fn test_level_runs() {
+        assert_eq!(level_runs(&[0,0,0,1,1,2,0,0], &[L; 8]), &[0..3, 3..5, 5..6, 6..8]);
+    }
+
+    #[cfg(test)] #[test]
+    fn test_isolating_run_sequences() {
+        // Example 3 from http://www.unicode.org/reports/tr9/#BD13:
+
+        //              0  1    2   3    4  5  6  7    8   9   10
+        let classes = &[L, RLI, AL, LRI, L, R, L, PDI, AL, PDI, L];
+        let levels =  &[0, 0,   1,  1,   2, 3, 2, 1,   1,  0,   0];
+        let para_level = 0;
+
+        let sequences = isolating_run_sequences(para_level, classes, levels);
+        let runs: Vec<Vec<LevelRun>> = sequences.iter().map(|s| s.runs.clone()).collect();
+        assert_eq!(runs, vec![vec![4..5], vec![5..6], vec![6..7], vec![2..4, 7..9], vec![0..2, 9..11]]);
+    }
+}
+
+/// 3.3.4 - 3.3.6. Resolve implicit levels and types.
+mod implicit {
+    use super::{BidiClass, class_for_level, is_rtl, LevelRun};
+    use super::BidiClass::*;
+    use super::prepare::{IsolatingRunSequence, not_removed_by_x9, removed_by_x9};
+    use std::cmp::max;
+
+    /// 3.3.4 Resolving Weak Types
+    ///
+    /// http://www.unicode.org/reports/tr9/#Resolving_Weak_Types
+    pub fn resolve_weak(sequence: &IsolatingRunSequence, classes: &mut [BidiClass]) {
+        // FIXME (#8): This function applies steps W1-W6 in a single pass.  This can produce
+        // incorrect results in cases where a "later" rule changes the value of `prev_class` seen
+        // by an "earlier" rule.  We should either split this into separate passes, or preserve
+        // extra state so each rule can see the correct previous class.
+
+        let mut prev_class = sequence.sos;
+        let mut last_strong_is_al = false;
+        let mut et_run_indices = Vec::new(); // for W5
+
+        // Like sequence.runs.iter().flat_map(Clone::clone), but make indices itself clonable.
+        fn id(x: LevelRun) -> LevelRun { x }
+        let mut indices = sequence.runs.iter().cloned().flat_map(id as fn(LevelRun) -> LevelRun);
+
+        while let Some(i) = indices.next() {
+            match classes[i] {
+                // http://www.unicode.org/reports/tr9/#W1
+                NSM => {
+                    classes[i] = match prev_class {
+                        RLI | LRI | FSI | PDI => ON,
+                        _ => prev_class
+                    };
+                }
+                EN => {
+                    if last_strong_is_al {
+                        // W2. If previous strong char was AL, change EN to AN.
+                        classes[i] = AN;
+                    } else {
+                        // W5. If a run of ETs is adjacent to an EN, change the ETs to EN.
+                        for j in &et_run_indices {
+                            classes[*j] = EN;
+                        }
+                        et_run_indices.clear();
+                    }
+                }
+                // http://www.unicode.org/reports/tr9/#W3
+                AL => classes[i] = R,
+
+                // http://www.unicode.org/reports/tr9/#W4
+                ES | CS => {
+                    let next_class = indices.clone().map(|j| classes[j]).filter(not_removed_by_x9)
+                        .next().unwrap_or(sequence.eos);
+                    classes[i] = match (prev_class, classes[i], next_class) {
+                        (EN, ES, EN) |
+                        (EN, CS, EN) => EN,
+                        (AN, CS, AN) => AN,
+                        (_,  _,  _ ) => ON,
+                    }
+                }
+                // http://www.unicode.org/reports/tr9/#W5
+                ET => {
+                    match prev_class {
+                        EN => classes[i] = EN,
+                        _ => et_run_indices.push(i) // In case this is followed by an EN.
+                    }
+                }
+                class => if removed_by_x9(class) {
+                    continue
+                }
+            }
+
+            prev_class = classes[i];
+            match prev_class {
+                L | R => { last_strong_is_al = false; }
+                AL => { last_strong_is_al = true;  }
+                _ => {}
+            }
+            if prev_class != ET {
+                // W6. If we didn't find an adjacent EN, turn any ETs into ON instead.
+                for j in &et_run_indices {
+                    classes[*j] = ON;
+                }
+                et_run_indices.clear();
+            }
+        }
+
+        // W7. If the previous strong char was L, change EN to L.
+        let mut last_strong_is_l = sequence.sos == L;
+        for run in &sequence.runs {
+            for i in run.clone() {
+                match classes[i] {
+                    EN if last_strong_is_l => { classes[i] = L; }
+                    L => { last_strong_is_l = true; }
+                    R | AL => { last_strong_is_l = false; }
+                    _ => {}
+                }
+            }
+        }
+    }
+
+    /// 3.3.5 Resolving Neutral Types
+    ///
+    /// http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types
+    pub fn resolve_neutral(sequence: &IsolatingRunSequence, levels: &[u8],
+                           classes: &mut [BidiClass])
+    {
+        let mut indices = sequence.runs.iter().flat_map(Clone::clone);
+        let mut prev_class = sequence.sos;
+
+        // Neutral or Isolate formatting characters (NI).
+        // http://www.unicode.org/reports/tr9/#NI
+        fn ni(class: BidiClass) -> bool {
+            matches!(class, B | S | WS | ON | FSI | LRI | RLI | PDI)
+        }
+
+        while let Some(mut i) = indices.next() {
+            // N0. Process bracket pairs.
+            // TODO
+
+            // Process sequences of NI characters.
+            let mut ni_run = Vec::new();
+            if ni(classes[i]) {
+                // Consume a run of consecutive NI characters.
+                ni_run.push(i);
+                let mut next_class;
+                loop {
+                    match indices.next() {
+                        Some(j) => {
+                            i = j;
+                            if removed_by_x9(classes[i]) {
+                                continue
+                            }
+                            next_class = classes[j];
+                            if ni(next_class) {
+                                ni_run.push(i);
+                            } else {
+                                break
+                            }
+                        }
+                        None => {
+                            next_class = sequence.eos;
+                            break
+                        }
+                    };
+                }
+
+                // N1-N2.
+                let new_class = match (prev_class, next_class) {
+                    (L,  L ) => L,
+                    (R,  R ) |
+                    (R,  AN) |
+                    (R,  EN) |
+                    (AN, R ) |
+                    (AN, AN) |
+                    (AN, EN) |
+                    (EN, R ) |
+                    (EN, AN) |
+                    (EN, EN) => R,
+                    (_,  _ ) => class_for_level(levels[i]),
+                };
+                for j in &ni_run {
+                    classes[*j] = new_class;
+                }
+                ni_run.clear();
+            }
+            prev_class = classes[i];
+        }
+    }
+
+    /// 3.3.6 Resolving Implicit Levels
+    ///
+    /// Returns the maximum embedding level in the paragraph.
+    ///
+    /// http://www.unicode.org/reports/tr9/#Resolving_Implicit_Levels
+    pub fn resolve_levels(classes: &[BidiClass], levels: &mut [u8]) -> u8 {
+        let mut max_level = 0;
+
+        assert!(classes.len() == levels.len());
+        for i in 0..levels.len() {
+            match (is_rtl(levels[i]), classes[i]) {
+                // http://www.unicode.org/reports/tr9/#I1
+                (false, R)  => levels[i] += 1,
+                (false, AN) |
+                (false, EN) => levels[i] += 2,
+                // http://www.unicode.org/reports/tr9/#I2
+                (true, L)  |
+                (true, EN) |
+                (true, AN) => levels[i] += 1,
+                (_, _) => {}
+            }
+            max_level = max(max_level, levels[i]);
+        }
+        max_level
+    }
+}
 
 #[cfg(test)]
-mod tests {
-    use super::*;
+mod test {
+    use super::BidiClass::*;
 
     #[test]
-    fn test_initial_text_info() {
-        let text = "a1";
-        assert_eq!(
-            InitialInfo::new(text, None),
-            InitialInfo {
-                text: &text,
-                original_classes: vec![L, EN],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..2,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
-
-        let text = "غ א";
-        assert_eq!(
-            InitialInfo::new(text, None),
-            InitialInfo {
-                text: &text,
-                original_classes: vec![AL, AL, WS, R, R],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..5,
-                        level: Level::rtl(),
-                    },
-                ],
-            }
-        );
+    fn test_initial_scan() {
+        use super::{InitialProperties, initial_scan, ParagraphInfo};
 
-        let text = "a\u{2029}b";
-        assert_eq!(
-            InitialInfo::new(text, None),
-            InitialInfo {
-                text: &text,
-                original_classes: vec![L, B, B, B, L],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..4,
-                        level: Level::ltr(),
-                    },
-                    ParagraphInfo {
-                        range: 4..5,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
+        assert_eq!(initial_scan("a1", None), InitialProperties {
+            initial_classes: vec![L, EN],
+            paragraphs: vec![ParagraphInfo { range: 0..2, level: 0 }],
+        });
+        assert_eq!(initial_scan("غ א", None), InitialProperties {
+            initial_classes: vec![AL, AL, WS, R, R],
+            paragraphs: vec![ParagraphInfo { range: 0..5, level: 1 }],
+        });
+        {
+            let para1 = ParagraphInfo { range: 0..4, level: 0 };
+            let para2 = ParagraphInfo { range: 4..5, level: 0 };
+            assert_eq!(initial_scan("a\u{2029}b", None), InitialProperties {
+                initial_classes: vec![L, B, B, B, L],
+                paragraphs: vec![para1, para2],
+            });
+        }
 
-        let text = format!("{}א{}a", chars::FSI, chars::PDI);
-        assert_eq!(
-            InitialInfo::new(&text, None),
-            InitialInfo {
-                text: &text,
-                original_classes: vec![RLI, RLI, RLI, R, R, PDI, PDI, PDI, L],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..9,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
+        let fsi = '\u{2068}';
+        let pdi = '\u{2069}';
+
+        let s = format!("{}א{}a", fsi, pdi);
+        assert_eq!(initial_scan(&s, None), InitialProperties {
+            initial_classes: vec![RLI, RLI, RLI, R, R, PDI, PDI, PDI, L],
+            paragraphs: vec![ParagraphInfo { range: 0..9, level: 0 }],
+        });
+    }
+
+    #[test]
+    fn test_bidi_class() {
+        use super::bidi_class;
+
+        assert_eq!(bidi_class('c'), L);
+        assert_eq!(bidi_class('\u{05D1}'), R);
+        assert_eq!(bidi_class('\u{0627}'), AL);
     }
 
     #[test]
     fn test_process_text() {
-        let text = "abc123";
-        assert_eq!(
-            BidiInfo::new(text, Some(Level::ltr())),
-            BidiInfo {
-                text: &text,
-                levels: Level::vec(&[0, 0, 0, 0, 0, 0]),
-                original_classes: vec![L, L, L, EN, EN, EN],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..6,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
-
-        let text = "abc אבג";
-        assert_eq!(
-            BidiInfo::new(text, Some(Level::ltr())),
-            BidiInfo {
-                text: &text,
-                levels: Level::vec(&[0, 0, 0, 0, 1, 1, 1, 1, 1, 1]),
-                original_classes: vec![L, L, L, WS, R, R, R, R, R, R],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..10,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
-        assert_eq!(
-            BidiInfo::new(text, Some(Level::rtl())),
-            BidiInfo {
-                text: &text,
-                levels: Level::vec(&[2, 2, 2, 1, 1, 1, 1, 1, 1, 1]),
-                original_classes: vec![L, L, L, WS, R, R, R, R, R, R],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..10,
-                        level: Level::rtl(),
-                    },
-                ],
-            }
-        );
+        use super::{BidiInfo, ParagraphInfo, process_text};
 
-        let text = "אבג abc";
-        assert_eq!(
-            BidiInfo::new(text, Some(Level::ltr())),
-            BidiInfo {
-                text: &text,
-                levels: Level::vec(&[1, 1, 1, 1, 1, 1, 0, 0, 0, 0]),
-                original_classes: vec![R, R, R, R, R, R, WS, L, L, L],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..10,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
-        assert_eq!(
-            BidiInfo::new(text, None),
-            BidiInfo {
-                text: &text,
-                levels: Level::vec(&[1, 1, 1, 1, 1, 1, 1, 2, 2, 2]),
-                original_classes: vec![R, R, R, R, R, R, WS, L, L, L],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..10,
-                        level: Level::rtl(),
-                    },
-                ],
-            }
-        );
-
-        let text = "غ2ظ א2ג";
-        assert_eq!(
-            BidiInfo::new(text, Some(Level::ltr())),
-            BidiInfo {
-                text: &text,
-                levels: Level::vec(&[1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1]),
-                original_classes: vec![AL, AL, EN, AL, AL, WS, R, R, EN, R, R],
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..11,
-                        level: Level::ltr(),
-                    },
-                ],
-            }
-        );
-
-        let text = "a א.\nג";
-        assert_eq!(
-            BidiInfo::new(text, None),
-            BidiInfo {
-                text: &text,
-                original_classes: vec![L, WS, R, R, CS, B, R, R],
-                levels: Level::vec(&[0, 0, 1, 1, 0, 0, 1, 1]),
-                paragraphs: vec![
-                    ParagraphInfo {
-                        range: 0..6,
-                        level: Level::ltr(),
-                    },
-                    ParagraphInfo {
-                        range: 6..8,
-                        level: Level::rtl(),
-                    },
-                ],
-            }
-        );
-    }
-
-    #[test]
-    fn test_bidi_info_has_rtl() {
-        // ASCII only
-        assert_eq!(BidiInfo::new("123", None).has_rtl(), false);
-        assert_eq!(BidiInfo::new("123", Some(Level::ltr())).has_rtl(), false);
-        assert_eq!(BidiInfo::new("123", Some(Level::rtl())).has_rtl(), false);
-        assert_eq!(BidiInfo::new("abc", None).has_rtl(), false);
-        assert_eq!(BidiInfo::new("abc", Some(Level::ltr())).has_rtl(), false);
-        assert_eq!(BidiInfo::new("abc", Some(Level::rtl())).has_rtl(), false);
-        assert_eq!(BidiInfo::new("abc 123", None).has_rtl(), false);
-        assert_eq!(BidiInfo::new("abc\n123", None).has_rtl(), false);
-
-        // With Hebrew
-        assert_eq!(BidiInfo::new("אבּג", None).has_rtl(), true);
-        assert_eq!(
-            BidiInfo::new("אבּג", Some(Level::ltr())).has_rtl(),
-            true
-        );
-        assert_eq!(
-            BidiInfo::new("אבּג", Some(Level::rtl())).has_rtl(),
-            true
-        );
-        assert_eq!(BidiInfo::new("abc אבּג", None).has_rtl(), true);
-        assert_eq!(BidiInfo::new("abc\nאבּג", None).has_rtl(), true);
-        assert_eq!(BidiInfo::new("אבּג abc", None).has_rtl(), true);
-        assert_eq!(BidiInfo::new("אבּג\nabc", None).has_rtl(), true);
-        assert_eq!(BidiInfo::new("אבּג 123", None).has_rtl(), true);
-        assert_eq!(BidiInfo::new("אבּג\n123", None).has_rtl(), true);
+        assert_eq!(process_text("abc123", Some(0)), BidiInfo {
+            levels:  vec![0, 0, 0, 0,  0,  0],
+            classes: vec![L, L, L, EN, EN, EN],
+            paragraphs: vec![ParagraphInfo { range: 0..6, level: 0 }],
+        });
+        assert_eq!(process_text("abc אבג", Some(0)), BidiInfo {
+            levels:  vec![0, 0, 0, 0,  1,1, 1,1, 1,1],
+            classes: vec![L, L, L, WS, R,R, R,R, R,R],
+            paragraphs: vec![ParagraphInfo { range: 0..10, level: 0 }],
+        });
+        assert_eq!(process_text("abc אבג", Some(1)), BidiInfo {
+            levels:  vec![2, 2, 2, 1,  1,1, 1,1, 1,1],
+            classes: vec![L, L, L, WS, R,R, R,R, R,R],
+            paragraphs: vec![ParagraphInfo { range: 0..10, level: 1 }],
+        });
+        assert_eq!(process_text("אבג abc", Some(0)), BidiInfo {
+            levels:  vec![1,1, 1,1, 1,1, 0,  0, 0, 0],
+            classes: vec![R,R, R,R, R,R, WS, L, L, L],
+            paragraphs: vec![ParagraphInfo { range: 0..10, level: 0 }],
+        });
+        assert_eq!(process_text("אבג abc", None), BidiInfo {
+            levels:  vec![1,1, 1,1, 1,1, 1,  2, 2, 2],
+            classes: vec![R,R, R,R, R,R, WS, L, L, L],
+            paragraphs: vec![ParagraphInfo { range: 0..10, level: 1 }],
+        });
+        assert_eq!(process_text("غ2ظ א2ג", Some(0)), BidiInfo {
+            levels:  vec![1, 1,  2,  1, 1,  1,  1,1, 2,  1,1],
+            classes: vec![AL,AL, EN, AL,AL, WS, R,R, EN, R,R],
+            paragraphs: vec![ParagraphInfo { range: 0..11, level: 0 }],
+        });
+        assert_eq!(process_text("a א.\nג", None), BidiInfo {
+            classes: vec![L, WS, R,R, CS, B, R,R],
+            levels:  vec![0, 0,  1,1, 0,  0, 1,1],
+            paragraphs: vec![ParagraphInfo { range: 0..6, level: 0 },
+                             ParagraphInfo { range: 6..8, level: 1 }],
+        });
     }
 
     #[test]
     fn test_reorder_line() {
-        fn reorder(text: &str) -> Cow<str> {
-            let bidi_info = BidiInfo::new(text, None);
-            let para = &bidi_info.paragraphs[0];
-            let line = para.range.clone();
-            bidi_info.reorder_line(para, line)
+        use super::{process_text, reorder_line};
+        use std::borrow::Cow;
+        fn reorder(s: &str) -> Cow<str> {
+            let info = process_text(s, None);
+            let para = &info.paragraphs[0];
+            reorder_line(s, para.range.clone(), &info.levels)
         }
-
         assert_eq!(reorder("abc123"), "abc123");
         assert_eq!(reorder("1.-2"), "1.-2");
         assert_eq!(reorder("1-.2"), "1-.2");
         assert_eq!(reorder("abc אבג"), "abc גבא");
-
-        // Numbers being weak LTR characters, cannot reorder strong RTL
+        //Numbers being weak LTR characters, cannot reorder strong RTL
         assert_eq!(reorder("123 אבג"), "גבא 123");
-
-        // Testing for RLE Character
-        assert_eq!(
-            reorder("\u{202B}abc אבג\u{202C}"),
-            "\u{202B}\u{202C}גבא abc"
-        );
-
-        // Testing neutral characters
+        //Testing for RLE Character
+        assert_eq!(reorder("\u{202B}abc אבג\u{202C}"), "\u{202B}\u{202C}גבא abc");
+        //Testing neutral characters
         assert_eq!(reorder("אבג? אבג"), "גבא ?גבא");
-
-        // Testing neutral characters with special case
+        //Testing neutral characters with special case
         assert_eq!(reorder("A אבג?"), "A גבא?");
-
-        // Testing neutral characters with Implicit RTL Marker
-        // The given test highlights a possible non-conformance issue that will perhaps be fixed in
-        // the subsequent steps.
+        //Testing neutral characters with Implicit RTL Marker
+        //The given test highlights a possible non-conformance issue that will perhaps be fixed in the subsequent steps.
         //assert_eq!(reorder("A אבג?\u{202f}"), "A \u{202f}?גבא");
         assert_eq!(reorder("אבג abc"), "abc גבא");
-        assert_eq!(
-            reorder("abc\u{2067}.-\u{2069}ghi"),
-            "abc\u{2067}-.\u{2069}ghi"
-        );
-        assert_eq!(
-            reorder("Hello, \u{2068}\u{202E}world\u{202C}\u{2069}!"),
-            "Hello, \u{2068}\u{202E}\u{202C}dlrow\u{2069}!"
-        );
+        assert_eq!(reorder("abc\u{2067}.-\u{2069}ghi"),
+                           "abc\u{2067}-.\u{2069}ghi");
+        assert_eq!(reorder("Hello, \u{2068}\u{202E}world\u{202C}\u{2069}!"),
+                           "Hello, \u{2068}\u{202E}\u{202C}dlrow\u{2069}!");
+    }
+
+    #[test]
+    fn test_is_ltr() {
+        use super::is_ltr;
+        assert_eq!(is_ltr(10), true);
+        assert_eq!(is_ltr(11), false);
+        assert_eq!(is_ltr(20), true);
+    }
+
+    #[test]
+    fn test_is_rtl() {
+        use super::is_rtl;
+        assert_eq!(is_rtl(13), true);
+        assert_eq!(is_rtl(11), true);
+        assert_eq!(is_rtl(20), false);
+    }
+
+    #[test]
+    fn test_removed_by_x9() {
+        use prepare::removed_by_x9;
+        let rem_classes = &[RLE, LRE, RLO, LRO, PDF, BN];
+        let not_classes = &[L, RLI, AL, LRI, PDI];
+        for x in rem_classes {
+            assert_eq!(removed_by_x9(*x), true);
+        }
+        for x in not_classes {
+            assert_eq!(removed_by_x9(*x), false);
+        }
+    }
+
+    #[test]
+    fn test_not_removed_by_x9() {
+        use prepare::not_removed_by_x9;
+        let non_x9_classes = &[L, R, AL, EN, ES, ET, AN, CS, NSM, B, S, WS, ON, LRI, RLI, FSI, PDI];
+        for x in non_x9_classes {
+            assert_eq!(not_removed_by_x9(&x), true);
+        }
     }
 }
-
-
-#[cfg(all(feature = "with_serde", test))]
-mod serde_tests {
-    use serde_test::{Token, assert_tokens};
-    use super::*;
-
-    #[test]
-    fn test_levels() {
-        let text = "abc אבג";
-        let bidi_info = BidiInfo::new(text, None);
-        let levels = bidi_info.levels;
-        assert_eq!(text.as_bytes().len(), 10);
-        assert_eq!(levels.len(), 10);
-        assert_tokens(
-            &levels,
-            &[
-                Token::Seq { len: Some(10) },
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(0),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(0),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(0),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(0),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(1),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(1),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(1),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(1),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(1),
-                Token::NewtypeStruct { name: "Level" },
-                Token::U8(1),
-                Token::SeqEnd,
-            ],
-        );
-    }
-}
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/src/prepare.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2015 The Servo Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! 3.3.3 Preparations for Implicit Processing
-//!
-//! http://www.unicode.org/reports/tr9/#Preparations_for_Implicit_Processing
-
-use std::cmp::max;
-use std::ops::Range;
-
-use super::char_data::BidiClass;
-use super::level::Level;
-
-use BidiClass::*;
-
-/// A maximal substring of characters with the same embedding level.
-///
-/// Represented as a range of byte indices.
-pub type LevelRun = Range<usize>;
-
-/// Output of `isolating_run_sequences` (steps X9-X10)
-pub struct IsolatingRunSequence {
-    pub runs: Vec<LevelRun>,
-    pub sos: BidiClass, // Start-of-sequence type.
-    pub eos: BidiClass, // End-of-sequence type.
-}
-
-/// Compute the set of isolating run sequences.
-///
-/// An isolating run sequence is a maximal sequence of level runs such that for all level runs
-/// except the last one in the sequence, the last character of the run is an isolate initiator
-/// whose matching PDI is the first character of the next level run in the sequence.
-///
-/// Note: This function does *not* return the sequences in order by their first characters.
-pub fn isolating_run_sequences(
-    para_level: Level,
-    initial_classes: &[BidiClass],
-    levels: &[Level],
-) -> Vec<IsolatingRunSequence> {
-    let runs = level_runs(levels, initial_classes);
-
-    // Compute the set of isolating run sequences.
-    // http://www.unicode.org/reports/tr9/#BD13
-
-    let mut sequences = Vec::with_capacity(runs.len());
-
-    // When we encounter an isolate initiator, we push the current sequence onto the
-    // stack so we can resume it after the matching PDI.
-    let mut stack = vec![Vec::new()];
-
-    for run in runs {
-        assert!(run.len() > 0);
-        assert!(stack.len() > 0);
-
-        let start_class = initial_classes[run.start];
-        let end_class = initial_classes[run.end - 1];
-
-        let mut sequence = if start_class == PDI && stack.len() > 1 {
-            // Continue a previous sequence interrupted by an isolate.
-            stack.pop().unwrap()
-        } else {
-            // Start a new sequence.
-            Vec::new()
-        };
-
-        sequence.push(run);
-
-        if matches!(end_class, RLI | LRI | FSI) {
-            // Resume this sequence after the isolate.
-            stack.push(sequence);
-        } else {
-            // This sequence is finished.
-            sequences.push(sequence);
-        }
-    }
-    // Pop any remaning sequences off the stack.
-    sequences.extend(stack.into_iter().rev().filter(|seq| seq.len() > 0));
-
-    // Determine the `sos` and `eos` class for each sequence.
-    // http://www.unicode.org/reports/tr9/#X10
-    return sequences
-               .into_iter()
-               .map(
-        |sequence| {
-            assert!(!sequence.len() > 0);
-            let start = sequence[0].start;
-            let end = sequence[sequence.len() - 1].end;
-
-            // Get the level inside these level runs.
-            let level = levels[start];
-
-            // Get the level of the last non-removed char before the runs.
-            let pred_level = match initial_classes[..start]
-                      .iter()
-                      .rposition(not_removed_by_x9) {
-                Some(idx) => levels[idx],
-                None => para_level,
-            };
-
-            // Get the level of the next non-removed char after the runs.
-            let succ_level = if matches!(initial_classes[end - 1], RLI | LRI | FSI) {
-                para_level
-            } else {
-                match initial_classes[end..].iter().position(not_removed_by_x9) {
-                    Some(idx) => levels[idx],
-                    None => para_level,
-                }
-            };
-
-            IsolatingRunSequence {
-                runs: sequence,
-                sos: max(level, pred_level).bidi_class(),
-                eos: max(level, succ_level).bidi_class(),
-            }
-        },
-    )
-               .collect();
-}
-
-/// Finds the level runs in a paragraph.
-///
-/// http://www.unicode.org/reports/tr9/#BD7
-fn level_runs(levels: &[Level], original_classes: &[BidiClass]) -> Vec<LevelRun> {
-    assert!(levels.len() == original_classes.len());
-
-    let mut runs = Vec::new();
-    if levels.len() == 0 {
-        return runs;
-    }
-
-    let mut current_run_level = levels[0];
-    let mut current_run_start = 0;
-
-    for i in 1..levels.len() {
-        if !removed_by_x9(original_classes[i]) {
-            if levels[i] != current_run_level {
-                // End the last run and start a new one.
-                runs.push(current_run_start..i);
-                current_run_level = levels[i];
-                current_run_start = i;
-            }
-        }
-    }
-    runs.push(current_run_start..levels.len());
-    runs
-}
-
-/// Should this character be ignored in steps after X9?
-///
-/// http://www.unicode.org/reports/tr9/#X9
-pub fn removed_by_x9(class: BidiClass) -> bool {
-    matches!(class, RLE | LRE | RLO | LRO | PDF | BN)
-}
-
-// For use as a predicate for `position` / `rposition`
-pub fn not_removed_by_x9(class: &BidiClass) -> bool {
-    !removed_by_x9(*class)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_level_runs() {
-        let levels = &[0, 0, 0, 1, 1, 2, 0, 0];
-        assert_eq!(
-            level_runs(&Level::vec(levels), &[L; 8]),
-            &[0..3, 3..5, 5..6, 6..8]
-        );
-    }
-
-    /// Example 3 from http://www.unicode.org/reports/tr9/#BD13:
-    #[cfg_attr(rustfmt, rustfmt_skip)]
-    #[test]
-    fn test_isolating_run_sequences() {
-        //  char index  0  1    2   3    4  5  6  7    8   9   10
-        let classes = &[L, RLI, AL, LRI, L, R, L, PDI, AL, PDI, L];
-        let levels =  &[0, 0,   1,  1,   2, 3, 2, 1,   1,  0,   0];
-        let para_level = Level::ltr();
-
-        let sequences = isolating_run_sequences(para_level, classes, &Level::vec(levels));
-        let runs: Vec<Vec<LevelRun>> = sequences.iter().map(|s| s.runs.clone()).collect();
-        assert_eq!(
-            runs,
-            vec![vec![4..5], vec![5..6], vec![6..7], vec![2..4, 7..9], vec![0..2, 9..11]]
-        );
-    }
-
-    #[test]
-    fn test_removed_by_x9() {
-        let rem_classes = &[RLE, LRE, RLO, LRO, PDF, BN];
-        let not_classes = &[L, RLI, AL, LRI, PDI];
-        for x in rem_classes {
-            assert_eq!(removed_by_x9(*x), true);
-        }
-        for x in not_classes {
-            assert_eq!(removed_by_x9(*x), false);
-        }
-    }
-
-    #[test]
-    fn test_not_removed_by_x9() {
-        let non_x9_classes = &[L, R, AL, EN, ES, ET, AN, CS, NSM, B, S, WS, ON, LRI, RLI, FSI, PDI];
-        for x in non_x9_classes {
-            assert_eq!(not_removed_by_x9(&x), true);
-        }
-    }
-}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/unicode-bidi/src/tables.rs
@@ -0,0 +1,492 @@
+// NOTE:
+// The following code was generated by "tools/generate.py". do not edit directly
+
+#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
+
+/// The version of [Unicode](http://www.unicode.org/)
+/// that the `bidi_class` function is based on.
+pub const UNICODE_VERSION: (u64, u64, u64) = (9, 0, 0);
+pub use self::BidiClass::*;
+
+    #[allow(non_camel_case_types)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
+    /// Represents the Unicode character property **Bidi_Class**, also known as
+    /// the *bidirectional character type*.
+    ///
+    /// Use the `bidi_class` function to look up the BidiClass of a code point.
+    ///
+    /// http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
+    pub enum BidiClass {
+        AL,
+        AN,
+        B,
+        BN,
+        CS,
+        EN,
+        ES,
+        ET,
+        FSI,
+        L,
+        LRE,
+        LRI,
+        LRO,
+        NSM,
+        ON,
+        PDF,
+        PDI,
+        R,
+        RLE,
+        RLI,
+        RLO,
+        S,
+        WS,
+    }
+
+    fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
+        use ::std::cmp::Ordering::{Equal, Less, Greater};
+        match r.binary_search_by(|&(lo, hi, _)| {
+            if lo <= c && c <= hi { Equal }
+            else if hi < c { Less }
+            else { Greater }
+        }) {
+            Ok(idx) => {
+                let (_, _, cat) = r[idx];
+                cat
+            }
+            // UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
+            // for Bidi_Class have the value Left_To_Right (L)."
+            Err(_) => L
+        }
+    }
+
+    /// Find the BidiClass of a single char.
+    pub fn bidi_class(c: char) -> BidiClass {
+        bsearch_range_value_table(c, bidi_class_table)
+    }
+
+    const bidi_class_table: &'static [(char, char, BidiClass)] = &[
+        ('\u{0}', '\u{8}', BN), ('\u{9}', '\u{9}', S), ('\u{a}', '\u{a}', B), ('\u{b}', '\u{b}', S),
+        ('\u{c}', '\u{c}', WS), ('\u{d}', '\u{d}', B), ('\u{e}', '\u{1b}', BN), ('\u{1c}', '\u{1e}',
+        B), ('\u{1f}', '\u{1f}', S), ('\u{20}', '\u{20}', WS), ('\u{21}', '\u{22}', ON), ('\u{23}',
+        '\u{25}', ET), ('\u{26}', '\u{2a}', ON), ('\u{2b}', '\u{2b}', ES), ('\u{2c}', '\u{2c}', CS),
+        ('\u{2d}', '\u{2d}', ES), ('\u{2e}', '\u{2f}', CS), ('\u{30}', '\u{39}', EN), ('\u{3a}',
+        '\u{3a}', CS), ('\u{3b}', '\u{40}', ON), ('\u{41}', '\u{5a}', L), ('\u{5b}', '\u{60}', ON),
+        ('\u{61}', '\u{7a}', L), ('\u{7b}', '\u{7e}', ON), ('\u{7f}', '\u{84}', BN), ('\u{85}',
+        '\u{85}', B), ('\u{86}', '\u{9f}', BN), ('\u{a0}', '\u{a0}', CS), ('\u{a1}', '\u{a1}', ON),
+        ('\u{a2}', '\u{a5}', ET), ('\u{a6}', '\u{a9}', ON), ('\u{aa}', '\u{aa}', L), ('\u{ab}',
+        '\u{ac}', ON), ('\u{ad}', '\u{ad}', BN), ('\u{ae}', '\u{af}', ON), ('\u{b0}', '\u{b1}', ET),
+        ('\u{b2}', '\u{b3}', EN), ('\u{b4}', '\u{b4}', ON), ('\u{b5}', '\u{b5}', L), ('\u{b6}',
+        '\u{b8}', ON), ('\u{b9}', '\u{b9}', EN), ('\u{ba}', '\u{ba}', L), ('\u{bb}', '\u{bf}', ON),
+        ('\u{c0}', '\u{d6}', L), ('\u{d7}', '\u{d7}', ON), ('\u{d8}', '\u{f6}', L), ('\u{f7}',
+        '\u{f7}', ON), ('\u{f8}', '\u{2b8}', L), ('\u{2b9}', '\u{2ba}', ON), ('\u{2bb}', '\u{2c1}',
+        L), ('\u{2c2}', '\u{2cf}', ON), ('\u{2d0}', '\u{2d1}', L), ('\u{2d2}', '\u{2df}', ON),
+        ('\u{2e0}', '\u{2e4}', L), ('\u{2e5}', '\u{2ed}', ON), ('\u{2ee}', '\u{2ee}', L),
+        ('\u{2ef}', '\u{2ff}', ON), ('\u{300}', '\u{36f}', NSM), ('\u{370}', '\u{373}', L),
+        ('\u{374}', '\u{375}', ON), ('\u{376}', '\u{377}', L), ('\u{37a}', '\u{37d}', L),
+        ('\u{37e}', '\u{37e}', ON), ('\u{37f}', '\u{37f}', L), ('\u{384}', '\u{385}', ON),
+        ('\u{386}', '\u{386}', L), ('\u{387}', '\u{387}', ON), ('\u{388}', '\u{38a}', L),
+        ('\u{38c}', '\u{38c}', L), ('\u{38e}', '\u{3a1}', L), ('\u{3a3}', '\u{3f5}', L), ('\u{3f6}',
+        '\u{3f6}', ON), ('\u{3f7}', '\u{482}', L), ('\u{483}', '\u{489}', NSM), ('\u{48a}',
+        '\u{52f}', L), ('\u{531}', '\u{556}', L), ('\u{559}', '\u{55f}', L), ('\u{561}', '\u{587}',
+        L), ('\u{589}', '\u{589}', L), ('\u{58a}', '\u{58a}', ON), ('\u{58d}', '\u{58e}', ON),
+        ('\u{58f}', '\u{58f}', ET), ('\u{590}', '\u{590}', R), ('\u{591}', '\u{5bd}', NSM),
+        ('\u{5be}', '\u{5be}', R), ('\u{5bf}', '\u{5bf}', NSM), ('\u{5c0}', '\u{5c0}', R),
+        ('\u{5c1}', '\u{5c2}', NSM), ('\u{5c3}', '\u{5c3}', R), ('\u{5c4}', '\u{5c5}', NSM),
+        ('\u{5c6}', '\u{5c6}', R), ('\u{5c7}', '\u{5c7}', NSM), ('\u{5c8}', '\u{5ff}', R),
+        ('\u{600}', '\u{605}', AN), ('\u{606}', '\u{607}', ON), ('\u{608}', '\u{608}', AL),
+        ('\u{609}', '\u{60a}', ET), ('\u{60b}', '\u{60b}', AL), ('\u{60c}', '\u{60c}', CS),
+        ('\u{60d}', '\u{60d}', AL), ('\u{60e}', '\u{60f}', ON), ('\u{610}', '\u{61a}', NSM),
+        ('\u{61b}', '\u{64a}', AL), ('\u{64b}', '\u{65f}', NSM), ('\u{660}', '\u{669}', AN),
+        ('\u{66a}', '\u{66a}', ET), ('\u{66b}', '\u{66c}', AN), ('\u{66d}', '\u{66f}', AL),
+        ('\u{670}', '\u{670}', NSM), ('\u{671}', '\u{6d5}', AL), ('\u{6d6}', '\u{6dc}', NSM),
+        ('\u{6dd}', '\u{6dd}', AN), ('\u{6de}', '\u{6de}', ON), ('\u{6df}', '\u{6e4}', NSM),
+        ('\u{6e5}', '\u{6e6}', AL), ('\u{6e7}', '\u{6e8}', NSM), ('\u{6e9}', '\u{6e9}', ON),
+        ('\u{6ea}', '\u{6ed}', NSM), ('\u{6ee}', '\u{6ef}', AL), ('\u{6f0}', '\u{6f9}', EN),
+        ('\u{6fa}', '\u{710}', AL), ('\u{711}', '\u{711}', NSM), ('\u{712}', '\u{72f}', AL),
+        ('\u{730}', '\u{74a}', NSM), ('\u{74b}', '\u{7a5}', AL), ('\u{7a6}', '\u{7b0}', NSM),
+        ('\u{7b1}', '\u{7bf}', AL), ('\u{7c0}', '\u{7ea}', R), ('\u{7eb}', '\u{7f3}', NSM),
+        ('\u{7f4}', '\u{7f5}', R), ('\u{7f6}', '\u{7f9}', ON), ('\u{7fa}', '\u{815}', R),
+        ('\u{816}', '\u{819}', NSM), ('\u{81a}', '\u{81a}', R), ('\u{81b}', '\u{823}', NSM),
+        ('\u{824}', '\u{824}', R), ('\u{825}', '\u{827}', NSM), ('\u{828}', '\u{828}', R),
+        ('\u{829}', '\u{82d}', NSM), ('\u{82e}', '\u{858}', R), ('\u{859}', '\u{85b}', NSM),
+        ('\u{85c}', '\u{89f}', R), ('\u{8a0}', '\u{8d3}', AL), ('\u{8d4}', '\u{8e1}', NSM),
+        ('\u{8e2}', '\u{8e2}', AN), ('\u{8e3}', '\u{902}', NSM), ('\u{903}', '\u{939}', L),
+        ('\u{93a}', '\u{93a}', NSM), ('\u{93b}', '\u{93b}', L), ('\u{93c}', '\u{93c}', NSM),
+        ('\u{93d}', '\u{940}', L), ('\u{941}', '\u{948}', NSM), ('\u{949}', '\u{94c}', L),
+        ('\u{94d}', '\u{94d}', NSM), ('\u{94e}', '\u{950}', L), ('\u{951}', '\u{957}', NSM),
+        ('\u{958}', '\u{961}', L), ('\u{962}', '\u{963}', NSM), ('\u{964}', '\u{980}', L),
+        ('\u{981}', '\u{981}', NSM), ('\u{982}', '\u{983}', L), ('\u{985}', '\u{98c}', L),
+        ('\u{98f}', '\u{990}', L), ('\u{993}', '\u{9a8}', L), ('\u{9aa}', '\u{9b0}', L), ('\u{9b2}',
+        '\u{9b2}', L), ('\u{9b6}', '\u{9b9}', L), ('\u{9bc}', '\u{9bc}', NSM), ('\u{9bd}',
+        '\u{9c0}', L), ('\u{9c1}', '\u{9c4}', NSM), ('\u{9c7}', '\u{9c8}', L), ('\u{9cb}',
+        '\u{9cc}', L), ('\u{9cd}', '\u{9cd}', NSM), ('\u{9ce}', '\u{9ce}', L), ('\u{9d7}',
+        '\u{9d7}', L), ('\u{9dc}', '\u{9dd}', L), ('\u{9df}', '\u{9e1}', L), ('\u{9e2}', '\u{9e3}',
+        NSM), ('\u{9e6}', '\u{9f1}', L), ('\u{9f2}', '\u{9f3}', ET), ('\u{9f4}', '\u{9fa}', L),
+        ('\u{9fb}', '\u{9fb}', ET), ('\u{a01}', '\u{a02}', NSM), ('\u{a03}', '\u{a03}', L),
+        ('\u{a05}', '\u{a0a}', L), ('\u{a0f}', '\u{a10}', L), ('\u{a13}', '\u{a28}', L), ('\u{a2a}',
+        '\u{a30}', L), ('\u{a32}', '\u{a33}', L), ('\u{a35}', '\u{a36}', L), ('\u{a38}', '\u{a39}',
+        L), ('\u{a3c}', '\u{a3c}', NSM), ('\u{a3e}', '\u{a40}', L), ('\u{a41}', '\u{a42}', NSM),
+        ('\u{a47}', '\u{a48}', NSM), ('\u{a4b}', '\u{a4d}', NSM), ('\u{a51}', '\u{a51}', NSM),
+        ('\u{a59}', '\u{a5c}', L), ('\u{a5e}', '\u{a5e}', L), ('\u{a66}', '\u{a6f}', L), ('\u{a70}',
+        '\u{a71}', NSM), ('\u{a72}', '\u{a74}', L), ('\u{a75}', '\u{a75}', NSM), ('\u{a81}',
+        '\u{a82}', NSM), ('\u{a83}', '\u{a83}', L), ('\u{a85}', '\u{a8d}', L), ('\u{a8f}',
+        '\u{a91}', L), ('\u{a93}', '\u{aa8}', L), ('\u{aaa}', '\u{ab0}', L), ('\u{ab2}', '\u{ab3}',
+        L), ('\u{ab5}', '\u{ab9}', L), ('\u{abc}', '\u{abc}', NSM), ('\u{abd}', '\u{ac0}', L),
+        ('\u{ac1}', '\u{ac5}', NSM), ('\u{ac7}', '\u{ac8}', NSM), ('\u{ac9}', '\u{ac9}', L),
+        ('\u{acb}', '\u{acc}', L), ('\u{acd}', '\u{acd}', NSM), ('\u{ad0}', '\u{ad0}', L),
+        ('\u{ae0}', '\u{ae1}', L), ('\u{ae2}', '\u{ae3}', NSM), ('\u{ae6}', '\u{af0}', L),
+        ('\u{af1}', '\u{af1}', ET), ('\u{af9}', '\u{af9}', L), ('\u{b01}', '\u{b01}', NSM),
+        ('\u{b02}', '\u{b03}', L), ('\u{b05}', '\u{b0c}', L), ('\u{b0f}', '\u{b10}', L), ('\u{b13}',
+        '\u{b28}', L), ('\u{b2a}', '\u{b30}', L), ('\u{b32}', '\u{b33}', L), ('\u{b35}', '\u{b39}',
+        L), ('\u{b3c}', '\u{b3c}', NSM), ('\u{b3d}', '\u{b3e}', L), ('\u{b3f}', '\u{b3f}', NSM),
+        ('\u{b40}', '\u{b40}', L), ('\u{b41}', '\u{b44}', NSM), ('\u{b47}', '\u{b48}', L),
+        ('\u{b4b}', '\u{b4c}', L), ('\u{b4d}', '\u{b4d}', NSM), ('\u{b56}', '\u{b56}', NSM),
+        ('\u{b57}', '\u{b57}', L), ('\u{b5c}', '\u{b5d}', L), ('\u{b5f}', '\u{b61}', L), ('\u{b62}',
+        '\u{b63}', NSM), ('\u{b66}', '\u{b77}', L), ('\u{b82}', '\u{b82}', NSM), ('\u{b83}',
+        '\u{b83}', L), ('\u{b85}', '\u{b8a}', L), ('\u{b8e}', '\u{b90}', L), ('\u{b92}', '\u{b95}',
+        L), ('\u{b99}', '\u{b9a}', L), ('\u{b9c}', '\u{b9c}', L), ('\u{b9e}', '\u{b9f}', L),
+        ('\u{ba3}', '\u{ba4}', L), ('\u{ba8}', '\u{baa}', L), ('\u{bae}', '\u{bb9}', L), ('\u{bbe}',
+        '\u{bbf}', L), ('\u{bc0}', '\u{bc0}', NSM), ('\u{bc1}', '\u{bc2}', L), ('\u{bc6}',
+        '\u{bc8}', L), ('\u{bca}', '\u{bcc}', L), ('\u{bcd}', '\u{bcd}', NSM), ('\u{bd0}',
+        '\u{bd0}', L), ('\u{bd7}', '\u{bd7}', L), ('\u{be6}', '\u{bf2}', L), ('\u{bf3}', '\u{bf8}',
+        ON), ('\u{bf9}', '\u{bf9}', ET), ('\u{bfa}', '\u{bfa}', ON), ('\u{c00}', '\u{c00}', NSM),
+        ('\u{c01}', '\u{c03}', L), ('\u{c05}', '\u{c0c}', L), ('\u{c0e}', '\u{c10}', L), ('\u{c12}',
+        '\u{c28}', L), ('\u{c2a}', '\u{c39}', L), ('\u{c3d}', '\u{c3d}', L), ('\u{c3e}', '\u{c40}',
+        NSM), ('\u{c41}', '\u{c44}', L), ('\u{c46}', '\u{c48}', NSM), ('\u{c4a}', '\u{c4d}', NSM),
+        ('\u{c55}', '\u{c56}', NSM), ('\u{c58}', '\u{c5a}', L), ('\u{c60}', '\u{c61}', L),
+        ('\u{c62}', '\u{c63}', NSM), ('\u{c66}', '\u{c6f}', L), ('\u{c78}', '\u{c7e}', ON),
+        ('\u{c7f}', '\u{c80}', L), ('\u{c81}', '\u{c81}', NSM), ('\u{c82}', '\u{c83}', L),
+        ('\u{c85}', '\u{c8c}', L), ('\u{c8e}', '\u{c90}', L), ('\u{c92}', '\u{ca8}', L), ('\u{caa}',
+        '\u{cb3}', L), ('\u{cb5}', '\u{cb9}', L), ('\u{cbc}', '\u{cbc}', NSM), ('\u{cbd}',
+        '\u{cc4}', L), ('\u{cc6}', '\u{cc8}', L), ('\u{cca}', '\u{ccb}', L), ('\u{ccc}', '\u{ccd}',
+        NSM), ('\u{cd5}', '\u{cd6}', L), ('\u{cde}', '\u{cde}', L), ('\u{ce0}', '\u{ce1}', L),
+        ('\u{ce2}', '\u{ce3}', NSM), ('\u{ce6}', '\u{cef}', L), ('\u{cf1}', '\u{cf2}', L),
+        ('\u{d01}', '\u{d01}', NSM), ('\u{d02}', '\u{d03}', L), ('\u{d05}', '\u{d0c}', L),
+        ('\u{d0e}', '\u{d10}', L), ('\u{d12}', '\u{d3a}', L), ('\u{d3d}', '\u{d40}', L), ('\u{d41}',
+        '\u{d44}', NSM), ('\u{d46}', '\u{d48}', L), ('\u{d4a}', '\u{d4c}', L), ('\u{d4d}',
+        '\u{d4d}', NSM), ('\u{d4e}', '\u{d4f}', L), ('\u{d54}', '\u{d61}', L), ('\u{d62}',
+        '\u{d63}', NSM), ('\u{d66}', '\u{d7f}', L), ('\u{d82}', '\u{d83}', L), ('\u{d85}',
+        '\u{d96}', L), ('\u{d9a}', '\u{db1}', L), ('\u{db3}', '\u{dbb}', L), ('\u{dbd}', '\u{dbd}',
+        L), ('\u{dc0}', '\u{dc6}', L), ('\u{dca}', '\u{dca}', NSM), ('\u{dcf}', '\u{dd1}', L),
+        ('\u{dd2}', '\u{dd4}', NSM), ('\u{dd6}', '\u{dd6}', NSM), ('\u{dd8}', '\u{ddf}', L),
+        ('\u{de6}', '\u{def}', L), ('\u{df2}', '\u{df4}', L), ('\u{e01}', '\u{e30}', L), ('\u{e31}',
+        '\u{e31}', NSM), ('\u{e32}', '\u{e33}', L), ('\u{e34}', '\u{e3a}', NSM), ('\u{e3f}',
+        '\u{e3f}', ET), ('\u{e40}', '\u{e46}', L), ('\u{e47}', '\u{e4e}', NSM), ('\u{e4f}',
+        '\u{e5b}', L), ('\u{e81}', '\u{e82}', L), ('\u{e84}', '\u{e84}', L), ('\u{e87}', '\u{e88}',
+        L), ('\u{e8a}', '\u{e8a}', L), ('\u{e8d}', '\u{e8d}', L), ('\u{e94}', '\u{e97}', L),
+        ('\u{e99}', '\u{e9f}', L), ('\u{ea1}', '\u{ea3}', L), ('\u{ea5}', '\u{ea5}', L), ('\u{ea7}',
+        '\u{ea7}', L), ('\u{eaa}', '\u{eab}', L), ('\u{ead}', '\u{eb0}', L), ('\u{eb1}', '\u{eb1}',
+        NSM), ('\u{eb2}', '\u{eb3}', L), ('\u{eb4}', '\u{eb9}', NSM), ('\u{ebb}', '\u{ebc}', NSM),
+        ('\u{ebd}', '\u{ebd}', L), ('\u{ec0}', '\u{ec4}', L), ('\u{ec6}', '\u{ec6}', L), ('\u{ec8}',
+        '\u{ecd}', NSM), ('\u{ed0}', '\u{ed9}', L), ('\u{edc}', '\u{edf}', L), ('\u{f00}',
+        '\u{f17}', L), ('\u{f18}', '\u{f19}', NSM), ('\u{f1a}', '\u{f34}', L), ('\u{f35}',
+        '\u{f35}', NSM), ('\u{f36}', '\u{f36}', L), ('\u{f37}', '\u{f37}', NSM), ('\u{f38}',
+        '\u{f38}', L), ('\u{f39}', '\u{f39}', NSM), ('\u{f3a}', '\u{f3d}', ON), ('\u{f3e}',
+        '\u{f47}', L), ('\u{f49}', '\u{f6c}', L), ('\u{f71}', '\u{f7e}', NSM), ('\u{f7f}',
+        '\u{f7f}', L), ('\u{f80}', '\u{f84}', NSM), ('\u{f85}', '\u{f85}', L), ('\u{f86}',
+        '\u{f87}', NSM), ('\u{f88}', '\u{f8c}', L), ('\u{f8d}', '\u{f97}', NSM), ('\u{f99}',
+        '\u{fbc}', NSM), ('\u{fbe}', '\u{fc5}', L), ('\u{fc6}', '\u{fc6}', NSM), ('\u{fc7}',
+        '\u{fcc}', L), ('\u{fce}', '\u{fda}', L), ('\u{1000}', '\u{102c}', L), ('\u{102d}',
+        '\u{1030}', NSM), ('\u{1031}', '\u{1031}', L), ('\u{1032}', '\u{1037}', NSM), ('\u{1038}',
+        '\u{1038}', L), ('\u{1039}', '\u{103a}', NSM), ('\u{103b}', '\u{103c}', L), ('\u{103d}',
+        '\u{103e}', NSM), ('\u{103f}', '\u{1057}', L), ('\u{1058}', '\u{1059}', NSM), ('\u{105a}',
+        '\u{105d}', L), ('\u{105e}', '\u{1060}', NSM), ('\u{1061}', '\u{1070}', L), ('\u{1071}',
+        '\u{1074}', NSM), ('\u{1075}', '\u{1081}', L), ('\u{1082}', '\u{1082}', NSM), ('\u{1083}',
+        '\u{1084}', L), ('\u{1085}', '\u{1086}', NSM), ('\u{1087}', '\u{108c}', L), ('\u{108d}',
+        '\u{108d}', NSM), ('\u{108e}', '\u{109c}', L), ('\u{109d}', '\u{109d}', NSM), ('\u{109e}',
+        '\u{10c5}', L), ('\u{10c7}', '\u{10c7}', L), ('\u{10cd}', '\u{10cd}', L), ('\u{10d0}',
+        '\u{1248}', L), ('\u{124a}', '\u{124d}', L), ('\u{1250}', '\u{1256}', L), ('\u{1258}',
+        '\u{1258}', L), ('\u{125a}', '\u{125d}', L), ('\u{1260}', '\u{1288}', L), ('\u{128a}',
+        '\u{128d}', L), ('\u{1290}', '\u{12b0}', L), ('\u{12b2}', '\u{12b5}', L), ('\u{12b8}',
+        '\u{12be}', L), ('\u{12c0}', '\u{12c0}', L), ('\u{12c2}', '\u{12c5}', L), ('\u{12c8}',
+        '\u{12d6}', L), ('\u{12d8}', '\u{1310}', L), ('\u{1312}', '\u{1315}', L), ('\u{1318}',
+        '\u{135a}', L), ('\u{135d}', '\u{135f}', NSM), ('\u{1360}', '\u{137c}', L), ('\u{1380}',
+        '\u{138f}', L), ('\u{1390}', '\u{1399}', ON), ('\u{13a0}', '\u{13f5}', L), ('\u{13f8}',
+        '\u{13fd}', L), ('\u{1400}', '\u{1400}', ON), ('\u{1401}', '\u{167f}', L), ('\u{1680}',
+        '\u{1680}', WS), ('\u{1681}', '\u{169a}', L), ('\u{169b}', '\u{169c}', ON), ('\u{16a0}',
+        '\u{16f8}', L), ('\u{1700}', '\u{170c}', L), ('\u{170e}', '\u{1711}', L), ('\u{1712}',
+        '\u{1714}', NSM), ('\u{1720}', '\u{1731}', L), ('\u{1732}', '\u{1734}', NSM), ('\u{1735}',
+        '\u{1736}', L), ('\u{1740}', '\u{1751}', L), ('\u{1752}', '\u{1753}', NSM), ('\u{1760}',
+        '\u{176c}', L), ('\u{176e}', '\u{1770}', L), ('\u{1772}', '\u{1773}', NSM), ('\u{1780}',
+        '\u{17b3}', L), ('\u{17b4}', '\u{17b5}', NSM), ('\u{17b6}', '\u{17b6}', L), ('\u{17b7}',
+        '\u{17bd}', NSM), ('\u{17be}', '\u{17c5}', L), ('\u{17c6}', '\u{17c6}', NSM), ('\u{17c7}',
+        '\u{17c8}', L), ('\u{17c9}', '\u{17d3}', NSM), ('\u{17d4}', '\u{17da}', L), ('\u{17db}',
+        '\u{17db}', ET), ('\u{17dc}', '\u{17dc}', L), ('\u{17dd}', '\u{17dd}', NSM), ('\u{17e0}',
+        '\u{17e9}', L), ('\u{17f0}', '\u{17f9}', ON), ('\u{1800}', '\u{180a}', ON), ('\u{180b}',
+        '\u{180d}', NSM), ('\u{180e}', '\u{180e}', BN), ('\u{1810}', '\u{1819}', L), ('\u{1820}',
+        '\u{1877}', L), ('\u{1880}', '\u{1884}', L), ('\u{1885}', '\u{1886}', NSM), ('\u{1887}',
+        '\u{18a8}', L), ('\u{18a9}', '\u{18a9}', NSM), ('\u{18aa}', '\u{18aa}', L), ('\u{18b0}',
+        '\u{18f5}', L), ('\u{1900}', '\u{191e}', L), ('\u{1920}', '\u{1922}', NSM), ('\u{1923}',
+        '\u{1926}', L), ('\u{1927}', '\u{1928}', NSM), ('\u{1929}', '\u{192b}', L), ('\u{1930}',
+        '\u{1931}', L), ('\u{1932}', '\u{1932}', NSM), ('\u{1933}', '\u{1938}', L), ('\u{1939}',
+        '\u{193b}', NSM), ('\u{1940}', '\u{1940}', ON), ('\u{1944}', '\u{1945}', ON), ('\u{1946}',
+        '\u{196d}', L), ('\u{1970}', '\u{1974}', L), ('\u{1980}', '\u{19ab}', L), ('\u{19b0}',
+        '\u{19c9}', L), ('\u{19d0}', '\u{19da}', L), ('\u{19de}', '\u{19ff}', ON), ('\u{1a00}',
+        '\u{1a16}', L), ('\u{1a17}', '\u{1a18}', NSM), ('\u{1a19}', '\u{1a1a}', L), ('\u{1a1b}',
+        '\u{1a1b}', NSM), ('\u{1a1e}', '\u{1a55}', L), ('\u{1a56}', '\u{1a56}', NSM), ('\u{1a57}',
+        '\u{1a57}', L), ('\u{1a58}', '\u{1a5e}', NSM), ('\u{1a60}', '\u{1a60}', NSM), ('\u{1a61}',
+        '\u{1a61}', L), ('\u{1a62}', '\u{1a62}', NSM), ('\u{1a63}', '\u{1a64}', L), ('\u{1a65}',
+        '\u{1a6c}', NSM), ('\u{1a6d}', '\u{1a72}', L), ('\u{1a73}', '\u{1a7c}', NSM), ('\u{1a7f}',
+        '\u{1a7f}', NSM), ('\u{1a80}', '\u{1a89}', L), ('\u{1a90}', '\u{1a99}', L), ('\u{1aa0}',
+        '\u{1aad}', L), ('\u{1ab0}', '\u{1abe}', NSM), ('\u{1b00}', '\u{1b03}', NSM), ('\u{1b04}',
+        '\u{1b33}', L), ('\u{1b34}', '\u{1b34}', NSM), ('\u{1b35}', '\u{1b35}', L), ('\u{1b36}',
+        '\u{1b3a}', NSM), ('\u{1b3b}', '\u{1b3b}', L), ('\u{1b3c}', '\u{1b3c}', NSM), ('\u{1b3d}',
+        '\u{1b41}', L), ('\u{1b42}', '\u{1b42}', NSM), ('\u{1b43}', '\u{1b4b}', L), ('\u{1b50}',
+        '\u{1b6a}', L), ('\u{1b6b}', '\u{1b73}', NSM), ('\u{1b74}', '\u{1b7c}', L), ('\u{1b80}',
+        '\u{1b81}', NSM), ('\u{1b82}', '\u{1ba1}', L), ('\u{1ba2}', '\u{1ba5}', NSM), ('\u{1ba6}',
+        '\u{1ba7}', L), ('\u{1ba8}', '\u{1ba9}', NSM), ('\u{1baa}', '\u{1baa}', L), ('\u{1bab}',
+        '\u{1bad}', NSM), ('\u{1bae}', '\u{1be5}', L), ('\u{1be6}', '\u{1be6}', NSM), ('\u{1be7}',
+        '\u{1be7}', L), ('\u{1be8}', '\u{1be9}', NSM), ('\u{1bea}', '\u{1bec}', L), ('\u{1bed}',
+        '\u{1bed}', NSM), ('\u{1bee}', '\u{1bee}', L), ('\u{1bef}', '\u{1bf1}', NSM), ('\u{1bf2}',
+        '\u{1bf3}', L), ('\u{1bfc}', '\u{1c2b}', L), ('\u{1c2c}', '\u{1c33}', NSM), ('\u{1c34}',
+        '\u{1c35}', L), ('\u{1c36}', '\u{1c37}', NSM), ('\u{1c3b}', '\u{1c49}', L), ('\u{1c4d}',
+        '\u{1c88}', L), ('\u{1cc0}', '\u{1cc7}', L), ('\u{1cd0}', '\u{1cd2}', NSM), ('\u{1cd3}',
+        '\u{1cd3}', L), ('\u{1cd4}', '\u{1ce0}', NSM), ('\u{1ce1}', '\u{1ce1}', L), ('\u{1ce2}',
+        '\u{1ce8}', NSM), ('\u{1ce9}', '\u{1cec}', L), ('\u{1ced}', '\u{1ced}', NSM), ('\u{1cee}',
+        '\u{1cf3}', L), ('\u{1cf4}', '\u{1cf4}', NSM), ('\u{1cf5}', '\u{1cf6}', L), ('\u{1cf8}',
+        '\u{1cf9}', NSM), ('\u{1d00}', '\u{1dbf}', L), ('\u{1dc0}', '\u{1df5}', NSM), ('\u{1dfb}',
+        '\u{1dff}', NSM), ('\u{1e00}', '\u{1f15}', L), ('\u{1f18}', '\u{1f1d}', L), ('\u{1f20}',
+        '\u{1f45}', L), ('\u{1f48}', '\u{1f4d}', L), ('\u{1f50}', '\u{1f57}', L), ('\u{1f59}',
+        '\u{1f59}', L), ('\u{1f5b}', '\u{1f5b}', L), ('\u{1f5d}', '\u{1f5d}', L), ('\u{1f5f}',
+        '\u{1f7d}', L), ('\u{1f80}', '\u{1fb4}', L), ('\u{1fb6}', '\u{1fbc}', L), ('\u{1fbd}',
+        '\u{1fbd}', ON), ('\u{1fbe}', '\u{1fbe}', L), ('\u{1fbf}', '\u{1fc1}', ON), ('\u{1fc2}',
+        '\u{1fc4}', L), ('\u{1fc6}', '\u{1fcc}', L), ('\u{1fcd}', '\u{1fcf}', ON), ('\u{1fd0}',
+        '\u{1fd3}', L), ('\u{1fd6}', '\u{1fdb}', L), ('\u{1fdd}', '\u{1fdf}', ON), ('\u{1fe0}',
+        '\u{1fec}', L), ('\u{1fed}', '\u{1fef}', ON), ('\u{1ff2}', '\u{1ff4}', L), ('\u{1ff6}',
+        '\u{1ffc}', L), ('\u{1ffd}', '\u{1ffe}', ON), ('\u{2000}', '\u{200a}', WS), ('\u{200b}',
+        '\u{200d}', BN), ('\u{200e}', '\u{200e}', L), ('\u{200f}', '\u{200f}', R), ('\u{2010}',
+        '\u{2027}', ON), ('\u{2028}', '\u{2028}', WS), ('\u{2029}', '\u{2029}', B), ('\u{202a}',
+        '\u{202a}', LRE), ('\u{202b}', '\u{202b}', RLE), ('\u{202c}', '\u{202c}', PDF), ('\u{202d}',
+        '\u{202d}', LRO), ('\u{202e}', '\u{202e}', RLO), ('\u{202f}', '\u{202f}', CS), ('\u{2030}',
+        '\u{2034}', ET), ('\u{2035}', '\u{2043}', ON), ('\u{2044}', '\u{2044}', CS), ('\u{2045}',
+        '\u{205e}', ON), ('\u{205f}', '\u{205f}', WS), ('\u{2060}', '\u{2064}', BN), ('\u{2066}',
+        '\u{2066}', LRI), ('\u{2067}', '\u{2067}', RLI), ('\u{2068}', '\u{2068}', FSI), ('\u{2069}',
+        '\u{2069}', PDI), ('\u{206a}', '\u{206f}', BN), ('\u{2070}', '\u{2070}', EN), ('\u{2071}',
+        '\u{2071}', L), ('\u{2074}', '\u{2079}', EN), ('\u{207a}', '\u{207b}', ES), ('\u{207c}',
+        '\u{207e}', ON), ('\u{207f}', '\u{207f}', L), ('\u{2080}', '\u{2089}', EN), ('\u{208a}',
+        '\u{208b}', ES), ('\u{208c}', '\u{208e}', ON), ('\u{2090}', '\u{209c}', L), ('\u{20a0}',
+        '\u{20cf}', ET), ('\u{20d0}', '\u{20f0}', NSM), ('\u{2100}', '\u{2101}', ON), ('\u{2102}',
+        '\u{2102}', L), ('\u{2103}', '\u{2106}', ON), ('\u{2107}', '\u{2107}', L), ('\u{2108}',
+        '\u{2109}', ON), ('\u{210a}', '\u{2113}', L), ('\u{2114}', '\u{2114}', ON), ('\u{2115}',
+        '\u{2115}', L), ('\u{2116}', '\u{2118}', ON), ('\u{2119}', '\u{211d}', L), ('\u{211e}',
+        '\u{2123}', ON), ('\u{2124}', '\u{2124}', L), ('\u{2125}', '\u{2125}', ON), ('\u{2126}',
+        '\u{2126}', L), ('\u{2127}', '\u{2127}', ON), ('\u{2128}', '\u{2128}', L), ('\u{2129}',
+        '\u{2129}', ON), ('\u{212a}', '\u{212d}', L), ('\u{212e}', '\u{212e}', ET), ('\u{212f}',
+        '\u{2139}', L), ('\u{213a}', '\u{213b}', ON), ('\u{213c}', '\u{213f}', L), ('\u{2140}',
+        '\u{2144}', ON), ('\u{2145}', '\u{2149}', L), ('\u{214a}', '\u{214d}', ON), ('\u{214e}',
+        '\u{214f}', L), ('\u{2150}', '\u{215f}', ON), ('\u{2160}', '\u{2188}', L), ('\u{2189}',
+        '\u{218b}', ON), ('\u{2190}', '\u{2211}', ON), ('\u{2212}', '\u{2212}', ES), ('\u{2213}',
+        '\u{2213}', ET), ('\u{2214}', '\u{2335}', ON), ('\u{2336}', '\u{237a}', L), ('\u{237b}',
+        '\u{2394}', ON), ('\u{2395}', '\u{2395}', L), ('\u{2396}', '\u{23fe}', ON), ('\u{2400}',
+        '\u{2426}', ON), ('\u{2440}', '\u{244a}', ON), ('\u{2460}', '\u{2487}', ON), ('\u{2488}',
+        '\u{249b}', EN), ('\u{249c}', '\u{24e9}', L), ('\u{24ea}', '\u{26ab}', ON), ('\u{26ac}',
+        '\u{26ac}', L), ('\u{26ad}', '\u{27ff}', ON), ('\u{2800}', '\u{28ff}', L), ('\u{2900}',
+        '\u{2b73}', ON), ('\u{2b76}', '\u{2b95}', ON), ('\u{2b98}', '\u{2bb9}', ON), ('\u{2bbd}',
+        '\u{2bc8}', ON), ('\u{2bca}', '\u{2bd1}', ON), ('\u{2bec}', '\u{2bef}', ON), ('\u{2c00}',
+        '\u{2c2e}', L), ('\u{2c30}', '\u{2c5e}', L), ('\u{2c60}', '\u{2ce4}', L), ('\u{2ce5}',
+        '\u{2cea}', ON), ('\u{2ceb}', '\u{2cee}', L), ('\u{2cef}', '\u{2cf1}', NSM), ('\u{2cf2}',
+        '\u{2cf3}', L), ('\u{2cf9}', '\u{2cff}', ON), ('\u{2d00}', '\u{2d25}', L), ('\u{2d27}',
+        '\u{2d27}', L), ('\u{2d2d}', '\u{2d2d}', L), ('\u{2d30}', '\u{2d67}', L), ('\u{2d6f}',
+        '\u{2d70}', L), ('\u{2d7f}', '\u{2d7f}', NSM), ('\u{2d80}', '\u{2d96}', L), ('\u{2da0}',
+        '\u{2da6}', L), ('\u{2da8}', '\u{2dae}', L), ('\u{2db0}', '\u{2db6}', L), ('\u{2db8}',
+        '\u{2dbe}', L), ('\u{2dc0}', '\u{2dc6}', L), ('\u{2dc8}', '\u{2dce}', L), ('\u{2dd0}',
+        '\u{2dd6}', L), ('\u{2dd8}', '\u{2dde}', L), ('\u{2de0}', '\u{2dff}', NSM), ('\u{2e00}',
+        '\u{2e44}', ON), ('\u{2e80}', '\u{2e99}', ON), ('\u{2e9b}', '\u{2ef3}', ON), ('\u{2f00}',
+        '\u{2fd5}', ON), ('\u{2ff0}', '\u{2ffb}', ON), ('\u{3000}', '\u{3000}', WS), ('\u{3001}',
+        '\u{3004}', ON), ('\u{3005}', '\u{3007}', L), ('\u{3008}', '\u{3020}', ON), ('\u{3021}',
+        '\u{3029}', L), ('\u{302a}', '\u{302d}', NSM), ('\u{302e}', '\u{302f}', L), ('\u{3030}',
+        '\u{3030}', ON), ('\u{3031}', '\u{3035}', L), ('\u{3036}', '\u{3037}', ON), ('\u{3038}',
+        '\u{303c}', L), ('\u{303d}', '\u{303f}', ON), ('\u{3041}', '\u{3096}', L), ('\u{3099}',
+        '\u{309a}', NSM), ('\u{309b}', '\u{309c}', ON), ('\u{309d}', '\u{309f}', L), ('\u{30a0}',
+        '\u{30a0}', ON), ('\u{30a1}', '\u{30fa}', L), ('\u{30fb}', '\u{30fb}', ON), ('\u{30fc}',
+        '\u{30ff}', L), ('\u{3105}', '\u{312d}', L), ('\u{3131}', '\u{318e}', L), ('\u{3190}',
+        '\u{31ba}', L), ('\u{31c0}', '\u{31e3}', ON), ('\u{31f0}', '\u{321c}', L), ('\u{321d}',
+        '\u{321e}', ON), ('\u{3220}', '\u{324f}', L), ('\u{3250}', '\u{325f}', ON), ('\u{3260}',
+        '\u{327b}', L), ('\u{327c}', '\u{327e}', ON), ('\u{327f}', '\u{32b0}', L), ('\u{32b1}',
+        '\u{32bf}', ON), ('\u{32c0}', '\u{32cb}', L), ('\u{32cc}', '\u{32cf}', ON), ('\u{32d0}',
+        '\u{32fe}', L), ('\u{3300}', '\u{3376}', L), ('\u{3377}', '\u{337a}', ON), ('\u{337b}',
+        '\u{33dd}', L), ('\u{33de}', '\u{33df}', ON), ('\u{33e0}', '\u{33fe}', L), ('\u{33ff}',
+        '\u{33ff}', ON), ('\u{3400}', '\u{4db5}', L), ('\u{4dc0}', '\u{4dff}', ON), ('\u{4e00}',
+        '\u{9fd5}', L), ('\u{a000}', '\u{a48c}', L), ('\u{a490}', '\u{a4c6}', ON), ('\u{a4d0}',
+        '\u{a60c}', L), ('\u{a60d}', '\u{a60f}', ON), ('\u{a610}', '\u{a62b}', L), ('\u{a640}',
+        '\u{a66e}', L), ('\u{a66f}', '\u{a672}', NSM), ('\u{a673}', '\u{a673}', ON), ('\u{a674}',
+        '\u{a67d}', NSM), ('\u{a67e}', '\u{a67f}', ON), ('\u{a680}', '\u{a69d}', L), ('\u{a69e}',
+        '\u{a69f}', NSM), ('\u{a6a0}', '\u{a6ef}', L), ('\u{a6f0}', '\u{a6f1}', NSM), ('\u{a6f2}',
+        '\u{a6f7}', L), ('\u{a700}', '\u{a721}', ON), ('\u{a722}', '\u{a787}', L), ('\u{a788}',
+        '\u{a788}', ON), ('\u{a789}', '\u{a7ae}', L), ('\u{a7b0}', '\u{a7b7}', L), ('\u{a7f7}',
+        '\u{a801}', L), ('\u{a802}', '\u{a802}', NSM), ('\u{a803}', '\u{a805}', L), ('\u{a806}',
+        '\u{a806}', NSM), ('\u{a807}', '\u{a80a}', L), ('\u{a80b}', '\u{a80b}', NSM), ('\u{a80c}',
+        '\u{a824}', L), ('\u{a825}', '\u{a826}', NSM), ('\u{a827}', '\u{a827}', L), ('\u{a828}',
+        '\u{a82b}', ON), ('\u{a830}', '\u{a837}', L), ('\u{a838}', '\u{a839}', ET), ('\u{a840}',
+        '\u{a873}', L), ('\u{a874}', '\u{a877}', ON), ('\u{a880}', '\u{a8c3}', L), ('\u{a8c4}',
+        '\u{a8c5}', NSM), ('\u{a8ce}', '\u{a8d9}', L), ('\u{a8e0}', '\u{a8f1}', NSM), ('\u{a8f2}',
+        '\u{a8fd}', L), ('\u{a900}', '\u{a925}', L), ('\u{a926}', '\u{a92d}', NSM), ('\u{a92e}',
+        '\u{a946}', L), ('\u{a947}', '\u{a951}', NSM), ('\u{a952}', '\u{a953}', L), ('\u{a95f}',
+        '\u{a97c}', L), ('\u{a980}', '\u{a982}', NSM), ('\u{a983}', '\u{a9b2}', L), ('\u{a9b3}',
+        '\u{a9b3}', NSM), ('\u{a9b4}', '\u{a9b5}', L), ('\u{a9b6}', '\u{a9b9}', NSM), ('\u{a9ba}',
+        '\u{a9bb}', L), ('\u{a9bc}', '\u{a9bc}', NSM), ('\u{a9bd}', '\u{a9cd}', L), ('\u{a9cf}',
+        '\u{a9d9}', L), ('\u{a9de}', '\u{a9e4}', L), ('\u{a9e5}', '\u{a9e5}', NSM), ('\u{a9e6}',
+        '\u{a9fe}', L), ('\u{aa00}', '\u{aa28}', L), ('\u{aa29}', '\u{aa2e}', NSM), ('\u{aa2f}',
+        '\u{aa30}', L), ('\u{aa31}', '\u{aa32}', NSM), ('\u{aa33}', '\u{aa34}', L), ('\u{aa35}',
+        '\u{aa36}', NSM), ('\u{aa40}', '\u{aa42}', L), ('\u{aa43}', '\u{aa43}', NSM), ('\u{aa44}',
+        '\u{aa4b}', L), ('\u{aa4c}', '\u{aa4c}', NSM), ('\u{aa4d}', '\u{aa4d}', L), ('\u{aa50}',
+        '\u{aa59}', L), ('\u{aa5c}', '\u{aa7b}', L), ('\u{aa7c}', '\u{aa7c}', NSM), ('\u{aa7d}',
+        '\u{aaaf}', L), ('\u{aab0}', '\u{aab0}', NSM), ('\u{aab1}', '\u{aab1}', L), ('\u{aab2}',
+        '\u{aab4}', NSM), ('\u{aab5}', '\u{aab6}', L), ('\u{aab7}', '\u{aab8}', NSM), ('\u{aab9}',
+        '\u{aabd}', L), ('\u{aabe}', '\u{aabf}', NSM), ('\u{aac0}', '\u{aac0}', L), ('\u{aac1}',
+        '\u{aac1}', NSM), ('\u{aac2}', '\u{aac2}', L), ('\u{aadb}', '\u{aaeb}', L), ('\u{aaec}',
+        '\u{aaed}', NSM), ('\u{aaee}', '\u{aaf5}', L), ('\u{aaf6}', '\u{aaf6}', NSM), ('\u{ab01}',
+        '\u{ab06}', L), ('\u{ab09}', '\u{ab0e}', L), ('\u{ab11}', '\u{ab16}', L), ('\u{ab20}',
+        '\u{ab26}', L), ('\u{ab28}', '\u{ab2e}', L), ('\u{ab30}', '\u{ab65}', L), ('\u{ab70}',
+        '\u{abe4}', L), ('\u{abe5}', '\u{abe5}', NSM), ('\u{abe6}', '\u{abe7}', L), ('\u{abe8}',
+        '\u{abe8}', NSM), ('\u{abe9}', '\u{abec}', L), ('\u{abed}', '\u{abed}', NSM), ('\u{abf0}',
+        '\u{abf9}', L), ('\u{ac00}', '\u{d7a3}', L), ('\u{d7b0}', '\u{d7c6}', L), ('\u{d7cb}',
+        '\u{d7fb}', L), ('\u{e000}', '\u{fa6d}', L), ('\u{fa70}', '\u{fad9}', L), ('\u{fb00}',
+        '\u{fb06}', L), ('\u{fb13}', '\u{fb17}', L), ('\u{fb1d}', '\u{fb1d}', R), ('\u{fb1e}',
+        '\u{fb1e}', NSM), ('\u{fb1f}', '\u{fb28}', R), ('\u{fb29}', '\u{fb29}', ES), ('\u{fb2a}',
+        '\u{fb4f}', R), ('\u{fb50}', '\u{fd3d}', AL), ('\u{fd3e}', '\u{fd3f}', ON), ('\u{fd40}',
+        '\u{fdcf}', AL), ('\u{fdf0}', '\u{fdfc}', AL), ('\u{fdfd}', '\u{fdfd}', ON), ('\u{fdfe}',
+        '\u{fdff}', AL), ('\u{fe00}', '\u{fe0f}', NSM), ('\u{fe10}', '\u{fe19}', ON), ('\u{fe20}',
+        '\u{fe2f}', NSM), ('\u{fe30}', '\u{fe4f}', ON), ('\u{fe50}', '\u{fe50}', CS), ('\u{fe51}',
+        '\u{fe51}', ON), ('\u{fe52}', '\u{fe52}', CS), ('\u{fe54}', '\u{fe54}', ON), ('\u{fe55}',
+        '\u{fe55}', CS), ('\u{fe56}', '\u{fe5e}', ON), ('\u{fe5f}', '\u{fe5f}', ET), ('\u{fe60}',
+        '\u{fe61}', ON), ('\u{fe62}', '\u{fe63}', ES), ('\u{fe64}', '\u{fe66}', ON), ('\u{fe68}',
+        '\u{fe68}', ON), ('\u{fe69}', '\u{fe6a}', ET), ('\u{fe6b}', '\u{fe6b}', ON), ('\u{fe70}',
+        '\u{fefe}', AL), ('\u{feff}', '\u{feff}', BN), ('\u{ff01}', '\u{ff02}', ON), ('\u{ff03}',
+        '\u{ff05}', ET), ('\u{ff06}', '\u{ff0a}', ON), ('\u{ff0b}', '\u{ff0b}', ES), ('\u{ff0c}',
+        '\u{ff0c}', CS), ('\u{ff0d}', '\u{ff0d}', ES), ('\u{ff0e}', '\u{ff0f}', CS), ('\u{ff10}',
+        '\u{ff19}', EN), ('\u{ff1a}', '\u{ff1a}', CS), ('\u{ff1b}', '\u{ff20}', ON), ('\u{ff21}',
+        '\u{ff3a}', L), ('\u{ff3b}', '\u{ff40}', ON), ('\u{ff41}', '\u{ff5a}', L), ('\u{ff5b}',
+        '\u{ff65}', ON), ('\u{ff66}', '\u{ffbe}', L), ('\u{ffc2}', '\u{ffc7}', L), ('\u{ffca}',
+        '\u{ffcf}', L), ('\u{ffd2}', '\u{ffd7}', L), ('\u{ffda}', '\u{ffdc}', L), ('\u{ffe0}',
+        '\u{ffe1}', ET), ('\u{ffe2}', '\u{ffe4}', ON), ('\u{ffe5}', '\u{ffe6}', ET), ('\u{ffe8}',
+        '\u{ffee}', ON), ('\u{fff9}', '\u{fffd}', ON), ('\u{10000}', '\u{1000b}', L), ('\u{1000d}',
+        '\u{10026}', L), ('\u{10028}', '\u{1003a}', L), ('\u{1003c}', '\u{1003d}', L), ('\u{1003f}',
+        '\u{1004d}', L), ('\u{10050}', '\u{1005d}', L), ('\u{10080}', '\u{100fa}', L), ('\u{10100}',
+        '\u{10100}', L), ('\u{10101}', '\u{10101}', ON), ('\u{10102}', '\u{10102}', L),
+        ('\u{10107}', '\u{10133}', L), ('\u{10137}', '\u{1013f}', L), ('\u{10140}', '\u{1018c}',
+        ON), ('\u{1018d}', '\u{1018e}', L), ('\u{10190}', '\u{1019b}', ON), ('\u{101a0}',
+        '\u{101a0}', ON), ('\u{101d0}', '\u{101fc}', L), ('\u{101fd}', '\u{101fd}', NSM),
+        ('\u{10280}', '\u{1029c}', L), ('\u{102a0}', '\u{102d0}', L), ('\u{102e0}', '\u{102e0}',
+        NSM), ('\u{102e1}', '\u{102fb}', EN), ('\u{10300}', '\u{10323}', L), ('\u{10330}',
+        '\u{1034a}', L), ('\u{10350}', '\u{10375}', L), ('\u{10376}', '\u{1037a}', NSM),
+        ('\u{10380}', '\u{1039d}', L), ('\u{1039f}', '\u{103c3}', L), ('\u{103c8}', '\u{103d5}', L),
+        ('\u{10400}', '\u{1049d}', L), ('\u{104a0}', '\u{104a9}', L), ('\u{104b0}', '\u{104d3}', L),
+        ('\u{104d8}', '\u{104fb}', L), ('\u{10500}', '\u{10527}', L), ('\u{10530}', '\u{10563}', L),
+        ('\u{1056f}', '\u{1056f}', L), ('\u{10600}', '\u{10736}', L), ('\u{10740}', '\u{10755}', L),
+        ('\u{10760}', '\u{10767}', L), ('\u{10800}', '\u{1091e}', R), ('\u{1091f}', '\u{1091f}',
+        ON), ('\u{10920}', '\u{10a00}', R), ('\u{10a01}', '\u{10a03}', NSM), ('\u{10a04}',
+        '\u{10a04}', R), ('\u{10a05}', '\u{10a06}', NSM), ('\u{10a07}', '\u{10a0b}', R),
+        ('\u{10a0c}', '\u{10a0f}', NSM), ('\u{10a10}', '\u{10a37}', R), ('\u{10a38}', '\u{10a3a}',
+        NSM), ('\u{10a3b}', '\u{10a3e}', R), ('\u{10a3f}', '\u{10a3f}', NSM), ('\u{10a40}',
+        '\u{10ae4}', R), ('\u{10ae5}', '\u{10ae6}', NSM), ('\u{10ae7}', '\u{10b38}', R),
+        ('\u{10b39}', '\u{10b3f}', ON), ('\u{10b40}', '\u{10e5f}', R), ('\u{10e60}', '\u{10e7e}',
+        AN), ('\u{10e7f}', '\u{10fff}', R), ('\u{11000}', '\u{11000}', L), ('\u{11001}',
+        '\u{11001}', NSM), ('\u{11002}', '\u{11037}', L), ('\u{11038}', '\u{11046}', NSM),
+        ('\u{11047}', '\u{1104d}', L), ('\u{11052}', '\u{11065}', ON), ('\u{11066}', '\u{1106f}',
+        L), ('\u{1107f}', '\u{11081}', NSM), ('\u{11082}', '\u{110b2}', L), ('\u{110b3}',
+        '\u{110b6}', NSM), ('\u{110b7}', '\u{110b8}', L), ('\u{110b9}', '\u{110ba}', NSM),
+        ('\u{110bb}', '\u{110c1}', L), ('\u{110d0}', '\u{110e8}', L), ('\u{110f0}', '\u{110f9}', L),
+        ('\u{11100}', '\u{11102}', NSM), ('\u{11103}', '\u{11126}', L), ('\u{11127}', '\u{1112b}',
+        NSM), ('\u{1112c}', '\u{1112c}', L), ('\u{1112d}', '\u{11134}', NSM), ('\u{11136}',
+        '\u{11143}', L), ('\u{11150}', '\u{11172}', L), ('\u{11173}', '\u{11173}', NSM),
+        ('\u{11174}', '\u{11176}', L), ('\u{11180}', '\u{11181}', NSM), ('\u{11182}', '\u{111b5}',
+        L), ('\u{111b6}', '\u{111be}', NSM), ('\u{111bf}', '\u{111c9}', L), ('\u{111ca}',
+        '\u{111cc}', NSM), ('\u{111cd}', '\u{111cd}', L), ('\u{111d0}', '\u{111df}', L),
+        ('\u{111e1}', '\u{111f4}', L), ('\u{11200}', '\u{11211}', L), ('\u{11213}', '\u{1122e}', L),
+        ('\u{1122f}', '\u{11231}', NSM), ('\u{11232}', '\u{11233}', L), ('\u{11234}', '\u{11234}',
+        NSM), ('\u{11235}', '\u{11235}', L), ('\u{11236}', '\u{11237}', NSM), ('\u{11238}',
+        '\u{1123d}', L), ('\u{1123e}', '\u{1123e}', NSM), ('\u{11280}', '\u{11286}', L),
+        ('\u{11288}', '\u{11288}', L), ('\u{1128a}', '\u{1128d}', L), ('\u{1128f}', '\u{1129d}', L),
+        ('\u{1129f}', '\u{112a9}', L), ('\u{112b0}', '\u{112de}', L), ('\u{112df}', '\u{112df}',
+        NSM), ('\u{112e0}', '\u{112e2}', L), ('\u{112e3}', '\u{112ea}', NSM), ('\u{112f0}',
+        '\u{112f9}', L), ('\u{11300}', '\u{11301}', NSM), ('\u{11302}', '\u{11303}', L),
+        ('\u{11305}', '\u{1130c}', L), ('\u{1130f}', '\u{11310}', L), ('\u{11313}', '\u{11328}', L),
+        ('\u{1132a}', '\u{11330}', L), ('\u{11332}', '\u{11333}', L), ('\u{11335}', '\u{11339}', L),
+        ('\u{1133c}', '\u{1133c}', NSM), ('\u{1133d}', '\u{1133f}', L), ('\u{11340}', '\u{11340}',
+        NSM), ('\u{11341}', '\u{11344}', L), ('\u{11347}', '\u{11348}', L), ('\u{1134b}',
+        '\u{1134d}', L), ('\u{11350}', '\u{11350}', L), ('\u{11357}', '\u{11357}', L), ('\u{1135d}',
+        '\u{11363}', L), ('\u{11366}', '\u{1136c}', NSM), ('\u{11370}', '\u{11374}', NSM),
+        ('\u{11400}', '\u{11437}', L), ('\u{11438}', '\u{1143f}', NSM), ('\u{11440}', '\u{11441}',
+        L), ('\u{11442}', '\u{11444}', NSM), ('\u{11445}', '\u{11445}', L), ('\u{11446}',
+        '\u{11446}', NSM), ('\u{11447}', '\u{11459}', L), ('\u{1145b}', '\u{1145b}', L),
+        ('\u{1145d}', '\u{1145d}', L), ('\u{11480}', '\u{114b2}', L), ('\u{114b3}', '\u{114b8}',
+        NSM), ('\u{114b9}', '\u{114b9}', L), ('\u{114ba}', '\u{114ba}', NSM), ('\u{114bb}',
+        '\u{114be}', L), ('\u{114bf}', '\u{114c0}', NSM), ('\u{114c1}', '\u{114c1}', L),
+        ('\u{114c2}', '\u{114c3}', NSM), ('\u{114c4}', '\u{114c7}', L), ('\u{114d0}', '\u{114d9}',
+        L), ('\u{11580}', '\u{115b1}', L), ('\u{115b2}', '\u{115b5}', NSM), ('\u{115b8}',
+        '\u{115bb}', L), ('\u{115bc}', '\u{115bd}', NSM), ('\u{115be}', '\u{115be}', L),
+        ('\u{115bf}', '\u{115c0}', NSM), ('\u{115c1}', '\u{115db}', L), ('\u{115dc}', '\u{115dd}',
+        NSM), ('\u{11600}', '\u{11632}', L), ('\u{11633}', '\u{1163a}', NSM), ('\u{1163b}',
+        '\u{1163c}', L), ('\u{1163d}', '\u{1163d}', NSM), ('\u{1163e}', '\u{1163e}', L),
+        ('\u{1163f}', '\u{11640}', NSM), ('\u{11641}', '\u{11644}', L), ('\u{11650}', '\u{11659}',
+        L), ('\u{11660}', '\u{1166c}', ON), ('\u{11680}', '\u{116aa}', L), ('\u{116ab}',
+        '\u{116ab}', NSM), ('\u{116ac}', '\u{116ac}', L), ('\u{116ad}', '\u{116ad}', NSM),
+        ('\u{116ae}', '\u{116af}', L), ('\u{116b0}', '\u{116b5}', NSM), ('\u{116b6}', '\u{116b6}',
+        L), ('\u{116b7}', '\u{116b7}', NSM), ('\u{116c0}', '\u{116c9}', L), ('\u{11700}',
+        '\u{11719}', L), ('\u{1171d}', '\u{1171f}', NSM), ('\u{11720}', '\u{11721}', L),
+        ('\u{11722}', '\u{11725}', NSM), ('\u{11726}', '\u{11726}', L), ('\u{11727}', '\u{1172b}',
+        NSM), ('\u{11730}', '\u{1173f}', L), ('\u{118a0}', '\u{118f2}', L), ('\u{118ff}',
+        '\u{118ff}', L), ('\u{11ac0}', '\u{11af8}', L), ('\u{11c00}', '\u{11c08}', L), ('\u{11c0a}',
+        '\u{11c2f}', L), ('\u{11c30}', '\u{11c36}', NSM), ('\u{11c38}', '\u{11c3d}', NSM),
+        ('\u{11c3e}', '\u{11c45}', L), ('\u{11c50}', '\u{11c6c}', L), ('\u{11c70}', '\u{11c8f}', L),
+        ('\u{11c92}', '\u{11ca7}', NSM), ('\u{11ca9}', '\u{11ca9}', L), ('\u{11caa}', '\u{11cb0}',
+        NSM), ('\u{11cb1}', '\u{11cb1}', L), ('\u{11cb2}', '\u{11cb3}', NSM), ('\u{11cb4}',
+        '\u{11cb4}', L), ('\u{11cb5}', '\u{11cb6}', NSM), ('\u{12000}', '\u{12399}', L),
+        ('\u{12400}', '\u{1246e}', L), ('\u{12470}', '\u{12474}', L), ('\u{12480}', '\u{12543}', L),
+        ('\u{13000}', '\u{1342e}', L), ('\u{14400}', '\u{14646}', L), ('\u{16800}', '\u{16a38}', L),
+        ('\u{16a40}', '\u{16a5e}', L), ('\u{16a60}', '\u{16a69}', L), ('\u{16a6e}', '\u{16a6f}', L),
+        ('\u{16ad0}', '\u{16aed}', L), ('\u{16af0}', '\u{16af4}', NSM), ('\u{16af5}', '\u{16af5}',
+        L), ('\u{16b00}', '\u{16b2f}', L), ('\u{16b30}', '\u{16b36}', NSM), ('\u{16b37}',
+        '\u{16b45}', L), ('\u{16b50}', '\u{16b59}', L), ('\u{16b5b}', '\u{16b61}', L), ('\u{16b63}',
+        '\u{16b77}', L), ('\u{16b7d}', '\u{16b8f}', L), ('\u{16f00}', '\u{16f44}', L), ('\u{16f50}',
+        '\u{16f7e}', L), ('\u{16f8f}', '\u{16f92}', NSM), ('\u{16f93}', '\u{16f9f}', L),
+        ('\u{16fe0}', '\u{16fe0}', L), ('\u{17000}', '\u{187ec}', L), ('\u{18800}', '\u{18af2}', L),
+        ('\u{1b000}', '\u{1b001}', L), ('\u{1bc00}', '\u{1bc6a}', L), ('\u{1bc70}', '\u{1bc7c}', L),
+        ('\u{1bc80}', '\u{1bc88}', L), ('\u{1bc90}', '\u{1bc99}', L), ('\u{1bc9c}', '\u{1bc9c}', L),
+        ('\u{1bc9d}', '\u{1bc9e}', NSM), ('\u{1bc9f}', '\u{1bc9f}', L), ('\u{1bca0}', '\u{1bca3}',
+        BN), ('\u{1d000}', '\u{1d0f5}', L), ('\u{1d100}', '\u{1d126}', L), ('\u{1d129}',
+        '\u{1d166}', L), ('\u{1d167}', '\u{1d169}', NSM), ('\u{1d16a}', '\u{1d172}', L),
+        ('\u{1d173}', '\u{1d17a}', BN), ('\u{1d17b}', '\u{1d182}', NSM), ('\u{1d183}', '\u{1d184}',
+        L), ('\u{1d185}', '\u{1d18b}', NSM), ('\u{1d18c}', '\u{1d1a9}', L), ('\u{1d1aa}',
+        '\u{1d1ad}', NSM), ('\u{1d1ae}', '\u{1d1e8}', L), ('\u{1d200}', '\u{1d241}', ON),
+        ('\u{1d242}', '\u{1d244}', NSM), ('\u{1d245}', '\u{1d245}', ON), ('\u{1d300}', '\u{1d356}',
+        ON), ('\u{1d360}', '\u{1d371}', L), ('\u{1d400}', '\u{1d454}', L), ('\u{1d456}',
+        '\u{1d49c}', L), ('\u{1d49e}', '\u{1d49f}', L), ('\u{1d4a2}', '\u{1d4a2}', L), ('\u{1d4a5}',
+        '\u{1d4a6}', L), ('\u{1d4a9}', '\u{1d4ac}', L), ('\u{1d4ae}', '\u{1d4b9}', L), ('\u{1d4bb}',
+        '\u{1d4bb}', L), ('\u{1d4bd}', '\u{1d4c3}', L), ('\u{1d4c5}', '\u{1d505}', L), ('\u{1d507}',
+        '\u{1d50a}', L), ('\u{1d50d}', '\u{1d514}', L), ('\u{1d516}', '\u{1d51c}', L), ('\u{1d51e}',
+        '\u{1d539}', L), ('\u{1d53b}', '\u{1d53e}', L), ('\u{1d540}', '\u{1d544}', L), ('\u{1d546}',
+        '\u{1d546}', L), ('\u{1d54a}', '\u{1d550}', L), ('\u{1d552}', '\u{1d6a5}', L), ('\u{1d6a8}',
+        '\u{1d6da}', L), ('\u{1d6db}', '\u{1d6db}', ON), ('\u{1d6dc}', '\u{1d714}', L),
+        ('\u{1d715}', '\u{1d715}', ON), ('\u{1d716}', '\u{1d74e}', L), ('\u{1d74f}', '\u{1d74f}',
+        ON), ('\u{1d750}', '\u{1d788}', L), ('\u{1d789}', '\u{1d789}', ON), ('\u{1d78a}',
+        '\u{1d7c2}', L), ('\u{1d7c3}', '\u{1d7c3}', ON), ('\u{1d7c4}', '\u{1d7cb}', L),
+        ('\u{1d7ce}', '\u{1d7ff}', EN), ('\u{1d800}', '\u{1d9ff}', L), ('\u{1da00}', '\u{1da36}',
+        NSM), ('\u{1da37}', '\u{1da3a}', L), ('\u{1da3b}', '\u{1da6c}', NSM), ('\u{1da6d}',
+        '\u{1da74}', L), ('\u{1da75}', '\u{1da75}', NSM), ('\u{1da76}', '\u{1da83}', L),
+        ('\u{1da84}', '\u{1da84}', NSM), ('\u{1da85}', '\u{1da8b}', L), ('\u{1da9b}', '\u{1da9f}',
+        NSM), ('\u{1daa1}', '\u{1daaf}', NSM), ('\u{1e000}', '\u{1e006}', NSM), ('\u{1e008}',
+        '\u{1e018}', NSM), ('\u{1e01b}', '\u{1e021}', NSM), ('\u{1e023}', '\u{1e024}', NSM),
+        ('\u{1e026}', '\u{1e02a}', NSM), ('\u{1e800}', '\u{1e8cf}', R), ('\u{1e8d0}', '\u{1e8d6}',
+        NSM), ('\u{1e8d7}', '\u{1e943}', R), ('\u{1e944}', '\u{1e94a}', NSM), ('\u{1e94b}',
+        '\u{1edff}', R), ('\u{1ee00}', '\u{1eeef}', AL), ('\u{1eef0}', '\u{1eef1}', ON),
+        ('\u{1eef2}', '\u{1eeff}', AL), ('\u{1ef00}', '\u{1efff}', R), ('\u{1f000}', '\u{1f02b}',
+        ON), ('\u{1f030}', '\u{1f093}', ON), ('\u{1f0a0}', '\u{1f0ae}', ON), ('\u{1f0b1}',
+        '\u{1f0bf}', ON), ('\u{1f0c1}', '\u{1f0cf}', ON), ('\u{1f0d1}', '\u{1f0f5}', ON),
+        ('\u{1f100}', '\u{1f10a}', EN), ('\u{1f10b}', '\u{1f10c}', ON), ('\u{1f110}', '\u{1f12e}',
+        L), ('\u{1f130}', '\u{1f169}', L), ('\u{1f16a}', '\u{1f16b}', ON), ('\u{1f170}',
+        '\u{1f1ac}', L), ('\u{1f1e6}', '\u{1f202}', L), ('\u{1f210}', '\u{1f23b}', L), ('\u{1f240}',
+        '\u{1f248}', L), ('\u{1f250}', '\u{1f251}', L), ('\u{1f300}', '\u{1f6d2}', ON),
+        ('\u{1f6e0}', '\u{1f6ec}', ON), ('\u{1f6f0}', '\u{1f6f6}', ON), ('\u{1f700}', '\u{1f773}',
+        ON), ('\u{1f780}', '\u{1f7d4}', ON), ('\u{1f800}', '\u{1f80b}', ON), ('\u{1f810}',
+        '\u{1f847}', ON), ('\u{1f850}', '\u{1f859}', ON), ('\u{1f860}', '\u{1f887}', ON),
+        ('\u{1f890}', '\u{1f8ad}', ON), ('\u{1f910}', '\u{1f91e}', ON), ('\u{1f920}', '\u{1f927}',
+        ON), ('\u{1f930}', '\u{1f930}', ON), ('\u{1f933}', '\u{1f93e}', ON), ('\u{1f940}',
+        '\u{1f94b}', ON), ('\u{1f950}', '\u{1f95e}', ON), ('\u{1f980}', '\u{1f991}', ON),
+        ('\u{1f9c0}', '\u{1f9c0}', ON), ('\u{20000}', '\u{2a6d6}', L), ('\u{2a700}', '\u{2b734}',
+        L), ('\u{2b740}', '\u{2b81d}', L), ('\u{2b820}', '\u{2cea1}', L), ('\u{2f800}', '\u{2fa1d}',
+        L), ('\u{e0001}', '\u{e0001}', BN), ('\u{e0020}', '\u{e007f}', BN), ('\u{e0100}',
+        '\u{e01ef}', NSM), ('\u{f0000}', '\u{ffffd}', L), ('\u{100000}', '\u{10fffd}', L)
+    ];
+
deleted file mode 100644
--- a/third_party/rust/unicode-bidi/tests/conformance_tests.rs
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright 2014 The html5ever Project Developers. See the
-// COPYRIGHT file at the top-level directory of this distribution.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(all(test, not(feature = "unstable")))]
-
-extern crate unicode_bidi;
-
-use unicode_bidi::{bidi_class, BidiInfo, format_chars, level, Level};
-
-#[derive(Debug)]
-struct Fail {
-    pub line_num: usize,
-    pub input_base_level: Option<Level>,
-    pub input_classes: Vec<String>,
-    pub input_string: String,
-    pub exp_base_level: Option<Level>,
-    pub exp_levels: Vec<String>,
-    pub exp_ordering: Vec<String>,
-    pub actual_base_level: Option<Level>,
-    pub actual_levels: Vec<Level>,
-    // TODO pub actual_ordering: Vec<String>,
-}
-
-#[test]
-#[should_panic(expected = "12827 test cases failed! (243920 passed)")]
-fn test_basic_conformance() {
-    let test_data = include_str!("data/BidiTest.txt");
-
-    // Test set state
-    let mut passed_num: i32 = 0;
-    let mut fails: Vec<Fail> = Vec::new();
-    let mut exp_levels: Vec<String> = Vec::new();
-    let mut exp_ordering: Vec<String> = Vec::new();
-
-    for (line_num, line) in test_data.lines().enumerate() {
-        let line = line.trim();
-
-        // Empty and comment lines
-        if line.is_empty() || line.starts_with('#') {
-            // Ignore
-            continue;
-        }
-
-        // State setting lines
-        if line.starts_with('@') {
-            let tokens: Vec<String> = line.split_whitespace().map(|x| x.to_owned()).collect();
-            let (setting, values) = (tokens[0].as_ref(), tokens[1..].to_vec());
-            match setting {
-                "@Levels:" => {
-                    exp_levels = values.to_owned();
-                }
-                "@Reorder:" => {
-                    exp_ordering = values.to_owned();
-                }
-                _ => {
-                    // Ignore, to allow some degree of forward compatibility
-                }
-            }
-            continue;
-        }
-
-        // Data lines
-        {
-            // Levels and ordering need to be set before any data line
-            assert!(!exp_levels.is_empty());
-            assert!(exp_ordering.len() <= exp_levels.len());
-
-            let fields: Vec<&str> = line.split(';').collect();
-            let input_classes: Vec<&str> = fields[0].split_whitespace().collect();
-            let bitset: u8 = fields[1].trim().parse().unwrap();
-            assert!(!input_classes.is_empty());
-            assert!(bitset > 0);
-
-            let input_string = get_sample_string_from_bidi_classes(&input_classes);
-
-            for input_base_level in gen_base_levels_for_base_tests(bitset) {
-                let bidi_info = BidiInfo::new(&input_string, input_base_level);
-
-                // Check levels
-                let exp_levels: Vec<String> = exp_levels.iter().map(|x| x.to_owned()).collect();
-                let levels = gen_levels_list_from_bidi_info(&input_string, &bidi_info);
-                if levels != exp_levels {
-                    fails.push(
-                        Fail {
-                            line_num: line_num,
-                            input_base_level: input_base_level,
-                            input_classes: input_classes.iter().map(|x| x.to_string()).collect(),
-                            input_string: input_string.to_owned(),
-                            exp_base_level: None,
-                            exp_levels: exp_levels.to_owned(),
-                            exp_ordering: exp_ordering.to_owned(),
-                            actual_base_level: None,
-                            actual_levels: levels.to_owned(),
-                        }
-                    );
-                } else {
-                    passed_num += 1;
-                }
-
-                // Check reorder map
-                // TODO: Add reorder map to API output and test the map here
-            }
-        }
-    }
-
-    if !fails.is_empty() {
-        // TODO: Show a list of failed cases when the number is less than 1K
-        panic!(
-            "{} test cases failed! ({} passed) {{\n\
-            \n\
-            0: {:?}\n\
-            \n\
-            ...\n\
-            \n\
-            {}: {:?}\n\
-            \n\
-            }}",
-            fails.len(),
-            passed_num,
-            fails[0],
-            fails.len() - 1,
-            fails[fails.len() - 1],
-        );
-    }
-}
-
-#[test]
-#[should_panic(expected = "14558 test cases failed! (77141 passed)")]
-fn test_character_conformance() {
-    let test_data = include_str!("data/BidiCharacterTest.txt");
-
-    // Test set state
-    let mut passed_num: i32 = 0;
-    let mut fails: Vec<Fail> = Vec::new();
-
-    for (line_num, line) in test_data.lines().enumerate() {
-        let line = line.trim();
-
-        // Empty and comment lines
-        if line.is_empty() || line.starts_with('#') {
-            // Ignore
-            continue;
-        }
-
-        // Data lines
-        {
-            let fields: Vec<&str> = line.split(';').collect();
-            let input_chars: Vec<char> = fields[0]
-                .split_whitespace()
-                .map(|cp_hex| u32::from_str_radix(cp_hex, 16).unwrap())
-                .map(|cp_u32| std::char::from_u32(cp_u32).unwrap())
-                .collect();
-            let input_string: String = input_chars.into_iter().collect();
-            let input_base_level: Option<Level> =
-                gen_base_level_for_characters_tests(fields[1].trim().parse().unwrap());
-            let exp_base_level: Level = Level::new(fields[2].trim().parse().unwrap()).unwrap();
-            let exp_levels: Vec<String> =
-                fields[3].split_whitespace().map(|x| x.to_owned()).collect();
-            let exp_ordering: Vec<String> =
-                fields[4].split_whitespace().map(|x| x.to_owned()).collect();
-
-            let bidi_info = BidiInfo::new(&input_string, input_base_level);
-
-            // Check levels
-            let levels = gen_levels_list_from_bidi_info(&input_string, &bidi_info);
-            if levels != exp_levels {
-                fails.push(
-                    Fail {
-                        line_num: line_num,
-                        input_base_level: input_base_level,
-                        input_classes: vec![],
-                        input_string: input_string.to_owned(),
-                        exp_base_level: Some(exp_base_level),
-                        exp_levels: exp_levels.to_owned(),
-                        exp_ordering: exp_ordering.to_owned(),
-                        actual_base_level: None,
-                        actual_levels: levels.to_owned(),
-                    }
-                );
-            } else {
-                passed_num += 1;
-            }
-
-            // Check reorder map
-            // TODO: Add reorder map to API output and test the map here
-        }
-    }
-
-    if !fails.is_empty() {
-        // TODO: Show a list of failed cases when the number is less than 1K
-        panic!(
-            "{} test cases failed! ({} passed) {{\n\
-            \n\
-            0: {:?}\n\
-            \n\
-            ...\n\
-            \n\
-            {}: {:?}\n\
-            \n\
-            }}",
-            fails.len(),
-            passed_num,
-            fails[0],
-            fails.len() - 1,
-            fails[fails.len() - 1],
-        );
-    }
-}
-
-// TODO: Support auto-RTL
-fn gen_base_levels_for_base_tests(bitset: u8) -> Vec<Option<Level>> {
-    /// Values: auto-LTR, LTR, RTL
-    const VALUES: &'static [Option<Level>] = &[None, Some(level::LTR_LEVEL), Some(level::RTL_LEVEL)];
-    assert!(bitset < (1 << VALUES.len()));
-    (0..VALUES.len())
-        .filter(|bit| bitset & (1u8 << bit) == 1)
-        .map(|idx| VALUES[idx])
-        .collect()
-}
-
-// TODO: Support auto-RTL
-fn gen_base_level_for_characters_tests(idx: usize) -> Option<Level> {
-    /// Values: LTR, RTL, auto-LTR
-    const VALUES: &'static [Option<Level>] = &[Some(level::LTR_LEVEL), Some(level::RTL_LEVEL), None];
-    assert!(idx < VALUES.len());
-    VALUES[idx]
-}
-
-/// We need to collaps levels to one-per-character from one-per-byte format.
-fn gen_levels_list_from_bidi_info(input_str: &str, bidi_info: &BidiInfo) -> Vec<Level> {
-    let para = &bidi_info.paragraphs[0];
-    let levels = bidi_info.reordered_levels(para, para.range.clone());
-    // TODO: Move to impl BidiInfo as pub api
-    input_str.char_indices().map(|(i, _)| levels[i]).collect()
-}
-
-fn get_sample_string_from_bidi_classes(class_names: &[&str]) -> String {
-    class_names
-        .iter()
-        .map(|class_name| gen_char_from_bidi_class(class_name))
-        .collect()
-}
-
-/// TODO: Auto-gen in tables.rs ?
-fn gen_char_from_bidi_class(class_name: &str) -> char {
-    match class_name {
-        "AL" => '\u{060b}',
-        "AN" => '\u{0605}',
-        "B" => '\u{000a}',
-        "BN" => '\u{0000}',
-        "CS" => '\u{002c}',
-        "EN" => '\u{0039}',
-        "ES" => '\u{002b}',
-        "ET" => '\u{0023}',
-        "FSI" => format_chars::FSI,
-        "L" => '\u{0041}',
-        "LRE" => format_chars::LRE,
-        "LRI" => format_chars::LRI,
-        "LRO" => format_chars::LRO,
-        "NSM" => '\u{0300}',
-        "ON" => '\u{0021}',
-        "PDF" => format_chars::PDF,
-        "PDI" => format_chars::PDI,
-        "R" => '\u{0590}',
-        "RLE" => format_chars::RLE,
-        "RLI" => format_chars::RLI,
-        "RLO" => format_chars::RLO,
-        "S" => '\u{0009}',
-        "WS" => '\u{000c}',
-        &_ => panic!("Invalid Bidi_Class name: {}", class_name),
-    }
-}
-
-#[test]
-fn test_gen_char_from_bidi_class() {
-    use unicode_bidi::BidiClass::*;
-    for &class in &[
-        AL,
-        AN,
-        B,
-        BN,
-        CS,
-        EN,
-        ES,
-        ET,
-        FSI,
-        L,
-        LRE,
-        LRI,
-        LRO,
-        NSM,
-        ON,
-        PDF,
-        PDI,
-        R,
-        RLE,
-        RLI,
-        RLO,
-        S,
-        WS,
-    ] {
-        let class_name = format!("{:?}", class);
-        let sample_char = gen_char_from_bidi_class(&class_name);
-        assert_eq!(bidi_class(sample_char), class);
-    }
-}
--- a/third_party/rust/unicode-bidi/tools/generate.py
+++ b/third_party/rust/unicode-bidi/tools/generate.py
@@ -11,60 +11,43 @@
 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 # option. This file may not be copied, modified, or distributed
 # except according to those terms.
 
 
 import fileinput, re, os, sys, operator
 
-
-DATA_DIR = 'data'
-TESTS_DATA_DIR = 'tests/data'
-README_NAME = "ReadMe.txt"
-UNICODE_DATA_NAME = "UnicodeData.txt"
-TABLES_PATH = os.path.join("src", "char_data", "tables.rs")
-
-PREAMBLE = '''// NOTE:
+preamble = '''// NOTE:
 // The following code was generated by "tools/generate.py". do not edit directly
 
 #![allow(missing_docs, non_upper_case_globals, non_snake_case)]
-#![cfg_attr(rustfmt, rustfmt_skip)]
 '''
 
 # these are the surrogate codepoints, which are not valid rust characters
-surrogate_codepoints = (0xD800, 0xDFFF)
-
-def fetch(name, dst):
-    if not os.path.exists(dst):
-        os.system("curl -o '%s' 'http://www.unicode.org/Public/UNIDATA/%s'" % (dst, name))
-    if not os.path.exists(dst):
-        sys.stderr.write("cannot fetch %s" % name)
-        exit(1)
+surrogate_codepoints = (0xd800, 0xdfff)
 
-def fetch_data(name):
-    dst = os.path.join(DATA_DIR, os.path.basename(name))
-    fetch(name, dst)
+def fetch(f):
+    if not os.path.exists(os.path.basename(f)):
+        os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s"
+                  % f)
 
-def fetch_test_data(name):
-    dst = os.path.join(TESTS_DATA_DIR, os.path.basename(name))
-    fetch(name, dst)
-
-def open_data(name):
-    return open(os.path.join(DATA_DIR, name))
+    if not os.path.exists(os.path.basename(f)):
+        sys.stderr.write("cannot load %s" % f)
+        exit(1)
 
 def is_surrogate(n):
     return surrogate_codepoints[0] <= n <= surrogate_codepoints[1]
 
-def load_unicode_data():
-    fetch_data(UNICODE_DATA_NAME)
+def load_unicode_data(f):
+    fetch(f)
     udict = {};
 
     range_start = -1;
-    for line in fileinput.input(os.path.join(DATA_DIR, UNICODE_DATA_NAME)):
+    for line in fileinput.input(f):
         data = line.split(';');
         if len(data) != 15:
             continue
         cp = int(data[0], 16);
         if is_surrogate(cp):
             continue
         if range_start >= 0:
             for i in xrange(range_start, cp):
@@ -85,35 +68,35 @@ def load_unicode_data():
 
         if bidi not in bidi_class:
             bidi_class[bidi] = []
         bidi_class[bidi].append(code)
 
     # Default Bidi_Class for unassigned codepoints.
     # http://www.unicode.org/Public/UNIDATA/extracted/DerivedBidiClass.txt
     default_ranges = [
-        (0x0600, 0x07BF, "AL"), (0x08A0, 0x08FF, "AL"),
-        (0xFB50, 0xFDCF, "AL"), (0xFDF0, 0xFDFF, "AL"),
-        (0xFE70, 0xFEFF, "AL"), (0x1EE00, 0x1EEFF, "AL"),
+            (0x0600, 0x07BF, "AL"), (0x08A0, 0x08FF, "AL"),
+            (0xFB50, 0xFDCF, "AL"), (0xFDF0, 0xFDFF, "AL"),
+            (0xFE70, 0xFEFF, "AL"), (0x1EE00, 0x0001EEFF, "AL"),
 
-        (0x0590, 0x05FF, "R"), (0x07C0, 0x089F, "R"),
-        (0xFB1D, 0xFB4F, "R"), (0x10800, 0x10FFF, "R"),
-        (0x1E800, 0x1EDFF, "R"), (0x1EF00, 0x1EFFF, "R"),
+            (0x0590, 0x05FF, "R"), (0x07C0, 0x089F, "R"),
+            (0xFB1D, 0xFB4F, "R"), (0x00010800, 0x00010FFF, "R"),
+            (0x0001E800, 0x0001EDFF, "R"), (0x0001EF00, 0x0001EFFF, "R"),
 
-        (0x20A0, 0x20CF, "ET"),
-    ]
+            (0x20A0, 0x20CF, "ET")]
 
     for (start, end, default) in default_ranges:
         for code in range(start, end+1):
             if not code in udict:
                 bidi_class[default].append(code)
 
-    return group_categories(bidi_class)
+    bidi_class = group_cats(bidi_class)
+    return bidi_class
 
-def group_categories(cats):
+def group_cats(cats):
     cats_out = []
     for cat in cats:
         cats_out.extend([(x, y, cat) for (x, y) in group_cat(cats[cat])])
     cats_out.sort(key=lambda w: w[0])
     return (sorted(cats.keys()), cats_out)
 
 def group_cat(cat):
     cat_out = []
@@ -144,85 +127,94 @@ def format_table_content(f, content, ind
         else:
             f.write(line + ",\n")
             line = " "*indent + chunk
     f.write(line)
 
 def escape_char(c):
     return "'\\u{%x}'" % c
 
-def emit_table(
-    file_,
-    t_name,
-    t_data,
-    t_type = "&'static [(char, char)]",
-    is_pub=True,
-    pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))
-):
+def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
+        pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))):
+    pub_string = ""
     if is_pub:
-        file_.write("pub ")
-    file_.write("const %s: %s = &[\n" % (t_name, t_type))
-
+        pub_string = "pub "
+    f.write("    %sconst %s: %s = &[\n" % (pub_string, name, t_type))
     data = ""
     first = True
     for dat in t_data:
         if not first:
             data += ","
         first = False
         data += pfun(dat)
-    format_table_content(file_, data, 4)
-    file_.write("\n];\n\n")
+    format_table_content(f, data, 8)
+    f.write("\n    ];\n\n")
+
+def emit_bidi_module(f, bidi_class, cats):
+    f.write("""pub use self::BidiClass::*;
 
-def emit_bidi_module(file_, bidi_class_table, cats):
-    file_.write("""
-#[allow(non_camel_case_types)]
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-/// Represents values of the Unicode character property
-/// [Bidi_Class](http://www.unicode.org/reports/tr44/#Bidi_Class), also
-/// known as the *bidirectional character type*.
-///
-/// * http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
-/// * http://www.unicode.org/reports/tr44/#Bidi_Class_Values
-pub enum BidiClass {
+    #[allow(non_camel_case_types)]
+    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
+    /// Represents the Unicode character property **Bidi_Class**, also known as
+    /// the *bidirectional character type*.
+    ///
+    /// Use the `bidi_class` function to look up the BidiClass of a code point.
+    ///
+    /// http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
+    pub enum BidiClass {
 """)
     for cat in cats:
-        file_.write("    " + cat + ",\n")
-    file_.write("""}
+        f.write("        " + cat + ",\n")
+    f.write("""    }
 
-use self::BidiClass::*;
+    fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
+        use ::std::cmp::Ordering::{Equal, Less, Greater};
+        match r.binary_search_by(|&(lo, hi, _)| {
+            if lo <= c && c <= hi { Equal }
+            else if hi < c { Less }
+            else { Greater }
+        }) {
+            Ok(idx) => {
+                let (_, _, cat) = r[idx];
+                cat
+            }
+            // UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
+            // for Bidi_Class have the value Left_To_Right (L)."
+            Err(_) => L
+        }
+    }
+
+    /// Find the BidiClass of a single char.
+    pub fn bidi_class(c: char) -> BidiClass {
+        bsearch_range_value_table(c, bidi_class_table)
+    }
+
 """)
 
-    emit_table(
-        file_,
-        "bidi_class_table",
-        bidi_class_table,
-        "&'static [(char, char, BidiClass)]",
+    emit_table(f, "bidi_class_table", bidi_class, "&'static [(char, char, BidiClass)]",
         pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]),
-    )
-
-def get_unicode_version():
-    fetch_data(README_NAME)
-    with open_data(README_NAME) as readme:
-        pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
-        return re.search(pattern, readme.read()).groups()
+        is_pub=False)
 
 if __name__ == "__main__":
-    # Find Unicode Version
-    if not os.path.exists(DATA_DIR):
-        os.mkdir(DATA_DIR)
-    unicode_version = get_unicode_version()
+    os.chdir("../src/") # changing download path to /unicode-bidi/src/
+    r = "tables.rs"
+    # downloading the test case files
+    # fetch("BidiTest.txt")
+    # fetch("BidiCharacterTest.txt")
 
-    # Build data tables
-    if os.path.exists(TABLES_PATH):
-        os.remove(TABLES_PATH)
-    with open(TABLES_PATH, "w") as file_:
-        file_.write(PREAMBLE)
-        file_.write("""
-/// The [Unicode version](http://www.unicode.org/versions/) of data
+    if os.path.exists(r):
+        os.remove(r)
+    with open(r, "w") as rf:
+        # write the file's preamble
+        rf.write(preamble)
+
+        # download and parse all the data
+        fetch("ReadMe.txt")
+        with open("ReadMe.txt") as readme:
+            pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
+            unicode_version = re.search(pattern, readme.read()).groups()
+        rf.write("""
+/// The version of [Unicode](http://www.unicode.org/)
+/// that the `bidi_class` function is based on.
 pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
 """ % unicode_version)
-
-        (bidi_categories, bidi_class_table) = load_unicode_data()
-        emit_bidi_module(file_, bidi_class_table, bidi_categories)
-
-    # Fetch test data files
-    fetch_test_data("BidiTest.txt")
-    fetch_test_data("BidiCharacterTest.txt")
+        (bidi_cats, bidi_class) = load_unicode_data("UnicodeData.txt")
+        emit_bidi_module(rf, bidi_class, bidi_cats)
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -669,25 +669,25 @@ name = "rand"
 version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rayon"
-version = "0.7.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rayon-core"
-version = "1.0.0"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -840,17 +840,17 @@ dependencies = [
  "nsstring_vendor 0.1.0",
  "num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_derive 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1100,17 +1100,17 @@ dependencies = [
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "plane-split 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender_traits 0.39.0",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
@@ -1226,18 +1226,18 @@ dependencies = [
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
 "checksum plane-split 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b3624c9e5e728dcc6347bde5762406b0f0707bea527d585e8f7b6ac44fdd33a"
 "checksum precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf1fc3616b3ef726a847f2cd2388c646ef6a1f1ba4835c2629004da48184150"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
 "checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
 "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
 "checksum quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7375cf7ad34a92e8fd18dd9c42f58b9a11def59ab48bec955bf359a788335592"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
-"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
-"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
+"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
+"checksum rayon-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd1e76f8ee0322fbbeb0c43a07e1757fcf8ff06bb0ff92da017625882ddc04dd"
 "checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
 "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -656,25 +656,25 @@ name = "rand"
 version = "0.3.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rayon"
-version = "0.7.0"
+version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rayon-core"
-version = "1.0.0"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -827,17 +827,17 @@ dependencies = [
  "nsstring_vendor 0.1.0",
  "num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "style_derive 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1087,17 +1087,17 @@ dependencies = [
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gamma-lut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "plane-split 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender_traits 0.39.0",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
@@ -1213,18 +1213,18 @@ dependencies = [
 "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
 "checksum plane-split 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b3624c9e5e728dcc6347bde5762406b0f0707bea527d585e8f7b6ac44fdd33a"
 "checksum precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf1fc3616b3ef726a847f2cd2388c646ef6a1f1ba4835c2629004da48184150"
 "checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
 "checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
 "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
 "checksum quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7375cf7ad34a92e8fd18dd9c42f58b9a11def59ab48bec955bf359a788335592"
 "checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
-"checksum rayon 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8c83adcb08e5b922e804fe1918142b422602ef11f2fd670b0b52218cb5984a20"
-"checksum rayon-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "767d91bacddf07d442fe39257bf04fd95897d1c47c545d009f6beb03efd038f8"
+"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a"
+"checksum rayon-core 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd1e76f8ee0322fbbeb0c43a07e1757fcf8ff06bb0ff92da017625882ddc04dd"
 "checksum redox_syscall 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd35cc9a8bdec562c757e3d43c1526b5c6d2653e23e2315065bc25556550753"
 "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
 "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
 "checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"