Merge pull request dart-lang/markdown#446 from jonasfj/crashtest
Wrote some crashtest for running against markdown files from pub.dev
diff --git a/pkgs/markdown/.github/dependabot.yaml b/pkgs/markdown/.github/dependabot.yaml
new file mode 100644
index 0000000..2144819
--- /dev/null
+++ b/pkgs/markdown/.github/dependabot.yaml
@@ -0,0 +1,8 @@
+# Dependabot configuration file.
+version: 2
+
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
diff --git a/pkgs/markdown/.github/workflows/test-package.yml b/pkgs/markdown/.github/workflows/test-package.yml
index 1712bfe..82b378a 100644
--- a/pkgs/markdown/.github/workflows/test-package.yml
+++ b/pkgs/markdown/.github/workflows/test-package.yml
@@ -22,8 +22,8 @@
matrix:
sdk: [dev]
steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1.0
+ - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
+ - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d
with:
sdk: ${{ matrix.sdk }}
- id: install
@@ -49,8 +49,8 @@
os: [ubuntu-latest]
sdk: [2.17.0, dev]
steps:
- - uses: actions/checkout@v2
- - uses: dart-lang/setup-dart@v1.0
+ - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
+ - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d
with:
sdk: ${{ matrix.sdk }}
- id: install
@@ -59,3 +59,23 @@
- name: Run VM tests
run: dart test --platform vm
if: always() && steps.install.outcome == 'success'
+
+ coverage:
+ needs: test
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
+ - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d
+ with:
+ sdk: dev
+ - name: Install dependencies
+ run: dart pub get
+ - name: Install coverage
+ run: dart pub global activate coverage
+ - name: Collect and report coverage
+ run: dart pub global run coverage:test_with_coverage
+ - name: Upload coverage
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ path-to-lcov: coverage/lcov.info
diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md
index 9742ee2..58e4ab0 100644
--- a/pkgs/markdown/CHANGELOG.md
+++ b/pkgs/markdown/CHANGELOG.md
@@ -1,3 +1,20 @@
+## 7.0.0-dev
+
+* **Breaking change**: `close()` of `DelimiterSyntax` and `LinkSyntax`
+ returns multiple nodes instead of single one.
+
+## 6.0.2-dev
+
+* Fix a crash in checkbox lists when mixing checkbox items with
+ non-checkbox items.
+* Add a new syntax `BlockHtmlSyntax` to parse HTML blocks.
+* Add a new syntax `DecodeHtmlSyntax` to decode HTML entity and numeric
+ character references.
+* Deprecate `BlockTagBlockHtmlSyntax`, `LongBlockHtmlSyntax` and
+ `OtherTagBlockHtmlSyntax`. These syntaxes will be removed from the next major
+ version.
+* Add an option `caseSensitive` to `TextSyntax`.
+
## 6.0.0
* Require Dart 2.17
diff --git a/pkgs/markdown/README.md b/pkgs/markdown/README.md
index cf6a000..a952014 100644
--- a/pkgs/markdown/README.md
+++ b/pkgs/markdown/README.md
@@ -1,5 +1,7 @@
[](https://github.com/dart-lang/markdown/actions?query=workflow%3A"Dart+CI"+branch%3Amaster)
[](https://pub.dev/packages/markdown)
+[](https://pub.dev/packages/markdown/publisher)
+[](https://coveralls.io/github/dart-lang/markdown?branch=master)
A portable Markdown library written in Dart. It can parse Markdown into
HTML on both the client and server.
diff --git a/pkgs/markdown/analysis_options.yaml b/pkgs/markdown/analysis_options.yaml
index 8dc8263..ac272aa 100644
--- a/pkgs/markdown/analysis_options.yaml
+++ b/pkgs/markdown/analysis_options.yaml
@@ -1,4 +1,6 @@
+# https://dart.dev/guides/language/analysis-options
include: package:lints/recommended.yaml
+
analyzer:
language:
strict-inference: true
@@ -17,13 +19,37 @@
rules:
# https://github.com/dart-lang/linter/issues/574
#- comment_references
+ - always_declare_return_types
+ - avoid_catching_errors
+ - avoid_dynamic_calls
+ - avoid_private_typedef_functions
+ - avoid_redundant_argument_values
+ - avoid_unused_constructor_parameters
+ - avoid_void_async
+ - cancel_subscriptions
- directives_ordering
+ - literal_only_boolean_expressions
+ - missing_whitespace_between_adjacent_strings
+ - no_adjacent_strings_in_list
+ - omit_local_variable_types
- only_throw_errors
- package_api_docs
+ - prefer_asserts_in_initializer_lists
+ - prefer_const_constructors
+ - prefer_const_declarations
+ - prefer_final_locals
+ - prefer_relative_imports
+ - prefer_single_quotes
+ - sort_pub_dependencies
- test_types_in_equals
- throw_in_finally
- - prefer_final_locals
+ - type_annotate_public_apis
+ - unawaited_futures
+ - unnecessary_await_in_return
+ - unnecessary_lambdas
+ - unnecessary_parenthesis
+ - unnecessary_raw_strings
- use_if_null_to_convert_nulls_to_bools
- use_raw_strings
+ - use_string_buffers
- use_super_parameters
- - unnecessary_raw_strings
diff --git a/pkgs/markdown/benchmark/benchmark.dart b/pkgs/markdown/benchmark/benchmark.dart
index 4c4d61f..63a8d1f 100644
--- a/pkgs/markdown/benchmark/benchmark.dart
+++ b/pkgs/markdown/benchmark/benchmark.dart
@@ -38,7 +38,8 @@
// the VM doesn't optimize "dead" code away.
if (result != expected) {
print('Incorrect output:\n$result');
- exit(1);
+ exitCode = 1;
+ return;
}
// Don't print the first run. It's always terrible since the VM hasn't
diff --git a/pkgs/markdown/example/app.dart b/pkgs/markdown/example/app.dart
index 0b06b6b..d8ea6e7 100644
--- a/pkgs/markdown/example/app.dart
+++ b/pkgs/markdown/example/app.dart
@@ -4,6 +4,7 @@
import 'dart:async';
import 'dart:html';
+
import 'package:markdown/markdown.dart' as md;
import 'highlight.dart';
@@ -14,11 +15,15 @@
final nullSanitizer = NullTreeSanitizer();
const typing = Duration(milliseconds: 150);
-final introText = '''Markdown is the **best**!
+const introText = '''Markdown is the **best**!
* It has lists.
* It has [links](https://dart.dev).
-* It has _so much more_...''';
+* It has...
+ ```dart
+ void sourceCode() {}
+ ```
+* ...and _so much more_...''';
// Flavor support.
final basicRadio = querySelector('#basic-radio') as HtmlElement;
diff --git a/pkgs/markdown/lib/markdown.dart b/pkgs/markdown/lib/markdown.dart
index 6155242..de6792d 100644
--- a/pkgs/markdown/lib/markdown.dart
+++ b/pkgs/markdown/lib/markdown.dart
@@ -40,7 +40,6 @@
export 'src/block_parser.dart';
export 'src/block_syntaxes/block_html_syntax.dart';
export 'src/block_syntaxes/block_syntax.dart';
-export 'src/block_syntaxes/block_tag_block_html_syntax.dart';
export 'src/block_syntaxes/blockquote_syntax.dart';
export 'src/block_syntaxes/code_block_syntax.dart';
export 'src/block_syntaxes/dummy_block_syntax.dart';
@@ -50,11 +49,10 @@
export 'src/block_syntaxes/header_syntax.dart';
export 'src/block_syntaxes/header_with_id_syntax.dart';
export 'src/block_syntaxes/horizontal_rule_syntax.dart';
+export 'src/block_syntaxes/html_block_syntax.dart';
export 'src/block_syntaxes/list_syntax.dart';
-export 'src/block_syntaxes/long_block_html_syntax.dart';
export 'src/block_syntaxes/ordered_list_syntax.dart';
export 'src/block_syntaxes/ordered_list_with_checkbox_syntax.dart';
-export 'src/block_syntaxes/other_tag_block_html_syntax.dart';
export 'src/block_syntaxes/paragraph_syntax.dart';
export 'src/block_syntaxes/setext_header_syntax.dart';
export 'src/block_syntaxes/setext_header_with_id_syntax.dart';
diff --git a/pkgs/markdown/lib/src/assets/case_folding.dart b/pkgs/markdown/lib/src/assets/case_folding.dart
new file mode 100644
index 0000000..09081aa
--- /dev/null
+++ b/pkgs/markdown/lib/src/assets/case_folding.dart
@@ -0,0 +1,1316 @@
+// Generated file. do not edit.
+//
+// Source: tool/case_folding.txt
+// Script: tool/update_case_folding.dart
+// ignore_for_file: prefer_single_quotes
+
+const caseFoldingMap = {
+ "A": "a",
+ "B": "b",
+ "C": "c",
+ "D": "d",
+ "E": "e",
+ "F": "f",
+ "G": "g",
+ "H": "h",
+ "I": "i",
+ "J": "j",
+ "K": "k",
+ "L": "l",
+ "M": "m",
+ "N": "n",
+ "O": "o",
+ "P": "p",
+ "Q": "q",
+ "R": "r",
+ "S": "s",
+ "T": "t",
+ "U": "u",
+ "V": "v",
+ "W": "w",
+ "X": "x",
+ "Y": "y",
+ "Z": "z",
+ "À": "à",
+ "Á": "á",
+ "Â": "â",
+ "Ã": "ã",
+ "Ä": "ä",
+ "Å": "å",
+ "Æ": "æ",
+ "Ç": "ç",
+ "È": "è",
+ "É": "é",
+ "Ê": "ê",
+ "Ë": "ë",
+ "Ì": "ì",
+ "Í": "í",
+ "Î": "î",
+ "Ï": "ï",
+ "Ð": "ð",
+ "Ñ": "ñ",
+ "Ò": "ò",
+ "Ó": "ó",
+ "Ô": "ô",
+ "Õ": "õ",
+ "Ö": "ö",
+ "Ø": "ø",
+ "Ù": "ù",
+ "Ú": "ú",
+ "Û": "û",
+ "Ü": "ü",
+ "Ý": "ý",
+ "Þ": "þ",
+ "Ā": "ā",
+ "Ă": "ă",
+ "Ą": "ą",
+ "Ć": "ć",
+ "Ĉ": "ĉ",
+ "Ċ": "ċ",
+ "Č": "č",
+ "Ď": "ď",
+ "Đ": "đ",
+ "Ē": "ē",
+ "Ĕ": "ĕ",
+ "Ė": "ė",
+ "Ę": "ę",
+ "Ě": "ě",
+ "Ĝ": "ĝ",
+ "Ğ": "ğ",
+ "Ġ": "ġ",
+ "Ģ": "ģ",
+ "Ĥ": "ĥ",
+ "Ħ": "ħ",
+ "Ĩ": "ĩ",
+ "Ī": "ī",
+ "Ĭ": "ĭ",
+ "Į": "į",
+ "İ": "i̇",
+ "Ĵ": "ĵ",
+ "Ķ": "ķ",
+ "Ĺ": "ĺ",
+ "Ļ": "ļ",
+ "Ľ": "ľ",
+ "Ŀ": "ŀ",
+ "Ł": "ł",
+ "Ń": "ń",
+ "Ņ": "ņ",
+ "Ň": "ň",
+ "Ŋ": "ŋ",
+ "Ō": "ō",
+ "Ŏ": "ŏ",
+ "Ő": "ő",
+ "Ŕ": "ŕ",
+ "Ŗ": "ŗ",
+ "Ř": "ř",
+ "Ś": "ś",
+ "Ŝ": "ŝ",
+ "Ş": "ş",
+ "Š": "š",
+ "Ţ": "ţ",
+ "Ť": "ť",
+ "Ŧ": "ŧ",
+ "Ũ": "ũ",
+ "Ū": "ū",
+ "Ŭ": "ŭ",
+ "Ů": "ů",
+ "Ű": "ű",
+ "Ų": "ų",
+ "Ŵ": "ŵ",
+ "Ŷ": "ŷ",
+ "Ÿ": "ÿ",
+ "Ź": "ź",
+ "Ż": "ż",
+ "Ž": "ž",
+ "Ɓ": "ɓ",
+ "Ƃ": "ƃ",
+ "Ƅ": "ƅ",
+ "Ɔ": "ɔ",
+ "Ƈ": "ƈ",
+ "Ɖ": "ɖ",
+ "Ɗ": "ɗ",
+ "Ƌ": "ƌ",
+ "Ǝ": "ǝ",
+ "Ə": "ə",
+ "Ɛ": "ɛ",
+ "Ƒ": "ƒ",
+ "Ɠ": "ɠ",
+ "Ɣ": "ɣ",
+ "Ɩ": "ɩ",
+ "Ɨ": "ɨ",
+ "Ƙ": "ƙ",
+ "Ɯ": "ɯ",
+ "Ɲ": "ɲ",
+ "Ɵ": "ɵ",
+ "Ơ": "ơ",
+ "Ƣ": "ƣ",
+ "Ƥ": "ƥ",
+ "Ƨ": "ƨ",
+ "Ʃ": "ʃ",
+ "Ƭ": "ƭ",
+ "Ʈ": "ʈ",
+ "Ư": "ư",
+ "Ʊ": "ʊ",
+ "Ʋ": "ʋ",
+ "Ƴ": "ƴ",
+ "Ƶ": "ƶ",
+ "Ʒ": "ʒ",
+ "Ƹ": "ƹ",
+ "Ƽ": "ƽ",
+ "DŽ": "dž",
+ "Dž": "dž",
+ "LJ": "lj",
+ "Lj": "lj",
+ "NJ": "nj",
+ "Nj": "nj",
+ "Ǎ": "ǎ",
+ "Ǐ": "ǐ",
+ "Ǒ": "ǒ",
+ "Ǔ": "ǔ",
+ "Ǖ": "ǖ",
+ "Ǘ": "ǘ",
+ "Ǚ": "ǚ",
+ "Ǜ": "ǜ",
+ "Ǟ": "ǟ",
+ "Ǡ": "ǡ",
+ "Ǣ": "ǣ",
+ "Ǥ": "ǥ",
+ "Ǧ": "ǧ",
+ "Ǩ": "ǩ",
+ "Ǫ": "ǫ",
+ "Ǭ": "ǭ",
+ "Ǯ": "ǯ",
+ "DZ": "dz",
+ "Dz": "dz",
+ "Ǵ": "ǵ",
+ "Ƕ": "ƕ",
+ "Ƿ": "ƿ",
+ "Ǹ": "ǹ",
+ "Ǻ": "ǻ",
+ "Ǽ": "ǽ",
+ "Ǿ": "ǿ",
+ "Ȁ": "ȁ",
+ "Ȃ": "ȃ",
+ "Ȅ": "ȅ",
+ "Ȇ": "ȇ",
+ "Ȉ": "ȉ",
+ "Ȋ": "ȋ",
+ "Ȍ": "ȍ",
+ "Ȏ": "ȏ",
+ "Ȑ": "ȑ",
+ "Ȓ": "ȓ",
+ "Ȕ": "ȕ",
+ "Ȗ": "ȗ",
+ "Ș": "ș",
+ "Ț": "ț",
+ "Ȝ": "ȝ",
+ "Ȟ": "ȟ",
+ "Ƞ": "ƞ",
+ "Ȣ": "ȣ",
+ "Ȥ": "ȥ",
+ "Ȧ": "ȧ",
+ "Ȩ": "ȩ",
+ "Ȫ": "ȫ",
+ "Ȭ": "ȭ",
+ "Ȯ": "ȯ",
+ "Ȱ": "ȱ",
+ "Ȳ": "ȳ",
+ "Ⱥ": "ⱥ",
+ "Ȼ": "ȼ",
+ "Ƚ": "ƚ",
+ "Ⱦ": "ⱦ",
+ "Ɂ": "ɂ",
+ "Ƀ": "ƀ",
+ "Ʉ": "ʉ",
+ "Ʌ": "ʌ",
+ "Ɇ": "ɇ",
+ "Ɉ": "ɉ",
+ "Ɋ": "ɋ",
+ "Ɍ": "ɍ",
+ "Ɏ": "ɏ",
+ "Ͱ": "ͱ",
+ "Ͳ": "ͳ",
+ "Ͷ": "ͷ",
+ "Ϳ": "ϳ",
+ "Ά": "ά",
+ "Έ": "έ",
+ "Ή": "ή",
+ "Ί": "ί",
+ "Ό": "ό",
+ "Ύ": "ύ",
+ "Ώ": "ώ",
+ "Α": "α",
+ "Β": "β",
+ "Γ": "γ",
+ "Δ": "δ",
+ "Ε": "ε",
+ "Ζ": "ζ",
+ "Η": "η",
+ "Θ": "θ",
+ "Ι": "ι",
+ "Κ": "κ",
+ "Λ": "λ",
+ "Μ": "μ",
+ "Ν": "ν",
+ "Ξ": "ξ",
+ "Ο": "ο",
+ "Π": "π",
+ "Ρ": "ρ",
+ "Σ": "σ",
+ "Τ": "τ",
+ "Υ": "υ",
+ "Φ": "φ",
+ "Χ": "χ",
+ "Ψ": "ψ",
+ "Ω": "ω",
+ "Ϊ": "ϊ",
+ "Ϋ": "ϋ",
+ "Ϣ": "ϣ",
+ "Ϥ": "ϥ",
+ "Ϧ": "ϧ",
+ "Ϩ": "ϩ",
+ "Ϫ": "ϫ",
+ "Ϭ": "ϭ",
+ "Ϯ": "ϯ",
+ "Ϸ": "ϸ",
+ "Ϻ": "ϻ",
+ "Ѐ": "ѐ",
+ "Ё": "ё",
+ "Ђ": "ђ",
+ "Ѓ": "ѓ",
+ "Є": "є",
+ "Ѕ": "ѕ",
+ "І": "і",
+ "Ї": "ї",
+ "Ј": "ј",
+ "Љ": "љ",
+ "Њ": "њ",
+ "Ћ": "ћ",
+ "Ќ": "ќ",
+ "Ѝ": "ѝ",
+ "Ў": "ў",
+ "Џ": "џ",
+ "А": "а",
+ "Б": "б",
+ "В": "в",
+ "Г": "г",
+ "Д": "д",
+ "Е": "е",
+ "Ж": "ж",
+ "З": "з",
+ "И": "и",
+ "Й": "й",
+ "К": "к",
+ "Л": "л",
+ "М": "м",
+ "Н": "н",
+ "О": "о",
+ "П": "п",
+ "Р": "р",
+ "С": "с",
+ "Т": "т",
+ "У": "у",
+ "Ф": "ф",
+ "Х": "х",
+ "Ц": "ц",
+ "Ч": "ч",
+ "Ш": "ш",
+ "Щ": "щ",
+ "Ъ": "ъ",
+ "Ы": "ы",
+ "Ь": "ь",
+ "Э": "э",
+ "Ю": "ю",
+ "Я": "я",
+ "Ѡ": "ѡ",
+ "Ѣ": "ѣ",
+ "Ѥ": "ѥ",
+ "Ѧ": "ѧ",
+ "Ѩ": "ѩ",
+ "Ѫ": "ѫ",
+ "Ѭ": "ѭ",
+ "Ѯ": "ѯ",
+ "Ѱ": "ѱ",
+ "Ѳ": "ѳ",
+ "Ѵ": "ѵ",
+ "Ѷ": "ѷ",
+ "Ѹ": "ѹ",
+ "Ѻ": "ѻ",
+ "Ѽ": "ѽ",
+ "Ѿ": "ѿ",
+ "Ҁ": "ҁ",
+ "Ҋ": "ҋ",
+ "Ҍ": "ҍ",
+ "Ҏ": "ҏ",
+ "Ґ": "ґ",
+ "Ғ": "ғ",
+ "Ҕ": "ҕ",
+ "Җ": "җ",
+ "Ҙ": "ҙ",
+ "Қ": "қ",
+ "Ҝ": "ҝ",
+ "Ҟ": "ҟ",
+ "Ҡ": "ҡ",
+ "Ң": "ң",
+ "Ҧ": "ҧ",
+ "Ҩ": "ҩ",
+ "Ҫ": "ҫ",
+ "Ҭ": "ҭ",
+ "Ү": "ү",
+ "Ұ": "ұ",
+ "Ҳ": "ҳ",
+ "Ҷ": "ҷ",
+ "Ҹ": "ҹ",
+ "Һ": "һ",
+ "Ҽ": "ҽ",
+ "Ҿ": "ҿ",
+ "Ӂ": "ӂ",
+ "Ӄ": "ӄ",
+ "Ӆ": "ӆ",
+ "Ӈ": "ӈ",
+ "Ӊ": "ӊ",
+ "Ӌ": "ӌ",
+ "Ӎ": "ӎ",
+ "Ӑ": "ӑ",
+ "Ӓ": "ӓ",
+ "Ӗ": "ӗ",
+ "Ә": "ә",
+ "Ӛ": "ӛ",
+ "Ӝ": "ӝ",
+ "Ӟ": "ӟ",
+ "Ӡ": "ӡ",
+ "Ӣ": "ӣ",
+ "Ӥ": "ӥ",
+ "Ӧ": "ӧ",
+ "Ө": "ө",
+ "Ӫ": "ӫ",
+ "Ӭ": "ӭ",
+ "Ӯ": "ӯ",
+ "Ӱ": "ӱ",
+ "Ӳ": "ӳ",
+ "Ӵ": "ӵ",
+ "Ӷ": "ӷ",
+ "Ӹ": "ӹ",
+ "Ӻ": "ӻ",
+ "Ӽ": "ӽ",
+ "Ӿ": "ӿ",
+ "Ԁ": "ԁ",
+ "Ԃ": "ԃ",
+ "Ԅ": "ԅ",
+ "Ԇ": "ԇ",
+ "Ԉ": "ԉ",
+ "Ԋ": "ԋ",
+ "Ԍ": "ԍ",
+ "Ԏ": "ԏ",
+ "Ԑ": "ԑ",
+ "Ԓ": "ԓ",
+ "Ԕ": "ԕ",
+ "Ԗ": "ԗ",
+ "Ԙ": "ԙ",
+ "Ԛ": "ԛ",
+ "Ԝ": "ԝ",
+ "Ԟ": "ԟ",
+ "Ԡ": "ԡ",
+ "Ԣ": "ԣ",
+ "Ԥ": "ԥ",
+ "Ԧ": "ԧ",
+ "Ԩ": "ԩ",
+ "Ԫ": "ԫ",
+ "Ԭ": "ԭ",
+ "Ԯ": "ԯ",
+ "Ա": "ա",
+ "Բ": "բ",
+ "Գ": "գ",
+ "Դ": "դ",
+ "Ե": "ե",
+ "Զ": "զ",
+ "Է": "է",
+ "Ը": "ը",
+ "Թ": "թ",
+ "Ժ": "ժ",
+ "Ի": "ի",
+ "Լ": "լ",
+ "Խ": "խ",
+ "Ծ": "ծ",
+ "Կ": "կ",
+ "Հ": "հ",
+ "Ձ": "ձ",
+ "Ղ": "ղ",
+ "Ճ": "ճ",
+ "Մ": "մ",
+ "Յ": "յ",
+ "Ն": "ն",
+ "Շ": "շ",
+ "Ո": "ո",
+ "Չ": "չ",
+ "Պ": "պ",
+ "Ջ": "ջ",
+ "Ռ": "ռ",
+ "Ս": "ս",
+ "Վ": "վ",
+ "Տ": "տ",
+ "Ր": "ր",
+ "Ց": "ց",
+ "Ւ": "ւ",
+ "Փ": "փ",
+ "Ք": "ք",
+ "Օ": "օ",
+ "Ֆ": "ֆ",
+ "Ⴀ": "ⴀ",
+ "Ⴁ": "ⴁ",
+ "Ⴂ": "ⴂ",
+ "Ⴃ": "ⴃ",
+ "Ⴄ": "ⴄ",
+ "Ⴅ": "ⴅ",
+ "Ⴆ": "ⴆ",
+ "Ⴇ": "ⴇ",
+ "Ⴈ": "ⴈ",
+ "Ⴉ": "ⴉ",
+ "Ⴊ": "ⴊ",
+ "Ⴋ": "ⴋ",
+ "Ⴌ": "ⴌ",
+ "Ⴍ": "ⴍ",
+ "Ⴎ": "ⴎ",
+ "Ⴏ": "ⴏ",
+ "Ⴐ": "ⴐ",
+ "Ⴑ": "ⴑ",
+ "Ⴒ": "ⴒ",
+ "Ⴓ": "ⴓ",
+ "Ⴔ": "ⴔ",
+ "Ⴕ": "ⴕ",
+ "Ⴖ": "ⴖ",
+ "Ⴗ": "ⴗ",
+ "Ⴘ": "ⴘ",
+ "Ⴙ": "ⴙ",
+ "Ⴚ": "ⴚ",
+ "Ⴛ": "ⴛ",
+ "Ⴜ": "ⴜ",
+ "Ⴝ": "ⴝ",
+ "Ⴞ": "ⴞ",
+ "Ⴟ": "ⴟ",
+ "Ⴠ": "ⴠ",
+ "Ⴡ": "ⴡ",
+ "Ⴢ": "ⴢ",
+ "Ⴣ": "ⴣ",
+ "Ⴤ": "ⴤ",
+ "Ⴥ": "ⴥ",
+ "Ⴧ": "ⴧ",
+ "Ⴭ": "ⴭ",
+ "Ა": "ა",
+ "Ბ": "ბ",
+ "Გ": "გ",
+ "Დ": "დ",
+ "Ე": "ე",
+ "Ვ": "ვ",
+ "Ზ": "ზ",
+ "Თ": "თ",
+ "Ი": "ი",
+ "Კ": "კ",
+ "Ლ": "ლ",
+ "Მ": "მ",
+ "Ნ": "ნ",
+ "Ო": "ო",
+ "Პ": "პ",
+ "Ჟ": "ჟ",
+ "Რ": "რ",
+ "Ს": "ს",
+ "Ტ": "ტ",
+ "Უ": "უ",
+ "Ფ": "ფ",
+ "Ქ": "ქ",
+ "Ღ": "ღ",
+ "Ყ": "ყ",
+ "Შ": "შ",
+ "Ჩ": "ჩ",
+ "Ც": "ც",
+ "Ძ": "ძ",
+ "Წ": "წ",
+ "Ჭ": "ჭ",
+ "Ხ": "ხ",
+ "Ჯ": "ჯ",
+ "Ჰ": "ჰ",
+ "Ჱ": "ჱ",
+ "Ჲ": "ჲ",
+ "Ჳ": "ჳ",
+ "Ჴ": "ჴ",
+ "Ჵ": "ჵ",
+ "Ჶ": "ჶ",
+ "Ჷ": "ჷ",
+ "Ჸ": "ჸ",
+ "Ჹ": "ჹ",
+ "Ჺ": "ჺ",
+ "Ჽ": "ჽ",
+ "Ჾ": "ჾ",
+ "Ჿ": "ჿ",
+ "Ḁ": "ḁ",
+ "Ḃ": "ḃ",
+ "Ḅ": "ḅ",
+ "Ḇ": "ḇ",
+ "Ḉ": "ḉ",
+ "Ḋ": "ḋ",
+ "Ḍ": "ḍ",
+ "Ḏ": "ḏ",
+ "Ḑ": "ḑ",
+ "Ḓ": "ḓ",
+ "Ḕ": "ḕ",
+ "Ḗ": "ḗ",
+ "Ḙ": "ḙ",
+ "Ḛ": "ḛ",
+ "Ḝ": "ḝ",
+ "Ḟ": "ḟ",
+ "Ḡ": "ḡ",
+ "Ḣ": "ḣ",
+ "Ḥ": "ḥ",
+ "Ḧ": "ḧ",
+ "Ḩ": "ḩ",
+ "Ḫ": "ḫ",
+ "Ḭ": "ḭ",
+ "Ḯ": "ḯ",
+ "Ḱ": "ḱ",
+ "Ḳ": "ḳ",
+ "Ḵ": "ḵ",
+ "Ḷ": "ḷ",
+ "Ḹ": "ḹ",
+ "Ḻ": "ḻ",
+ "Ḽ": "ḽ",
+ "Ḿ": "ḿ",
+ "Ṁ": "ṁ",
+ "Ṃ": "ṃ",
+ "Ṅ": "ṅ",
+ "Ṇ": "ṇ",
+ "Ṉ": "ṉ",
+ "Ṋ": "ṋ",
+ "Ṍ": "ṍ",
+ "Ṏ": "ṏ",
+ "Ṑ": "ṑ",
+ "Ṓ": "ṓ",
+ "Ṕ": "ṕ",
+ "Ṗ": "ṗ",
+ "Ṙ": "ṙ",
+ "Ṛ": "ṛ",
+ "Ṝ": "ṝ",
+ "Ṟ": "ṟ",
+ "Ṡ": "ṡ",
+ "Ṣ": "ṣ",
+ "Ṥ": "ṥ",
+ "Ṧ": "ṧ",
+ "Ṩ": "ṩ",
+ "Ṫ": "ṫ",
+ "Ṭ": "ṭ",
+ "Ṯ": "ṯ",
+ "Ṱ": "ṱ",
+ "Ṳ": "ṳ",
+ "Ṵ": "ṵ",
+ "Ṷ": "ṷ",
+ "Ṹ": "ṹ",
+ "Ṻ": "ṻ",
+ "Ṽ": "ṽ",
+ "Ṿ": "ṿ",
+ "Ẁ": "ẁ",
+ "Ẃ": "ẃ",
+ "Ẅ": "ẅ",
+ "Ẇ": "ẇ",
+ "Ẉ": "ẉ",
+ "Ẋ": "ẋ",
+ "Ẍ": "ẍ",
+ "Ẏ": "ẏ",
+ "Ẑ": "ẑ",
+ "Ẓ": "ẓ",
+ "Ẕ": "ẕ",
+ "ẞ": "ss",
+ "Ạ": "ạ",
+ "Ả": "ả",
+ "Ấ": "ấ",
+ "Ầ": "ầ",
+ "Ẩ": "ẩ",
+ "Ẫ": "ẫ",
+ "Ậ": "ậ",
+ "Ắ": "ắ",
+ "Ằ": "ằ",
+ "Ẳ": "ẳ",
+ "Ẵ": "ẵ",
+ "Ặ": "ặ",
+ "Ẹ": "ẹ",
+ "Ẻ": "ẻ",
+ "Ẽ": "ẽ",
+ "Ế": "ế",
+ "Ề": "ề",
+ "Ể": "ể",
+ "Ễ": "ễ",
+ "Ệ": "ệ",
+ "Ỉ": "ỉ",
+ "Ị": "ị",
+ "Ọ": "ọ",
+ "Ỏ": "ỏ",
+ "Ố": "ố",
+ "Ồ": "ồ",
+ "Ổ": "ổ",
+ "Ỗ": "ỗ",
+ "Ộ": "ộ",
+ "Ớ": "ớ",
+ "Ờ": "ờ",
+ "Ở": "ở",
+ "Ỡ": "ỡ",
+ "Ợ": "ợ",
+ "Ụ": "ụ",
+ "Ủ": "ủ",
+ "Ứ": "ứ",
+ "Ừ": "ừ",
+ "Ử": "ử",
+ "Ữ": "ữ",
+ "Ự": "ự",
+ "Ỳ": "ỳ",
+ "Ỵ": "ỵ",
+ "Ỷ": "ỷ",
+ "Ỹ": "ỹ",
+ "Ỻ": "ỻ",
+ "Ỽ": "ỽ",
+ "Ỿ": "ỿ",
+ "Ἀ": "ἀ",
+ "Ἁ": "ἁ",
+ "Ἂ": "ἂ",
+ "Ἃ": "ἃ",
+ "Ἄ": "ἄ",
+ "Ἅ": "ἅ",
+ "Ἆ": "ἆ",
+ "Ἇ": "ἇ",
+ "Ἐ": "ἐ",
+ "Ἑ": "ἑ",
+ "Ἒ": "ἒ",
+ "Ἓ": "ἓ",
+ "Ἔ": "ἔ",
+ "Ἕ": "ἕ",
+ "Ἠ": "ἠ",
+ "Ἡ": "ἡ",
+ "Ἢ": "ἢ",
+ "Ἣ": "ἣ",
+ "Ἤ": "ἤ",
+ "Ἥ": "ἥ",
+ "Ἦ": "ἦ",
+ "Ἧ": "ἧ",
+ "Ἰ": "ἰ",
+ "Ἱ": "ἱ",
+ "Ἲ": "ἲ",
+ "Ἳ": "ἳ",
+ "Ἴ": "ἴ",
+ "Ἵ": "ἵ",
+ "Ἶ": "ἶ",
+ "Ἷ": "ἷ",
+ "Ὀ": "ὀ",
+ "Ὁ": "ὁ",
+ "Ὂ": "ὂ",
+ "Ὃ": "ὃ",
+ "Ὄ": "ὄ",
+ "Ὅ": "ὅ",
+ "Ὑ": "ὑ",
+ "Ὓ": "ὓ",
+ "Ὕ": "ὕ",
+ "Ὗ": "ὗ",
+ "Ὠ": "ὠ",
+ "Ὡ": "ὡ",
+ "Ὢ": "ὢ",
+ "Ὣ": "ὣ",
+ "Ὤ": "ὤ",
+ "Ὥ": "ὥ",
+ "Ὦ": "ὦ",
+ "Ὧ": "ὧ",
+ "ᾈ": "ἀι",
+ "ᾉ": "ἁι",
+ "ᾊ": "ἂι",
+ "ᾋ": "ἃι",
+ "ᾌ": "ἄι",
+ "ᾍ": "ἅι",
+ "ᾎ": "ἆι",
+ "ᾏ": "ἇι",
+ "ᾘ": "ἠι",
+ "ᾙ": "ἡι",
+ "ᾚ": "ἢι",
+ "ᾛ": "ἣι",
+ "ᾜ": "ἤι",
+ "ᾝ": "ἥι",
+ "ᾞ": "ἦι",
+ "ᾟ": "ἧι",
+ "ᾨ": "ὠι",
+ "ᾩ": "ὡι",
+ "ᾪ": "ὢι",
+ "ᾫ": "ὣι",
+ "ᾬ": "ὤι",
+ "ᾭ": "ὥι",
+ "ᾮ": "ὦι",
+ "ᾯ": "ὧι",
+ "Ᾰ": "ᾰ",
+ "Ᾱ": "ᾱ",
+ "Ὰ": "ὰ",
+ "Ά": "ά",
+ "ᾼ": "αι",
+ "Ὲ": "ὲ",
+ "Έ": "έ",
+ "Ὴ": "ὴ",
+ "Ή": "ή",
+ "ῌ": "ηι",
+ "Ῐ": "ῐ",
+ "Ῑ": "ῑ",
+ "Ὶ": "ὶ",
+ "Ί": "ί",
+ "Ῠ": "ῠ",
+ "Ῡ": "ῡ",
+ "Ὺ": "ὺ",
+ "Ύ": "ύ",
+ "Ῥ": "ῥ",
+ "Ὸ": "ὸ",
+ "Ό": "ό",
+ "Ὼ": "ὼ",
+ "Ώ": "ώ",
+ "ῼ": "ωι",
+ "Ⓐ": "ⓐ",
+ "Ⓑ": "ⓑ",
+ "Ⓒ": "ⓒ",
+ "Ⓓ": "ⓓ",
+ "Ⓔ": "ⓔ",
+ "Ⓕ": "ⓕ",
+ "Ⓖ": "ⓖ",
+ "Ⓗ": "ⓗ",
+ "Ⓘ": "ⓘ",
+ "Ⓙ": "ⓙ",
+ "Ⓚ": "ⓚ",
+ "Ⓛ": "ⓛ",
+ "Ⓜ": "ⓜ",
+ "Ⓝ": "ⓝ",
+ "Ⓞ": "ⓞ",
+ "Ⓟ": "ⓟ",
+ "Ⓠ": "ⓠ",
+ "Ⓡ": "ⓡ",
+ "Ⓢ": "ⓢ",
+ "Ⓣ": "ⓣ",
+ "Ⓤ": "ⓤ",
+ "Ⓥ": "ⓥ",
+ "Ⓦ": "ⓦ",
+ "Ⓧ": "ⓧ",
+ "Ⓨ": "ⓨ",
+ "Ⓩ": "ⓩ",
+ "Ⰰ": "ⰰ",
+ "Ⰱ": "ⰱ",
+ "Ⰲ": "ⰲ",
+ "Ⰳ": "ⰳ",
+ "Ⰴ": "ⰴ",
+ "Ⰵ": "ⰵ",
+ "Ⰶ": "ⰶ",
+ "Ⰷ": "ⰷ",
+ "Ⰸ": "ⰸ",
+ "Ⰹ": "ⰹ",
+ "Ⰺ": "ⰺ",
+ "Ⰻ": "ⰻ",
+ "Ⰼ": "ⰼ",
+ "Ⰽ": "ⰽ",
+ "Ⰾ": "ⰾ",
+ "Ⰿ": "ⰿ",
+ "Ⱀ": "ⱀ",
+ "Ⱁ": "ⱁ",
+ "Ⱂ": "ⱂ",
+ "Ⱃ": "ⱃ",
+ "Ⱄ": "ⱄ",
+ "Ⱅ": "ⱅ",
+ "Ⱆ": "ⱆ",
+ "Ⱇ": "ⱇ",
+ "Ⱈ": "ⱈ",
+ "Ⱉ": "ⱉ",
+ "Ⱊ": "ⱊ",
+ "Ⱋ": "ⱋ",
+ "Ⱌ": "ⱌ",
+ "Ⱍ": "ⱍ",
+ "Ⱎ": "ⱎ",
+ "Ⱏ": "ⱏ",
+ "Ⱐ": "ⱐ",
+ "Ⱑ": "ⱑ",
+ "Ⱒ": "ⱒ",
+ "Ⱓ": "ⱓ",
+ "Ⱔ": "ⱔ",
+ "Ⱕ": "ⱕ",
+ "Ⱖ": "ⱖ",
+ "Ⱗ": "ⱗ",
+ "Ⱘ": "ⱘ",
+ "Ⱙ": "ⱙ",
+ "Ⱚ": "ⱚ",
+ "Ⱛ": "ⱛ",
+ "Ⱜ": "ⱜ",
+ "Ⱝ": "ⱝ",
+ "Ⱞ": "ⱞ",
+ "Ⱟ": "ⱟ",
+ "Ⱡ": "ⱡ",
+ "Ɫ": "ɫ",
+ "Ᵽ": "ᵽ",
+ "Ɽ": "ɽ",
+ "Ⱨ": "ⱨ",
+ "Ⱪ": "ⱪ",
+ "Ⱬ": "ⱬ",
+ "Ɑ": "ɑ",
+ "Ɱ": "ɱ",
+ "Ɐ": "ɐ",
+ "Ɒ": "ɒ",
+ "Ⱳ": "ⱳ",
+ "Ⱶ": "ⱶ",
+ "Ȿ": "ȿ",
+ "Ɀ": "ɀ",
+ "Ⲁ": "ⲁ",
+ "Ⲃ": "ⲃ",
+ "Ⲅ": "ⲅ",
+ "Ⲇ": "ⲇ",
+ "Ⲉ": "ⲉ",
+ "Ⲋ": "ⲋ",
+ "Ⲍ": "ⲍ",
+ "Ⲏ": "ⲏ",
+ "Ⲑ": "ⲑ",
+ "Ⲓ": "ⲓ",
+ "Ⲕ": "ⲕ",
+ "Ⲗ": "ⲗ",
+ "Ⲙ": "ⲙ",
+ "Ⲛ": "ⲛ",
+ "Ⲝ": "ⲝ",
+ "Ⲟ": "ⲟ",
+ "Ⲡ": "ⲡ",
+ "Ⲣ": "ⲣ",
+ "Ⲥ": "ⲥ",
+ "Ⲧ": "ⲧ",
+ "Ⲩ": "ⲩ",
+ "Ⲫ": "ⲫ",
+ "Ⲭ": "ⲭ",
+ "Ⲯ": "ⲯ",
+ "Ⲱ": "ⲱ",
+ "Ⲳ": "ⲳ",
+ "Ⲵ": "ⲵ",
+ "Ⲷ": "ⲷ",
+ "Ⲹ": "ⲹ",
+ "Ⲻ": "ⲻ",
+ "Ⲽ": "ⲽ",
+ "Ⲿ": "ⲿ",
+ "Ⳁ": "ⳁ",
+ "Ⳃ": "ⳃ",
+ "Ⳅ": "ⳅ",
+ "Ⳇ": "ⳇ",
+ "Ⳉ": "ⳉ",
+ "Ⳋ": "ⳋ",
+ "Ⳍ": "ⳍ",
+ "Ⳏ": "ⳏ",
+ "Ⳑ": "ⳑ",
+ "Ⳓ": "ⳓ",
+ "Ⳕ": "ⳕ",
+ "Ⳗ": "ⳗ",
+ "Ⳙ": "ⳙ",
+ "Ⳛ": "ⳛ",
+ "Ⳝ": "ⳝ",
+ "Ⳟ": "ⳟ",
+ "Ⳡ": "ⳡ",
+ "Ⳣ": "ⳣ",
+ "Ⳬ": "ⳬ",
+ "Ⳮ": "ⳮ",
+ "Ⳳ": "ⳳ",
+ "Ꙁ": "ꙁ",
+ "Ꙃ": "ꙃ",
+ "Ꙅ": "ꙅ",
+ "Ꙇ": "ꙇ",
+ "Ꙉ": "ꙉ",
+ "Ꙋ": "ꙋ",
+ "Ꙍ": "ꙍ",
+ "Ꙏ": "ꙏ",
+ "Ꙑ": "ꙑ",
+ "Ꙓ": "ꙓ",
+ "Ꙕ": "ꙕ",
+ "Ꙗ": "ꙗ",
+ "Ꙙ": "ꙙ",
+ "Ꙛ": "ꙛ",
+ "Ꙝ": "ꙝ",
+ "Ꙟ": "ꙟ",
+ "Ꙡ": "ꙡ",
+ "Ꙣ": "ꙣ",
+ "Ꙥ": "ꙥ",
+ "Ꙧ": "ꙧ",
+ "Ꙩ": "ꙩ",
+ "Ꙫ": "ꙫ",
+ "Ꙭ": "ꙭ",
+ "Ꚁ": "ꚁ",
+ "Ꚃ": "ꚃ",
+ "Ꚅ": "ꚅ",
+ "Ꚇ": "ꚇ",
+ "Ꚉ": "ꚉ",
+ "Ꚋ": "ꚋ",
+ "Ꚍ": "ꚍ",
+ "Ꚏ": "ꚏ",
+ "Ꚑ": "ꚑ",
+ "Ꚓ": "ꚓ",
+ "Ꚕ": "ꚕ",
+ "Ꚗ": "ꚗ",
+ "Ꚙ": "ꚙ",
+ "Ꚛ": "ꚛ",
+ "Ꜣ": "ꜣ",
+ "Ꜥ": "ꜥ",
+ "Ꜧ": "ꜧ",
+ "Ꜩ": "ꜩ",
+ "Ꜫ": "ꜫ",
+ "Ꜭ": "ꜭ",
+ "Ꜯ": "ꜯ",
+ "Ꜳ": "ꜳ",
+ "Ꜵ": "ꜵ",
+ "Ꜷ": "ꜷ",
+ "Ꜹ": "ꜹ",
+ "Ꜻ": "ꜻ",
+ "Ꜽ": "ꜽ",
+ "Ꜿ": "ꜿ",
+ "Ꝁ": "ꝁ",
+ "Ꝃ": "ꝃ",
+ "Ꝅ": "ꝅ",
+ "Ꝇ": "ꝇ",
+ "Ꝉ": "ꝉ",
+ "Ꝋ": "ꝋ",
+ "Ꝍ": "ꝍ",
+ "Ꝏ": "ꝏ",
+ "Ꝑ": "ꝑ",
+ "Ꝓ": "ꝓ",
+ "Ꝕ": "ꝕ",
+ "Ꝗ": "ꝗ",
+ "Ꝙ": "ꝙ",
+ "Ꝛ": "ꝛ",
+ "Ꝝ": "ꝝ",
+ "Ꝟ": "ꝟ",
+ "Ꝡ": "ꝡ",
+ "Ꝣ": "ꝣ",
+ "Ꝥ": "ꝥ",
+ "Ꝧ": "ꝧ",
+ "Ꝩ": "ꝩ",
+ "Ꝫ": "ꝫ",
+ "Ꝭ": "ꝭ",
+ "Ꝯ": "ꝯ",
+ "Ꝺ": "ꝺ",
+ "Ꝼ": "ꝼ",
+ "Ᵹ": "ᵹ",
+ "Ꝿ": "ꝿ",
+ "Ꞁ": "ꞁ",
+ "Ꞃ": "ꞃ",
+ "Ꞅ": "ꞅ",
+ "Ꞇ": "ꞇ",
+ "Ꞌ": "ꞌ",
+ "Ɥ": "ɥ",
+ "Ꞑ": "ꞑ",
+ "Ꞓ": "ꞓ",
+ "Ꞗ": "ꞗ",
+ "Ꞙ": "ꞙ",
+ "Ꞛ": "ꞛ",
+ "Ꞝ": "ꞝ",
+ "Ꞟ": "ꞟ",
+ "Ꞡ": "ꞡ",
+ "Ꞣ": "ꞣ",
+ "Ꞥ": "ꞥ",
+ "Ꞧ": "ꞧ",
+ "Ꞩ": "ꞩ",
+ "Ɦ": "ɦ",
+ "Ɜ": "ɜ",
+ "Ɡ": "ɡ",
+ "Ɬ": "ɬ",
+ "Ɪ": "ɪ",
+ "Ʞ": "ʞ",
+ "Ʇ": "ʇ",
+ "Ʝ": "ʝ",
+ "Ꭓ": "ꭓ",
+ "Ꞵ": "ꞵ",
+ "Ꞷ": "ꞷ",
+ "Ꞹ": "ꞹ",
+ "Ꞻ": "ꞻ",
+ "Ꞽ": "ꞽ",
+ "Ꞿ": "ꞿ",
+ "Ꟁ": "ꟁ",
+ "Ꟃ": "ꟃ",
+ "Ꞔ": "ꞔ",
+ "Ʂ": "ʂ",
+ "Ᶎ": "ᶎ",
+ "Ꟈ": "ꟈ",
+ "Ꟊ": "ꟊ",
+ "Ꟑ": "ꟑ",
+ "Ꟗ": "ꟗ",
+ "Ꟙ": "ꟙ",
+ "Ꟶ": "ꟶ",
+ "A": "a",
+ "B": "b",
+ "C": "c",
+ "D": "d",
+ "E": "e",
+ "F": "f",
+ "G": "g",
+ "H": "h",
+ "I": "i",
+ "J": "j",
+ "K": "k",
+ "L": "l",
+ "M": "m",
+ "N": "n",
+ "O": "o",
+ "P": "p",
+ "Q": "q",
+ "R": "r",
+ "S": "s",
+ "T": "t",
+ "U": "u",
+ "V": "v",
+ "W": "w",
+ "X": "x",
+ "Y": "y",
+ "Z": "z",
+ "𐐀": "𐐨",
+ "𐐁": "𐐩",
+ "𐐂": "𐐪",
+ "𐐃": "𐐫",
+ "𐐄": "𐐬",
+ "𐐅": "𐐭",
+ "𐐆": "𐐮",
+ "𐐇": "𐐯",
+ "𐐈": "𐐰",
+ "𐐉": "𐐱",
+ "𐐊": "𐐲",
+ "𐐋": "𐐳",
+ "𐐌": "𐐴",
+ "𐐍": "𐐵",
+ "𐐎": "𐐶",
+ "𐐏": "𐐷",
+ "𐐐": "𐐸",
+ "𐐑": "𐐹",
+ "𐐒": "𐐺",
+ "𐐓": "𐐻",
+ "𐐔": "𐐼",
+ "𐐕": "𐐽",
+ "𐐖": "𐐾",
+ "𐐗": "𐐿",
+ "𐐘": "𐑀",
+ "𐐙": "𐑁",
+ "𐐚": "𐑂",
+ "𐐛": "𐑃",
+ "𐐜": "𐑄",
+ "𐐝": "𐑅",
+ "𐐞": "𐑆",
+ "𐐟": "𐑇",
+ "𐐠": "𐑈",
+ "𐐡": "𐑉",
+ "𐐢": "𐑊",
+ "𐐣": "𐑋",
+ "𐐤": "𐑌",
+ "𐐥": "𐑍",
+ "𐐦": "𐑎",
+ "𐐧": "𐑏",
+ "𐒰": "𐓘",
+ "𐒱": "𐓙",
+ "𐒲": "𐓚",
+ "𐒳": "𐓛",
+ "𐒴": "𐓜",
+ "𐒵": "𐓝",
+ "𐒶": "𐓞",
+ "𐒷": "𐓟",
+ "𐒸": "𐓠",
+ "𐒹": "𐓡",
+ "𐒺": "𐓢",
+ "𐒻": "𐓣",
+ "𐒼": "𐓤",
+ "𐒽": "𐓥",
+ "𐒾": "𐓦",
+ "𐒿": "𐓧",
+ "𐓀": "𐓨",
+ "𐓁": "𐓩",
+ "𐓂": "𐓪",
+ "𐓃": "𐓫",
+ "𐓄": "𐓬",
+ "𐓅": "𐓭",
+ "𐓆": "𐓮",
+ "𐓇": "𐓯",
+ "𐓈": "𐓰",
+ "𐓉": "𐓱",
+ "𐓊": "𐓲",
+ "𐓋": "𐓳",
+ "𐓌": "𐓴",
+ "𐓍": "𐓵",
+ "𐓎": "𐓶",
+ "𐓏": "𐓷",
+ "𐓐": "𐓸",
+ "𐓑": "𐓹",
+ "𐓒": "𐓺",
+ "𐓓": "𐓻",
+ "𐕰": "𐖗",
+ "𐕱": "𐖘",
+ "𐕲": "𐖙",
+ "𐕳": "𐖚",
+ "𐕴": "𐖛",
+ "𐕵": "𐖜",
+ "𐕶": "𐖝",
+ "𐕷": "𐖞",
+ "𐕸": "𐖟",
+ "𐕹": "𐖠",
+ "𐕺": "𐖡",
+ "𐕼": "𐖣",
+ "𐕽": "𐖤",
+ "𐕾": "𐖥",
+ "𐕿": "𐖦",
+ "𐖀": "𐖧",
+ "𐖁": "𐖨",
+ "𐖂": "𐖩",
+ "𐖃": "𐖪",
+ "𐖄": "𐖫",
+ "𐖅": "𐖬",
+ "𐖆": "𐖭",
+ "𐖇": "𐖮",
+ "𐖈": "𐖯",
+ "𐖉": "𐖰",
+ "𐖊": "𐖱",
+ "𐖌": "𐖳",
+ "𐖍": "𐖴",
+ "𐖎": "𐖵",
+ "𐖏": "𐖶",
+ "𐖐": "𐖷",
+ "𐖑": "𐖸",
+ "𐖒": "𐖹",
+ "𐖔": "𐖻",
+ "𐖕": "𐖼",
+ "𐲀": "𐳀",
+ "𐲁": "𐳁",
+ "𐲂": "𐳂",
+ "𐲃": "𐳃",
+ "𐲄": "𐳄",
+ "𐲅": "𐳅",
+ "𐲆": "𐳆",
+ "𐲇": "𐳇",
+ "𐲈": "𐳈",
+ "𐲉": "𐳉",
+ "𐲊": "𐳊",
+ "𐲋": "𐳋",
+ "𐲌": "𐳌",
+ "𐲍": "𐳍",
+ "𐲎": "𐳎",
+ "𐲏": "𐳏",
+ "𐲐": "𐳐",
+ "𐲑": "𐳑",
+ "𐲒": "𐳒",
+ "𐲓": "𐳓",
+ "𐲔": "𐳔",
+ "𐲕": "𐳕",
+ "𐲖": "𐳖",
+ "𐲗": "𐳗",
+ "𐲘": "𐳘",
+ "𐲙": "𐳙",
+ "𐲚": "𐳚",
+ "𐲛": "𐳛",
+ "𐲜": "𐳜",
+ "𐲝": "𐳝",
+ "𐲞": "𐳞",
+ "𐲟": "𐳟",
+ "𐲠": "𐳠",
+ "𐲡": "𐳡",
+ "𐲢": "𐳢",
+ "𐲣": "𐳣",
+ "𐲤": "𐳤",
+ "𐲥": "𐳥",
+ "𐲦": "𐳦",
+ "𐲧": "𐳧",
+ "𐲨": "𐳨",
+ "𐲩": "𐳩",
+ "𐲪": "𐳪",
+ "𐲫": "𐳫",
+ "𐲬": "𐳬",
+ "𐲭": "𐳭",
+ "𐲮": "𐳮",
+ "𐲯": "𐳯",
+ "𐲰": "𐳰",
+ "𐲱": "𐳱",
+ "𐲲": "𐳲",
+ "𑢠": "𑣀",
+ "𑢡": "𑣁",
+ "𑢢": "𑣂",
+ "𑢣": "𑣃",
+ "𑢤": "𑣄",
+ "𑢥": "𑣅",
+ "𑢦": "𑣆",
+ "𑢧": "𑣇",
+ "𑢨": "𑣈",
+ "𑢩": "𑣉",
+ "𑢪": "𑣊",
+ "𑢫": "𑣋",
+ "𑢬": "𑣌",
+ "𑢭": "𑣍",
+ "𑢮": "𑣎",
+ "𑢯": "𑣏",
+ "𑢰": "𑣐",
+ "𑢱": "𑣑",
+ "𑢲": "𑣒",
+ "𑢳": "𑣓",
+ "𑢴": "𑣔",
+ "𑢵": "𑣕",
+ "𑢶": "𑣖",
+ "𑢷": "𑣗",
+ "𑢸": "𑣘",
+ "𑢹": "𑣙",
+ "𑢺": "𑣚",
+ "𑢻": "𑣛",
+ "𑢼": "𑣜",
+ "𑢽": "𑣝",
+ "𑢾": "𑣞",
+ "𑢿": "𑣟",
+ "𖹀": "𖹠",
+ "𖹁": "𖹡",
+ "𖹂": "𖹢",
+ "𖹃": "𖹣",
+ "𖹄": "𖹤",
+ "𖹅": "𖹥",
+ "𖹆": "𖹦",
+ "𖹇": "𖹧",
+ "𖹈": "𖹨",
+ "𖹉": "𖹩",
+ "𖹊": "𖹪",
+ "𖹋": "𖹫",
+ "𖹌": "𖹬",
+ "𖹍": "𖹭",
+ "𖹎": "𖹮",
+ "𖹏": "𖹯",
+ "𖹐": "𖹰",
+ "𖹑": "𖹱",
+ "𖹒": "𖹲",
+ "𖹓": "𖹳",
+ "𖹔": "𖹴",
+ "𖹕": "𖹵",
+ "𖹖": "𖹶",
+ "𖹗": "𖹷",
+ "𖹘": "𖹸",
+ "𖹙": "𖹹",
+ "𖹚": "𖹺",
+ "𖹛": "𖹻",
+ "𖹜": "𖹼",
+ "𖹝": "𖹽",
+ "𖹞": "𖹾",
+ "𖹟": "𖹿",
+ "𞤀": "𞤢",
+ "𞤁": "𞤣",
+ "𞤂": "𞤤",
+ "𞤃": "𞤥",
+ "𞤄": "𞤦",
+ "𞤅": "𞤧",
+ "𞤆": "𞤨",
+ "𞤇": "𞤩",
+ "𞤈": "𞤪",
+ "𞤉": "𞤫",
+ "𞤊": "𞤬",
+ "𞤋": "𞤭",
+ "𞤌": "𞤮",
+ "𞤍": "𞤯",
+ "𞤎": "𞤰",
+ "𞤏": "𞤱",
+ "𞤐": "𞤲",
+ "𞤑": "𞤳",
+ "𞤒": "𞤴",
+ "𞤓": "𞤵",
+ "𞤔": "𞤶",
+ "𞤕": "𞤷",
+ "𞤖": "𞤸",
+ "𞤗": "𞤹",
+ "𞤘": "𞤺",
+ "𞤙": "𞤻",
+ "𞤚": "𞤼",
+ "𞤛": "𞤽",
+ "𞤜": "𞤾",
+ "𞤝": "𞤿",
+ "𞤞": "𞥀",
+ "𞤟": "𞥁",
+ "𞤠": "𞥂",
+ "𞤡": "𞥃"
+};
diff --git a/pkgs/markdown/lib/src/assets/html_entities.dart b/pkgs/markdown/lib/src/assets/html_entities.dart
new file mode 100644
index 0000000..2599762
--- /dev/null
+++ b/pkgs/markdown/lib/src/assets/html_entities.dart
@@ -0,0 +1,2133 @@
+// Generated file. do not edit.
+//
+// Source: tool/entities.json
+// Script: tool/update_entities.dart
+// ignore_for_file: prefer_single_quotes
+
+const htmlEntitiesMap = {
+ "Æ": "Æ",
+ "&": "&",
+ "Á": "Á",
+ "Ă": "Ă",
+ "Â": "Â",
+ "А": "А",
+ "𝔄": "𝔄",
+ "À": "À",
+ "Α": "Α",
+ "Ā": "Ā",
+ "⩓": "⩓",
+ "Ą": "Ą",
+ "𝔸": "𝔸",
+ "⁡": "",
+ "Å": "Å",
+ "𝒜": "𝒜",
+ "≔": "≔",
+ "Ã": "Ã",
+ "Ä": "Ä",
+ "∖": "∖",
+ "⫧": "⫧",
+ "⌆": "⌆",
+ "Б": "Б",
+ "∵": "∵",
+ "ℬ": "ℬ",
+ "Β": "Β",
+ "𝔅": "𝔅",
+ "𝔹": "𝔹",
+ "˘": "˘",
+ "ℬ": "ℬ",
+ "≎": "≎",
+ "Ч": "Ч",
+ "©": "©",
+ "Ć": "Ć",
+ "⋒": "⋒",
+ "ⅅ": "ⅅ",
+ "ℭ": "ℭ",
+ "Č": "Č",
+ "Ç": "Ç",
+ "Ĉ": "Ĉ",
+ "∰": "∰",
+ "Ċ": "Ċ",
+ "¸": "¸",
+ "·": "·",
+ "ℭ": "ℭ",
+ "Χ": "Χ",
+ "⊙": "⊙",
+ "⊖": "⊖",
+ "⊕": "⊕",
+ "⊗": "⊗",
+ "∲": "∲",
+ "”": "”",
+ "’": "’",
+ "∷": "∷",
+ "⩴": "⩴",
+ "≡": "≡",
+ "∯": "∯",
+ "∮": "∮",
+ "ℂ": "ℂ",
+ "∐": "∐",
+ "∳": "∳",
+ "⨯": "⨯",
+ "𝒞": "𝒞",
+ "⋓": "⋓",
+ "≍": "≍",
+ "ⅅ": "ⅅ",
+ "⤑": "⤑",
+ "Ђ": "Ђ",
+ "Ѕ": "Ѕ",
+ "Џ": "Џ",
+ "‡": "‡",
+ "↡": "↡",
+ "⫤": "⫤",
+ "Ď": "Ď",
+ "Д": "Д",
+ "∇": "∇",
+ "Δ": "Δ",
+ "𝔇": "𝔇",
+ "´": "´",
+ "˙": "˙",
+ "˝": "˝",
+ "`": "`",
+ "˜": "˜",
+ "⋄": "⋄",
+ "ⅆ": "ⅆ",
+ "𝔻": "𝔻",
+ "¨": "¨",
+ "⃜": "⃜",
+ "≐": "≐",
+ "∯": "∯",
+ "¨": "¨",
+ "⇓": "⇓",
+ "⇐": "⇐",
+ "⇔": "⇔",
+ "⫤": "⫤",
+ "⟸": "⟸",
+ "⟺": "⟺",
+ "⟹": "⟹",
+ "⇒": "⇒",
+ "⊨": "⊨",
+ "⇑": "⇑",
+ "⇕": "⇕",
+ "∥": "∥",
+ "↓": "↓",
+ "⤓": "⤓",
+ "⇵": "⇵",
+ "̑": "̑",
+ "⥐": "⥐",
+ "⥞": "⥞",
+ "↽": "↽",
+ "⥖": "⥖",
+ "⥟": "⥟",
+ "⇁": "⇁",
+ "⥗": "⥗",
+ "⊤": "⊤",
+ "↧": "↧",
+ "⇓": "⇓",
+ "𝒟": "𝒟",
+ "Đ": "Đ",
+ "Ŋ": "Ŋ",
+ "Ð": "Ð",
+ "É": "É",
+ "Ě": "Ě",
+ "Ê": "Ê",
+ "Э": "Э",
+ "Ė": "Ė",
+ "𝔈": "𝔈",
+ "È": "È",
+ "∈": "∈",
+ "Ē": "Ē",
+ "◻": "◻",
+ "▫": "▫",
+ "Ę": "Ę",
+ "𝔼": "𝔼",
+ "Ε": "Ε",
+ "⩵": "⩵",
+ "≂": "≂",
+ "⇌": "⇌",
+ "ℰ": "ℰ",
+ "⩳": "⩳",
+ "Η": "Η",
+ "Ë": "Ë",
+ "∃": "∃",
+ "ⅇ": "ⅇ",
+ "Ф": "Ф",
+ "𝔉": "𝔉",
+ "◼": "◼",
+ "▪": "▪",
+ "𝔽": "𝔽",
+ "∀": "∀",
+ "ℱ": "ℱ",
+ "ℱ": "ℱ",
+ "Ѓ": "Ѓ",
+ ">": ">",
+ "Γ": "Γ",
+ "Ϝ": "Ϝ",
+ "Ğ": "Ğ",
+ "Ģ": "Ģ",
+ "Ĝ": "Ĝ",
+ "Г": "Г",
+ "Ġ": "Ġ",
+ "𝔊": "𝔊",
+ "⋙": "⋙",
+ "𝔾": "𝔾",
+ "≥": "≥",
+ "⋛": "⋛",
+ "≧": "≧",
+ "⪢": "⪢",
+ "≷": "≷",
+ "⩾": "⩾",
+ "≳": "≳",
+ "𝒢": "𝒢",
+ "≫": "≫",
+ "Ъ": "Ъ",
+ "ˇ": "ˇ",
+ "^": "^",
+ "Ĥ": "Ĥ",
+ "ℌ": "ℌ",
+ "ℋ": "ℋ",
+ "ℍ": "ℍ",
+ "─": "─",
+ "ℋ": "ℋ",
+ "Ħ": "Ħ",
+ "≎": "≎",
+ "≏": "≏",
+ "Е": "Е",
+ "IJ": "IJ",
+ "Ё": "Ё",
+ "Í": "Í",
+ "Î": "Î",
+ "И": "И",
+ "İ": "İ",
+ "ℑ": "ℑ",
+ "Ì": "Ì",
+ "ℑ": "ℑ",
+ "Ī": "Ī",
+ "ⅈ": "ⅈ",
+ "⇒": "⇒",
+ "∬": "∬",
+ "∫": "∫",
+ "⋂": "⋂",
+ "⁣": "",
+ "⁢": "",
+ "Į": "Į",
+ "𝕀": "𝕀",
+ "Ι": "Ι",
+ "ℐ": "ℐ",
+ "Ĩ": "Ĩ",
+ "І": "І",
+ "Ï": "Ï",
+ "Ĵ": "Ĵ",
+ "Й": "Й",
+ "𝔍": "𝔍",
+ "𝕁": "𝕁",
+ "𝒥": "𝒥",
+ "Ј": "Ј",
+ "Є": "Є",
+ "Х": "Х",
+ "Ќ": "Ќ",
+ "Κ": "Κ",
+ "Ķ": "Ķ",
+ "К": "К",
+ "𝔎": "𝔎",
+ "𝕂": "𝕂",
+ "𝒦": "𝒦",
+ "Љ": "Љ",
+ "<": "<",
+ "Ĺ": "Ĺ",
+ "Λ": "Λ",
+ "⟪": "⟪",
+ "ℒ": "ℒ",
+ "↞": "↞",
+ "Ľ": "Ľ",
+ "Ļ": "Ļ",
+ "Л": "Л",
+ "⟨": "⟨",
+ "←": "←",
+ "⇤": "⇤",
+ "⇆": "⇆",
+ "⌈": "⌈",
+ "⟦": "⟦",
+ "⥡": "⥡",
+ "⇃": "⇃",
+ "⥙": "⥙",
+ "⌊": "⌊",
+ "↔": "↔",
+ "⥎": "⥎",
+ "⊣": "⊣",
+ "↤": "↤",
+ "⥚": "⥚",
+ "⊲": "⊲",
+ "⧏": "⧏",
+ "⊴": "⊴",
+ "⥑": "⥑",
+ "⥠": "⥠",
+ "↿": "↿",
+ "⥘": "⥘",
+ "↼": "↼",
+ "⥒": "⥒",
+ "⇐": "⇐",
+ "⇔": "⇔",
+ "⋚": "⋚",
+ "≦": "≦",
+ "≶": "≶",
+ "⪡": "⪡",
+ "⩽": "⩽",
+ "≲": "≲",
+ "𝔏": "𝔏",
+ "⋘": "⋘",
+ "⇚": "⇚",
+ "Ŀ": "Ŀ",
+ "⟵": "⟵",
+ "⟷": "⟷",
+ "⟶": "⟶",
+ "⟸": "⟸",
+ "⟺": "⟺",
+ "⟹": "⟹",
+ "𝕃": "𝕃",
+ "↙": "↙",
+ "↘": "↘",
+ "ℒ": "ℒ",
+ "↰": "↰",
+ "Ł": "Ł",
+ "≪": "≪",
+ "⤅": "⤅",
+ "М": "М",
+ " ": " ",
+ "ℳ": "ℳ",
+ "𝔐": "𝔐",
+ "∓": "∓",
+ "𝕄": "𝕄",
+ "ℳ": "ℳ",
+ "Μ": "Μ",
+ "Њ": "Њ",
+ "Ń": "Ń",
+ "Ň": "Ň",
+ "Ņ": "Ņ",
+ "Н": "Н",
+ "​": "",
+ "​": "",
+ "​": "",
+ "​": "",
+ "≫": "≫",
+ "≪": "≪",
+ "
": "\n",
+ "𝔑": "𝔑",
+ "⁠": "",
+ " ": " ",
+ "ℕ": "ℕ",
+ "⫬": "⫬",
+ "≢": "≢",
+ "≭": "≭",
+ "∦": "∦",
+ "∉": "∉",
+ "≠": "≠",
+ "≂̸": "≂̸",
+ "∄": "∄",
+ "≯": "≯",
+ "≱": "≱",
+ "≧̸": "≧̸",
+ "≫̸": "≫̸",
+ "≹": "≹",
+ "⩾̸": "⩾̸",
+ "≵": "≵",
+ "≎̸": "≎̸",
+ "≏̸": "≏̸",
+ "⋪": "⋪",
+ "⧏̸": "⧏̸",
+ "⋬": "⋬",
+ "≮": "≮",
+ "≰": "≰",
+ "≸": "≸",
+ "≪̸": "≪̸",
+ "⩽̸": "⩽̸",
+ "≴": "≴",
+ "⪢̸": "⪢̸",
+ "⪡̸": "⪡̸",
+ "⊀": "⊀",
+ "⪯̸": "⪯̸",
+ "⋠": "⋠",
+ "∌": "∌",
+ "⋫": "⋫",
+ "⧐̸": "⧐̸",
+ "⋭": "⋭",
+ "⊏̸": "⊏̸",
+ "⋢": "⋢",
+ "⊐̸": "⊐̸",
+ "⋣": "⋣",
+ "⊂⃒": "⊂⃒",
+ "⊈": "⊈",
+ "⊁": "⊁",
+ "⪰̸": "⪰̸",
+ "⋡": "⋡",
+ "≿̸": "≿̸",
+ "⊃⃒": "⊃⃒",
+ "⊉": "⊉",
+ "≁": "≁",
+ "≄": "≄",
+ "≇": "≇",
+ "≉": "≉",
+ "∤": "∤",
+ "𝒩": "𝒩",
+ "Ñ": "Ñ",
+ "Ν": "Ν",
+ "Œ": "Œ",
+ "Ó": "Ó",
+ "Ô": "Ô",
+ "О": "О",
+ "Ő": "Ő",
+ "𝔒": "𝔒",
+ "Ò": "Ò",
+ "Ō": "Ō",
+ "Ω": "Ω",
+ "Ο": "Ο",
+ "𝕆": "𝕆",
+ "“": "“",
+ "‘": "‘",
+ "⩔": "⩔",
+ "𝒪": "𝒪",
+ "Ø": "Ø",
+ "Õ": "Õ",
+ "⨷": "⨷",
+ "Ö": "Ö",
+ "‾": "‾",
+ "⏞": "⏞",
+ "⎴": "⎴",
+ "⏜": "⏜",
+ "∂": "∂",
+ "П": "П",
+ "𝔓": "𝔓",
+ "Φ": "Φ",
+ "Π": "Π",
+ "±": "±",
+ "ℌ": "ℌ",
+ "ℙ": "ℙ",
+ "⪻": "⪻",
+ "≺": "≺",
+ "⪯": "⪯",
+ "≼": "≼",
+ "≾": "≾",
+ "″": "″",
+ "∏": "∏",
+ "∷": "∷",
+ "∝": "∝",
+ "𝒫": "𝒫",
+ "Ψ": "Ψ",
+ """: "\"",
+ "𝔔": "𝔔",
+ "ℚ": "ℚ",
+ "𝒬": "𝒬",
+ "⤐": "⤐",
+ "®": "®",
+ "Ŕ": "Ŕ",
+ "⟫": "⟫",
+ "↠": "↠",
+ "⤖": "⤖",
+ "Ř": "Ř",
+ "Ŗ": "Ŗ",
+ "Р": "Р",
+ "ℜ": "ℜ",
+ "∋": "∋",
+ "⇋": "⇋",
+ "⥯": "⥯",
+ "ℜ": "ℜ",
+ "Ρ": "Ρ",
+ "⟩": "⟩",
+ "→": "→",
+ "⇥": "⇥",
+ "⇄": "⇄",
+ "⌉": "⌉",
+ "⟧": "⟧",
+ "⥝": "⥝",
+ "⇂": "⇂",
+ "⥕": "⥕",
+ "⌋": "⌋",
+ "⊢": "⊢",
+ "↦": "↦",
+ "⥛": "⥛",
+ "⊳": "⊳",
+ "⧐": "⧐",
+ "⊵": "⊵",
+ "⥏": "⥏",
+ "⥜": "⥜",
+ "↾": "↾",
+ "⥔": "⥔",
+ "⇀": "⇀",
+ "⥓": "⥓",
+ "⇒": "⇒",
+ "ℝ": "ℝ",
+ "⥰": "⥰",
+ "⇛": "⇛",
+ "ℛ": "ℛ",
+ "↱": "↱",
+ "⧴": "⧴",
+ "Щ": "Щ",
+ "Ш": "Ш",
+ "Ь": "Ь",
+ "Ś": "Ś",
+ "⪼": "⪼",
+ "Š": "Š",
+ "Ş": "Ş",
+ "Ŝ": "Ŝ",
+ "С": "С",
+ "𝔖": "𝔖",
+ "↓": "↓",
+ "←": "←",
+ "→": "→",
+ "↑": "↑",
+ "Σ": "Σ",
+ "∘": "∘",
+ "𝕊": "𝕊",
+ "√": "√",
+ "□": "□",
+ "⊓": "⊓",
+ "⊏": "⊏",
+ "⊑": "⊑",
+ "⊐": "⊐",
+ "⊒": "⊒",
+ "⊔": "⊔",
+ "𝒮": "𝒮",
+ "⋆": "⋆",
+ "⋐": "⋐",
+ "⋐": "⋐",
+ "⊆": "⊆",
+ "≻": "≻",
+ "⪰": "⪰",
+ "≽": "≽",
+ "≿": "≿",
+ "∋": "∋",
+ "∑": "∑",
+ "⋑": "⋑",
+ "⊃": "⊃",
+ "⊇": "⊇",
+ "⋑": "⋑",
+ "Þ": "Þ",
+ "™": "™",
+ "Ћ": "Ћ",
+ "Ц": "Ц",
+ "	": "\t",
+ "Τ": "Τ",
+ "Ť": "Ť",
+ "Ţ": "Ţ",
+ "Т": "Т",
+ "𝔗": "𝔗",
+ "∴": "∴",
+ "Θ": "Θ",
+ "  ": " ",
+ " ": " ",
+ "∼": "∼",
+ "≃": "≃",
+ "≅": "≅",
+ "≈": "≈",
+ "𝕋": "𝕋",
+ "⃛": "⃛",
+ "𝒯": "𝒯",
+ "Ŧ": "Ŧ",
+ "Ú": "Ú",
+ "↟": "↟",
+ "⥉": "⥉",
+ "Ў": "Ў",
+ "Ŭ": "Ŭ",
+ "Û": "Û",
+ "У": "У",
+ "Ű": "Ű",
+ "𝔘": "𝔘",
+ "Ù": "Ù",
+ "Ū": "Ū",
+ "_": "_",
+ "⏟": "⏟",
+ "⎵": "⎵",
+ "⏝": "⏝",
+ "⋃": "⋃",
+ "⊎": "⊎",
+ "Ų": "Ų",
+ "𝕌": "𝕌",
+ "↑": "↑",
+ "⤒": "⤒",
+ "⇅": "⇅",
+ "↕": "↕",
+ "⥮": "⥮",
+ "⊥": "⊥",
+ "↥": "↥",
+ "⇑": "⇑",
+ "⇕": "⇕",
+ "↖": "↖",
+ "↗": "↗",
+ "ϒ": "ϒ",
+ "Υ": "Υ",
+ "Ů": "Ů",
+ "𝒰": "𝒰",
+ "Ũ": "Ũ",
+ "Ü": "Ü",
+ "⊫": "⊫",
+ "⫫": "⫫",
+ "В": "В",
+ "⊩": "⊩",
+ "⫦": "⫦",
+ "⋁": "⋁",
+ "‖": "‖",
+ "‖": "‖",
+ "∣": "∣",
+ "|": "|",
+ "❘": "❘",
+ "≀": "≀",
+ " ": " ",
+ "𝔙": "𝔙",
+ "𝕍": "𝕍",
+ "𝒱": "𝒱",
+ "⊪": "⊪",
+ "Ŵ": "Ŵ",
+ "⋀": "⋀",
+ "𝔚": "𝔚",
+ "𝕎": "𝕎",
+ "𝒲": "𝒲",
+ "𝔛": "𝔛",
+ "Ξ": "Ξ",
+ "𝕏": "𝕏",
+ "𝒳": "𝒳",
+ "Я": "Я",
+ "Ї": "Ї",
+ "Ю": "Ю",
+ "Ý": "Ý",
+ "Ŷ": "Ŷ",
+ "Ы": "Ы",
+ "𝔜": "𝔜",
+ "𝕐": "𝕐",
+ "𝒴": "𝒴",
+ "Ÿ": "Ÿ",
+ "Ж": "Ж",
+ "Ź": "Ź",
+ "Ž": "Ž",
+ "З": "З",
+ "Ż": "Ż",
+ "​": "",
+ "Ζ": "Ζ",
+ "ℨ": "ℨ",
+ "ℤ": "ℤ",
+ "𝒵": "𝒵",
+ "á": "á",
+ "ă": "ă",
+ "∾": "∾",
+ "∾̳": "∾̳",
+ "∿": "∿",
+ "â": "â",
+ "´": "´",
+ "а": "а",
+ "æ": "æ",
+ "⁡": "",
+ "𝔞": "𝔞",
+ "à": "à",
+ "ℵ": "ℵ",
+ "ℵ": "ℵ",
+ "α": "α",
+ "ā": "ā",
+ "⨿": "⨿",
+ "&": "&",
+ "∧": "∧",
+ "⩕": "⩕",
+ "⩜": "⩜",
+ "⩘": "⩘",
+ "⩚": "⩚",
+ "∠": "∠",
+ "⦤": "⦤",
+ "∠": "∠",
+ "∡": "∡",
+ "⦨": "⦨",
+ "⦩": "⦩",
+ "⦪": "⦪",
+ "⦫": "⦫",
+ "⦬": "⦬",
+ "⦭": "⦭",
+ "⦮": "⦮",
+ "⦯": "⦯",
+ "∟": "∟",
+ "⊾": "⊾",
+ "⦝": "⦝",
+ "∢": "∢",
+ "Å": "Å",
+ "⍼": "⍼",
+ "ą": "ą",
+ "𝕒": "𝕒",
+ "≈": "≈",
+ "⩰": "⩰",
+ "⩯": "⩯",
+ "≊": "≊",
+ "≋": "≋",
+ "'": "'",
+ "≈": "≈",
+ "≊": "≊",
+ "å": "å",
+ "𝒶": "𝒶",
+ "*": "*",
+ "≈": "≈",
+ "≍": "≍",
+ "ã": "ã",
+ "ä": "ä",
+ "∳": "∳",
+ "⨑": "⨑",
+ "⫭": "⫭",
+ "≌": "≌",
+ "϶": "϶",
+ "‵": "‵",
+ "∽": "∽",
+ "⋍": "⋍",
+ "⊽": "⊽",
+ "⌅": "⌅",
+ "⌅": "⌅",
+ "⎵": "⎵",
+ "⎶": "⎶",
+ "≌": "≌",
+ "б": "б",
+ "„": "„",
+ "∵": "∵",
+ "∵": "∵",
+ "⦰": "⦰",
+ "϶": "϶",
+ "ℬ": "ℬ",
+ "β": "β",
+ "ℶ": "ℶ",
+ "≬": "≬",
+ "𝔟": "𝔟",
+ "⋂": "⋂",
+ "◯": "◯",
+ "⋃": "⋃",
+ "⨀": "⨀",
+ "⨁": "⨁",
+ "⨂": "⨂",
+ "⨆": "⨆",
+ "★": "★",
+ "▽": "▽",
+ "△": "△",
+ "⨄": "⨄",
+ "⋁": "⋁",
+ "⋀": "⋀",
+ "⤍": "⤍",
+ "⧫": "⧫",
+ "▪": "▪",
+ "▴": "▴",
+ "▾": "▾",
+ "◂": "◂",
+ "▸": "▸",
+ "␣": "␣",
+ "▒": "▒",
+ "░": "░",
+ "▓": "▓",
+ "█": "█",
+ "=⃥": "=⃥",
+ "≡⃥": "≡⃥",
+ "⌐": "⌐",
+ "𝕓": "𝕓",
+ "⊥": "⊥",
+ "⊥": "⊥",
+ "⋈": "⋈",
+ "╗": "╗",
+ "╔": "╔",
+ "╖": "╖",
+ "╓": "╓",
+ "═": "═",
+ "╦": "╦",
+ "╩": "╩",
+ "╤": "╤",
+ "╧": "╧",
+ "╝": "╝",
+ "╚": "╚",
+ "╜": "╜",
+ "╙": "╙",
+ "║": "║",
+ "╬": "╬",
+ "╣": "╣",
+ "╠": "╠",
+ "╫": "╫",
+ "╢": "╢",
+ "╟": "╟",
+ "⧉": "⧉",
+ "╕": "╕",
+ "╒": "╒",
+ "┐": "┐",
+ "┌": "┌",
+ "─": "─",
+ "╥": "╥",
+ "╨": "╨",
+ "┬": "┬",
+ "┴": "┴",
+ "⊟": "⊟",
+ "⊞": "⊞",
+ "⊠": "⊠",
+ "╛": "╛",
+ "╘": "╘",
+ "┘": "┘",
+ "└": "└",
+ "│": "│",
+ "╪": "╪",
+ "╡": "╡",
+ "╞": "╞",
+ "┼": "┼",
+ "┤": "┤",
+ "├": "├",
+ "‵": "‵",
+ "˘": "˘",
+ "¦": "¦",
+ "𝒷": "𝒷",
+ "⁏": "⁏",
+ "∽": "∽",
+ "⋍": "⋍",
+ "\": r"\",
+ "⧅": "⧅",
+ "⟈": "⟈",
+ "•": "•",
+ "•": "•",
+ "≎": "≎",
+ "⪮": "⪮",
+ "≏": "≏",
+ "≏": "≏",
+ "ć": "ć",
+ "∩": "∩",
+ "⩄": "⩄",
+ "⩉": "⩉",
+ "⩋": "⩋",
+ "⩇": "⩇",
+ "⩀": "⩀",
+ "∩︀": "∩︀",
+ "⁁": "⁁",
+ "ˇ": "ˇ",
+ "⩍": "⩍",
+ "č": "č",
+ "ç": "ç",
+ "ĉ": "ĉ",
+ "⩌": "⩌",
+ "⩐": "⩐",
+ "ċ": "ċ",
+ "¸": "¸",
+ "⦲": "⦲",
+ "¢": "¢",
+ "·": "·",
+ "𝔠": "𝔠",
+ "ч": "ч",
+ "✓": "✓",
+ "✓": "✓",
+ "χ": "χ",
+ "○": "○",
+ "⧃": "⧃",
+ "ˆ": "ˆ",
+ "≗": "≗",
+ "↺": "↺",
+ "↻": "↻",
+ "®": "®",
+ "Ⓢ": "Ⓢ",
+ "⊛": "⊛",
+ "⊚": "⊚",
+ "⊝": "⊝",
+ "≗": "≗",
+ "⨐": "⨐",
+ "⫯": "⫯",
+ "⧂": "⧂",
+ "♣": "♣",
+ "♣": "♣",
+ ":": ":",
+ "≔": "≔",
+ "≔": "≔",
+ ",": ",",
+ "@": "@",
+ "∁": "∁",
+ "∘": "∘",
+ "∁": "∁",
+ "ℂ": "ℂ",
+ "≅": "≅",
+ "⩭": "⩭",
+ "∮": "∮",
+ "𝕔": "𝕔",
+ "∐": "∐",
+ "©": "©",
+ "℗": "℗",
+ "↵": "↵",
+ "✗": "✗",
+ "𝒸": "𝒸",
+ "⫏": "⫏",
+ "⫑": "⫑",
+ "⫐": "⫐",
+ "⫒": "⫒",
+ "⋯": "⋯",
+ "⤸": "⤸",
+ "⤵": "⤵",
+ "⋞": "⋞",
+ "⋟": "⋟",
+ "↶": "↶",
+ "⤽": "⤽",
+ "∪": "∪",
+ "⩈": "⩈",
+ "⩆": "⩆",
+ "⩊": "⩊",
+ "⊍": "⊍",
+ "⩅": "⩅",
+ "∪︀": "∪︀",
+ "↷": "↷",
+ "⤼": "⤼",
+ "⋞": "⋞",
+ "⋟": "⋟",
+ "⋎": "⋎",
+ "⋏": "⋏",
+ "¤": "¤",
+ "↶": "↶",
+ "↷": "↷",
+ "⋎": "⋎",
+ "⋏": "⋏",
+ "∲": "∲",
+ "∱": "∱",
+ "⌭": "⌭",
+ "⇓": "⇓",
+ "⥥": "⥥",
+ "†": "†",
+ "ℸ": "ℸ",
+ "↓": "↓",
+ "‐": "‐",
+ "⊣": "⊣",
+ "⤏": "⤏",
+ "˝": "˝",
+ "ď": "ď",
+ "д": "д",
+ "ⅆ": "ⅆ",
+ "‡": "‡",
+ "⇊": "⇊",
+ "⩷": "⩷",
+ "°": "°",
+ "δ": "δ",
+ "⦱": "⦱",
+ "⥿": "⥿",
+ "𝔡": "𝔡",
+ "⇃": "⇃",
+ "⇂": "⇂",
+ "⋄": "⋄",
+ "⋄": "⋄",
+ "♦": "♦",
+ "♦": "♦",
+ "¨": "¨",
+ "ϝ": "ϝ",
+ "⋲": "⋲",
+ "÷": "÷",
+ "÷": "÷",
+ "⋇": "⋇",
+ "⋇": "⋇",
+ "ђ": "ђ",
+ "⌞": "⌞",
+ "⌍": "⌍",
+ "$": r"$",
+ "𝕕": "𝕕",
+ "˙": "˙",
+ "≐": "≐",
+ "≑": "≑",
+ "∸": "∸",
+ "∔": "∔",
+ "⊡": "⊡",
+ "⌆": "⌆",
+ "↓": "↓",
+ "⇊": "⇊",
+ "⇃": "⇃",
+ "⇂": "⇂",
+ "⤐": "⤐",
+ "⌟": "⌟",
+ "⌌": "⌌",
+ "𝒹": "𝒹",
+ "ѕ": "ѕ",
+ "⧶": "⧶",
+ "đ": "đ",
+ "⋱": "⋱",
+ "▿": "▿",
+ "▾": "▾",
+ "⇵": "⇵",
+ "⥯": "⥯",
+ "⦦": "⦦",
+ "џ": "џ",
+ "⟿": "⟿",
+ "⩷": "⩷",
+ "≑": "≑",
+ "é": "é",
+ "⩮": "⩮",
+ "ě": "ě",
+ "≖": "≖",
+ "ê": "ê",
+ "≕": "≕",
+ "э": "э",
+ "ė": "ė",
+ "ⅇ": "ⅇ",
+ "≒": "≒",
+ "𝔢": "𝔢",
+ "⪚": "⪚",
+ "è": "è",
+ "⪖": "⪖",
+ "⪘": "⪘",
+ "⪙": "⪙",
+ "⏧": "⏧",
+ "ℓ": "ℓ",
+ "⪕": "⪕",
+ "⪗": "⪗",
+ "ē": "ē",
+ "∅": "∅",
+ "∅": "∅",
+ "∅": "∅",
+ " ": " ",
+ " ": " ",
+ " ": " ",
+ "ŋ": "ŋ",
+ " ": " ",
+ "ę": "ę",
+ "𝕖": "𝕖",
+ "⋕": "⋕",
+ "⧣": "⧣",
+ "⩱": "⩱",
+ "ε": "ε",
+ "ε": "ε",
+ "ϵ": "ϵ",
+ "≖": "≖",
+ "≕": "≕",
+ "≂": "≂",
+ "⪖": "⪖",
+ "⪕": "⪕",
+ "=": "=",
+ "≟": "≟",
+ "≡": "≡",
+ "⩸": "⩸",
+ "⧥": "⧥",
+ "≓": "≓",
+ "⥱": "⥱",
+ "ℯ": "ℯ",
+ "≐": "≐",
+ "≂": "≂",
+ "η": "η",
+ "ð": "ð",
+ "ë": "ë",
+ "€": "€",
+ "!": "!",
+ "∃": "∃",
+ "ℰ": "ℰ",
+ "ⅇ": "ⅇ",
+ "≒": "≒",
+ "ф": "ф",
+ "♀": "♀",
+ "ffi": "ffi",
+ "ff": "ff",
+ "ffl": "ffl",
+ "𝔣": "𝔣",
+ "fi": "fi",
+ "fj": "fj",
+ "♭": "♭",
+ "fl": "fl",
+ "▱": "▱",
+ "ƒ": "ƒ",
+ "𝕗": "𝕗",
+ "∀": "∀",
+ "⋔": "⋔",
+ "⫙": "⫙",
+ "⨍": "⨍",
+ "½": "½",
+ "⅓": "⅓",
+ "¼": "¼",
+ "⅕": "⅕",
+ "⅙": "⅙",
+ "⅛": "⅛",
+ "⅔": "⅔",
+ "⅖": "⅖",
+ "¾": "¾",
+ "⅗": "⅗",
+ "⅜": "⅜",
+ "⅘": "⅘",
+ "⅚": "⅚",
+ "⅝": "⅝",
+ "⅞": "⅞",
+ "⁄": "⁄",
+ "⌢": "⌢",
+ "𝒻": "𝒻",
+ "≧": "≧",
+ "⪌": "⪌",
+ "ǵ": "ǵ",
+ "γ": "γ",
+ "ϝ": "ϝ",
+ "⪆": "⪆",
+ "ğ": "ğ",
+ "ĝ": "ĝ",
+ "г": "г",
+ "ġ": "ġ",
+ "≥": "≥",
+ "⋛": "⋛",
+ "≥": "≥",
+ "≧": "≧",
+ "⩾": "⩾",
+ "⩾": "⩾",
+ "⪩": "⪩",
+ "⪀": "⪀",
+ "⪂": "⪂",
+ "⪄": "⪄",
+ "⋛︀": "⋛︀",
+ "⪔": "⪔",
+ "𝔤": "𝔤",
+ "≫": "≫",
+ "⋙": "⋙",
+ "ℷ": "ℷ",
+ "ѓ": "ѓ",
+ "≷": "≷",
+ "⪒": "⪒",
+ "⪥": "⪥",
+ "⪤": "⪤",
+ "≩": "≩",
+ "⪊": "⪊",
+ "⪊": "⪊",
+ "⪈": "⪈",
+ "⪈": "⪈",
+ "≩": "≩",
+ "⋧": "⋧",
+ "𝕘": "𝕘",
+ "`": "`",
+ "ℊ": "ℊ",
+ "≳": "≳",
+ "⪎": "⪎",
+ "⪐": "⪐",
+ ">": ">",
+ "⪧": "⪧",
+ "⩺": "⩺",
+ "⋗": "⋗",
+ "⦕": "⦕",
+ "⩼": "⩼",
+ "⪆": "⪆",
+ "⥸": "⥸",
+ "⋗": "⋗",
+ "⋛": "⋛",
+ "⪌": "⪌",
+ "≷": "≷",
+ "≳": "≳",
+ "≩︀": "≩︀",
+ "≩︀": "≩︀",
+ "⇔": "⇔",
+ " ": " ",
+ "½": "½",
+ "ℋ": "ℋ",
+ "ъ": "ъ",
+ "↔": "↔",
+ "⥈": "⥈",
+ "↭": "↭",
+ "ℏ": "ℏ",
+ "ĥ": "ĥ",
+ "♥": "♥",
+ "♥": "♥",
+ "…": "…",
+ "⊹": "⊹",
+ "𝔥": "𝔥",
+ "⤥": "⤥",
+ "⤦": "⤦",
+ "⇿": "⇿",
+ "∻": "∻",
+ "↩": "↩",
+ "↪": "↪",
+ "𝕙": "𝕙",
+ "―": "―",
+ "𝒽": "𝒽",
+ "ℏ": "ℏ",
+ "ħ": "ħ",
+ "⁃": "⁃",
+ "‐": "‐",
+ "í": "í",
+ "⁣": "",
+ "î": "î",
+ "и": "и",
+ "е": "е",
+ "¡": "¡",
+ "⇔": "⇔",
+ "𝔦": "𝔦",
+ "ì": "ì",
+ "ⅈ": "ⅈ",
+ "⨌": "⨌",
+ "∭": "∭",
+ "⧜": "⧜",
+ "℩": "℩",
+ "ij": "ij",
+ "ī": "ī",
+ "ℑ": "ℑ",
+ "ℐ": "ℐ",
+ "ℑ": "ℑ",
+ "ı": "ı",
+ "⊷": "⊷",
+ "Ƶ": "Ƶ",
+ "∈": "∈",
+ "℅": "℅",
+ "∞": "∞",
+ "⧝": "⧝",
+ "ı": "ı",
+ "∫": "∫",
+ "⊺": "⊺",
+ "ℤ": "ℤ",
+ "⊺": "⊺",
+ "⨗": "⨗",
+ "⨼": "⨼",
+ "ё": "ё",
+ "į": "į",
+ "𝕚": "𝕚",
+ "ι": "ι",
+ "⨼": "⨼",
+ "¿": "¿",
+ "𝒾": "𝒾",
+ "∈": "∈",
+ "⋹": "⋹",
+ "⋵": "⋵",
+ "⋴": "⋴",
+ "⋳": "⋳",
+ "∈": "∈",
+ "⁢": "",
+ "ĩ": "ĩ",
+ "і": "і",
+ "ï": "ï",
+ "ĵ": "ĵ",
+ "й": "й",
+ "𝔧": "𝔧",
+ "ȷ": "ȷ",
+ "𝕛": "𝕛",
+ "𝒿": "𝒿",
+ "ј": "ј",
+ "є": "є",
+ "κ": "κ",
+ "ϰ": "ϰ",
+ "ķ": "ķ",
+ "к": "к",
+ "𝔨": "𝔨",
+ "ĸ": "ĸ",
+ "х": "х",
+ "ќ": "ќ",
+ "𝕜": "𝕜",
+ "𝓀": "𝓀",
+ "⇚": "⇚",
+ "⇐": "⇐",
+ "⤛": "⤛",
+ "⤎": "⤎",
+ "≦": "≦",
+ "⪋": "⪋",
+ "⥢": "⥢",
+ "ĺ": "ĺ",
+ "⦴": "⦴",
+ "ℒ": "ℒ",
+ "λ": "λ",
+ "⟨": "⟨",
+ "⦑": "⦑",
+ "⟨": "⟨",
+ "⪅": "⪅",
+ "«": "«",
+ "←": "←",
+ "⇤": "⇤",
+ "⤟": "⤟",
+ "⤝": "⤝",
+ "↩": "↩",
+ "↫": "↫",
+ "⤹": "⤹",
+ "⥳": "⥳",
+ "↢": "↢",
+ "⪫": "⪫",
+ "⤙": "⤙",
+ "⪭": "⪭",
+ "⪭︀": "⪭︀",
+ "⤌": "⤌",
+ "❲": "❲",
+ "{": "{",
+ "[": "[",
+ "⦋": "⦋",
+ "⦏": "⦏",
+ "⦍": "⦍",
+ "ľ": "ľ",
+ "ļ": "ļ",
+ "⌈": "⌈",
+ "{": "{",
+ "л": "л",
+ "⤶": "⤶",
+ "“": "“",
+ "„": "„",
+ "⥧": "⥧",
+ "⥋": "⥋",
+ "↲": "↲",
+ "≤": "≤",
+ "←": "←",
+ "↢": "↢",
+ "↽": "↽",
+ "↼": "↼",
+ "⇇": "⇇",
+ "↔": "↔",
+ "⇆": "⇆",
+ "⇋": "⇋",
+ "↭": "↭",
+ "⋋": "⋋",
+ "⋚": "⋚",
+ "≤": "≤",
+ "≦": "≦",
+ "⩽": "⩽",
+ "⩽": "⩽",
+ "⪨": "⪨",
+ "⩿": "⩿",
+ "⪁": "⪁",
+ "⪃": "⪃",
+ "⋚︀": "⋚︀",
+ "⪓": "⪓",
+ "⪅": "⪅",
+ "⋖": "⋖",
+ "⋚": "⋚",
+ "⪋": "⪋",
+ "≶": "≶",
+ "≲": "≲",
+ "⥼": "⥼",
+ "⌊": "⌊",
+ "𝔩": "𝔩",
+ "≶": "≶",
+ "⪑": "⪑",
+ "↽": "↽",
+ "↼": "↼",
+ "⥪": "⥪",
+ "▄": "▄",
+ "љ": "љ",
+ "≪": "≪",
+ "⇇": "⇇",
+ "⌞": "⌞",
+ "⥫": "⥫",
+ "◺": "◺",
+ "ŀ": "ŀ",
+ "⎰": "⎰",
+ "⎰": "⎰",
+ "≨": "≨",
+ "⪉": "⪉",
+ "⪉": "⪉",
+ "⪇": "⪇",
+ "⪇": "⪇",
+ "≨": "≨",
+ "⋦": "⋦",
+ "⟬": "⟬",
+ "⇽": "⇽",
+ "⟦": "⟦",
+ "⟵": "⟵",
+ "⟷": "⟷",
+ "⟼": "⟼",
+ "⟶": "⟶",
+ "↫": "↫",
+ "↬": "↬",
+ "⦅": "⦅",
+ "𝕝": "𝕝",
+ "⨭": "⨭",
+ "⨴": "⨴",
+ "∗": "∗",
+ "_": "_",
+ "◊": "◊",
+ "◊": "◊",
+ "⧫": "⧫",
+ "(": "(",
+ "⦓": "⦓",
+ "⇆": "⇆",
+ "⌟": "⌟",
+ "⇋": "⇋",
+ "⥭": "⥭",
+ "‎": "",
+ "⊿": "⊿",
+ "‹": "‹",
+ "𝓁": "𝓁",
+ "↰": "↰",
+ "≲": "≲",
+ "⪍": "⪍",
+ "⪏": "⪏",
+ "[": "[",
+ "‘": "‘",
+ "‚": "‚",
+ "ł": "ł",
+ "<": "<",
+ "⪦": "⪦",
+ "⩹": "⩹",
+ "⋖": "⋖",
+ "⋋": "⋋",
+ "⋉": "⋉",
+ "⥶": "⥶",
+ "⩻": "⩻",
+ "⦖": "⦖",
+ "◃": "◃",
+ "⊴": "⊴",
+ "◂": "◂",
+ "⥊": "⥊",
+ "⥦": "⥦",
+ "≨︀": "≨︀",
+ "≨︀": "≨︀",
+ "∺": "∺",
+ "¯": "¯",
+ "♂": "♂",
+ "✠": "✠",
+ "✠": "✠",
+ "↦": "↦",
+ "↦": "↦",
+ "↧": "↧",
+ "↤": "↤",
+ "↥": "↥",
+ "▮": "▮",
+ "⨩": "⨩",
+ "м": "м",
+ "—": "—",
+ "∡": "∡",
+ "𝔪": "𝔪",
+ "℧": "℧",
+ "µ": "µ",
+ "∣": "∣",
+ "*": "*",
+ "⫰": "⫰",
+ "·": "·",
+ "−": "−",
+ "⊟": "⊟",
+ "∸": "∸",
+ "⨪": "⨪",
+ "⫛": "⫛",
+ "…": "…",
+ "∓": "∓",
+ "⊧": "⊧",
+ "𝕞": "𝕞",
+ "∓": "∓",
+ "𝓂": "𝓂",
+ "∾": "∾",
+ "μ": "μ",
+ "⊸": "⊸",
+ "⊸": "⊸",
+ "⋙̸": "⋙̸",
+ "≫⃒": "≫⃒",
+ "≫̸": "≫̸",
+ "⇍": "⇍",
+ "⇎": "⇎",
+ "⋘̸": "⋘̸",
+ "≪⃒": "≪⃒",
+ "≪̸": "≪̸",
+ "⇏": "⇏",
+ "⊯": "⊯",
+ "⊮": "⊮",
+ "∇": "∇",
+ "ń": "ń",
+ "∠⃒": "∠⃒",
+ "≉": "≉",
+ "⩰̸": "⩰̸",
+ "≋̸": "≋̸",
+ "ʼn": "ʼn",
+ "≉": "≉",
+ "♮": "♮",
+ "♮": "♮",
+ "ℕ": "ℕ",
+ " ": " ",
+ "≎̸": "≎̸",
+ "≏̸": "≏̸",
+ "⩃": "⩃",
+ "ň": "ň",
+ "ņ": "ņ",
+ "≇": "≇",
+ "⩭̸": "⩭̸",
+ "⩂": "⩂",
+ "н": "н",
+ "–": "–",
+ "≠": "≠",
+ "⇗": "⇗",
+ "⤤": "⤤",
+ "↗": "↗",
+ "↗": "↗",
+ "≐̸": "≐̸",
+ "≢": "≢",
+ "⤨": "⤨",
+ "≂̸": "≂̸",
+ "∄": "∄",
+ "∄": "∄",
+ "𝔫": "𝔫",
+ "≧̸": "≧̸",
+ "≱": "≱",
+ "≱": "≱",
+ "≧̸": "≧̸",
+ "⩾̸": "⩾̸",
+ "⩾̸": "⩾̸",
+ "≵": "≵",
+ "≯": "≯",
+ "≯": "≯",
+ "⇎": "⇎",
+ "↮": "↮",
+ "⫲": "⫲",
+ "∋": "∋",
+ "⋼": "⋼",
+ "⋺": "⋺",
+ "∋": "∋",
+ "њ": "њ",
+ "⇍": "⇍",
+ "≦̸": "≦̸",
+ "↚": "↚",
+ "‥": "‥",
+ "≰": "≰",
+ "↚": "↚",
+ "↮": "↮",
+ "≰": "≰",
+ "≦̸": "≦̸",
+ "⩽̸": "⩽̸",
+ "⩽̸": "⩽̸",
+ "≮": "≮",
+ "≴": "≴",
+ "≮": "≮",
+ "⋪": "⋪",
+ "⋬": "⋬",
+ "∤": "∤",
+ "𝕟": "𝕟",
+ "¬": "¬",
+ "∉": "∉",
+ "⋹̸": "⋹̸",
+ "⋵̸": "⋵̸",
+ "∉": "∉",
+ "⋷": "⋷",
+ "⋶": "⋶",
+ "∌": "∌",
+ "∌": "∌",
+ "⋾": "⋾",
+ "⋽": "⋽",
+ "∦": "∦",
+ "∦": "∦",
+ "⫽⃥": "⫽⃥",
+ "∂̸": "∂̸",
+ "⨔": "⨔",
+ "⊀": "⊀",
+ "⋠": "⋠",
+ "⪯̸": "⪯̸",
+ "⊀": "⊀",
+ "⪯̸": "⪯̸",
+ "⇏": "⇏",
+ "↛": "↛",
+ "⤳̸": "⤳̸",
+ "↝̸": "↝̸",
+ "↛": "↛",
+ "⋫": "⋫",
+ "⋭": "⋭",
+ "⊁": "⊁",
+ "⋡": "⋡",
+ "⪰̸": "⪰̸",
+ "𝓃": "𝓃",
+ "∤": "∤",
+ "∦": "∦",
+ "≁": "≁",
+ "≄": "≄",
+ "≄": "≄",
+ "∤": "∤",
+ "∦": "∦",
+ "⋢": "⋢",
+ "⋣": "⋣",
+ "⊄": "⊄",
+ "⫅̸": "⫅̸",
+ "⊈": "⊈",
+ "⊂⃒": "⊂⃒",
+ "⊈": "⊈",
+ "⫅̸": "⫅̸",
+ "⊁": "⊁",
+ "⪰̸": "⪰̸",
+ "⊅": "⊅",
+ "⫆̸": "⫆̸",
+ "⊉": "⊉",
+ "⊃⃒": "⊃⃒",
+ "⊉": "⊉",
+ "⫆̸": "⫆̸",
+ "≹": "≹",
+ "ñ": "ñ",
+ "≸": "≸",
+ "⋪": "⋪",
+ "⋬": "⋬",
+ "⋫": "⋫",
+ "⋭": "⋭",
+ "ν": "ν",
+ "#": "#",
+ "№": "№",
+ " ": " ",
+ "⊭": "⊭",
+ "⤄": "⤄",
+ "≍⃒": "≍⃒",
+ "⊬": "⊬",
+ "≥⃒": "≥⃒",
+ ">⃒": ">⃒",
+ "⧞": "⧞",
+ "⤂": "⤂",
+ "≤⃒": "≤⃒",
+ "<⃒": "<⃒",
+ "⊴⃒": "⊴⃒",
+ "⤃": "⤃",
+ "⊵⃒": "⊵⃒",
+ "∼⃒": "∼⃒",
+ "⇖": "⇖",
+ "⤣": "⤣",
+ "↖": "↖",
+ "↖": "↖",
+ "⤧": "⤧",
+ "Ⓢ": "Ⓢ",
+ "ó": "ó",
+ "⊛": "⊛",
+ "⊚": "⊚",
+ "ô": "ô",
+ "о": "о",
+ "⊝": "⊝",
+ "ő": "ő",
+ "⨸": "⨸",
+ "⊙": "⊙",
+ "⦼": "⦼",
+ "œ": "œ",
+ "⦿": "⦿",
+ "𝔬": "𝔬",
+ "˛": "˛",
+ "ò": "ò",
+ "⧁": "⧁",
+ "⦵": "⦵",
+ "Ω": "Ω",
+ "∮": "∮",
+ "↺": "↺",
+ "⦾": "⦾",
+ "⦻": "⦻",
+ "‾": "‾",
+ "⧀": "⧀",
+ "ō": "ō",
+ "ω": "ω",
+ "ο": "ο",
+ "⦶": "⦶",
+ "⊖": "⊖",
+ "𝕠": "𝕠",
+ "⦷": "⦷",
+ "⦹": "⦹",
+ "⊕": "⊕",
+ "∨": "∨",
+ "↻": "↻",
+ "⩝": "⩝",
+ "ℴ": "ℴ",
+ "ℴ": "ℴ",
+ "ª": "ª",
+ "º": "º",
+ "⊶": "⊶",
+ "⩖": "⩖",
+ "⩗": "⩗",
+ "⩛": "⩛",
+ "ℴ": "ℴ",
+ "ø": "ø",
+ "⊘": "⊘",
+ "õ": "õ",
+ "⊗": "⊗",
+ "⨶": "⨶",
+ "ö": "ö",
+ "⌽": "⌽",
+ "∥": "∥",
+ "¶": "¶",
+ "∥": "∥",
+ "⫳": "⫳",
+ "⫽": "⫽",
+ "∂": "∂",
+ "п": "п",
+ "%": "%",
+ ".": ".",
+ "‰": "‰",
+ "⊥": "⊥",
+ "‱": "‱",
+ "𝔭": "𝔭",
+ "φ": "φ",
+ "ϕ": "ϕ",
+ "ℳ": "ℳ",
+ "☎": "☎",
+ "π": "π",
+ "⋔": "⋔",
+ "ϖ": "ϖ",
+ "ℏ": "ℏ",
+ "ℎ": "ℎ",
+ "ℏ": "ℏ",
+ "+": "+",
+ "⨣": "⨣",
+ "⊞": "⊞",
+ "⨢": "⨢",
+ "∔": "∔",
+ "⨥": "⨥",
+ "⩲": "⩲",
+ "±": "±",
+ "⨦": "⨦",
+ "⨧": "⨧",
+ "±": "±",
+ "⨕": "⨕",
+ "𝕡": "𝕡",
+ "£": "£",
+ "≺": "≺",
+ "⪳": "⪳",
+ "⪷": "⪷",
+ "≼": "≼",
+ "⪯": "⪯",
+ "≺": "≺",
+ "⪷": "⪷",
+ "≼": "≼",
+ "⪯": "⪯",
+ "⪹": "⪹",
+ "⪵": "⪵",
+ "⋨": "⋨",
+ "≾": "≾",
+ "′": "′",
+ "ℙ": "ℙ",
+ "⪵": "⪵",
+ "⪹": "⪹",
+ "⋨": "⋨",
+ "∏": "∏",
+ "⌮": "⌮",
+ "⌒": "⌒",
+ "⌓": "⌓",
+ "∝": "∝",
+ "∝": "∝",
+ "≾": "≾",
+ "⊰": "⊰",
+ "𝓅": "𝓅",
+ "ψ": "ψ",
+ " ": " ",
+ "𝔮": "𝔮",
+ "⨌": "⨌",
+ "𝕢": "𝕢",
+ "⁗": "⁗",
+ "𝓆": "𝓆",
+ "ℍ": "ℍ",
+ "⨖": "⨖",
+ "?": "?",
+ "≟": "≟",
+ """: "\"",
+ "⇛": "⇛",
+ "⇒": "⇒",
+ "⤜": "⤜",
+ "⤏": "⤏",
+ "⥤": "⥤",
+ "∽̱": "∽̱",
+ "ŕ": "ŕ",
+ "√": "√",
+ "⦳": "⦳",
+ "⟩": "⟩",
+ "⦒": "⦒",
+ "⦥": "⦥",
+ "⟩": "⟩",
+ "»": "»",
+ "→": "→",
+ "⥵": "⥵",
+ "⇥": "⇥",
+ "⤠": "⤠",
+ "⤳": "⤳",
+ "⤞": "⤞",
+ "↪": "↪",
+ "↬": "↬",
+ "⥅": "⥅",
+ "⥴": "⥴",
+ "↣": "↣",
+ "↝": "↝",
+ "⤚": "⤚",
+ "∶": "∶",
+ "ℚ": "ℚ",
+ "⤍": "⤍",
+ "❳": "❳",
+ "}": "}",
+ "]": "]",
+ "⦌": "⦌",
+ "⦎": "⦎",
+ "⦐": "⦐",
+ "ř": "ř",
+ "ŗ": "ŗ",
+ "⌉": "⌉",
+ "}": "}",
+ "р": "р",
+ "⤷": "⤷",
+ "⥩": "⥩",
+ "”": "”",
+ "”": "”",
+ "↳": "↳",
+ "ℜ": "ℜ",
+ "ℛ": "ℛ",
+ "ℜ": "ℜ",
+ "ℝ": "ℝ",
+ "▭": "▭",
+ "®": "®",
+ "⥽": "⥽",
+ "⌋": "⌋",
+ "𝔯": "𝔯",
+ "⇁": "⇁",
+ "⇀": "⇀",
+ "⥬": "⥬",
+ "ρ": "ρ",
+ "ϱ": "ϱ",
+ "→": "→",
+ "↣": "↣",
+ "⇁": "⇁",
+ "⇀": "⇀",
+ "⇄": "⇄",
+ "⇌": "⇌",
+ "⇉": "⇉",
+ "↝": "↝",
+ "⋌": "⋌",
+ "˚": "˚",
+ "≓": "≓",
+ "⇄": "⇄",
+ "⇌": "⇌",
+ "‏": "",
+ "⎱": "⎱",
+ "⎱": "⎱",
+ "⫮": "⫮",
+ "⟭": "⟭",
+ "⇾": "⇾",
+ "⟧": "⟧",
+ "⦆": "⦆",
+ "𝕣": "𝕣",
+ "⨮": "⨮",
+ "⨵": "⨵",
+ ")": ")",
+ "⦔": "⦔",
+ "⨒": "⨒",
+ "⇉": "⇉",
+ "›": "›",
+ "𝓇": "𝓇",
+ "↱": "↱",
+ "]": "]",
+ "’": "’",
+ "’": "’",
+ "⋌": "⋌",
+ "⋊": "⋊",
+ "▹": "▹",
+ "⊵": "⊵",
+ "▸": "▸",
+ "⧎": "⧎",
+ "⥨": "⥨",
+ "℞": "℞",
+ "ś": "ś",
+ "‚": "‚",
+ "≻": "≻",
+ "⪴": "⪴",
+ "⪸": "⪸",
+ "š": "š",
+ "≽": "≽",
+ "⪰": "⪰",
+ "ş": "ş",
+ "ŝ": "ŝ",
+ "⪶": "⪶",
+ "⪺": "⪺",
+ "⋩": "⋩",
+ "⨓": "⨓",
+ "≿": "≿",
+ "с": "с",
+ "⋅": "⋅",
+ "⊡": "⊡",
+ "⩦": "⩦",
+ "⇘": "⇘",
+ "⤥": "⤥",
+ "↘": "↘",
+ "↘": "↘",
+ "§": "§",
+ ";": ";",
+ "⤩": "⤩",
+ "∖": "∖",
+ "∖": "∖",
+ "✶": "✶",
+ "𝔰": "𝔰",
+ "⌢": "⌢",
+ "♯": "♯",
+ "щ": "щ",
+ "ш": "ш",
+ "∣": "∣",
+ "∥": "∥",
+ "­": "",
+ "σ": "σ",
+ "ς": "ς",
+ "ς": "ς",
+ "∼": "∼",
+ "⩪": "⩪",
+ "≃": "≃",
+ "≃": "≃",
+ "⪞": "⪞",
+ "⪠": "⪠",
+ "⪝": "⪝",
+ "⪟": "⪟",
+ "≆": "≆",
+ "⨤": "⨤",
+ "⥲": "⥲",
+ "←": "←",
+ "∖": "∖",
+ "⨳": "⨳",
+ "⧤": "⧤",
+ "∣": "∣",
+ "⌣": "⌣",
+ "⪪": "⪪",
+ "⪬": "⪬",
+ "⪬︀": "⪬︀",
+ "ь": "ь",
+ "/": "/",
+ "⧄": "⧄",
+ "⌿": "⌿",
+ "𝕤": "𝕤",
+ "♠": "♠",
+ "♠": "♠",
+ "∥": "∥",
+ "⊓": "⊓",
+ "⊓︀": "⊓︀",
+ "⊔": "⊔",
+ "⊔︀": "⊔︀",
+ "⊏": "⊏",
+ "⊑": "⊑",
+ "⊏": "⊏",
+ "⊑": "⊑",
+ "⊐": "⊐",
+ "⊒": "⊒",
+ "⊐": "⊐",
+ "⊒": "⊒",
+ "□": "□",
+ "□": "□",
+ "▪": "▪",
+ "▪": "▪",
+ "→": "→",
+ "𝓈": "𝓈",
+ "∖": "∖",
+ "⌣": "⌣",
+ "⋆": "⋆",
+ "☆": "☆",
+ "★": "★",
+ "ϵ": "ϵ",
+ "ϕ": "ϕ",
+ "¯": "¯",
+ "⊂": "⊂",
+ "⫅": "⫅",
+ "⪽": "⪽",
+ "⊆": "⊆",
+ "⫃": "⫃",
+ "⫁": "⫁",
+ "⫋": "⫋",
+ "⊊": "⊊",
+ "⪿": "⪿",
+ "⥹": "⥹",
+ "⊂": "⊂",
+ "⊆": "⊆",
+ "⫅": "⫅",
+ "⊊": "⊊",
+ "⫋": "⫋",
+ "⫇": "⫇",
+ "⫕": "⫕",
+ "⫓": "⫓",
+ "≻": "≻",
+ "⪸": "⪸",
+ "≽": "≽",
+ "⪰": "⪰",
+ "⪺": "⪺",
+ "⪶": "⪶",
+ "⋩": "⋩",
+ "≿": "≿",
+ "∑": "∑",
+ "♪": "♪",
+ "¹": "¹",
+ "²": "²",
+ "³": "³",
+ "⊃": "⊃",
+ "⫆": "⫆",
+ "⪾": "⪾",
+ "⫘": "⫘",
+ "⊇": "⊇",
+ "⫄": "⫄",
+ "⟉": "⟉",
+ "⫗": "⫗",
+ "⥻": "⥻",
+ "⫂": "⫂",
+ "⫌": "⫌",
+ "⊋": "⊋",
+ "⫀": "⫀",
+ "⊃": "⊃",
+ "⊇": "⊇",
+ "⫆": "⫆",
+ "⊋": "⊋",
+ "⫌": "⫌",
+ "⫈": "⫈",
+ "⫔": "⫔",
+ "⫖": "⫖",
+ "⇙": "⇙",
+ "⤦": "⤦",
+ "↙": "↙",
+ "↙": "↙",
+ "⤪": "⤪",
+ "ß": "ß",
+ "⌖": "⌖",
+ "τ": "τ",
+ "⎴": "⎴",
+ "ť": "ť",
+ "ţ": "ţ",
+ "т": "т",
+ "⃛": "⃛",
+ "⌕": "⌕",
+ "𝔱": "𝔱",
+ "∴": "∴",
+ "∴": "∴",
+ "θ": "θ",
+ "ϑ": "ϑ",
+ "ϑ": "ϑ",
+ "≈": "≈",
+ "∼": "∼",
+ " ": " ",
+ "≈": "≈",
+ "∼": "∼",
+ "þ": "þ",
+ "˜": "˜",
+ "×": "×",
+ "⊠": "⊠",
+ "⨱": "⨱",
+ "⨰": "⨰",
+ "∭": "∭",
+ "⤨": "⤨",
+ "⊤": "⊤",
+ "⌶": "⌶",
+ "⫱": "⫱",
+ "𝕥": "𝕥",
+ "⫚": "⫚",
+ "⤩": "⤩",
+ "‴": "‴",
+ "™": "™",
+ "▵": "▵",
+ "▿": "▿",
+ "◃": "◃",
+ "⊴": "⊴",
+ "≜": "≜",
+ "▹": "▹",
+ "⊵": "⊵",
+ "◬": "◬",
+ "≜": "≜",
+ "⨺": "⨺",
+ "⨹": "⨹",
+ "⧍": "⧍",
+ "⨻": "⨻",
+ "⏢": "⏢",
+ "𝓉": "𝓉",
+ "ц": "ц",
+ "ћ": "ћ",
+ "ŧ": "ŧ",
+ "≬": "≬",
+ "↞": "↞",
+ "↠": "↠",
+ "⇑": "⇑",
+ "⥣": "⥣",
+ "ú": "ú",
+ "↑": "↑",
+ "ў": "ў",
+ "ŭ": "ŭ",
+ "û": "û",
+ "у": "у",
+ "⇅": "⇅",
+ "ű": "ű",
+ "⥮": "⥮",
+ "⥾": "⥾",
+ "𝔲": "𝔲",
+ "ù": "ù",
+ "↿": "↿",
+ "↾": "↾",
+ "▀": "▀",
+ "⌜": "⌜",
+ "⌜": "⌜",
+ "⌏": "⌏",
+ "◸": "◸",
+ "ū": "ū",
+ "¨": "¨",
+ "ų": "ų",
+ "𝕦": "𝕦",
+ "↑": "↑",
+ "↕": "↕",
+ "↿": "↿",
+ "↾": "↾",
+ "⊎": "⊎",
+ "υ": "υ",
+ "ϒ": "ϒ",
+ "υ": "υ",
+ "⇈": "⇈",
+ "⌝": "⌝",
+ "⌝": "⌝",
+ "⌎": "⌎",
+ "ů": "ů",
+ "◹": "◹",
+ "𝓊": "𝓊",
+ "⋰": "⋰",
+ "ũ": "ũ",
+ "▵": "▵",
+ "▴": "▴",
+ "⇈": "⇈",
+ "ü": "ü",
+ "⦧": "⦧",
+ "⇕": "⇕",
+ "⫨": "⫨",
+ "⫩": "⫩",
+ "⊨": "⊨",
+ "⦜": "⦜",
+ "ϵ": "ϵ",
+ "ϰ": "ϰ",
+ "∅": "∅",
+ "ϕ": "ϕ",
+ "ϖ": "ϖ",
+ "∝": "∝",
+ "↕": "↕",
+ "ϱ": "ϱ",
+ "ς": "ς",
+ "⊊︀": "⊊︀",
+ "⫋︀": "⫋︀",
+ "⊋︀": "⊋︀",
+ "⫌︀": "⫌︀",
+ "ϑ": "ϑ",
+ "⊲": "⊲",
+ "⊳": "⊳",
+ "в": "в",
+ "⊢": "⊢",
+ "∨": "∨",
+ "⊻": "⊻",
+ "≚": "≚",
+ "⋮": "⋮",
+ "|": "|",
+ "|": "|",
+ "𝔳": "𝔳",
+ "⊲": "⊲",
+ "⊂⃒": "⊂⃒",
+ "⊃⃒": "⊃⃒",
+ "𝕧": "𝕧",
+ "∝": "∝",
+ "⊳": "⊳",
+ "𝓋": "𝓋",
+ "⫋︀": "⫋︀",
+ "⊊︀": "⊊︀",
+ "⫌︀": "⫌︀",
+ "⊋︀": "⊋︀",
+ "⦚": "⦚",
+ "ŵ": "ŵ",
+ "⩟": "⩟",
+ "∧": "∧",
+ "≙": "≙",
+ "℘": "℘",
+ "𝔴": "𝔴",
+ "𝕨": "𝕨",
+ "℘": "℘",
+ "≀": "≀",
+ "≀": "≀",
+ "𝓌": "𝓌",
+ "⋂": "⋂",
+ "◯": "◯",
+ "⋃": "⋃",
+ "▽": "▽",
+ "𝔵": "𝔵",
+ "⟺": "⟺",
+ "⟷": "⟷",
+ "ξ": "ξ",
+ "⟸": "⟸",
+ "⟵": "⟵",
+ "⟼": "⟼",
+ "⋻": "⋻",
+ "⨀": "⨀",
+ "𝕩": "𝕩",
+ "⨁": "⨁",
+ "⨂": "⨂",
+ "⟹": "⟹",
+ "⟶": "⟶",
+ "𝓍": "𝓍",
+ "⨆": "⨆",
+ "⨄": "⨄",
+ "△": "△",
+ "⋁": "⋁",
+ "⋀": "⋀",
+ "ý": "ý",
+ "я": "я",
+ "ŷ": "ŷ",
+ "ы": "ы",
+ "¥": "¥",
+ "𝔶": "𝔶",
+ "ї": "ї",
+ "𝕪": "𝕪",
+ "𝓎": "𝓎",
+ "ю": "ю",
+ "ÿ": "ÿ",
+ "ź": "ź",
+ "ž": "ž",
+ "з": "з",
+ "ż": "ż",
+ "ℨ": "ℨ",
+ "ζ": "ζ",
+ "𝔷": "𝔷",
+ "ж": "ж",
+ "⇝": "⇝",
+ "𝕫": "𝕫",
+ "𝓏": "𝓏",
+ "‍": "",
+ "‌": ""
+};
diff --git a/pkgs/markdown/lib/src/ast.dart b/pkgs/markdown/lib/src/ast.dart
index 182fc4c..3fb2561 100644
--- a/pkgs/markdown/lib/src/ast.dart
+++ b/pkgs/markdown/lib/src/ast.dart
@@ -21,7 +21,7 @@
String? generatedId;
/// Instantiates a [tag] Element with [children].
- Element(this.tag, this.children) : attributes = <String, String>{};
+ Element(this.tag, this.children) : attributes = {};
/// Instantiates an empty, self-closing [tag] Element.
Element.empty(this.tag)
@@ -30,7 +30,7 @@
/// Instantiates a [tag] Element with no [children].
Element.withTag(this.tag)
- : children = [],
+ : children = const [],
attributes = {};
/// Instantiates a [tag] Element with a single Text child.
@@ -55,7 +55,10 @@
@override
String get textContent {
- return (children ?? []).map((child) => child.textContent).join('');
+ final children = this.children;
+ return children == null
+ ? ''
+ : children.map((child) => child.textContent).join();
}
}
diff --git a/pkgs/markdown/lib/src/block_parser.dart b/pkgs/markdown/lib/src/block_parser.dart
index cb88d8e..9289ae1 100644
--- a/pkgs/markdown/lib/src/block_parser.dart
+++ b/pkgs/markdown/lib/src/block_parser.dart
@@ -4,16 +4,14 @@
import 'ast.dart';
import 'block_syntaxes/block_syntax.dart';
-import 'block_syntaxes/block_tag_block_html_syntax.dart';
import 'block_syntaxes/blockquote_syntax.dart';
import 'block_syntaxes/code_block_syntax.dart';
import 'block_syntaxes/dummy_block_syntax.dart';
import 'block_syntaxes/empty_block_syntax.dart';
import 'block_syntaxes/header_syntax.dart';
import 'block_syntaxes/horizontal_rule_syntax.dart';
-import 'block_syntaxes/long_block_html_syntax.dart';
+import 'block_syntaxes/html_block_syntax.dart';
import 'block_syntaxes/ordered_list_syntax.dart';
-import 'block_syntaxes/other_tag_block_html_syntax.dart';
import 'block_syntaxes/paragraph_syntax.dart';
import 'block_syntaxes/setext_header_syntax.dart';
import 'block_syntaxes/unordered_list_syntax.dart';
@@ -43,15 +41,7 @@
/// The collection of built-in block parsers.
final List<BlockSyntax> standardBlockSyntaxes = [
const EmptyBlockSyntax(),
- const BlockTagBlockHtmlSyntax(),
- LongBlockHtmlSyntax(r'^ {0,3}<pre(?:\s|>|$)', '</pre>'),
- LongBlockHtmlSyntax(r'^ {0,3}<script(?:\s|>|$)', '</script>'),
- LongBlockHtmlSyntax(r'^ {0,3}<style(?:\s|>|$)', '</style>'),
- LongBlockHtmlSyntax('^ {0,3}<!--', '-->'),
- LongBlockHtmlSyntax(r'^ {0,3}<\?', r'\?>'),
- LongBlockHtmlSyntax('^ {0,3}<![A-Z]', '>'),
- LongBlockHtmlSyntax(r'^ {0,3}<!\[CDATA\[', r'\]\]>'),
- const OtherTagBlockHtmlSyntax(),
+ const HtmlBlockSyntax(),
const SetextHeaderSyntax(),
const HeaderSyntax(),
const CodeBlockSyntax(),
@@ -101,6 +91,10 @@
_pos++;
}
+ void retreat() {
+ _pos--;
+ }
+
bool get isDone => _pos >= lines.length;
/// Gets whether or not the current line matches the given pattern.
@@ -117,11 +111,28 @@
List<Node> parseLines() {
final blocks = <Node>[];
+
+ // If the `_pos` does not change before and after `parse()`, never try to
+ // parse the line at `_pos` with the same syntax again.
+ // For example the `TableSyntax` might not advance the `_pos` in `parse`
+ // method, beause of the header row does not match the delimiter row in the
+ // number of cells, which makes a table like structure not be recognized.
+ BlockSyntax? neverMatch;
+
while (!isDone) {
for (final syntax in blockSyntaxes) {
+ if (neverMatch == syntax) {
+ continue;
+ }
+
if (syntax.canParse(this)) {
+ final positionBefore = _pos;
final block = syntax.parse(this);
- if (block != null) blocks.add(block);
+ if (block != null) {
+ blocks.add(block);
+ }
+ neverMatch = _pos != positionBefore ? null : syntax;
+
break;
}
}
diff --git a/pkgs/markdown/lib/src/block_syntaxes/block_tag_block_html_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/block_tag_block_html_syntax.dart
index e017696..7e40ac9 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/block_tag_block_html_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/block_tag_block_html_syntax.dart
@@ -7,6 +7,7 @@
import '../patterns.dart';
import 'block_html_syntax.dart';
+@Deprecated('Use HtmlBlockSyntax instead')
class BlockTagBlockHtmlSyntax extends BlockHtmlSyntax {
static final _pattern = RegExp(
'^ {0,3}</?(?:address|article|aside|base|basefont|blockquote|body|'
diff --git a/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
index 7d16e55..00b7560 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/blockquote_syntax.dart
@@ -21,7 +21,7 @@
// Grab all of the lines that form the blockquote, stripping off the ">".
final childLines = <String>[];
- bool encounteredCodeBlock = false;
+ var encounteredCodeBlock = false;
while (!parser.isDone) {
final match = pattern.firstMatch(parser.current);
if (match != null) {
diff --git a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart
index a64e031..0b55f4a 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/fenced_code_block_syntax.dart
@@ -28,8 +28,8 @@
//
// > If the info string comes after a backtick fence, it may not contain
// > any backtick characters.
- return (codeFence.codeUnitAt(0) != $backquote ||
- !infoString!.codeUnits.contains($backquote));
+ return codeFence.codeUnitAt(0) != $backquote ||
+ !infoString!.codeUnits.contains($backquote);
}
@override
@@ -81,6 +81,7 @@
if (firstSpace >= 0) {
infoString = infoString.substring(0, firstSpace);
}
+ infoString = decodeHtmlCharacters(infoString);
if (parser.document.encodeHtml) {
infoString = escapeHtmlAttribute(infoString);
}
diff --git a/pkgs/markdown/lib/src/block_syntaxes/html_block_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/html_block_syntax.dart
new file mode 100644
index 0000000..a25da4b
--- /dev/null
+++ b/pkgs/markdown/lib/src/block_syntaxes/html_block_syntax.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../ast.dart';
+import '../block_parser.dart';
+import '../patterns.dart';
+import 'block_syntax.dart';
+
+/// Parse HTML blocks.
+// There are seven kinds of HTML block defined in the CommonMark spec:
+// https://spec.commonmark.org/0.30/#html-blocks.
+// These matching conditions and HTML block types mentioned in this syntax
+// correspond to these ones in the CommonMark spec.
+class HtmlBlockSyntax extends BlockSyntax {
+ @override
+ RegExp get pattern => htmlBlockPattern;
+
+ // All types of HTML blocks except type 7 may interrupt a paragraph, see the
+ // second paragraph after https://spec.commonmark.org/0.30/#example-148 for
+ // more detail.
+ @override
+ bool canEndBlock(BlockParser parser) =>
+ pattern.firstMatch(parser.current)!.namedGroup('condition_7') == null;
+
+ static final _endConditions = [
+ // For condition 1, it does not need to match the start tag, see
+ // https://spec.commonmark.org/0.30/#end-condition
+ RegExp('</(?:pre|script|style|textarea)>', caseSensitive: false),
+ RegExp('-->'),
+ RegExp(r'\?>'),
+ RegExp('>'),
+ RegExp(']]>'),
+ emptyPattern,
+ emptyPattern,
+ ];
+
+ const HtmlBlockSyntax();
+
+ @override
+ List<String> parseChildLines(BlockParser parser) {
+ final lines = <String>[];
+
+ final match = pattern.firstMatch(parser.current);
+ var matchedCondition = 0;
+ for (var i = 0; i < match!.groupCount; i++) {
+ if (match.group(i + 1) != null) {
+ matchedCondition = i;
+ break;
+ }
+ }
+
+ final endCondition = _endConditions[matchedCondition];
+ if (endCondition == emptyPattern) {
+ lines.add(parser.current);
+ parser.advance();
+
+ while (!parser.isDone && !endCondition.hasMatch(parser.current)) {
+ lines.add(parser.current);
+ parser.advance();
+ }
+ } else {
+ while (!parser.isDone) {
+ lines.add(parser.current);
+ if (endCondition.hasMatch(parser.current)) {
+ break;
+ }
+ parser.advance();
+ }
+ parser.advance();
+ }
+
+ // If the following lines start an HTML block again, put them together with
+ // current HTML block.
+ if (!parser.isDone &&
+ parser.next != null &&
+ pattern.hasMatch(parser.next!)) {
+ parser.advance();
+ lines.addAll(parseChildLines(parser));
+ }
+
+ return lines;
+ }
+
+ @override
+ Node parse(BlockParser parser) {
+ final childLines = parseChildLines(parser);
+ return Text(childLines.join('\n').trimRight());
+ }
+}
diff --git a/pkgs/markdown/lib/src/block_syntaxes/list_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/list_syntax.dart
index 483a0d8..7b6d0b1 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/list_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/list_syntax.dart
@@ -6,21 +6,32 @@
import '../block_parser.dart';
import '../patterns.dart';
import 'block_syntax.dart';
+import 'ordered_list_with_checkbox_syntax.dart';
+import 'unordered_list_with_checkbox_syntax.dart';
+
+/// As of Markdown 6.0.1 invisible indicators for checked/unchecked checkboxes are
+/// no longer used. These constants are now empty strings to reflect that.
+@Deprecated(
+ 'This string is no longer used internally. It will be removed in a future version.')
+const indicatorForUncheckedCheckBox = '';
+
+/// As of Markdown 6.0.1 invisible indicators for checked/unchecked checkboxes are
+/// no longer used. These constants are now empty strings to reflect that.
+@Deprecated(
+ 'This string is no longer used internally. It be will be removed in a future version.')
+const indicatorForCheckedCheckBox = '';
class ListItem {
- ListItem(this.lines);
+ const ListItem(
+ this.lines, {
+ this.taskListItemState,
+ });
- bool forceBlock = false;
final List<String> lines;
+ final TaskListItemState? taskListItemState;
}
-/// Invisible string used to placehold for an *unchecked* CheckBox.
-/// The character is Unicode Zero Width Space (U+200B).
-const indicatorForUncheckedCheckBox = '\u{200B}';
-
-/// Invisible string used to placehold for a *checked* CheckBox.
-/// This is 2 Unicode Zero Width Space (U+200B) characters.
-const indicatorForCheckedCheckBox = '\u{200B}\u{200B}';
+enum TaskListItemState { checked, unchecked }
/// Base class for both ordered and unordered lists.
abstract class ListSyntax extends BlockSyntax {
@@ -55,18 +66,36 @@
@override
Node parse(BlockParser parser) {
+ final taskListParserEnabled = this is UnorderedListWithCheckboxSyntax ||
+ this is OrderedListWithCheckboxSyntax;
final items = <ListItem>[];
var childLines = <String>[];
- final isCheckboxListSubclass =
- (listTag == 'ol_with_checkbox' || listTag == 'ul_with_checkbox');
+ TaskListItemState? taskListItemState;
void endItem() {
if (childLines.isNotEmpty) {
- items.add(ListItem(childLines));
+ items.add(ListItem(childLines, taskListItemState: taskListItemState));
childLines = <String>[];
}
}
+ String parseTaskListItem(String text) {
+ final pattern = RegExp(r'^ {0,3}\[([ xX])\][ \t]');
+
+ if (taskListParserEnabled && pattern.hasMatch(text)) {
+ return text.replaceFirstMapped(pattern, (match) {
+ taskListItemState = match[1] == ' '
+ ? TaskListItemState.unchecked
+ : TaskListItemState.checked;
+
+ return '';
+ });
+ } else {
+ taskListItemState = null;
+ return text;
+ }
+ }
+
late Match? possibleMatch;
bool tryMatch(RegExp pattern) {
possibleMatch = pattern.firstMatch(parser.current);
@@ -83,7 +112,7 @@
final leadingSpace =
_whitespaceRe.matchAsPrefix(parser.current)!.group(0)!;
final leadingExpandedTabLength = _expandedTabLength(leadingSpace);
- if (tryMatch(emptyPattern)) {
+ if (emptyPattern.hasMatch(parser.current)) {
if (emptyPattern.hasMatch(parser.next ?? '')) {
// Two blank lines ends a list.
break;
@@ -95,47 +124,21 @@
final line = parser.current
.replaceFirst(leadingSpace, ' ' * leadingExpandedTabLength)
.replaceFirst(indent, '');
- childLines.add(line);
+ childLines.add(parseTaskListItem(line));
} else if (tryMatch(hrPattern)) {
// Horizontal rule takes precedence to a new list item.
break;
- } else if ((isCheckboxListSubclass &&
- (tryMatch(ulWithCheckBoxPattern) ||
- tryMatch(olWithCheckBoxPattern))) ||
- tryMatch(ulPattern) ||
- tryMatch(olPattern)) {
- // We know we have a valid [possibleMatch] now, so capture it.
- final successfulMatch = possibleMatch!;
- // The checkbox "subclass" patterns ([ulWithCheckBoxPattern] and
- // [olWithCheckBoxPattern]) have 2 extra capturing groups at the 5
- // position to capture the checkbox. These shift the other groups
- // forward by 2 slots.
- final cbGroupOffset = isCheckboxListSubclass ? 2 : 0;
- final precedingWhitespace = successfulMatch[1]!;
- final digits = successfulMatch[2] ?? '';
+ } else if (tryMatch(ulPattern) || tryMatch(olPattern)) {
+ final match = possibleMatch!;
+ final precedingWhitespace = match[1]!;
+ final digits = match[2] ?? '';
if (startNumber == null && digits.isNotEmpty) {
startNumber = int.parse(digits);
}
- final marker = successfulMatch[3]!;
- // [checkBoxIndicator] is always empty unless a checkbox was found.
- String checkBoxIndicator = '';
- if (isCheckboxListSubclass) {
- // Look at checkbox capture group and get checkbox state.
- // If we find a checked or unchecked checkbox then we will
- // set [checkBoxIndicator] to one of our invisible
- // codes that we can later detect to know if we need to insert
- // a check or unchecked checkbox when we are inserting the
- // listitem li node.
- final String checkboxGroup = successfulMatch[5]!.toLowerCase();
- if (checkboxGroup == '[ ]') {
- checkBoxIndicator = indicatorForUncheckedCheckBox;
- } else if (checkboxGroup == '[x]') {
- checkBoxIndicator = indicatorForCheckedCheckBox;
- }
- }
- final firstWhitespace = successfulMatch[5 + cbGroupOffset] ?? '';
- final restWhitespace = successfulMatch[6 + cbGroupOffset] ?? '';
- final content = successfulMatch[7 + cbGroupOffset] ?? '';
+ final marker = match[3]!;
+ final firstWhitespace = match[5] ?? '';
+ final restWhitespace = match[6] ?? '';
+ final content = match[7] ?? '';
final isBlank = content.isEmpty;
if (listMarker != null && listMarker != marker) {
// Changing the bullet or ordered list delimiter starts a new list.
@@ -165,7 +168,7 @@
}
// End the current list item and start a new one.
endItem();
- childLines.add('$checkBoxIndicator$restWhitespace$content');
+ childLines.add(parseTaskListItem('$restWhitespace$content'));
} else if (BlockSyntax.isAtBlockEnd(parser)) {
// Done with the list.
break;
@@ -189,34 +192,27 @@
items.forEach(_removeLeadingEmptyLine);
final anyEmptyLines = _removeTrailingEmptyLines(items);
var anyEmptyLinesBetweenBlocks = false;
+ var containsTaskList = false;
for (final item in items) {
- final itemParser = BlockParser(item.lines, parser.document);
- final children = itemParser.parseLines();
- // If this is a checkbox sublass of ListSyntax then we must check
- // for possible invisible checkbox placeholder characters at
- // the start of first node's text to see if we need to insert a checkbox.
Element? checkboxToInsert;
- if (isCheckboxListSubclass) {
- if (children.isNotEmpty) {
- if (children.first.textContent
- .startsWith(indicatorForCheckedCheckBox)) {
- checkboxToInsert = Element.withTag('input')
- ..attributes['type'] = 'checkbox'
- ..attributes['checked'] = 'true';
- } else if (children.first.textContent
- .startsWith(indicatorForUncheckedCheckBox)) {
- checkboxToInsert = Element.withTag('input')
- ..attributes['type'] = 'checkbox';
- }
+ if (item.taskListItemState != null) {
+ containsTaskList = true;
+ checkboxToInsert = Element.withTag('input')
+ ..attributes['type'] = 'checkbox';
+ if (item.taskListItemState == TaskListItemState.checked) {
+ checkboxToInsert.attributes['checked'] = 'true';
}
}
- if (checkboxToInsert != null) {
- itemNodes.add(Element('li', [checkboxToInsert, ...children])
- ..attributes['class'] = 'task-list-item');
- } else {
- itemNodes.add(Element('li', children));
- }
+
+ final itemParser = BlockParser(item.lines, parser.document);
+ final children = itemParser.parseLines();
+ final itemElement = checkboxToInsert == null
+ ? Element('li', children)
+ : (Element('li', [checkboxToInsert, ...children])
+ ..attributes['class'] = 'task-list-item');
+
+ itemNodes.add(itemElement);
anyEmptyLinesBetweenBlocks =
anyEmptyLinesBetweenBlocks || itemParser.encounteredBlankLine;
}
@@ -242,21 +238,15 @@
}
}
- if (listTag == 'ol_with_checkbox') {
- final olWithCheckbox = Element('ol', itemNodes)
- ..attributes['class'] = 'contains-task-list';
- if (startNumber != 1) {
- olWithCheckbox.attributes['start'] = '$startNumber';
- }
- return olWithCheckbox;
- } else if (listTag == 'ul_with_checkbox') {
- return Element('ul', itemNodes)
- ..attributes['class'] = 'contains-task-list';
- } else if (listTag == 'ol' && startNumber != 1) {
- return Element(listTag, itemNodes)..attributes['start'] = '$startNumber';
- } else {
- return Element(listTag, itemNodes);
+ final listElement = Element(listTag, itemNodes);
+ if (listTag == 'ol' && startNumber != 1) {
+ listElement.attributes['start'] = '$startNumber';
}
+
+ if (containsTaskList) {
+ listElement.attributes['class'] = 'contains-task-list';
+ }
+ return listElement;
}
void _removeLeadingEmptyLine(ListItem item) {
diff --git a/pkgs/markdown/lib/src/block_syntaxes/long_block_html_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/long_block_html_syntax.dart
index 8332bce..89e294a 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/long_block_html_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/long_block_html_syntax.dart
@@ -10,6 +10,7 @@
///
/// In practice this means that the syntax dominates; it is allowed to eat
/// many lines, including blank lines, before matching its `endPattern`.
+@Deprecated('Use HtmlBlockSyntax instead')
class LongBlockHtmlSyntax extends BlockHtmlSyntax {
@override
final RegExp pattern;
diff --git a/pkgs/markdown/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart
index 2f8a66a..8d865e8 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart
@@ -2,16 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import '../patterns.dart';
-import 'list_syntax.dart';
+import 'ordered_list_syntax.dart';
-/// Parses ordered lists.
-class OrderedListWithCheckBoxSyntax extends ListSyntax {
- @override
- RegExp get pattern => olWithCheckBoxPattern;
-
- @override
- String get listTag => 'ol_with_checkbox';
-
- const OrderedListWithCheckBoxSyntax();
+/// Parses ordered lists with checkboxes.
+class OrderedListWithCheckboxSyntax extends OrderedListSyntax {
+ const OrderedListWithCheckboxSyntax();
}
diff --git a/pkgs/markdown/lib/src/block_syntaxes/other_tag_block_html_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/other_tag_block_html_syntax.dart
index edb5bfb..bcdc5c7 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/other_tag_block_html_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/other_tag_block_html_syntax.dart
@@ -5,6 +5,7 @@
import '../block_parser.dart';
import 'block_tag_block_html_syntax.dart';
+@Deprecated('Use HtmlBlockSyntax instead')
class OtherTagBlockHtmlSyntax extends BlockTagBlockHtmlSyntax {
@override
bool canEndBlock(BlockParser parser) => false;
diff --git a/pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart
index 2cbd4dd..fbd63c9 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart
@@ -36,6 +36,7 @@
final columnCount = alignments.length;
final headRow = _parseRow(parser, alignments, 'th');
if (headRow.children!.length != columnCount) {
+ parser.retreat();
return null;
}
final head = Element('thead', [headRow]);
@@ -50,7 +51,7 @@
if (children != null) {
while (children.length < columnCount) {
// Insert synthetic empty cells.
- children.add(Element.empty('td'));
+ children.add(Element('td', const []));
}
while (children.length > columnCount) {
children.removeLast();
@@ -71,29 +72,42 @@
}
List<String?> _parseAlignments(String line) {
- final startIndex = _walkPastOpeningPipe(line);
+ final columns = <String?>[];
+ // Set the value to `true` when hitting a non whitespace character other
+ // than the first pipe character.
+ var started = false;
+ var hitDash = false;
+ String? alignment;
- var endIndex = line.length - 1;
- while (endIndex > 0) {
- final ch = line.codeUnitAt(endIndex);
- if (ch == $pipe) {
- endIndex--;
- break;
+ for (var i = 0; i < line.length; i++) {
+ final char = line.codeUnitAt(i);
+ if (char == $space || char == $tab || (!started && char == $pipe)) {
+ continue;
}
- if (ch != $space && ch != $tab) {
- break;
+ started = true;
+
+ if (char == $colon) {
+ if (hitDash) {
+ alignment = alignment == 'left' ? 'center' : 'right';
+ } else {
+ alignment = 'left';
+ }
}
- endIndex--;
+
+ if (char == $pipe) {
+ columns.add(alignment);
+ hitDash = false;
+ alignment = null;
+ } else {
+ hitDash = true;
+ }
}
- // Optimization: We walk [line] too many times. One lap should do it.
- return line.substring(startIndex, endIndex + 1).split('|').map((column) {
- column = column.trim();
- if (column.startsWith(':') && column.endsWith(':')) return 'center';
- if (column.startsWith(':')) return 'left';
- if (column.endsWith(':')) return 'right';
- return null;
- }).toList();
+ if (hitDash) {
+ columns.add(alignment);
+ }
+
+ return columns;
}
/// Parses a table row at the current line into a table row element, with
@@ -166,7 +180,7 @@
for (var i = 0; i < row.length && i < alignments.length; i++) {
if (alignments[i] == null) continue;
- row[i].attributes['style'] = 'text-align: ${alignments[i]};';
+ row[i].attributes['align'] = '${alignments[i]}';
}
return Element('tr', row);
diff --git a/pkgs/markdown/lib/src/block_syntaxes/unordered_list_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/unordered_list_syntax.dart
index 6b1ae10..66bdf0f 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/unordered_list_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/unordered_list_syntax.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import '../block_parser.dart';
import '../patterns.dart';
import 'list_syntax.dart';
@@ -11,6 +12,21 @@
RegExp get pattern => ulPattern;
@override
+ bool canParse(BlockParser parser) {
+ // Check if it matches `hrPattern`, otherwise it will produce an infinite
+ // loop if put `UnorderedListSyntax` or `UnorderedListWithCheckboxSyntax`
+ // bofore `HorizontalRuleSyntax` and parse:
+ // ```
+ // * * *
+ // ```
+ if (hrPattern.hasMatch(parser.current)) {
+ return false;
+ }
+
+ return pattern.hasMatch(parser.current);
+ }
+
+ @override
String get listTag => 'ul';
const UnorderedListSyntax();
diff --git a/pkgs/markdown/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart b/pkgs/markdown/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart
index 795d8a7..5f3ddf0 100644
--- a/pkgs/markdown/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart
+++ b/pkgs/markdown/lib/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart
@@ -2,16 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import '../patterns.dart';
-import 'list_syntax.dart';
+import 'unordered_list_syntax.dart';
-/// Parses unordered lists.
-class UnorderedListWithCheckBoxSyntax extends ListSyntax {
- @override
- RegExp get pattern => ulWithCheckBoxPattern;
-
- @override
- String get listTag => 'ul_with_checkbox';
-
- const UnorderedListWithCheckBoxSyntax();
+/// Parses unordered lists with checkboxes.
+class UnorderedListWithCheckboxSyntax extends UnorderedListSyntax {
+ const UnorderedListWithCheckboxSyntax();
}
diff --git a/pkgs/markdown/lib/src/document.dart b/pkgs/markdown/lib/src/document.dart
index 1428dcd..a42823e 100644
--- a/pkgs/markdown/lib/src/document.dart
+++ b/pkgs/markdown/lib/src/document.dart
@@ -11,7 +11,7 @@
/// Maintains the context needed to parse a Markdown document.
class Document {
- final Map<String, LinkReference> linkReferences = <String, LinkReference>{};
+ final Map<String, LinkReference> linkReferences = {};
final Resolver? linkResolver;
final Resolver? imageLinkResolver;
final bool encodeHtml;
@@ -44,8 +44,12 @@
this.withDefaultInlineSyntaxes = true,
}) : hasCustomInlineSyntaxes = (inlineSyntaxes?.isNotEmpty ?? false) ||
(extensionSet?.inlineSyntaxes.isNotEmpty ?? false) {
- _blockSyntaxes.addAll(blockSyntaxes ?? []);
- _inlineSyntaxes.addAll(inlineSyntaxes ?? []);
+ if (blockSyntaxes != null) {
+ _blockSyntaxes.addAll(blockSyntaxes);
+ }
+ if (inlineSyntaxes != null) {
+ _inlineSyntaxes.addAll(inlineSyntaxes);
+ }
if (extensionSet == null) {
if (withDefaultBlockSyntaxes) {
diff --git a/pkgs/markdown/lib/src/extension_set.dart b/pkgs/markdown/lib/src/extension_set.dart
index 7f2be48..a7bf1ee 100644
--- a/pkgs/markdown/lib/src/extension_set.dart
+++ b/pkgs/markdown/lib/src/extension_set.dart
@@ -1,11 +1,10 @@
-import 'package:markdown/src/block_syntaxes/ordered_list_with_checkbox_syntax.dart';
-import 'package:markdown/src/block_syntaxes/unordered_list_with_checkbox_syntax.dart';
-
import 'block_syntaxes/block_syntax.dart';
import 'block_syntaxes/fenced_code_block_syntax.dart';
import 'block_syntaxes/header_with_id_syntax.dart';
+import 'block_syntaxes/ordered_list_with_checkbox_syntax.dart';
import 'block_syntaxes/setext_header_with_id_syntax.dart';
import 'block_syntaxes/table_syntax.dart';
+import 'block_syntaxes/unordered_list_with_checkbox_syntax.dart';
import 'inline_syntaxes/autolink_extension_syntax.dart';
import 'inline_syntaxes/color_swatch_syntax.dart';
import 'inline_syntaxes/emoji_syntax.dart';
@@ -27,10 +26,7 @@
/// fenced code blocks, or inline HTML.
///
/// [Markdown.pl]: http://daringfireball.net/projects/markdown/syntax
- static final ExtensionSet none = ExtensionSet(
- List<BlockSyntax>.unmodifiable(<BlockSyntax>[]),
- List<InlineSyntax>.unmodifiable(<InlineSyntax>[]),
- );
+ static final ExtensionSet none = ExtensionSet(const [], const []);
/// The [commonMark] extension set is close to compliance with [CommonMark].
///
@@ -60,8 +56,8 @@
const HeaderWithIdSyntax(),
const SetextHeaderWithIdSyntax(),
const TableSyntax(),
- const UnorderedListWithCheckBoxSyntax(),
- const OrderedListWithCheckBoxSyntax(),
+ const UnorderedListWithCheckboxSyntax(),
+ const OrderedListWithCheckboxSyntax(),
],
),
List<InlineSyntax>.unmodifiable(
@@ -82,8 +78,8 @@
<BlockSyntax>[
const FencedCodeBlockSyntax(),
const TableSyntax(),
- const UnorderedListWithCheckBoxSyntax(),
- const OrderedListWithCheckBoxSyntax(),
+ const UnorderedListWithCheckboxSyntax(),
+ const OrderedListWithCheckboxSyntax(),
],
),
List<InlineSyntax>.unmodifiable(
diff --git a/pkgs/markdown/lib/src/html_renderer.dart b/pkgs/markdown/lib/src/html_renderer.dart
index f317707..8b7dedc 100644
--- a/pkgs/markdown/lib/src/html_renderer.dart
+++ b/pkgs/markdown/lib/src/html_renderer.dart
@@ -77,7 +77,12 @@
'main',
'nav',
'section',
- 'table'
+ 'table',
+ 'thead',
+ 'tbody',
+ 'th',
+ 'tr',
+ 'td',
];
/// Translates a parsed AST to HTML.
@@ -103,13 +108,13 @@
@override
void visitText(Text text) {
- var content = text.text;
+ var content = text.textContent;
if (const ['br', 'p', 'li'].contains(_lastVisitedTag)) {
final lines = LineSplitter.split(content);
content = content.contains('<pre>')
? lines.join('\n')
: lines.map((line) => line.trimLeft()).join('\n');
- if (text.text.endsWith('\n')) {
+ if (text.textContent.endsWith('\n')) {
content = '$content\n';
}
}
diff --git a/pkgs/markdown/lib/src/inline_parser.dart b/pkgs/markdown/lib/src/inline_parser.dart
index 603d3da..e0f08c6 100644
--- a/pkgs/markdown/lib/src/inline_parser.dart
+++ b/pkgs/markdown/lib/src/inline_parser.dart
@@ -7,6 +7,7 @@
import 'document.dart';
import 'inline_syntaxes/autolink_syntax.dart';
import 'inline_syntaxes/code_syntax.dart';
+import 'inline_syntaxes/decode_html_syntax.dart';
import 'inline_syntaxes/delimiter_syntax.dart';
import 'inline_syntaxes/email_autolink_syntax.dart';
import 'inline_syntaxes/emphasis_syntax.dart';
@@ -92,6 +93,7 @@
if (document.withDefaultInlineSyntaxes) {
// Custom link resolvers go after the generic text syntax.
syntaxes.addAll([
+ DecodeHtmlSyntax(),
LinkSyntax(linkResolver: document.linkResolver),
ImageSyntax(linkResolver: document.imageLinkResolver)
]);
@@ -153,9 +155,9 @@
return;
}
final syntax = delimiter.syntax;
- if (syntax is LinkSyntax && syntaxes.any(((e) => e is LinkSyntax))) {
+ if (syntax is LinkSyntax && syntaxes.any((e) => e is LinkSyntax)) {
final nodeIndex = _tree.lastIndexWhere((n) => n == delimiter.node);
- final linkNode = syntax.close(this, delimiter, null, getChildren: () {
+ final linkNodes = syntax.close(this, delimiter, null, getChildren: () {
_processDelimiterRun(index);
// All of the nodes which lie past [index] are children of this
// link/image.
@@ -163,14 +165,14 @@
_tree.removeRange(nodeIndex + 1, _tree.length);
return children;
});
- if (linkNode != null) {
+ if (linkNodes != null) {
_delimiterStack.removeAt(index);
if (delimiter.char == $lbracket) {
for (final d in _delimiterStack.sublist(0, index)) {
if (d.char == $lbracket) d.isActive = false;
}
}
- _tree[nodeIndex] = linkNode;
+ _tree.replaceRange(nodeIndex, _tree.length, linkNodes);
advanceBy(1);
start = pos;
} else {
@@ -240,7 +242,7 @@
final openerTextNodeIndex = _tree.indexOf(openerTextNode);
final closerTextNode = closer.node;
var closerTextNodeIndex = _tree.indexOf(closerTextNode);
- final node = opener.syntax.close(
+ final nodes = opener.syntax.close(
this,
opener,
closer,
@@ -255,7 +257,7 @@
_tree.replaceRange(
openerTextNodeIndex + 1,
closerTextNodeIndex,
- [node!],
+ nodes!,
);
// Slide [closerTextNodeIndex] back accordingly.
closerTextNodeIndex = openerTextNodeIndex + 2;
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/autolink_extension_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/autolink_extension_syntax.dart
index ff2bc59..152b9a4 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/autolink_extension_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/autolink_extension_syntax.dart
@@ -3,134 +3,128 @@
// BSD-style license that can be found in the LICENSE file.
import '../ast.dart';
+import '../charcode.dart';
import '../inline_parser.dart';
import '../util.dart';
import 'inline_syntax.dart';
-/// Matches autolinks like `http://foo.com`.
+/// Matches autolinks like `http://foo.com` and `foo@bar.com`.
class AutolinkExtensionSyntax extends InlineSyntax {
- /// Broken up parts of the autolink regex for reusability and readability
+ static const _linkPattern =
+ // Autolinks can only come at the beginning of a line, after whitespace,
+ // or any of the delimiting characters *, _, ~, and (.
+ r'(?<=^|[\s*_~(>])'
- // Autolinks can only come at the beginning of a line, after whitespace, or
- // any of the delimiting characters *, _, ~, and (.
- static const start = r'(?:^|[\s*_~(>])';
+ // An extended url autolink will be recognised when one of the schemes
+ // http://, or https://, followed by a valid domain. See
+ // https://github.github.com/gfm/#extended-url-autolink.
+ r'(?:(?:https?|ftp):\/\/|www\.)'
- // An extended url autolink will be recognized when one of the schemes
- // http://, https://, or ftp://, followed by a valid domain
- static const scheme = r'(?:(?:https?|ftp):\/\/|www\.)';
+ // A valid domain consists of segments of alphanumeric characters,
+ // underscores (_) and hyphens (-) separated by periods (.). There must
+ // be at least one period, and no underscores may be present in the last
+ // two segments of the domain. See
+ // https://github.github.com/gfm/#valid-domain.
+ r'(?:[-_a-z0-9]+\.)*(?:[-a-z0-9]+\.[-a-z0-9]+)'
- // A valid domain consists of alphanumeric characters, underscores (_),
- // hyphens (-) and periods (.). There must be at least one period, and no
- // underscores may be present in the last two segments of the domain.
- static const domainPart = r'\w\-';
- static const domain = '[$domainPart][$domainPart.]+';
+ // After a valid domain, zero or more non-space non-< characters may
+ // follow.
+ r'[^\s<]*'
- // A valid domain consists of alphanumeric characters, underscores (_),
- // hyphens (-) and periods (.).
- static const path = r'[^\s<]*';
+ // Trailing punctuation (specifically, ?, !, ., ,, :, *, _, and ~) will
+ // not be considered part of the autolink, though they may be included in
+ // the interior of the link. See
+ // https://github.github.com/gfm/#extended-autolink-path-validation.
+ '(?<![?!.,:*_~])';
- // Trailing punctuation (specifically, ?, !, ., ,, :, *, _, and ~) will not
- // be considered part of the autolink
- static const truncatingPunctuationPositive = '[?!.,:*_~]';
+ // An extended email autolink, see
+ // https://github.github.com/gfm/#extended-email-autolink.
+ static const _emailPattern =
+ r'[-_.+a-z0-9]+@(?:[-_a-z0-9]+\.)+[-_a-z0-9]*[a-z0-9](?![-_])';
- static final regExpTrailingPunc = RegExp('$truncatingPunctuationPositive*\$');
- static final regExpEndsWithColon = RegExp(r'\&[a-zA-Z0-9]+;$');
- static final regExpWhiteSpace = RegExp(r'\s');
-
- AutolinkExtensionSyntax() : super('$start(($scheme)($domain)($path))');
+ AutolinkExtensionSyntax()
+ : super(
+ '($_linkPattern)|($_emailPattern)',
+ caseSensitive: false,
+ );
@override
bool tryMatch(InlineParser parser, [int? startMatchPos]) {
- return super.tryMatch(parser, parser.pos > 0 ? parser.pos - 1 : 0);
+ startMatchPos ??= parser.pos;
+ final startMatch = pattern.matchAsPrefix(parser.source, startMatchPos);
+ if (startMatch == null) {
+ return false;
+ }
+ parser.writeText();
+ return onMatch(parser, startMatch);
}
@override
bool onMatch(InlineParser parser, Match match) {
- var url = match[1]!;
- var href = url;
- var matchLength = url.length;
+ int consumeLength;
- if (url[0] == '>' || url.startsWith(regExpWhiteSpace)) {
- url = url.substring(1, url.length - 1);
- href = href.substring(1, href.length - 1);
- parser.pos++;
- matchLength--;
+ final isEmailLink = match[2] != null;
+ if (isEmailLink) {
+ consumeLength = match.match.length;
+ } else {
+ consumeLength = _getConsumeLength(match.match);
}
- // Prevent accidental standard autolink matches
- if (url.endsWith('>') && parser.source[parser.pos - 1] == '<') {
- return false;
+ var text = match.match.substring(0, consumeLength);
+ text = parser.encodeHtml ? escapeHtml(text) : text;
+
+ var destination = text;
+ if (isEmailLink) {
+ destination = 'mailto:$destination';
+ } else if (destination[0] == 'w') {
+ // When there is no scheme specified, insert the scheme `http`.
+ destination = 'http://$destination';
}
- // When an autolink ends in ), we scan the entire autolink for the total
- // number of parentheses. If there is a greater number of closing
- // parentheses than opening ones, we don’t consider the last character
- // part of the autolink, in order to facilitate including an autolink
- // inside a parenthesis:
- // https://github.github.com/gfm/#example-600
- if (url.endsWith(')')) {
- final opening = _countChars(url, '(');
- final closing = _countChars(url, ')');
+ final anchor = Element.text('a', text)
+ ..attributes['href'] = Uri.encodeFull(destination);
- if (closing > opening) {
- url = url.substring(0, url.length - 1);
- href = href.substring(0, href.length - 1);
- matchLength--;
- }
- }
+ parser
+ ..addNode(anchor)
+ ..consume(consumeLength);
- // Trailing punctuation (specifically, ?, !, ., ,, :, *, _, and ~) will
- // not be considered part of the autolink, though they may be included
- // in the interior of the link:
- // https://github.github.com/gfm/#example-599
- final trailingPunc = regExpTrailingPunc.firstMatch(url);
- if (trailingPunc != null) {
- final trailingLength = trailingPunc.match.length;
- url = url.substring(0, url.length - trailingLength);
- href = href.substring(0, href.length - trailingLength);
- matchLength -= trailingLength;
- }
-
- // If an autolink ends in a semicolon (;), we check to see if it appears
- // to resemble an
- // [entity reference](https://github.github.com/gfm/#entity-references);
- // if the preceding text is & followed by one or more alphanumeric
- // characters. If so, it is excluded from the autolink:
- // https://github.github.com/gfm/#example-602
- if (url.endsWith(';')) {
- final entityRef = regExpEndsWithColon.firstMatch(url);
- if (entityRef != null) {
- // Strip out HTML entity reference
- final entityRefLength = entityRef.match.length;
- url = url.substring(0, url.length - entityRefLength);
- href = href.substring(0, href.length - entityRefLength);
- matchLength -= entityRefLength;
- }
- }
-
- // The scheme http will be inserted automatically
- if (!href.startsWith('http://') &&
- !href.startsWith('https://') &&
- !href.startsWith('ftp://')) {
- href = 'http://$href';
- }
-
- final text = parser.encodeHtml ? escapeHtml(url) : url;
- final anchor = Element.text('a', text);
- anchor.attributes['href'] = Uri.encodeFull(href);
- parser.addNode(anchor);
-
- parser.consume(matchLength);
- return false;
+ return true;
}
- int _countChars(String input, String char) {
- var count = 0;
+ int _getConsumeLength(String text) {
+ var excludedLength = 0;
- for (var i = 0; i < input.length; i++) {
- if (input[i] == char) count++;
+ // When an autolink ends in `)`, see
+ // https://github.github.com/gfm/#example-625.
+ if (text.endsWith(')')) {
+ final match = RegExp(r'(\(.*)?(\)+)$').firstMatch(text)!;
+
+ if (match[1] == null) {
+ excludedLength = match[2]!.length;
+ } else {
+ var parenCount = 0;
+ for (var i = 0; i < text.length; i++) {
+ final char = text.codeUnitAt(i);
+ if (char == $lparen) {
+ parenCount++;
+ } else if (char == $rparen) {
+ parenCount--;
+ }
+ }
+ if (parenCount < 0) {
+ excludedLength = parenCount.abs();
+ }
+ }
+ }
+ // If an autolink ends in a semicolon `;`, see
+ // https://github.github.com/gfm/#example-627
+ else if (text.endsWith(';')) {
+ final match = RegExp(r'&[0-9a-z]+;$').firstMatch(text);
+ if (match != null) {
+ excludedLength = match.match.length;
+ }
}
- return count;
+ return text.length - excludedLength;
}
}
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/code_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/code_syntax.dart
index efc415d..afd6371 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/code_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/code_syntax.dart
@@ -20,7 +20,7 @@
//
// This conforms to the delimiters of inline code, both in Markdown.pl, and
// CommonMark.
- static final String _pattern = r'(`+(?!`))((?:.|\n)*?[^`])\1(?!`)';
+ static const _pattern = r'(`+(?!`))((?:.|\n)*?[^`])\1(?!`)';
CodeSyntax() : super(_pattern);
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/color_swatch_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/color_swatch_syntax.dart
index 0998d74..e44fdbf 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/color_swatch_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/color_swatch_syntax.dart
@@ -35,7 +35,7 @@
/// * `hsl(540,70%,50%)`
/// * `HSLA(540,70%,50%,0.3)`
/// * `Hsla(540,70%,50%,0.3)`
- static final String _pattern =
+ static const _pattern =
'`((#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{4}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8}))|'
r'([Rr][Gg][Bb][Aa]?\((\d+[%]?),(\d+[%]?),(\d+[%]?),?(\d+\.?\d+[%]?)?\))|'
r'([Hh][Ss][Ll][Aa]?\((\d+[%]?),(\d+[%]?),(\d+[%]?),?(\d+\.?\d+[%]?)?\)))`';
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/decode_html_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/decode_html_syntax.dart
new file mode 100644
index 0000000..348a6b2
--- /dev/null
+++ b/pkgs/markdown/lib/src/inline_syntaxes/decode_html_syntax.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import '../ast.dart';
+import '../charcode.dart';
+import '../inline_parser.dart';
+import '../patterns.dart';
+import '../util.dart';
+import 'inline_syntax.dart';
+
+/// Decodes numeric character references, for example decode `#` to `#`.
+// https://spec.commonmark.org/0.30/#entity-and-numeric-character-references
+class DecodeHtmlSyntax extends InlineSyntax {
+ DecodeHtmlSyntax()
+ : super(htmlCharactersPattern.pattern,
+ caseSensitive: false, startCharacter: $ampersand);
+
+ @override
+ bool tryMatch(InlineParser parser, [int? startMatchPos]) {
+ if (parser.pos > 0 && parser.charAt(parser.pos - 1) == $backquote) {
+ return false;
+ }
+
+ final match = pattern.matchAsPrefix(parser.source, parser.pos);
+ if (match == null) {
+ return false;
+ }
+
+ // TODO(Zhiguang): Enable HTML entity decoding when working on HTML escape
+ // issues.
+ if (match[1] != null) {
+ return false;
+ }
+
+ parser.writeText();
+ if (onMatch(parser, match)) parser.consume(match.match.length);
+ return true;
+ }
+
+ @override
+ bool onMatch(InlineParser parser, Match match) {
+ final decodedText = decodeHtmlCharacterFromMatch(match);
+
+ parser.addNode(Text(decodedText));
+ return true;
+ }
+}
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart
index 7b48ce2..712883f 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/delimiter_syntax.dart
@@ -63,7 +63,7 @@
syntax: this,
node: text,
allowIntraWord: allowIntraWord,
- tags: tags ?? [],
+ tags: tags ?? const [],
);
if (delimiterRun != null) {
parser.pushDelimiter(delimiterRun);
@@ -83,15 +83,15 @@
///
/// If a tag can be closed at the current position, then this method calls
/// [getChildren], in which [parser] parses any nested text into child nodes.
- /// The returned [Node] incorpororates these child nodes.
- Node? close(
+ /// The returned [Iterable] includes these children nodes.
+ Iterable<Node>? close(
InlineParser parser,
Delimiter opener,
Delimiter closer, {
required String tag,
required List<Node> Function() getChildren,
}) {
- return Element(tag, getChildren());
+ return [Element(tag, getChildren())];
}
}
@@ -217,7 +217,7 @@
']');
// TODO(srawlins): Unicode whitespace
- static final String whitespace = ' \t\r\n';
+ static const whitespace = ' \t\r\n';
@override
Text node;
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/email_autolink_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/email_autolink_syntax.dart
index f5b5962..e7b90ff 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/email_autolink_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/email_autolink_syntax.dart
@@ -12,7 +12,7 @@
///
/// See <http://spec.commonmark.org/0.28/#email-address>.
class EmailAutolinkSyntax extends InlineSyntax {
- static final _email =
+ static const _email =
r'''[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}'''
r'''[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*''';
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/inline_html_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/inline_html_syntax.dart
index 0151ba0..fb5b528 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/inline_html_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/inline_html_syntax.dart
@@ -4,9 +4,10 @@
import '../../markdown.dart';
import '../charcode.dart';
+import '../patterns.dart';
/// Leave inline HTML tags alone, from
-/// [CommonMark 0.28](http://spec.commonmark.org/0.28/#raw-html).
+/// [CommonMark 0.30](http://spec.commonmark.org/0.30/#raw-html).
///
/// This is not actually a good definition (nor CommonMark's) of an HTML tag,
/// but it is fast. It will leave text like `<a href='hi">` alone, which is
@@ -15,9 +16,29 @@
/// TODO(srawlins): improve accuracy while ensuring performance, once
/// Markdown benchmarking is more mature.
class InlineHtmlSyntax extends TextSyntax {
+ static const _pattern = '(?:$namedTagDefinition)'
+ // Or
+ '|'
+
+ // HTML comment, see
+ // https://spec.commonmark.org/0.30/#html-comment.
+ '<!--(?:(?:[^-<>]+-[^-<>]+)+|[^-<>]+)-->'
+ '|'
+
+ // Processing-instruction, see
+ // https://spec.commonmark.org/0.30/#processing-instruction
+ r'<\?.*?\?>'
+ '|'
+
+ // Declaration, see
+ // https://spec.commonmark.org/0.30/#declaration.
+ '(<![a-z]+.*?>)'
+ '|'
+
+ // CDATA section, see
+ // https://spec.commonmark.org/0.30/#cdata-section.
+ r'(<!\[CDATA\[.*?]]>)';
+
InlineHtmlSyntax()
- : super(
- r'<[/!?]?[A-Za-z][A-Za-z0-9-]*(?:\s[^>]*)?>',
- startCharacter: $lt,
- );
+ : super(_pattern, startCharacter: $lt, caseSensitive: false);
}
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
index 7522036..0546b93 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
@@ -9,6 +9,16 @@
import '../util.dart';
import 'delimiter_syntax.dart';
+/// A helper class holds params of link context.
+/// Footnote creation needs other info in [_tryCreateReferenceLink].
+class _LinkContext {
+ final InlineParser parser;
+ final SimpleDelimiter opener;
+ final List<Node> Function() getChildren;
+
+ const _LinkContext(this.parser, this.opener, this.getChildren);
+}
+
/// Matches links like `[blah][label]` and `[blah](url)`.
class LinkSyntax extends DelimiterSyntax {
static final _entirelyWhitespacePattern = RegExp(r'^\s*$');
@@ -23,13 +33,14 @@
super(pattern, startCharacter: startCharacter);
@override
- Node? close(
+ Iterable<Node>? close(
InlineParser parser,
covariant SimpleDelimiter opener,
Delimiter? closer, {
String? tag,
required List<Node> Function() getChildren,
}) {
+ final context = _LinkContext(parser, opener, getChildren);
final text = parser.source.substring(opener.endPos, parser.pos);
// The current character is the `]` that closed the link text. Examine the
// next character, to determine what type of link we might have (a '('
@@ -37,7 +48,7 @@
if (parser.pos + 1 >= parser.source.length) {
// The `]` is at the end of the document, but this may still be a valid
// shortcut reference link.
- return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+ return _tryCreateReferenceLink(context, text);
}
// Peek at the next character; don't advance, so as to avoid later stepping
@@ -50,11 +61,13 @@
final leftParenIndex = parser.pos;
final inlineLink = _parseInlineLink(parser);
if (inlineLink != null) {
- return _tryCreateInlineLink(
- parser,
- inlineLink,
- getChildren: getChildren,
- );
+ return [
+ _tryCreateInlineLink(
+ parser,
+ inlineLink,
+ getChildren: getChildren,
+ ),
+ ];
}
// At this point, we've matched `[...](`, but that `(` did not pan out to
// be an inline link. We must now check if `[...]` is simply a shortcut
@@ -63,7 +76,7 @@
// Reset the parser position.
parser.pos = leftParenIndex;
parser.advanceBy(-1);
- return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+ return _tryCreateReferenceLink(context, text);
}
if (char == $lbracket) {
@@ -75,18 +88,18 @@
// That opening `[` is not actually part of the link. Maybe a
// *shortcut* reference link (followed by a `[`).
parser.advanceBy(1);
- return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+ return _tryCreateReferenceLink(context, text);
}
final label = _parseReferenceLinkLabel(parser);
if (label != null) {
- return _tryCreateReferenceLink(parser, label, getChildren: getChildren);
+ return _tryCreateReferenceLink(context, label);
}
return null;
}
// The link text (inside `[...]`) was not followed with a opening `(` nor
// an opening `[`. Perhaps just a simple shortcut reference link (`[...]`).
- return _tryCreateReferenceLink(parser, text, getChildren: getChildren);
+ return _tryCreateReferenceLink(context, text);
}
/// Resolve a possible reference link.
@@ -148,17 +161,23 @@
/// Tries to create a reference link node.
///
- /// Returns the link if it was successfully created, `null` otherwise.
- Node? _tryCreateReferenceLink(
- InlineParser parser,
- String label, {
- required List<Node> Function() getChildren,
- }) {
- return _resolveReferenceLink(
+ /// Returns the nodes if it was successfully created, `null` otherwise.
+ Iterable<Node>? _tryCreateReferenceLink(
+ _LinkContext context,
+ String label,
+ ) {
+ final parser = context.parser;
+ final getChildren = context.getChildren;
+ final link = _resolveReferenceLink(
label,
parser.document.linkReferences,
getChildren: getChildren,
);
+ if (link != null) {
+ return [link];
+ }
+ // TODO: add footnote creation here
+ return null;
}
// Tries to create an inline link node.
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/text_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/text_syntax.dart
index 6ec4828..b73d09d 100644
--- a/pkgs/markdown/lib/src/inline_syntaxes/text_syntax.dart
+++ b/pkgs/markdown/lib/src/inline_syntaxes/text_syntax.dart
@@ -16,8 +16,12 @@
/// If [sub] is passed, it is used as a simple replacement for [pattern]. If
/// [startCharacter] is passed, it is used as a pre-matching check which is
/// faster than matching against [pattern].
- TextSyntax(super.pattern, {String sub = '', super.startCharacter})
- : substitute = sub;
+ TextSyntax(
+ super.pattern, {
+ String sub = '',
+ super.startCharacter,
+ super.caseSensitive,
+ }) : substitute = sub;
/// Adds a [Text] node to [parser] and returns `true` if there is a
/// [substitute], as long as the preceding character (if any) is not a `/`.
diff --git a/pkgs/markdown/lib/src/patterns.dart b/pkgs/markdown/lib/src/patterns.dart
index f2aa7d8..c13600d 100644
--- a/pkgs/markdown/lib/src/patterns.dart
+++ b/pkgs/markdown/lib/src/patterns.dart
@@ -31,32 +31,91 @@
/// SETEXT should win.
final hrPattern = RegExp(r'^ {0,3}([-*_])[ \t]*\1[ \t]*\1(?:\1|[ \t])*$');
-/// A line starting with one of these markers: `-`, `*`, `+`. May have up to
-/// three leading spaces before the marker and any number of spaces or tabs
-/// after.
+// why `{1}`?
+const _checkbox = r'\[[ xX]{1}\]';
+
+const _groupedWhitespaceAndEverything = r'([ \t])([ \t]*)(.*)';
+
+const _oneToNineDigits = r'\d{1,9}';
+
+const _zeroToFourWhitespace = r'[ \t]{0,4}';
+
+const _zeroToThreeSpaces = '[ ]{0,3}';
+
+/// A line starting with one of these markers: `-`, `*`, `+`.
+///
+/// May have up to three leading spaces before the marker and any number of
+/// spaces or tabs after.
///
/// Contains a dummy group at `[2]`, so that the groups in [ulPattern] and
/// [olPattern] match up; in both, `[2]` is the length of the number that begins
/// the list marker.
-final ulPattern = RegExp(r'^([ ]{0,3})()([*+-])(([ \t])([ \t]*)(.*))?$');
+final ulPattern = RegExp(''
+ '^($_zeroToThreeSpaces)'
+ // Empty group for group number alignment with [olPattern].
+ '()'
+ '([*+-])'
+ '($_groupedWhitespaceAndEverything)?\$');
-/// Similar to [ulPattern] but with a GitHub style checkbox
-/// `'[ ]'|'[x]'|'[X]'` following the number. The checkbox will
-/// be grabbed by group `[5]` and [ulPattern]'s groups `[5,6,7]` are all
-/// shifted 2 places to be `[7,8,9]`
-final ulWithCheckBoxPattern = RegExp(
- r'^([ ]{0,3})()([*+-])([ \t]{0,4})(\[[ xX]{1}\])(([ \t])([ \t]*)(.*))?$');
+/// Similar to [ulPattern] but with a GitHub-style checkbox
+/// (`'[ ]'|'[x]'|'[X]'`) following the number.
+///
+/// The checkbox will be grabbed by group `[5]` and [ulPattern]'s groups
+/// `[4]`, `[5]`, and `[6]` are all shifted 2 places to be `[6]`, `[7]`, and
+/// `[8]`.
+final ulWithCheckBoxPattern = RegExp(''
+ '^($_zeroToThreeSpaces)'
+ // Empty group for group number alignment with [olWithCheckBoxPattern].
+ '()'
+ '([*+-])'
+ '($_zeroToFourWhitespace)'
+ '($_checkbox)'
+ '($_groupedWhitespaceAndEverything)?\$');
+
+/// Similar to [ulWithCheckBoxPattern] but the checkbox is optional.
+// TODO(srawlins): This is temporary tech debt. I think we will collapse
+// [ulPattern] and [ulWithCheckBoxPattern] into this one pattern.
+final ulWithPossibleCheckboxPattern = RegExp(''
+ '^($_zeroToThreeSpaces)'
+ // Empty group for group number alignment with [olWithCheckBoxPattern].
+ '()'
+ '([*+-])'
+ '(($_zeroToFourWhitespace)($_checkbox))?'
+ // [7], [8], [9], and [10].
+ '($_groupedWhitespaceAndEverything)?\$');
/// A line starting with a number like `123.`. May have up to three leading
/// spaces before the marker and any number of spaces or tabs after.
-final olPattern = RegExp(r'^([ ]{0,3})(\d{1,9})([\.)])(([ \t])([ \t]*)(.*))?$');
+final olPattern = RegExp(''
+ '^($_zeroToThreeSpaces)'
+ '($_oneToNineDigits)'
+ r'([\.)])'
+ '($_groupedWhitespaceAndEverything)?\$');
-/// Similar to [olPattern] but with a GitHub style checkbox
-/// `'[ ]'|'[x]'|'[X]'` following the number. The checkbox will
-/// be grabbed by group `[5]` and [olPattern]'s groups `[5,6,7]` are all
-/// shifted 2 places to be `[7,8,9]`
-final olWithCheckBoxPattern = RegExp(
- r'^([ ]{0,3})(\d{1,9})([\.)])([ \t]{0,4})(\[[ xX]{1}\])(([ \t])([ \t]*)(.*))?$');
+/// Similar to [olPattern] but with a GitHub-style checkbox
+/// (`'[ ]'|'[x]'|'[X]'`) following the number.
+///
+/// The checkbox will be grabbed by group `[5]` and [olPattern]'s groups
+/// `[4]`, `[5]`, and `[6]` are all shifted 2 places to be `[6]`, `[7]`, and
+/// `[8]`.
+final olWithCheckBoxPattern = RegExp(''
+ '^($_zeroToThreeSpaces)'
+ '($_oneToNineDigits)'
+ r'([\.)])'
+ '($_zeroToFourWhitespace)'
+ '($_checkbox)'
+ '($_groupedWhitespaceAndEverything)?\$');
+
+/// Similar to [olWithCheckBoxPattern] but the checkbox is optional.
+// TODO(srawlins): This is temporary tech debt. I think we will collapse
+// [olPattern] and [olWithCheckBoxPattern] into this one pattern.
+final olWithPossibleCheckboxPattern = RegExp(''
+ '^($_zeroToThreeSpaces)'
+ '($_oneToNineDigits)'
+ r'([\.)])'
+ '(($_zeroToFourWhitespace)($_checkbox))?'
+ // [7], [8], [9], and [10].
+ '($_groupedWhitespaceAndEverything)?\$');
/// A line of hyphens separated by at least one pipe.
final tablePattern = RegExp(
@@ -65,3 +124,84 @@
/// A pattern which should never be used. It just satisfies non-nullability of
/// pattern fields.
final dummyPattern = RegExp('');
+
+/// A [String] pattern to match a named tag like `<table>` or `</table>`.
+const namedTagDefinition =
+ // Opening tag begins.
+ '<'
+
+ // Tag name.
+ '[a-z][a-z0-9-]*'
+
+ // Attribute begins, see
+ // https://spec.commonmark.org/0.30/#attribute.
+ r'(?:\s+'
+
+ // Attribute name, see
+ // https://spec.commonmark.org/0.30/#attribute-name.
+ '[a-z_:][a-z0-9._:-]*'
+
+ //
+ '(?:'
+ // Attribute value specification, see
+ // https://spec.commonmark.org/0.30/#attribute-value-specification.
+ r'\s*=\s*'
+
+ // Attribute value, see
+ // https://spec.commonmark.org/0.30/#unquoted-attribute-value.
+ r'''(?:[^\s"'=<>`]+?|'[^']*?'|"[^"]*?")'''
+
+ // Attribute ends.
+ ')?)*'
+
+ // Opening tag ends.
+ r'\s*/?>'
+
+ // Or
+ '|'
+
+ // Closing tag, see
+ // https://spec.commonmark.org/0.30/#closing-tag.
+ r'</[a-z][a-z0-9-]*\s*>';
+
+/// A pattern to match the start of an HTML block.
+///
+/// The 7 conditions here correspond to the 7 start conditions in the Commonmark
+/// specification one by one: https://spec.commonmark.org/0.30/#html-block.
+final htmlBlockPattern = RegExp(
+ '^ {0,3}(?:'
+ '<(?<condition_1>pre|script|style|textarea)'
+ r'(?:\s|>|$)'
+ '|'
+ '(?<condition_2><!--)'
+ '|'
+ r'(?<condition_3><\?)'
+ '|'
+ '(?<condition_4><![a-z])'
+ '|'
+ r'(?<condition_5><!\[CDATA\[)'
+ '|'
+ '</?(?<condition_6>address|article|aside|base|basefont|blockquote|body|'
+ 'caption|center|col|colgroup|dd|details|dialog|dir|DIV|dl|dt|fieldset|'
+ 'figcaption|figure|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|'
+ 'header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|'
+ 'optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|'
+ 'thead|title|tr|track|ul)'
+ r'(?:\s|>|/>|$)'
+ '|'
+
+ // Here we are more restrictive than the Commonmark definition (Rule #7).
+ // Otherwise some raw HTML test cases will fail, for example:
+ // https://spec.commonmark.org/0.30/#example-618.
+ // Because if a line is treated as an HTML block, it will output as Text node
+ // directly, the RawHtmlSyntax does not have a chance to validate if this
+ // HTML tag is legal or not.
+ '(?<condition_7>(?:$namedTagDefinition)\\s*\$))',
+ caseSensitive: false);
+
+/// A pattern to match HTML entity references and numeric character references.
+// https://spec.commonmark.org/0.30/#entity-and-numeric-character-references
+final htmlCharactersPattern = RegExp(
+ '&(?:([a-z0-9]+)|#([0-9]{1,7})|#x([a-f0-9]{1,6}));',
+ caseSensitive: false,
+);
diff --git a/pkgs/markdown/lib/src/util.dart b/pkgs/markdown/lib/src/util.dart
index c514acf..05ec697 100644
--- a/pkgs/markdown/lib/src/util.dart
+++ b/pkgs/markdown/lib/src/util.dart
@@ -4,7 +4,10 @@
import 'dart:convert';
+import 'assets/case_folding.dart';
+import 'assets/html_entities.dart';
import 'charcode.dart';
+import 'patterns.dart';
String escapeHtml(String html) =>
const HtmlEscape(HtmlEscapeMode.element).convert(html);
@@ -83,9 +86,62 @@
/// "Normalizes" a link label, according to the [CommonMark spec].
///
-/// [CommonMark spec] https://spec.commonmark.org/0.29/#link-label
-String normalizeLinkLabel(String label) =>
- label.trim().replaceAll(_oneOrMoreWhitespacePattern, ' ').toLowerCase();
+/// [CommonMark spec] https://spec.commonmark.org/0.30/#link-label
+String normalizeLinkLabel(String label) {
+ var text = label.trim().replaceAll(_oneOrMoreWhitespacePattern, ' ');
+ for (var i = 0; i < text.length; i++) {
+ final mapped = caseFoldingMap[text[i]];
+ if (mapped != null) {
+ text = text.replaceRange(i, i + 1, mapped);
+ }
+ }
+ return text;
+}
+
+/// Decodes HTML entity and numeric character references, for example decode
+/// `#` to `#`.
+String decodeHtmlCharacters(String input) =>
+ input.replaceAllMapped(htmlCharactersPattern, decodeHtmlCharacterFromMatch);
+
+/// Decodes HTML entity and numeric character references from the given [match].
+String decodeHtmlCharacterFromMatch(Match match) {
+ final text = match.match;
+ final entity = match[1];
+ final decimalNumber = match[2];
+ final hexadecimalNumber = match[3];
+
+ // Entity references, see
+ // https://spec.commonmark.org/0.30/#entity-references.
+ if (entity != null) {
+ return htmlEntitiesMap[text] ?? text;
+ }
+
+ // Decimal numeric character references, see
+ // https://spec.commonmark.org/0.30/#decimal-numeric-character-references.
+ else if (decimalNumber != null) {
+ final decimalValue = int.parse(decimalNumber);
+ int hexValue;
+ if (decimalValue < 1114112 && decimalValue > 1) {
+ hexValue = int.parse(decimalValue.toRadixString(16), radix: 16);
+ } else {
+ hexValue = 0xFFFd;
+ }
+
+ return String.fromCharCode(hexValue);
+ }
+
+ // Hexadecimal numeric character references, see
+ // https://spec.commonmark.org/0.30/#hexadecimal-numeric-character-references.
+ else if (hexadecimalNumber != null) {
+ var hexValue = int.parse(hexadecimalNumber, radix: 16);
+ if (hexValue > 0x10ffff || hexValue == 0) {
+ hexValue = 0xFFFd;
+ }
+ return String.fromCharCode(hexValue);
+ }
+
+ return text;
+}
extension MatchExtensions on Match {
/// Returns the whole match String
diff --git a/pkgs/markdown/lib/src/version.dart b/pkgs/markdown/lib/src/version.dart
index 0773426..0c814be 100644
--- a/pkgs/markdown/lib/src/version.dart
+++ b/pkgs/markdown/lib/src/version.dart
@@ -1,2 +1,2 @@
// Generated code. Do not modify.
-const packageVersion = '6.0.0';
+const packageVersion = '7.0.0-dev';
diff --git a/pkgs/markdown/pubspec.yaml b/pkgs/markdown/pubspec.yaml
index 660a558..9145fe4 100644
--- a/pkgs/markdown/pubspec.yaml
+++ b/pkgs/markdown/pubspec.yaml
@@ -1,5 +1,5 @@
name: markdown
-version: 6.0.0
+version: 7.0.0-dev
description: A portable Markdown library written in Dart that can parse
Markdown into HTML.
diff --git a/pkgs/markdown/test/common_mark/entity_and_numeric_character_references.unit b/pkgs/markdown/test/common_mark/entity_and_numeric_character_references.unit
index f26a97b..da96678 100644
--- a/pkgs/markdown/test/common_mark/entity_and_numeric_character_references.unit
+++ b/pkgs/markdown/test/common_mark/entity_and_numeric_character_references.unit
@@ -9,11 +9,11 @@
>>> Entity and numeric character references - 26
# Ӓ Ϡ �
<<<
-<p># Ӓ Ϡ �</p>
+<p># Ӓ Ϡ �</p>
>>> Entity and numeric character references - 27
" ആ ಫ
<<<
-<p>" ആ ಫ</p>
+<p>" ആ ಫ</p>
>>> Entity and numeric character references - 28
  &x; &#; &#x;
�
@@ -51,7 +51,7 @@
foo
```
<<<
-<pre><code class="language-f&ouml;&ouml;">foo
+<pre><code class="language-föö">foo
</code></pre>
>>> Entity and numeric character references - 35
`föö`
@@ -66,25 +66,27 @@
*foo*
*foo*
<<<
-<p>*foo*
+<p>*foo*
<em>foo</em></p>
>>> Entity and numeric character references - 38
* foo
* foo
<<<
-<p>* foo</p>
+<p>* foo</p>
<ul>
<li>foo</li>
</ul>
>>> Entity and numeric character references - 39
foo bar
<<<
-<p>foo bar</p>
+<p>foo
+
+bar</p>
>>> Entity and numeric character references - 40
	foo
<<<
-<p>	foo</p>
+<p>foo</p>
>>> Entity and numeric character references - 41
[a](url "tit")
<<<
diff --git a/pkgs/markdown/test/common_mark/html_blocks.unit b/pkgs/markdown/test/common_mark/html_blocks.unit
index f9afb32..54b229c 100644
--- a/pkgs/markdown/test/common_mark/html_blocks.unit
+++ b/pkgs/markdown/test/common_mark/html_blocks.unit
@@ -210,8 +210,12 @@
</textarea>
<<<
<textarea>
-<p><em>foo</em></p>
-<p><em>bar</em></p></textarea>
+
+*foo*
+
+_bar_
+
+</textarea>
>>> HTML blocks - 172
<style
type="text/css">
@@ -407,9 +411,13 @@
</table>
<<<
-<table><tr><td>
+<table>
+<tr>
+<td>
Hi
-</td></tr></table>
+</td>
+</tr>
+</table>
>>> HTML blocks - 191
<table>
@@ -423,8 +431,10 @@
</table>
<<<
-<table> <tr>
+<table>
+ <tr>
<pre><code><td>
Hi
</td>
-</code></pre> </tr></table>
+</code></pre> </tr>
+</table>
diff --git a/pkgs/markdown/test/common_mark/links.unit b/pkgs/markdown/test/common_mark/links.unit
index 8ce80f9..d144227 100644
--- a/pkgs/markdown/test/common_mark/links.unit
+++ b/pkgs/markdown/test/common_mark/links.unit
@@ -280,7 +280,7 @@
[SS]: /url
<<<
-<p>[ẞ]</p>
+<p><a href="/url">ẞ</a></p>
>>> Links - 540
[Foo
bar]: /url
diff --git a/pkgs/markdown/test/common_mark/raw_html.unit b/pkgs/markdown/test/common_mark/raw_html.unit
index f1fa258..cde09c4 100644
--- a/pkgs/markdown/test/common_mark/raw_html.unit
+++ b/pkgs/markdown/test/common_mark/raw_html.unit
@@ -5,7 +5,7 @@
>>> Raw HTML - 613
<a/><b2/>
<<<
-<p><a/><b2/></p>
+<p><a/><b2/></p>
>>> Raw HTML - 614
<a /><b2
data="foo" >
@@ -29,11 +29,11 @@
>>> Raw HTML - 618
<a h*#ref="hi">
<<<
-<a h*#ref="hi">
+<p><a h*#ref="hi"></p>
>>> Raw HTML - 619
<a href="hi'> <a href=hi'>
<<<
-<p><a href="hi'> <a href=hi'></p>
+<p><a href="hi'> <a href=hi'></p>
>>> Raw HTML - 620
< a><
foo><bar/ >
@@ -42,12 +42,12 @@
<<<
<p>< a><
foo><bar/ >
-<foo bar=baz
+<foo bar=baz
bim!bop /></p>
>>> Raw HTML - 621
<a href='bar'title=title>
<<<
-<a href='bar'title=title>
+<p><a href='bar'title=title></p>
>>> Raw HTML - 622
</a></foo >
<<<
@@ -55,13 +55,13 @@
>>> Raw HTML - 623
</a href="foo">
<<<
-</a href="foo">
+<p></a href="foo"></p>
>>> Raw HTML - 624
foo <!-- this is a
comment - with hyphen -->
<<<
-<p>foo <!-- this is a
-comment - with hyphen --></p>
+<p>foo <!-- this is a
+comment - with hyphen --></p>
>>> Raw HTML - 625
foo <!-- not a comment -- two hyphens -->
<<<
@@ -84,7 +84,7 @@
>>> Raw HTML - 629
foo <![CDATA[>&<]]>
<<<
-<p>foo <![CDATA[>&<]]></p>
+<p>foo <![CDATA[>&<]]></p>
>>> Raw HTML - 630
foo <a href="ö">
<<<
@@ -96,4 +96,4 @@
>>> Raw HTML - 632
<a href="\"">
<<<
-<a href="\"">
+<p><a href="""></p>
diff --git a/pkgs/markdown/test/document_test.dart b/pkgs/markdown/test/document_test.dart
index 8a26900..a9a8be7 100644
--- a/pkgs/markdown/test/document_test.dart
+++ b/pkgs/markdown/test/document_test.dart
@@ -20,7 +20,7 @@
});
group('with encodeHtml enabled', () {
- final document = Document(encodeHtml: true);
+ final document = Document();
test('encodes HTML in an inline code snippet', () {
final result =
@@ -54,8 +54,8 @@
test('encodeHtml spaces are preserved in text', () {
// Example to get a <p> tag rendered before a text node.
- final contents = 'Sample\n\n<pre>\n A\n B\n</pre>';
- final document = Document(encodeHtml: true);
+ const contents = 'Sample\n\n<pre>\n A\n B\n</pre>';
+ final document = Document();
final lines = LineSplitter.split(contents).toList();
final nodes = BlockParser(lines, document).parseLines();
final result = HtmlRenderer().render(nodes);
@@ -64,8 +64,8 @@
test('encode double quotes, greater than, and less than when escaped',
() {
- final contents = r'\>\"\< Hello';
- final document = Document(encodeHtml: true);
+ const contents = r'\>\"\< Hello';
+ final document = Document();
final nodes = document.parseInline(contents);
expect(nodes, hasLength(1));
expect(
@@ -113,7 +113,7 @@
});
test('leave double quotes, greater than, and less than when escaped', () {
- final contents = r'\>\"\< Hello';
+ const contents = r'\>\"\< Hello';
final document = Document(encodeHtml: false);
final nodes = document.parseInline(contents);
expect(nodes, hasLength(1));
diff --git a/pkgs/markdown/test/extensions/ordered_list_with_checkboxes.unit b/pkgs/markdown/test/extensions/ordered_list_with_checkboxes.unit
new file mode 100644
index 0000000..84cf86e
--- /dev/null
+++ b/pkgs/markdown/test/extensions/ordered_list_with_checkboxes.unit
@@ -0,0 +1,65 @@
+>>> checkbox with space
+1. [ ] one
+2. [ ] two
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+</ol>
+>>> empty checkbox
+1. [] one
+2. [] two
+<<<
+<ol>
+<li>[] one</li>
+<li>[] two</li>
+</ol>
+>>> checkbox with x
+1. [x] one
+2. [x] two
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ol>
+>>> checkbox with X
+1. [X] one
+2. [X] two
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ol>
+>>> mixed checkboxes
+1. [ ] one
+2. [] two
+3. [x] three
+4. [X] four
+5. five
+<<<
+<ol class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li>[] two</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>three</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>four</li>
+<li>five</li>
+</ol>
+>>> mixed leading spaces
+1.[ ] zero
+2. [ ] one
+3. [ ] two
+4. [ ] three
+5. [ ] four
+6. [ ] five
+<<<
+<p>1.[ ] zero</p>
+<ol start="2" class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+<li class="task-list-item"><input type="checkbox"></input>three</li>
+<li class="task-list-item"><input type="checkbox"></input>four</li>
+<li>
+<pre><code>[ ] five
+</code></pre>
+</li>
+</ol>
\ No newline at end of file
diff --git a/pkgs/markdown/test/extensions/tables.unit b/pkgs/markdown/test/extensions/tables.unit
index 9516fb3..2f076df 100644
--- a/pkgs/markdown/test/extensions/tables.unit
+++ b/pkgs/markdown/test/extensions/tables.unit
@@ -4,7 +4,20 @@
body | cells
<<<
-<table><thead><tr><th>head</th><th>cells</th></tr></thead><tbody><tr><td>body</td><td>cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+<th>cells</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+<td>cells</td>
+</tr>
+</tbody>
+</table>
>>> multiple rows
head | cells
-----|------
@@ -12,40 +25,124 @@
more | cells
<<<
-<table><thead><tr><th>head</th><th>cells</th></tr></thead><tbody><tr><td>body</td><td>cells</td></tr><tr><td>more</td><td>cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+<th>cells</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+<td>cells</td>
+</tr>
+<tr>
+<td>more</td>
+<td>cells</td>
+</tr>
+</tbody>
+</table>
>>> rows wrapped in pipes
| head | cells |
|------|-------|
| body | cells |
<<<
-<table><thead><tr><th>head</th><th>cells</th></tr></thead><tbody><tr><td>body</td><td>cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+<th>cells</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+<td>cells</td>
+</tr>
+</tbody>
+</table>
>>> rows wrapped in pipes, whitespace alignment row
| head | cells |
| -- | --- |
| body | cells |
<<<
-<table><thead><tr><th>head</th><th>cells</th></tr></thead><tbody><tr><td>body</td><td>cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+<th>cells</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+<td>cells</td>
+</tr>
+</tbody>
+</table>
>>> rows wrapped in pipes, tabs in whitespace
| head | cells |
| -- | --- |
| body | cells |
<<<
-<table><thead><tr><th>head</th><th>cells</th></tr></thead><tbody><tr><td>body</td><td>cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+<th>cells</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+<td>cells</td>
+</tr>
+</tbody>
+</table>
>>> cells with inline syntax
head `code` | _cells_
------------|--------
*text* | <span>text</span>
<<<
-<table><thead><tr><th>head <code>code</code></th><th><em>cells</em></th></tr></thead><tbody><tr><td><em>text</em></td><td><span>text</span></td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head <code>code</code></th>
+<th><em>cells</em></th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><em>text</em></td>
+<td><span>text</span></td>
+</tr>
+</tbody>
+</table>
>>> cells are parsed before inline syntax
header | _foo | bar_
-------|------------|---
text | text
<<<
-<table><thead><tr><th>header</th><th>_foo</th><th>bar_</th></tr></thead><tbody><tr><td>text</td><td>text</td><td /></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>header</th>
+<th>_foo</th>
+<th>bar_</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>text</td>
+<td>text</td>
+<td></td>
+</tr>
+</tbody>
+</table>
>>> cells contain reference links
header | header
-------|--------
@@ -53,20 +150,64 @@
[here]: http://url
<<<
-<table><thead><tr><th>header</th><th>header</th></tr></thead><tbody><tr><td>text</td><td><a href="http://url">link</a></td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>header</th>
+<th>header</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>text</td>
+<td><a href="http://url">link</a></td>
+</tr>
+</tbody>
+</table>
>>> one column tables
head
-----|
body
<<<
-<table><thead><tr><th>head</th></tr></thead><tbody><tr><td>body</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+</tr>
+</tbody>
+</table>
>>> varying cells per row
head | foo | bar
-----|-----|-----
body
row with | two cells
<<<
-<table><thead><tr><th>head</th><th>foo</th><th>bar</th></tr></thead><tbody><tr><td>body</td><td /><td /></tr><tr><td>row with</td><td>two cells</td><td /></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>head</th>
+<th>foo</th>
+<th>bar</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>body</td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>row with</td>
+<td>two cells</td>
+<td></td>
+</tr>
+</tbody>
+</table>
>>> left, center, and right alignment
head | cells | here
:----|:-----:|----:
@@ -74,7 +215,27 @@
too | many | cells | here
<<<
-<table><thead><tr><th style="text-align: left;">head</th><th style="text-align: center;">cells</th><th style="text-align: right;">here</th></tr></thead><tbody><tr><td style="text-align: left;">body</td><td style="text-align: center;">cells</td><td style="text-align: right;">here</td></tr><tr><td style="text-align: left;">too</td><td style="text-align: center;">many</td><td style="text-align: right;">cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th align="left">head</th>
+<th align="center">cells</th>
+<th align="right">here</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left">body</td>
+<td align="center">cells</td>
+<td align="right">here</td>
+</tr>
+<tr>
+<td align="left">too</td>
+<td align="center">many</td>
+<td align="right">cells</td>
+</tr>
+</tbody>
+</table>
>>> left, center, and right alignment, with whitespace
head | cells | here
:-- | :---: | ---:
@@ -82,7 +243,27 @@
too | many | cells | here
<<<
-<table><thead><tr><th style="text-align: left;">head</th><th style="text-align: center;">cells</th><th style="text-align: right;">here</th></tr></thead><tbody><tr><td style="text-align: left;">body</td><td style="text-align: center;">cells</td><td style="text-align: right;">here</td></tr><tr><td style="text-align: left;">too</td><td style="text-align: center;">many</td><td style="text-align: right;">cells</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th align="left">head</th>
+<th align="center">cells</th>
+<th align="right">here</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left">body</td>
+<td align="center">cells</td>
+<td align="right">here</td>
+</tr>
+<tr>
+<td align="left">too</td>
+<td align="center">many</td>
+<td align="right">cells</td>
+</tr>
+</tbody>
+</table>
>>> escape pipe
| Name | Character |
| --- | --- |
@@ -90,17 +271,60 @@
| Pipe | \| |
<<<
-<table><thead><tr><th>Name</th><th>Character</th></tr></thead><tbody><tr><td>Backtick</td><td>`</td></tr><tr><td>Pipe</td><td>|</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>Name</th>
+<th>Character</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Backtick</td>
+<td>`</td>
+</tr>
+<tr>
+<td>Pipe</td>
+<td>|</td>
+</tr>
+</tbody>
+</table>
>>> escape pipe, preserve trailing whitespace
| Name | Character |
| --- | --- |
| Pipe | \| abcdef |
<<<
-<table><thead><tr><th>Name</th><th>Character</th></tr></thead><tbody><tr><td>Pipe</td><td>| abcdef</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>Name</th>
+<th>Character</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Pipe</td>
+<td>| abcdef</td>
+</tr>
+</tbody>
+</table>
>>> trailing whitespace after final pipe
| Name | Character |
| --- | --- |
| Pipe | abcdef |
<<<
-<table><thead><tr><th>Name</th><th>Character</th></tr></thead><tbody><tr><td>Pipe</td><td>abcdef</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>Name</th>
+<th>Character</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>Pipe</td>
+<td>abcdef</td>
+</tr>
+</tbody>
+</table>
diff --git a/pkgs/markdown/test/extensions/unordered_list_with_checkboxes.unit b/pkgs/markdown/test/extensions/unordered_list_with_checkboxes.unit
new file mode 100644
index 0000000..170b6de
--- /dev/null
+++ b/pkgs/markdown/test/extensions/unordered_list_with_checkboxes.unit
@@ -0,0 +1,65 @@
+>>> checkbox with space
+* [ ] one
+* [ ] two
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+</ul>
+>>> empty checkbox
+* [] one
+* [] two
+<<<
+<ul>
+<li>[] one</li>
+<li>[] two</li>
+</ul>
+>>> checkbox with x
+* [x] one
+* [x] two
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ul>
+>>> checkbox with X
+* [X] one
+* [X] two
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox" checked="true"></input>one</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>two</li>
+</ul>
+>>> mixed checkboxes
+* [ ] one
+* [] two
+* [x] three
+* [X] four
+* five
+<<<
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li>[] two</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>three</li>
+<li class="task-list-item"><input type="checkbox" checked="true"></input>four</li>
+<li>five</li>
+</ul>
+>>> mixed leading spaces
+*[ ] zero
+* [ ] one
+* [ ] two
+* [ ] three
+* [ ] four
+* [ ] five
+<<<
+<p>*[ ] zero</p>
+<ul class="contains-task-list">
+<li class="task-list-item"><input type="checkbox"></input>one</li>
+<li class="task-list-item"><input type="checkbox"></input>two</li>
+<li class="task-list-item"><input type="checkbox"></input>three</li>
+<li class="task-list-item"><input type="checkbox"></input>four</li>
+<li>
+<pre><code>[ ] five
+</code></pre>
+</li>
+</ul>
\ No newline at end of file
diff --git a/pkgs/markdown/test/gfm/autolinks.unit b/pkgs/markdown/test/gfm/autolinks.unit
index d4c803b..4de9122 100644
--- a/pkgs/markdown/test/gfm/autolinks.unit
+++ b/pkgs/markdown/test/gfm/autolinks.unit
@@ -57,7 +57,7 @@
>>> Autolinks - 616
< http://foo.bar >
<<<
-<p>< <a href="http://foo.bar">http://foo.bar</a> ></p>
+<p>< http://foo.bar ></p>
>>> Autolinks - 617
<m:abc>
<<<
@@ -69,7 +69,7 @@
>>> Autolinks - 619
http://example.com
<<<
-<p><a href="http://example.com">http://example.com</a></p>
+<p>http://example.com</p>
>>> Autolinks - 620
foo@bar.example.com
<<<
diff --git a/pkgs/markdown/test/gfm/autolinks_extension.unit b/pkgs/markdown/test/gfm/autolinks_extension.unit
index ac41184..024fde1 100644
--- a/pkgs/markdown/test/gfm/autolinks_extension.unit
+++ b/pkgs/markdown/test/gfm/autolinks_extension.unit
@@ -23,9 +23,9 @@
(www.google.com/search?q=Markup+(business)
<<<
<p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a></p>
-<p><a href="http://www.google.com/search?q=Markup+(business))">www.google.com/search?q=Markup+(business))</a>)</p>
<p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>))</p>
-<p><a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>)</p>
+<p>(<a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a>)</p>
+<p>(<a href="http://www.google.com/search?q=Markup+(business)">www.google.com/search?q=Markup+(business)</a></p>
>>> Autolinks (extension) - 625
www.google.com/search?q=(business))+ok
<<<
@@ -35,7 +35,7 @@
www.google.com/search?q=commonmark&hl;
<<<
-<p><a href="http://www.google.com/search?q=commonmark&hl=en">www.google.com/search?q=commonmark&hl=en</a></p>
+<p><a href="http://www.google.com/search?q=commonmark&hl=en">www.google.com/search?q=commonmark&hl=en</a></p>
<p><a href="http://www.google.com/search?q=commonmark">www.google.com/search?q=commonmark</a>&hl;</p>
>>> Autolinks (extension) - 627
www.commonmark.org/he<lp
@@ -54,11 +54,11 @@
>>> Autolinks (extension) - 629
foo@bar.baz
<<<
-<p>foo@bar.baz</p>
+<p><a href="mailto:foo@bar.baz">foo@bar.baz</a></p>
>>> Autolinks (extension) - 630
hello@mail+xyz.example isn't valid, but hello+xyz@mail.example is.
<<<
-<p>hello@mail+xyz.example isn't valid, but hello+xyz@mail.example is.</p>
+<p>hello@mail+xyz.example isn't valid, but <a href="mailto:hello+xyz@mail.example">hello+xyz@mail.example</a> is.</p>
>>> Autolinks (extension) - 631
a.b-c_d@a.b
@@ -68,7 +68,7 @@
a.b-c_d@a.b_
<<<
-<p>a.b-c_d@a.b</p>
-<p>a.b-c_d@a.b.</p>
+<p><a href="mailto:a.b-c_d@a.b">a.b-c_d@a.b</a></p>
+<p><a href="mailto:a.b-c_d@a.b">a.b-c_d@a.b</a>.</p>
<p>a.b-c_d@a.b-</p>
<p>a.b-c_d@a.b_</p>
diff --git a/pkgs/markdown/test/gfm/entity_and_numeric_character_references.unit b/pkgs/markdown/test/gfm/entity_and_numeric_character_references.unit
index 5405ac2..be80572 100644
--- a/pkgs/markdown/test/gfm/entity_and_numeric_character_references.unit
+++ b/pkgs/markdown/test/gfm/entity_and_numeric_character_references.unit
@@ -9,11 +9,11 @@
>>> Entity and numeric character references - 322
# Ӓ Ϡ �
<<<
-<p># Ӓ Ϡ �</p>
+<p># Ӓ Ϡ �</p>
>>> Entity and numeric character references - 323
" ആ ಫ
<<<
-<p>" ആ ಫ</p>
+<p>" ആ ಫ</p>
>>> Entity and numeric character references - 324
  &x; &#; &#x;
�
@@ -51,7 +51,7 @@
foo
```
<<<
-<pre><code class="language-f&ouml;&ouml;">foo
+<pre><code class="language-föö">foo
</code></pre>
>>> Entity and numeric character references - 331
`föö`
@@ -66,25 +66,27 @@
*foo*
*foo*
<<<
-<p>*foo*
+<p>*foo*
<em>foo</em></p>
>>> Entity and numeric character references - 334
* foo
* foo
<<<
-<p>* foo</p>
+<p>* foo</p>
<ul>
<li>foo</li>
</ul>
>>> Entity and numeric character references - 335
foo bar
<<<
-<p>foo bar</p>
+<p>foo
+
+bar</p>
>>> Entity and numeric character references - 336
	foo
<<<
-<p>	foo</p>
+<p>foo</p>
>>> Entity and numeric character references - 337
[a](url "tit")
<<<
diff --git a/pkgs/markdown/test/gfm/html_blocks.unit b/pkgs/markdown/test/gfm/html_blocks.unit
index 78c47ab..f2562f4 100644
--- a/pkgs/markdown/test/gfm/html_blocks.unit
+++ b/pkgs/markdown/test/gfm/html_blocks.unit
@@ -395,9 +395,13 @@
</table>
<<<
-<table><tr><td>
+<table>
+<tr>
+<td>
Hi
-</td></tr></table>
+</td>
+</tr>
+</table>
>>> HTML blocks - 160
<table>
@@ -411,8 +415,10 @@
</table>
<<<
-<table> <tr>
+<table>
+ <tr>
<pre><code><td>
Hi
</td>
-</code></pre> </tr></table>
+</code></pre> </tr>
+</table>
diff --git a/pkgs/markdown/test/gfm/raw_html.unit b/pkgs/markdown/test/gfm/raw_html.unit
index f693be6..1802dba 100644
--- a/pkgs/markdown/test/gfm/raw_html.unit
+++ b/pkgs/markdown/test/gfm/raw_html.unit
@@ -5,7 +5,7 @@
>>> Raw HTML - 633
<a/><b2/>
<<<
-<p><a/><b2/></p>
+<p><a/><b2/></p>
>>> Raw HTML - 634
<a /><b2
data="foo" >
@@ -29,11 +29,11 @@
>>> Raw HTML - 638
<a h*#ref="hi">
<<<
-<a h*#ref="hi">
+<p><a h*#ref="hi"></p>
>>> Raw HTML - 639
<a href="hi'> <a href=hi'>
<<<
-<p><a href="hi'> <a href=hi'></p>
+<p><a href="hi'> <a href=hi'></p>
>>> Raw HTML - 640
< a><
foo><bar/ >
@@ -42,12 +42,12 @@
<<<
<p>< a><
foo><bar/ >
-<foo bar=baz
+<foo bar=baz
bim!bop /></p>
>>> Raw HTML - 641
<a href='bar'title=title>
<<<
-<a href='bar'title=title>
+<p><a href='bar'title=title></p>
>>> Raw HTML - 642
</a></foo >
<<<
@@ -55,13 +55,13 @@
>>> Raw HTML - 643
</a href="foo">
<<<
-</a href="foo">
+<p></a href="foo"></p>
>>> Raw HTML - 644
foo <!-- this is a
comment - with hyphen -->
<<<
-<p>foo <!-- this is a
-comment - with hyphen --></p>
+<p>foo <!-- this is a
+comment - with hyphen --></p>
>>> Raw HTML - 645
foo <!-- not a comment -- two hyphens -->
<<<
@@ -84,7 +84,7 @@
>>> Raw HTML - 649
foo <![CDATA[>&<]]>
<<<
-<p>foo <![CDATA[>&<]]></p>
+<p>foo <![CDATA[>&<]]></p>
>>> Raw HTML - 650
foo <a href="ö">
<<<
@@ -96,4 +96,4 @@
>>> Raw HTML - 652
<a href="\"">
<<<
-<a href="\"">
+<p><a href="""></p>
diff --git a/pkgs/markdown/test/gfm/tables_extension.unit b/pkgs/markdown/test/gfm/tables_extension.unit
index cd84708..625fca8 100644
--- a/pkgs/markdown/test/gfm/tables_extension.unit
+++ b/pkgs/markdown/test/gfm/tables_extension.unit
@@ -3,27 +3,80 @@
| --- | --- |
| baz | bim |
<<<
-<table><thead><tr><th>foo</th><th>bar</th></tr></thead><tbody><tr><td>baz</td><td>bim</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>foo</th>
+<th>bar</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>baz</td>
+<td>bim</td>
+</tr>
+</tbody>
+</table>
>>> Tables (extension) - 199
| abc | defghi |
:-: | -----------:
bar | baz
<<<
-<table><thead><tr><th style="text-align: center;">abc</th><th style="text-align: right;">defghi</th></tr></thead><tbody><tr><td style="text-align: center;">bar</td><td style="text-align: right;">baz</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th align="center">abc</th>
+<th align="right">defghi</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="center">bar</td>
+<td align="right">baz</td>
+</tr>
+</tbody>
+</table>
>>> Tables (extension) - 200
| f\|oo |
| ------ |
| b `\|` az |
| b **\|** im |
<<<
-<table><thead><tr><th>f|oo</th></tr></thead><tbody><tr><td>b <code>|</code> az</td></tr><tr><td>b <strong>|</strong> im</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>f|oo</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>b <code>|</code> az</td>
+</tr>
+<tr>
+<td>b <strong>|</strong> im</td>
+</tr>
+</tbody>
+</table>
>>> Tables (extension) - 201
| abc | def |
| --- | --- |
| bar | baz |
> bar
<<<
-<table><thead><tr><th>abc</th><th>def</th></tr></thead><tbody><tr><td>bar</td><td>baz</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>abc</th>
+<th>def</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>bar</td>
+<td>baz</td>
+</tr>
+</tbody>
+</table>
<blockquote>
<p>bar</p>
</blockquote>
@@ -35,14 +88,32 @@
bar
<<<
-<table><thead><tr><th>abc</th><th>def</th></tr></thead><tbody><tr><td>bar</td><td>baz</td></tr><tr><td>bar</td><td /></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>abc</th>
+<th>def</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>bar</td>
+<td>baz</td>
+</tr>
+<tr>
+<td>bar</td>
+<td></td>
+</tr>
+</tbody>
+</table>
<p>bar</p>
>>> Tables (extension) - 203
| abc | def |
| --- |
| bar |
<<<
-<p>| --- |
+<p>| abc | def |
+| --- |
| bar |</p>
>>> Tables (extension) - 204
| abc | def |
@@ -50,9 +121,33 @@
| bar |
| bar | baz | boo |
<<<
-<table><thead><tr><th>abc</th><th>def</th></tr></thead><tbody><tr><td>bar</td><td /></tr><tr><td>bar</td><td>baz</td></tr></tbody></table>
+<table>
+<thead>
+<tr>
+<th>abc</th>
+<th>def</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>bar</td>
+<td></td>
+</tr>
+<tr>
+<td>bar</td>
+<td>baz</td>
+</tr>
+</tbody>
+</table>
>>> Tables (extension) - 205
| abc | def |
| --- | --- |
<<<
-<table><thead><tr><th>abc</th><th>def</th></tr></thead></table>
+<table>
+<thead>
+<tr>
+<th>abc</th>
+<th>def</th>
+</tr>
+</thead>
+</table>
diff --git a/pkgs/markdown/test/html_renderer_test.dart b/pkgs/markdown/test/html_renderer_test.dart
index cc32869..77c33d3 100644
--- a/pkgs/markdown/test/html_renderer_test.dart
+++ b/pkgs/markdown/test/html_renderer_test.dart
@@ -40,7 +40,6 @@
test('with only default block syntaxes', () {
final result = markdownToHtml(
text,
- withDefaultBlockSyntaxes: true,
withDefaultInlineSyntaxes: false,
encodeHtml: false,
);
@@ -55,7 +54,6 @@
final result = markdownToHtml(
text,
withDefaultBlockSyntaxes: false,
- withDefaultInlineSyntaxes: true,
encodeHtml: false,
);
@@ -70,7 +68,6 @@
text,
withDefaultBlockSyntaxes: false,
withDefaultInlineSyntaxes: false,
- encodeHtml: true,
);
expect(
diff --git a/pkgs/markdown/test/markdown_test.dart b/pkgs/markdown/test/markdown_test.dart
index a9f6fde..35fde7e 100644
--- a/pkgs/markdown/test/markdown_test.dart
+++ b/pkgs/markdown/test/markdown_test.dart
@@ -8,9 +8,13 @@
import 'util.dart';
void main() async {
- await testDirectory('original');
+ testDirectory('original');
- // Block syntax extensions
+ // Block syntax extensions.
+ testFile(
+ 'extensions/fenced_blockquotes.unit',
+ blockSyntaxes: [const FencedBlockquoteSyntax()],
+ );
testFile(
'extensions/fenced_code_blocks.unit',
blockSyntaxes: [const FencedCodeBlockSyntax()],
@@ -20,6 +24,10 @@
blockSyntaxes: [const HeaderWithIdSyntax()],
);
testFile(
+ 'extensions/ordered_list_with_checkboxes.unit',
+ blockSyntaxes: [const OrderedListWithCheckboxSyntax()],
+ );
+ testFile(
'extensions/setext_headers_with_ids.unit',
blockSyntaxes: [const SetextHeaderWithIdSyntax()],
);
@@ -28,8 +36,8 @@
blockSyntaxes: [const TableSyntax()],
);
testFile(
- 'extensions/fenced_blockquotes.unit',
- blockSyntaxes: [const FencedBlockquoteSyntax()],
+ 'extensions/unordered_list_with_checkboxes.unit',
+ blockSyntaxes: [const UnorderedListWithCheckboxSyntax()],
);
// Inline syntax extensions
@@ -46,8 +54,8 @@
inlineSyntaxes: [StrikethroughSyntax()],
);
- await testDirectory('common_mark');
- await testDirectory('gfm', extensionSet: ExtensionSet.gitHubFlavored);
+ testDirectory('common_mark');
+ testDirectory('gfm');
group('Corner cases', () {
validateCore('Incorrect Links', '''
diff --git a/pkgs/markdown/test/util.dart b/pkgs/markdown/test/util.dart
index ad73c0c..fba598d 100644
--- a/pkgs/markdown/test/util.dart
+++ b/pkgs/markdown/test/util.dart
@@ -2,41 +2,63 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:isolate';
-
import 'package:io/ansi.dart' as ansi;
import 'package:markdown/markdown.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
+
import '../tool/expected_output.dart';
/// Runs tests defined in "*.unit" files inside directory [name].
-Future<void> testDirectory(String name, {ExtensionSet? extensionSet}) async {
- await for (final dataCase in dataCasesUnder(testDirectory: name)) {
+void testDirectory(String name, {ExtensionSet? extensionSet}) {
+ for (final dataCase in dataCasesUnder(testDirectory: name)) {
final description =
'${dataCase.directory}/${dataCase.file}.unit ${dataCase.description}';
+
+ final inlineSyntaxes = <InlineSyntax>[];
+ final blockSyntaxes = <BlockSyntax>[];
+
+ if (dataCase.file.endsWith('_extension')) {
+ final extension = dataCase.file.substring(
+ 0,
+ dataCase.file.lastIndexOf('_extension'),
+ );
+ switch (extension) {
+ case 'autolinks':
+ inlineSyntaxes.add(AutolinkExtensionSyntax());
+ break;
+ case 'strikethrough':
+ inlineSyntaxes.add(StrikethroughSyntax());
+ break;
+ case 'tables':
+ blockSyntaxes.add(const TableSyntax());
+ break;
+ case 'disallowed_raw_html':
+ // TODO(Zhiguang): https://github.com/dart-lang/markdown/pull/447
+ break;
+ default:
+ throw UnimplementedError('Unimplemented extension "$extension"');
+ }
+ }
+
validateCore(
description,
dataCase.input,
dataCase.expectedOutput,
extensionSet: extensionSet,
+ inlineSyntaxes: inlineSyntaxes,
+ blockSyntaxes: blockSyntaxes,
);
}
}
-Future<String> get markdownPackageRoot async {
- final packageUri = Uri.parse('package:markdown/markdown.dart');
- final isolateUri = await Isolate.resolvePackageUri(packageUri);
- return p.dirname(p.dirname(isolateUri!.toFilePath()));
-}
-
void testFile(
String file, {
Iterable<BlockSyntax> blockSyntaxes = const [],
Iterable<InlineSyntax> inlineSyntaxes = const [],
-}) async {
- final directory = p.join(await markdownPackageRoot, 'test');
- for (final dataCase in dataCasesInFile(path: p.join(directory, file))) {
+}) {
+ for (final dataCase
+ in dataCasesInFile(path: p.join(p.current, 'test', file))) {
final description =
'${dataCase.directory}/${dataCase.file}.unit ${dataCase.description}';
validateCore(
diff --git a/pkgs/markdown/test/version_test.dart b/pkgs/markdown/test/version_test.dart
index 14763d3..4397ad1 100644
--- a/pkgs/markdown/test/version_test.dart
+++ b/pkgs/markdown/test/version_test.dart
@@ -8,12 +8,9 @@
import 'package:test/test.dart';
import 'package:yaml/yaml.dart';
-import 'util.dart';
-
void main() {
test('check versions', () async {
- final packageRoot = await markdownPackageRoot;
- final binary = p.normalize(p.join(packageRoot, 'bin', 'markdown.dart'));
+ final binary = p.join(p.current, 'bin', 'markdown.dart');
final dartBin = Platform.executable;
final result = Process.runSync(dartBin, [binary, '--version']);
expect(
@@ -26,7 +23,7 @@
final binVersion = (result.stdout as String).trim();
- final pubspecFile = p.normalize(p.join(packageRoot, 'pubspec.yaml'));
+ final pubspecFile = p.join(p.current, 'pubspec.yaml');
final pubspecContent =
loadYaml(File(pubspecFile).readAsStringSync()) as YamlMap;
diff --git a/pkgs/markdown/tool/case_folding.txt b/pkgs/markdown/tool/case_folding.txt
new file mode 100644
index 0000000..932ace2
--- /dev/null
+++ b/pkgs/markdown/tool/case_folding.txt
@@ -0,0 +1,1624 @@
+# CaseFolding-14.0.0.txt
+# Date: 2021-03-08, 19:35:41 GMT
+# © 2021 Unicode®, Inc.
+# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Case Folding Properties
+#
+# This file is a supplement to the UnicodeData file.
+# It provides a case folding mapping generated from the Unicode Character Database.
+# If all characters are mapped according to the full mapping below, then
+# case differences (according to UnicodeData.txt and SpecialCasing.txt)
+# are eliminated.
+#
+# The data supports both implementations that require simple case foldings
+# (where string lengths don't change), and implementations that allow full case folding
+# (where string lengths may grow). Note that where they can be supported, the
+# full case foldings are superior: for example, they allow "MASSE" and "Maße" to match.
+#
+# All code points not listed in this file map to themselves.
+#
+# NOTE: case folding does not preserve normalization formats!
+#
+# For information on case folding, including how to have case folding
+# preserve normalization formats, see Section 3.13 Default Case Algorithms in
+# The Unicode Standard.
+#
+# ================================================================================
+# Format
+# ================================================================================
+# The entries in this file are in the following machine-readable format:
+#
+# <code>; <status>; <mapping>; # <name>
+#
+# The status field is:
+# C: common case folding, common mappings shared by both simple and full mappings.
+# F: full case folding, mappings that cause strings to grow in length. Multiple characters are separated by spaces.
+# S: simple case folding, mappings to single characters where different from F.
+# T: special case for uppercase I and dotted uppercase I
+# - For non-Turkic languages, this mapping is normally not used.
+# - For Turkic languages (tr, az), this mapping can be used instead of the normal mapping for these characters.
+# Note that the Turkic mappings do not maintain canonical equivalence without additional processing.
+# See the discussions of case mapping in the Unicode Standard for more information.
+#
+# Usage:
+# A. To do a simple case folding, use the mappings with status C + S.
+# B. To do a full case folding, use the mappings with status C + F.
+#
+# The mappings with status T can be used or omitted depending on the desired case-folding
+# behavior. (The default option is to exclude them.)
+#
+# =================================================================
+
+# Property: Case_Folding
+
+# All code points not explicitly listed for Case_Folding
+# have the value C for the status field, and the code point itself for the mapping field.
+
+# =================================================================
+0041; C; 0061; # LATIN CAPITAL LETTER A
+0042; C; 0062; # LATIN CAPITAL LETTER B
+0043; C; 0063; # LATIN CAPITAL LETTER C
+0044; C; 0064; # LATIN CAPITAL LETTER D
+0045; C; 0065; # LATIN CAPITAL LETTER E
+0046; C; 0066; # LATIN CAPITAL LETTER F
+0047; C; 0067; # LATIN CAPITAL LETTER G
+0048; C; 0068; # LATIN CAPITAL LETTER H
+0049; C; 0069; # LATIN CAPITAL LETTER I
+0049; T; 0131; # LATIN CAPITAL LETTER I
+004A; C; 006A; # LATIN CAPITAL LETTER J
+004B; C; 006B; # LATIN CAPITAL LETTER K
+004C; C; 006C; # LATIN CAPITAL LETTER L
+004D; C; 006D; # LATIN CAPITAL LETTER M
+004E; C; 006E; # LATIN CAPITAL LETTER N
+004F; C; 006F; # LATIN CAPITAL LETTER O
+0050; C; 0070; # LATIN CAPITAL LETTER P
+0051; C; 0071; # LATIN CAPITAL LETTER Q
+0052; C; 0072; # LATIN CAPITAL LETTER R
+0053; C; 0073; # LATIN CAPITAL LETTER S
+0054; C; 0074; # LATIN CAPITAL LETTER T
+0055; C; 0075; # LATIN CAPITAL LETTER U
+0056; C; 0076; # LATIN CAPITAL LETTER V
+0057; C; 0077; # LATIN CAPITAL LETTER W
+0058; C; 0078; # LATIN CAPITAL LETTER X
+0059; C; 0079; # LATIN CAPITAL LETTER Y
+005A; C; 007A; # LATIN CAPITAL LETTER Z
+00B5; C; 03BC; # MICRO SIGN
+00C0; C; 00E0; # LATIN CAPITAL LETTER A WITH GRAVE
+00C1; C; 00E1; # LATIN CAPITAL LETTER A WITH ACUTE
+00C2; C; 00E2; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+00C3; C; 00E3; # LATIN CAPITAL LETTER A WITH TILDE
+00C4; C; 00E4; # LATIN CAPITAL LETTER A WITH DIAERESIS
+00C5; C; 00E5; # LATIN CAPITAL LETTER A WITH RING ABOVE
+00C6; C; 00E6; # LATIN CAPITAL LETTER AE
+00C7; C; 00E7; # LATIN CAPITAL LETTER C WITH CEDILLA
+00C8; C; 00E8; # LATIN CAPITAL LETTER E WITH GRAVE
+00C9; C; 00E9; # LATIN CAPITAL LETTER E WITH ACUTE
+00CA; C; 00EA; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+00CB; C; 00EB; # LATIN CAPITAL LETTER E WITH DIAERESIS
+00CC; C; 00EC; # LATIN CAPITAL LETTER I WITH GRAVE
+00CD; C; 00ED; # LATIN CAPITAL LETTER I WITH ACUTE
+00CE; C; 00EE; # LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+00CF; C; 00EF; # LATIN CAPITAL LETTER I WITH DIAERESIS
+00D0; C; 00F0; # LATIN CAPITAL LETTER ETH
+00D1; C; 00F1; # LATIN CAPITAL LETTER N WITH TILDE
+00D2; C; 00F2; # LATIN CAPITAL LETTER O WITH GRAVE
+00D3; C; 00F3; # LATIN CAPITAL LETTER O WITH ACUTE
+00D4; C; 00F4; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+00D5; C; 00F5; # LATIN CAPITAL LETTER O WITH TILDE
+00D6; C; 00F6; # LATIN CAPITAL LETTER O WITH DIAERESIS
+00D8; C; 00F8; # LATIN CAPITAL LETTER O WITH STROKE
+00D9; C; 00F9; # LATIN CAPITAL LETTER U WITH GRAVE
+00DA; C; 00FA; # LATIN CAPITAL LETTER U WITH ACUTE
+00DB; C; 00FB; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+00DC; C; 00FC; # LATIN CAPITAL LETTER U WITH DIAERESIS
+00DD; C; 00FD; # LATIN CAPITAL LETTER Y WITH ACUTE
+00DE; C; 00FE; # LATIN CAPITAL LETTER THORN
+00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S
+0100; C; 0101; # LATIN CAPITAL LETTER A WITH MACRON
+0102; C; 0103; # LATIN CAPITAL LETTER A WITH BREVE
+0104; C; 0105; # LATIN CAPITAL LETTER A WITH OGONEK
+0106; C; 0107; # LATIN CAPITAL LETTER C WITH ACUTE
+0108; C; 0109; # LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+010A; C; 010B; # LATIN CAPITAL LETTER C WITH DOT ABOVE
+010C; C; 010D; # LATIN CAPITAL LETTER C WITH CARON
+010E; C; 010F; # LATIN CAPITAL LETTER D WITH CARON
+0110; C; 0111; # LATIN CAPITAL LETTER D WITH STROKE
+0112; C; 0113; # LATIN CAPITAL LETTER E WITH MACRON
+0114; C; 0115; # LATIN CAPITAL LETTER E WITH BREVE
+0116; C; 0117; # LATIN CAPITAL LETTER E WITH DOT ABOVE
+0118; C; 0119; # LATIN CAPITAL LETTER E WITH OGONEK
+011A; C; 011B; # LATIN CAPITAL LETTER E WITH CARON
+011C; C; 011D; # LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+011E; C; 011F; # LATIN CAPITAL LETTER G WITH BREVE
+0120; C; 0121; # LATIN CAPITAL LETTER G WITH DOT ABOVE
+0122; C; 0123; # LATIN CAPITAL LETTER G WITH CEDILLA
+0124; C; 0125; # LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+0126; C; 0127; # LATIN CAPITAL LETTER H WITH STROKE
+0128; C; 0129; # LATIN CAPITAL LETTER I WITH TILDE
+012A; C; 012B; # LATIN CAPITAL LETTER I WITH MACRON
+012C; C; 012D; # LATIN CAPITAL LETTER I WITH BREVE
+012E; C; 012F; # LATIN CAPITAL LETTER I WITH OGONEK
+0130; F; 0069 0307; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0130; T; 0069; # LATIN CAPITAL LETTER I WITH DOT ABOVE
+0132; C; 0133; # LATIN CAPITAL LIGATURE IJ
+0134; C; 0135; # LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+0136; C; 0137; # LATIN CAPITAL LETTER K WITH CEDILLA
+0139; C; 013A; # LATIN CAPITAL LETTER L WITH ACUTE
+013B; C; 013C; # LATIN CAPITAL LETTER L WITH CEDILLA
+013D; C; 013E; # LATIN CAPITAL LETTER L WITH CARON
+013F; C; 0140; # LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0141; C; 0142; # LATIN CAPITAL LETTER L WITH STROKE
+0143; C; 0144; # LATIN CAPITAL LETTER N WITH ACUTE
+0145; C; 0146; # LATIN CAPITAL LETTER N WITH CEDILLA
+0147; C; 0148; # LATIN CAPITAL LETTER N WITH CARON
+0149; F; 02BC 006E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+014A; C; 014B; # LATIN CAPITAL LETTER ENG
+014C; C; 014D; # LATIN CAPITAL LETTER O WITH MACRON
+014E; C; 014F; # LATIN CAPITAL LETTER O WITH BREVE
+0150; C; 0151; # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0152; C; 0153; # LATIN CAPITAL LIGATURE OE
+0154; C; 0155; # LATIN CAPITAL LETTER R WITH ACUTE
+0156; C; 0157; # LATIN CAPITAL LETTER R WITH CEDILLA
+0158; C; 0159; # LATIN CAPITAL LETTER R WITH CARON
+015A; C; 015B; # LATIN CAPITAL LETTER S WITH ACUTE
+015C; C; 015D; # LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+015E; C; 015F; # LATIN CAPITAL LETTER S WITH CEDILLA
+0160; C; 0161; # LATIN CAPITAL LETTER S WITH CARON
+0162; C; 0163; # LATIN CAPITAL LETTER T WITH CEDILLA
+0164; C; 0165; # LATIN CAPITAL LETTER T WITH CARON
+0166; C; 0167; # LATIN CAPITAL LETTER T WITH STROKE
+0168; C; 0169; # LATIN CAPITAL LETTER U WITH TILDE
+016A; C; 016B; # LATIN CAPITAL LETTER U WITH MACRON
+016C; C; 016D; # LATIN CAPITAL LETTER U WITH BREVE
+016E; C; 016F; # LATIN CAPITAL LETTER U WITH RING ABOVE
+0170; C; 0171; # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0172; C; 0173; # LATIN CAPITAL LETTER U WITH OGONEK
+0174; C; 0175; # LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+0176; C; 0177; # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+0178; C; 00FF; # LATIN CAPITAL LETTER Y WITH DIAERESIS
+0179; C; 017A; # LATIN CAPITAL LETTER Z WITH ACUTE
+017B; C; 017C; # LATIN CAPITAL LETTER Z WITH DOT ABOVE
+017D; C; 017E; # LATIN CAPITAL LETTER Z WITH CARON
+017F; C; 0073; # LATIN SMALL LETTER LONG S
+0181; C; 0253; # LATIN CAPITAL LETTER B WITH HOOK
+0182; C; 0183; # LATIN CAPITAL LETTER B WITH TOPBAR
+0184; C; 0185; # LATIN CAPITAL LETTER TONE SIX
+0186; C; 0254; # LATIN CAPITAL LETTER OPEN O
+0187; C; 0188; # LATIN CAPITAL LETTER C WITH HOOK
+0189; C; 0256; # LATIN CAPITAL LETTER AFRICAN D
+018A; C; 0257; # LATIN CAPITAL LETTER D WITH HOOK
+018B; C; 018C; # LATIN CAPITAL LETTER D WITH TOPBAR
+018E; C; 01DD; # LATIN CAPITAL LETTER REVERSED E
+018F; C; 0259; # LATIN CAPITAL LETTER SCHWA
+0190; C; 025B; # LATIN CAPITAL LETTER OPEN E
+0191; C; 0192; # LATIN CAPITAL LETTER F WITH HOOK
+0193; C; 0260; # LATIN CAPITAL LETTER G WITH HOOK
+0194; C; 0263; # LATIN CAPITAL LETTER GAMMA
+0196; C; 0269; # LATIN CAPITAL LETTER IOTA
+0197; C; 0268; # LATIN CAPITAL LETTER I WITH STROKE
+0198; C; 0199; # LATIN CAPITAL LETTER K WITH HOOK
+019C; C; 026F; # LATIN CAPITAL LETTER TURNED M
+019D; C; 0272; # LATIN CAPITAL LETTER N WITH LEFT HOOK
+019F; C; 0275; # LATIN CAPITAL LETTER O WITH MIDDLE TILDE
+01A0; C; 01A1; # LATIN CAPITAL LETTER O WITH HORN
+01A2; C; 01A3; # LATIN CAPITAL LETTER OI
+01A4; C; 01A5; # LATIN CAPITAL LETTER P WITH HOOK
+01A6; C; 0280; # LATIN LETTER YR
+01A7; C; 01A8; # LATIN CAPITAL LETTER TONE TWO
+01A9; C; 0283; # LATIN CAPITAL LETTER ESH
+01AC; C; 01AD; # LATIN CAPITAL LETTER T WITH HOOK
+01AE; C; 0288; # LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
+01AF; C; 01B0; # LATIN CAPITAL LETTER U WITH HORN
+01B1; C; 028A; # LATIN CAPITAL LETTER UPSILON
+01B2; C; 028B; # LATIN CAPITAL LETTER V WITH HOOK
+01B3; C; 01B4; # LATIN CAPITAL LETTER Y WITH HOOK
+01B5; C; 01B6; # LATIN CAPITAL LETTER Z WITH STROKE
+01B7; C; 0292; # LATIN CAPITAL LETTER EZH
+01B8; C; 01B9; # LATIN CAPITAL LETTER EZH REVERSED
+01BC; C; 01BD; # LATIN CAPITAL LETTER TONE FIVE
+01C4; C; 01C6; # LATIN CAPITAL LETTER DZ WITH CARON
+01C5; C; 01C6; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+01C7; C; 01C9; # LATIN CAPITAL LETTER LJ
+01C8; C; 01C9; # LATIN CAPITAL LETTER L WITH SMALL LETTER J
+01CA; C; 01CC; # LATIN CAPITAL LETTER NJ
+01CB; C; 01CC; # LATIN CAPITAL LETTER N WITH SMALL LETTER J
+01CD; C; 01CE; # LATIN CAPITAL LETTER A WITH CARON
+01CF; C; 01D0; # LATIN CAPITAL LETTER I WITH CARON
+01D1; C; 01D2; # LATIN CAPITAL LETTER O WITH CARON
+01D3; C; 01D4; # LATIN CAPITAL LETTER U WITH CARON
+01D5; C; 01D6; # LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+01D7; C; 01D8; # LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+01D9; C; 01DA; # LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+01DB; C; 01DC; # LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+01DE; C; 01DF; # LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
+01E0; C; 01E1; # LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
+01E2; C; 01E3; # LATIN CAPITAL LETTER AE WITH MACRON
+01E4; C; 01E5; # LATIN CAPITAL LETTER G WITH STROKE
+01E6; C; 01E7; # LATIN CAPITAL LETTER G WITH CARON
+01E8; C; 01E9; # LATIN CAPITAL LETTER K WITH CARON
+01EA; C; 01EB; # LATIN CAPITAL LETTER O WITH OGONEK
+01EC; C; 01ED; # LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
+01EE; C; 01EF; # LATIN CAPITAL LETTER EZH WITH CARON
+01F0; F; 006A 030C; # LATIN SMALL LETTER J WITH CARON
+01F1; C; 01F3; # LATIN CAPITAL LETTER DZ
+01F2; C; 01F3; # LATIN CAPITAL LETTER D WITH SMALL LETTER Z
+01F4; C; 01F5; # LATIN CAPITAL LETTER G WITH ACUTE
+01F6; C; 0195; # LATIN CAPITAL LETTER HWAIR
+01F7; C; 01BF; # LATIN CAPITAL LETTER WYNN
+01F8; C; 01F9; # LATIN CAPITAL LETTER N WITH GRAVE
+01FA; C; 01FB; # LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
+01FC; C; 01FD; # LATIN CAPITAL LETTER AE WITH ACUTE
+01FE; C; 01FF; # LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
+0200; C; 0201; # LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
+0202; C; 0203; # LATIN CAPITAL LETTER A WITH INVERTED BREVE
+0204; C; 0205; # LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
+0206; C; 0207; # LATIN CAPITAL LETTER E WITH INVERTED BREVE
+0208; C; 0209; # LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
+020A; C; 020B; # LATIN CAPITAL LETTER I WITH INVERTED BREVE
+020C; C; 020D; # LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
+020E; C; 020F; # LATIN CAPITAL LETTER O WITH INVERTED BREVE
+0210; C; 0211; # LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
+0212; C; 0213; # LATIN CAPITAL LETTER R WITH INVERTED BREVE
+0214; C; 0215; # LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
+0216; C; 0217; # LATIN CAPITAL LETTER U WITH INVERTED BREVE
+0218; C; 0219; # LATIN CAPITAL LETTER S WITH COMMA BELOW
+021A; C; 021B; # LATIN CAPITAL LETTER T WITH COMMA BELOW
+021C; C; 021D; # LATIN CAPITAL LETTER YOGH
+021E; C; 021F; # LATIN CAPITAL LETTER H WITH CARON
+0220; C; 019E; # LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
+0222; C; 0223; # LATIN CAPITAL LETTER OU
+0224; C; 0225; # LATIN CAPITAL LETTER Z WITH HOOK
+0226; C; 0227; # LATIN CAPITAL LETTER A WITH DOT ABOVE
+0228; C; 0229; # LATIN CAPITAL LETTER E WITH CEDILLA
+022A; C; 022B; # LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
+022C; C; 022D; # LATIN CAPITAL LETTER O WITH TILDE AND MACRON
+022E; C; 022F; # LATIN CAPITAL LETTER O WITH DOT ABOVE
+0230; C; 0231; # LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
+0232; C; 0233; # LATIN CAPITAL LETTER Y WITH MACRON
+023A; C; 2C65; # LATIN CAPITAL LETTER A WITH STROKE
+023B; C; 023C; # LATIN CAPITAL LETTER C WITH STROKE
+023D; C; 019A; # LATIN CAPITAL LETTER L WITH BAR
+023E; C; 2C66; # LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
+0241; C; 0242; # LATIN CAPITAL LETTER GLOTTAL STOP
+0243; C; 0180; # LATIN CAPITAL LETTER B WITH STROKE
+0244; C; 0289; # LATIN CAPITAL LETTER U BAR
+0245; C; 028C; # LATIN CAPITAL LETTER TURNED V
+0246; C; 0247; # LATIN CAPITAL LETTER E WITH STROKE
+0248; C; 0249; # LATIN CAPITAL LETTER J WITH STROKE
+024A; C; 024B; # LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
+024C; C; 024D; # LATIN CAPITAL LETTER R WITH STROKE
+024E; C; 024F; # LATIN CAPITAL LETTER Y WITH STROKE
+0345; C; 03B9; # COMBINING GREEK YPOGEGRAMMENI
+0370; C; 0371; # GREEK CAPITAL LETTER HETA
+0372; C; 0373; # GREEK CAPITAL LETTER ARCHAIC SAMPI
+0376; C; 0377; # GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
+037F; C; 03F3; # GREEK CAPITAL LETTER YOT
+0386; C; 03AC; # GREEK CAPITAL LETTER ALPHA WITH TONOS
+0388; C; 03AD; # GREEK CAPITAL LETTER EPSILON WITH TONOS
+0389; C; 03AE; # GREEK CAPITAL LETTER ETA WITH TONOS
+038A; C; 03AF; # GREEK CAPITAL LETTER IOTA WITH TONOS
+038C; C; 03CC; # GREEK CAPITAL LETTER OMICRON WITH TONOS
+038E; C; 03CD; # GREEK CAPITAL LETTER UPSILON WITH TONOS
+038F; C; 03CE; # GREEK CAPITAL LETTER OMEGA WITH TONOS
+0390; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0391; C; 03B1; # GREEK CAPITAL LETTER ALPHA
+0392; C; 03B2; # GREEK CAPITAL LETTER BETA
+0393; C; 03B3; # GREEK CAPITAL LETTER GAMMA
+0394; C; 03B4; # GREEK CAPITAL LETTER DELTA
+0395; C; 03B5; # GREEK CAPITAL LETTER EPSILON
+0396; C; 03B6; # GREEK CAPITAL LETTER ZETA
+0397; C; 03B7; # GREEK CAPITAL LETTER ETA
+0398; C; 03B8; # GREEK CAPITAL LETTER THETA
+0399; C; 03B9; # GREEK CAPITAL LETTER IOTA
+039A; C; 03BA; # GREEK CAPITAL LETTER KAPPA
+039B; C; 03BB; # GREEK CAPITAL LETTER LAMDA
+039C; C; 03BC; # GREEK CAPITAL LETTER MU
+039D; C; 03BD; # GREEK CAPITAL LETTER NU
+039E; C; 03BE; # GREEK CAPITAL LETTER XI
+039F; C; 03BF; # GREEK CAPITAL LETTER OMICRON
+03A0; C; 03C0; # GREEK CAPITAL LETTER PI
+03A1; C; 03C1; # GREEK CAPITAL LETTER RHO
+03A3; C; 03C3; # GREEK CAPITAL LETTER SIGMA
+03A4; C; 03C4; # GREEK CAPITAL LETTER TAU
+03A5; C; 03C5; # GREEK CAPITAL LETTER UPSILON
+03A6; C; 03C6; # GREEK CAPITAL LETTER PHI
+03A7; C; 03C7; # GREEK CAPITAL LETTER CHI
+03A8; C; 03C8; # GREEK CAPITAL LETTER PSI
+03A9; C; 03C9; # GREEK CAPITAL LETTER OMEGA
+03AA; C; 03CA; # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+03AB; C; 03CB; # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+03B0; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+03C2; C; 03C3; # GREEK SMALL LETTER FINAL SIGMA
+03CF; C; 03D7; # GREEK CAPITAL KAI SYMBOL
+03D0; C; 03B2; # GREEK BETA SYMBOL
+03D1; C; 03B8; # GREEK THETA SYMBOL
+03D5; C; 03C6; # GREEK PHI SYMBOL
+03D6; C; 03C0; # GREEK PI SYMBOL
+03D8; C; 03D9; # GREEK LETTER ARCHAIC KOPPA
+03DA; C; 03DB; # GREEK LETTER STIGMA
+03DC; C; 03DD; # GREEK LETTER DIGAMMA
+03DE; C; 03DF; # GREEK LETTER KOPPA
+03E0; C; 03E1; # GREEK LETTER SAMPI
+03E2; C; 03E3; # COPTIC CAPITAL LETTER SHEI
+03E4; C; 03E5; # COPTIC CAPITAL LETTER FEI
+03E6; C; 03E7; # COPTIC CAPITAL LETTER KHEI
+03E8; C; 03E9; # COPTIC CAPITAL LETTER HORI
+03EA; C; 03EB; # COPTIC CAPITAL LETTER GANGIA
+03EC; C; 03ED; # COPTIC CAPITAL LETTER SHIMA
+03EE; C; 03EF; # COPTIC CAPITAL LETTER DEI
+03F0; C; 03BA; # GREEK KAPPA SYMBOL
+03F1; C; 03C1; # GREEK RHO SYMBOL
+03F4; C; 03B8; # GREEK CAPITAL THETA SYMBOL
+03F5; C; 03B5; # GREEK LUNATE EPSILON SYMBOL
+03F7; C; 03F8; # GREEK CAPITAL LETTER SHO
+03F9; C; 03F2; # GREEK CAPITAL LUNATE SIGMA SYMBOL
+03FA; C; 03FB; # GREEK CAPITAL LETTER SAN
+03FD; C; 037B; # GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
+03FE; C; 037C; # GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
+03FF; C; 037D; # GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+0400; C; 0450; # CYRILLIC CAPITAL LETTER IE WITH GRAVE
+0401; C; 0451; # CYRILLIC CAPITAL LETTER IO
+0402; C; 0452; # CYRILLIC CAPITAL LETTER DJE
+0403; C; 0453; # CYRILLIC CAPITAL LETTER GJE
+0404; C; 0454; # CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0405; C; 0455; # CYRILLIC CAPITAL LETTER DZE
+0406; C; 0456; # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0407; C; 0457; # CYRILLIC CAPITAL LETTER YI
+0408; C; 0458; # CYRILLIC CAPITAL LETTER JE
+0409; C; 0459; # CYRILLIC CAPITAL LETTER LJE
+040A; C; 045A; # CYRILLIC CAPITAL LETTER NJE
+040B; C; 045B; # CYRILLIC CAPITAL LETTER TSHE
+040C; C; 045C; # CYRILLIC CAPITAL LETTER KJE
+040D; C; 045D; # CYRILLIC CAPITAL LETTER I WITH GRAVE
+040E; C; 045E; # CYRILLIC CAPITAL LETTER SHORT U
+040F; C; 045F; # CYRILLIC CAPITAL LETTER DZHE
+0410; C; 0430; # CYRILLIC CAPITAL LETTER A
+0411; C; 0431; # CYRILLIC CAPITAL LETTER BE
+0412; C; 0432; # CYRILLIC CAPITAL LETTER VE
+0413; C; 0433; # CYRILLIC CAPITAL LETTER GHE
+0414; C; 0434; # CYRILLIC CAPITAL LETTER DE
+0415; C; 0435; # CYRILLIC CAPITAL LETTER IE
+0416; C; 0436; # CYRILLIC CAPITAL LETTER ZHE
+0417; C; 0437; # CYRILLIC CAPITAL LETTER ZE
+0418; C; 0438; # CYRILLIC CAPITAL LETTER I
+0419; C; 0439; # CYRILLIC CAPITAL LETTER SHORT I
+041A; C; 043A; # CYRILLIC CAPITAL LETTER KA
+041B; C; 043B; # CYRILLIC CAPITAL LETTER EL
+041C; C; 043C; # CYRILLIC CAPITAL LETTER EM
+041D; C; 043D; # CYRILLIC CAPITAL LETTER EN
+041E; C; 043E; # CYRILLIC CAPITAL LETTER O
+041F; C; 043F; # CYRILLIC CAPITAL LETTER PE
+0420; C; 0440; # CYRILLIC CAPITAL LETTER ER
+0421; C; 0441; # CYRILLIC CAPITAL LETTER ES
+0422; C; 0442; # CYRILLIC CAPITAL LETTER TE
+0423; C; 0443; # CYRILLIC CAPITAL LETTER U
+0424; C; 0444; # CYRILLIC CAPITAL LETTER EF
+0425; C; 0445; # CYRILLIC CAPITAL LETTER HA
+0426; C; 0446; # CYRILLIC CAPITAL LETTER TSE
+0427; C; 0447; # CYRILLIC CAPITAL LETTER CHE
+0428; C; 0448; # CYRILLIC CAPITAL LETTER SHA
+0429; C; 0449; # CYRILLIC CAPITAL LETTER SHCHA
+042A; C; 044A; # CYRILLIC CAPITAL LETTER HARD SIGN
+042B; C; 044B; # CYRILLIC CAPITAL LETTER YERU
+042C; C; 044C; # CYRILLIC CAPITAL LETTER SOFT SIGN
+042D; C; 044D; # CYRILLIC CAPITAL LETTER E
+042E; C; 044E; # CYRILLIC CAPITAL LETTER YU
+042F; C; 044F; # CYRILLIC CAPITAL LETTER YA
+0460; C; 0461; # CYRILLIC CAPITAL LETTER OMEGA
+0462; C; 0463; # CYRILLIC CAPITAL LETTER YAT
+0464; C; 0465; # CYRILLIC CAPITAL LETTER IOTIFIED E
+0466; C; 0467; # CYRILLIC CAPITAL LETTER LITTLE YUS
+0468; C; 0469; # CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
+046A; C; 046B; # CYRILLIC CAPITAL LETTER BIG YUS
+046C; C; 046D; # CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
+046E; C; 046F; # CYRILLIC CAPITAL LETTER KSI
+0470; C; 0471; # CYRILLIC CAPITAL LETTER PSI
+0472; C; 0473; # CYRILLIC CAPITAL LETTER FITA
+0474; C; 0475; # CYRILLIC CAPITAL LETTER IZHITSA
+0476; C; 0477; # CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+0478; C; 0479; # CYRILLIC CAPITAL LETTER UK
+047A; C; 047B; # CYRILLIC CAPITAL LETTER ROUND OMEGA
+047C; C; 047D; # CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
+047E; C; 047F; # CYRILLIC CAPITAL LETTER OT
+0480; C; 0481; # CYRILLIC CAPITAL LETTER KOPPA
+048A; C; 048B; # CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
+048C; C; 048D; # CYRILLIC CAPITAL LETTER SEMISOFT SIGN
+048E; C; 048F; # CYRILLIC CAPITAL LETTER ER WITH TICK
+0490; C; 0491; # CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+0492; C; 0493; # CYRILLIC CAPITAL LETTER GHE WITH STROKE
+0494; C; 0495; # CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
+0496; C; 0497; # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
+0498; C; 0499; # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
+049A; C; 049B; # CYRILLIC CAPITAL LETTER KA WITH DESCENDER
+049C; C; 049D; # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
+049E; C; 049F; # CYRILLIC CAPITAL LETTER KA WITH STROKE
+04A0; C; 04A1; # CYRILLIC CAPITAL LETTER BASHKIR KA
+04A2; C; 04A3; # CYRILLIC CAPITAL LETTER EN WITH DESCENDER
+04A4; C; 04A5; # CYRILLIC CAPITAL LIGATURE EN GHE
+04A6; C; 04A7; # CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
+04A8; C; 04A9; # CYRILLIC CAPITAL LETTER ABKHASIAN HA
+04AA; C; 04AB; # CYRILLIC CAPITAL LETTER ES WITH DESCENDER
+04AC; C; 04AD; # CYRILLIC CAPITAL LETTER TE WITH DESCENDER
+04AE; C; 04AF; # CYRILLIC CAPITAL LETTER STRAIGHT U
+04B0; C; 04B1; # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
+04B2; C; 04B3; # CYRILLIC CAPITAL LETTER HA WITH DESCENDER
+04B4; C; 04B5; # CYRILLIC CAPITAL LIGATURE TE TSE
+04B6; C; 04B7; # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
+04B8; C; 04B9; # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
+04BA; C; 04BB; # CYRILLIC CAPITAL LETTER SHHA
+04BC; C; 04BD; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE
+04BE; C; 04BF; # CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
+04C0; C; 04CF; # CYRILLIC LETTER PALOCHKA
+04C1; C; 04C2; # CYRILLIC CAPITAL LETTER ZHE WITH BREVE
+04C3; C; 04C4; # CYRILLIC CAPITAL LETTER KA WITH HOOK
+04C5; C; 04C6; # CYRILLIC CAPITAL LETTER EL WITH TAIL
+04C7; C; 04C8; # CYRILLIC CAPITAL LETTER EN WITH HOOK
+04C9; C; 04CA; # CYRILLIC CAPITAL LETTER EN WITH TAIL
+04CB; C; 04CC; # CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
+04CD; C; 04CE; # CYRILLIC CAPITAL LETTER EM WITH TAIL
+04D0; C; 04D1; # CYRILLIC CAPITAL LETTER A WITH BREVE
+04D2; C; 04D3; # CYRILLIC CAPITAL LETTER A WITH DIAERESIS
+04D4; C; 04D5; # CYRILLIC CAPITAL LIGATURE A IE
+04D6; C; 04D7; # CYRILLIC CAPITAL LETTER IE WITH BREVE
+04D8; C; 04D9; # CYRILLIC CAPITAL LETTER SCHWA
+04DA; C; 04DB; # CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
+04DC; C; 04DD; # CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
+04DE; C; 04DF; # CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
+04E0; C; 04E1; # CYRILLIC CAPITAL LETTER ABKHASIAN DZE
+04E2; C; 04E3; # CYRILLIC CAPITAL LETTER I WITH MACRON
+04E4; C; 04E5; # CYRILLIC CAPITAL LETTER I WITH DIAERESIS
+04E6; C; 04E7; # CYRILLIC CAPITAL LETTER O WITH DIAERESIS
+04E8; C; 04E9; # CYRILLIC CAPITAL LETTER BARRED O
+04EA; C; 04EB; # CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
+04EC; C; 04ED; # CYRILLIC CAPITAL LETTER E WITH DIAERESIS
+04EE; C; 04EF; # CYRILLIC CAPITAL LETTER U WITH MACRON
+04F0; C; 04F1; # CYRILLIC CAPITAL LETTER U WITH DIAERESIS
+04F2; C; 04F3; # CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
+04F4; C; 04F5; # CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
+04F6; C; 04F7; # CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
+04F8; C; 04F9; # CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
+04FA; C; 04FB; # CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
+04FC; C; 04FD; # CYRILLIC CAPITAL LETTER HA WITH HOOK
+04FE; C; 04FF; # CYRILLIC CAPITAL LETTER HA WITH STROKE
+0500; C; 0501; # CYRILLIC CAPITAL LETTER KOMI DE
+0502; C; 0503; # CYRILLIC CAPITAL LETTER KOMI DJE
+0504; C; 0505; # CYRILLIC CAPITAL LETTER KOMI ZJE
+0506; C; 0507; # CYRILLIC CAPITAL LETTER KOMI DZJE
+0508; C; 0509; # CYRILLIC CAPITAL LETTER KOMI LJE
+050A; C; 050B; # CYRILLIC CAPITAL LETTER KOMI NJE
+050C; C; 050D; # CYRILLIC CAPITAL LETTER KOMI SJE
+050E; C; 050F; # CYRILLIC CAPITAL LETTER KOMI TJE
+0510; C; 0511; # CYRILLIC CAPITAL LETTER REVERSED ZE
+0512; C; 0513; # CYRILLIC CAPITAL LETTER EL WITH HOOK
+0514; C; 0515; # CYRILLIC CAPITAL LETTER LHA
+0516; C; 0517; # CYRILLIC CAPITAL LETTER RHA
+0518; C; 0519; # CYRILLIC CAPITAL LETTER YAE
+051A; C; 051B; # CYRILLIC CAPITAL LETTER QA
+051C; C; 051D; # CYRILLIC CAPITAL LETTER WE
+051E; C; 051F; # CYRILLIC CAPITAL LETTER ALEUT KA
+0520; C; 0521; # CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
+0522; C; 0523; # CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
+0524; C; 0525; # CYRILLIC CAPITAL LETTER PE WITH DESCENDER
+0526; C; 0527; # CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER
+0528; C; 0529; # CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK
+052A; C; 052B; # CYRILLIC CAPITAL LETTER DZZHE
+052C; C; 052D; # CYRILLIC CAPITAL LETTER DCHE
+052E; C; 052F; # CYRILLIC CAPITAL LETTER EL WITH DESCENDER
+0531; C; 0561; # ARMENIAN CAPITAL LETTER AYB
+0532; C; 0562; # ARMENIAN CAPITAL LETTER BEN
+0533; C; 0563; # ARMENIAN CAPITAL LETTER GIM
+0534; C; 0564; # ARMENIAN CAPITAL LETTER DA
+0535; C; 0565; # ARMENIAN CAPITAL LETTER ECH
+0536; C; 0566; # ARMENIAN CAPITAL LETTER ZA
+0537; C; 0567; # ARMENIAN CAPITAL LETTER EH
+0538; C; 0568; # ARMENIAN CAPITAL LETTER ET
+0539; C; 0569; # ARMENIAN CAPITAL LETTER TO
+053A; C; 056A; # ARMENIAN CAPITAL LETTER ZHE
+053B; C; 056B; # ARMENIAN CAPITAL LETTER INI
+053C; C; 056C; # ARMENIAN CAPITAL LETTER LIWN
+053D; C; 056D; # ARMENIAN CAPITAL LETTER XEH
+053E; C; 056E; # ARMENIAN CAPITAL LETTER CA
+053F; C; 056F; # ARMENIAN CAPITAL LETTER KEN
+0540; C; 0570; # ARMENIAN CAPITAL LETTER HO
+0541; C; 0571; # ARMENIAN CAPITAL LETTER JA
+0542; C; 0572; # ARMENIAN CAPITAL LETTER GHAD
+0543; C; 0573; # ARMENIAN CAPITAL LETTER CHEH
+0544; C; 0574; # ARMENIAN CAPITAL LETTER MEN
+0545; C; 0575; # ARMENIAN CAPITAL LETTER YI
+0546; C; 0576; # ARMENIAN CAPITAL LETTER NOW
+0547; C; 0577; # ARMENIAN CAPITAL LETTER SHA
+0548; C; 0578; # ARMENIAN CAPITAL LETTER VO
+0549; C; 0579; # ARMENIAN CAPITAL LETTER CHA
+054A; C; 057A; # ARMENIAN CAPITAL LETTER PEH
+054B; C; 057B; # ARMENIAN CAPITAL LETTER JHEH
+054C; C; 057C; # ARMENIAN CAPITAL LETTER RA
+054D; C; 057D; # ARMENIAN CAPITAL LETTER SEH
+054E; C; 057E; # ARMENIAN CAPITAL LETTER VEW
+054F; C; 057F; # ARMENIAN CAPITAL LETTER TIWN
+0550; C; 0580; # ARMENIAN CAPITAL LETTER REH
+0551; C; 0581; # ARMENIAN CAPITAL LETTER CO
+0552; C; 0582; # ARMENIAN CAPITAL LETTER YIWN
+0553; C; 0583; # ARMENIAN CAPITAL LETTER PIWR
+0554; C; 0584; # ARMENIAN CAPITAL LETTER KEH
+0555; C; 0585; # ARMENIAN CAPITAL LETTER OH
+0556; C; 0586; # ARMENIAN CAPITAL LETTER FEH
+0587; F; 0565 0582; # ARMENIAN SMALL LIGATURE ECH YIWN
+10A0; C; 2D00; # GEORGIAN CAPITAL LETTER AN
+10A1; C; 2D01; # GEORGIAN CAPITAL LETTER BAN
+10A2; C; 2D02; # GEORGIAN CAPITAL LETTER GAN
+10A3; C; 2D03; # GEORGIAN CAPITAL LETTER DON
+10A4; C; 2D04; # GEORGIAN CAPITAL LETTER EN
+10A5; C; 2D05; # GEORGIAN CAPITAL LETTER VIN
+10A6; C; 2D06; # GEORGIAN CAPITAL LETTER ZEN
+10A7; C; 2D07; # GEORGIAN CAPITAL LETTER TAN
+10A8; C; 2D08; # GEORGIAN CAPITAL LETTER IN
+10A9; C; 2D09; # GEORGIAN CAPITAL LETTER KAN
+10AA; C; 2D0A; # GEORGIAN CAPITAL LETTER LAS
+10AB; C; 2D0B; # GEORGIAN CAPITAL LETTER MAN
+10AC; C; 2D0C; # GEORGIAN CAPITAL LETTER NAR
+10AD; C; 2D0D; # GEORGIAN CAPITAL LETTER ON
+10AE; C; 2D0E; # GEORGIAN CAPITAL LETTER PAR
+10AF; C; 2D0F; # GEORGIAN CAPITAL LETTER ZHAR
+10B0; C; 2D10; # GEORGIAN CAPITAL LETTER RAE
+10B1; C; 2D11; # GEORGIAN CAPITAL LETTER SAN
+10B2; C; 2D12; # GEORGIAN CAPITAL LETTER TAR
+10B3; C; 2D13; # GEORGIAN CAPITAL LETTER UN
+10B4; C; 2D14; # GEORGIAN CAPITAL LETTER PHAR
+10B5; C; 2D15; # GEORGIAN CAPITAL LETTER KHAR
+10B6; C; 2D16; # GEORGIAN CAPITAL LETTER GHAN
+10B7; C; 2D17; # GEORGIAN CAPITAL LETTER QAR
+10B8; C; 2D18; # GEORGIAN CAPITAL LETTER SHIN
+10B9; C; 2D19; # GEORGIAN CAPITAL LETTER CHIN
+10BA; C; 2D1A; # GEORGIAN CAPITAL LETTER CAN
+10BB; C; 2D1B; # GEORGIAN CAPITAL LETTER JIL
+10BC; C; 2D1C; # GEORGIAN CAPITAL LETTER CIL
+10BD; C; 2D1D; # GEORGIAN CAPITAL LETTER CHAR
+10BE; C; 2D1E; # GEORGIAN CAPITAL LETTER XAN
+10BF; C; 2D1F; # GEORGIAN CAPITAL LETTER JHAN
+10C0; C; 2D20; # GEORGIAN CAPITAL LETTER HAE
+10C1; C; 2D21; # GEORGIAN CAPITAL LETTER HE
+10C2; C; 2D22; # GEORGIAN CAPITAL LETTER HIE
+10C3; C; 2D23; # GEORGIAN CAPITAL LETTER WE
+10C4; C; 2D24; # GEORGIAN CAPITAL LETTER HAR
+10C5; C; 2D25; # GEORGIAN CAPITAL LETTER HOE
+10C7; C; 2D27; # GEORGIAN CAPITAL LETTER YN
+10CD; C; 2D2D; # GEORGIAN CAPITAL LETTER AEN
+13F8; C; 13F0; # CHEROKEE SMALL LETTER YE
+13F9; C; 13F1; # CHEROKEE SMALL LETTER YI
+13FA; C; 13F2; # CHEROKEE SMALL LETTER YO
+13FB; C; 13F3; # CHEROKEE SMALL LETTER YU
+13FC; C; 13F4; # CHEROKEE SMALL LETTER YV
+13FD; C; 13F5; # CHEROKEE SMALL LETTER MV
+1C80; C; 0432; # CYRILLIC SMALL LETTER ROUNDED VE
+1C81; C; 0434; # CYRILLIC SMALL LETTER LONG-LEGGED DE
+1C82; C; 043E; # CYRILLIC SMALL LETTER NARROW O
+1C83; C; 0441; # CYRILLIC SMALL LETTER WIDE ES
+1C84; C; 0442; # CYRILLIC SMALL LETTER TALL TE
+1C85; C; 0442; # CYRILLIC SMALL LETTER THREE-LEGGED TE
+1C86; C; 044A; # CYRILLIC SMALL LETTER TALL HARD SIGN
+1C87; C; 0463; # CYRILLIC SMALL LETTER TALL YAT
+1C88; C; A64B; # CYRILLIC SMALL LETTER UNBLENDED UK
+1C90; C; 10D0; # GEORGIAN MTAVRULI CAPITAL LETTER AN
+1C91; C; 10D1; # GEORGIAN MTAVRULI CAPITAL LETTER BAN
+1C92; C; 10D2; # GEORGIAN MTAVRULI CAPITAL LETTER GAN
+1C93; C; 10D3; # GEORGIAN MTAVRULI CAPITAL LETTER DON
+1C94; C; 10D4; # GEORGIAN MTAVRULI CAPITAL LETTER EN
+1C95; C; 10D5; # GEORGIAN MTAVRULI CAPITAL LETTER VIN
+1C96; C; 10D6; # GEORGIAN MTAVRULI CAPITAL LETTER ZEN
+1C97; C; 10D7; # GEORGIAN MTAVRULI CAPITAL LETTER TAN
+1C98; C; 10D8; # GEORGIAN MTAVRULI CAPITAL LETTER IN
+1C99; C; 10D9; # GEORGIAN MTAVRULI CAPITAL LETTER KAN
+1C9A; C; 10DA; # GEORGIAN MTAVRULI CAPITAL LETTER LAS
+1C9B; C; 10DB; # GEORGIAN MTAVRULI CAPITAL LETTER MAN
+1C9C; C; 10DC; # GEORGIAN MTAVRULI CAPITAL LETTER NAR
+1C9D; C; 10DD; # GEORGIAN MTAVRULI CAPITAL LETTER ON
+1C9E; C; 10DE; # GEORGIAN MTAVRULI CAPITAL LETTER PAR
+1C9F; C; 10DF; # GEORGIAN MTAVRULI CAPITAL LETTER ZHAR
+1CA0; C; 10E0; # GEORGIAN MTAVRULI CAPITAL LETTER RAE
+1CA1; C; 10E1; # GEORGIAN MTAVRULI CAPITAL LETTER SAN
+1CA2; C; 10E2; # GEORGIAN MTAVRULI CAPITAL LETTER TAR
+1CA3; C; 10E3; # GEORGIAN MTAVRULI CAPITAL LETTER UN
+1CA4; C; 10E4; # GEORGIAN MTAVRULI CAPITAL LETTER PHAR
+1CA5; C; 10E5; # GEORGIAN MTAVRULI CAPITAL LETTER KHAR
+1CA6; C; 10E6; # GEORGIAN MTAVRULI CAPITAL LETTER GHAN
+1CA7; C; 10E7; # GEORGIAN MTAVRULI CAPITAL LETTER QAR
+1CA8; C; 10E8; # GEORGIAN MTAVRULI CAPITAL LETTER SHIN
+1CA9; C; 10E9; # GEORGIAN MTAVRULI CAPITAL LETTER CHIN
+1CAA; C; 10EA; # GEORGIAN MTAVRULI CAPITAL LETTER CAN
+1CAB; C; 10EB; # GEORGIAN MTAVRULI CAPITAL LETTER JIL
+1CAC; C; 10EC; # GEORGIAN MTAVRULI CAPITAL LETTER CIL
+1CAD; C; 10ED; # GEORGIAN MTAVRULI CAPITAL LETTER CHAR
+1CAE; C; 10EE; # GEORGIAN MTAVRULI CAPITAL LETTER XAN
+1CAF; C; 10EF; # GEORGIAN MTAVRULI CAPITAL LETTER JHAN
+1CB0; C; 10F0; # GEORGIAN MTAVRULI CAPITAL LETTER HAE
+1CB1; C; 10F1; # GEORGIAN MTAVRULI CAPITAL LETTER HE
+1CB2; C; 10F2; # GEORGIAN MTAVRULI CAPITAL LETTER HIE
+1CB3; C; 10F3; # GEORGIAN MTAVRULI CAPITAL LETTER WE
+1CB4; C; 10F4; # GEORGIAN MTAVRULI CAPITAL LETTER HAR
+1CB5; C; 10F5; # GEORGIAN MTAVRULI CAPITAL LETTER HOE
+1CB6; C; 10F6; # GEORGIAN MTAVRULI CAPITAL LETTER FI
+1CB7; C; 10F7; # GEORGIAN MTAVRULI CAPITAL LETTER YN
+1CB8; C; 10F8; # GEORGIAN MTAVRULI CAPITAL LETTER ELIFI
+1CB9; C; 10F9; # GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN
+1CBA; C; 10FA; # GEORGIAN MTAVRULI CAPITAL LETTER AIN
+1CBD; C; 10FD; # GEORGIAN MTAVRULI CAPITAL LETTER AEN
+1CBE; C; 10FE; # GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN
+1CBF; C; 10FF; # GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN
+1E00; C; 1E01; # LATIN CAPITAL LETTER A WITH RING BELOW
+1E02; C; 1E03; # LATIN CAPITAL LETTER B WITH DOT ABOVE
+1E04; C; 1E05; # LATIN CAPITAL LETTER B WITH DOT BELOW
+1E06; C; 1E07; # LATIN CAPITAL LETTER B WITH LINE BELOW
+1E08; C; 1E09; # LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
+1E0A; C; 1E0B; # LATIN CAPITAL LETTER D WITH DOT ABOVE
+1E0C; C; 1E0D; # LATIN CAPITAL LETTER D WITH DOT BELOW
+1E0E; C; 1E0F; # LATIN CAPITAL LETTER D WITH LINE BELOW
+1E10; C; 1E11; # LATIN CAPITAL LETTER D WITH CEDILLA
+1E12; C; 1E13; # LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
+1E14; C; 1E15; # LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+1E16; C; 1E17; # LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
+1E18; C; 1E19; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
+1E1A; C; 1E1B; # LATIN CAPITAL LETTER E WITH TILDE BELOW
+1E1C; C; 1E1D; # LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
+1E1E; C; 1E1F; # LATIN CAPITAL LETTER F WITH DOT ABOVE
+1E20; C; 1E21; # LATIN CAPITAL LETTER G WITH MACRON
+1E22; C; 1E23; # LATIN CAPITAL LETTER H WITH DOT ABOVE
+1E24; C; 1E25; # LATIN CAPITAL LETTER H WITH DOT BELOW
+1E26; C; 1E27; # LATIN CAPITAL LETTER H WITH DIAERESIS
+1E28; C; 1E29; # LATIN CAPITAL LETTER H WITH CEDILLA
+1E2A; C; 1E2B; # LATIN CAPITAL LETTER H WITH BREVE BELOW
+1E2C; C; 1E2D; # LATIN CAPITAL LETTER I WITH TILDE BELOW
+1E2E; C; 1E2F; # LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
+1E30; C; 1E31; # LATIN CAPITAL LETTER K WITH ACUTE
+1E32; C; 1E33; # LATIN CAPITAL LETTER K WITH DOT BELOW
+1E34; C; 1E35; # LATIN CAPITAL LETTER K WITH LINE BELOW
+1E36; C; 1E37; # LATIN CAPITAL LETTER L WITH DOT BELOW
+1E38; C; 1E39; # LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
+1E3A; C; 1E3B; # LATIN CAPITAL LETTER L WITH LINE BELOW
+1E3C; C; 1E3D; # LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
+1E3E; C; 1E3F; # LATIN CAPITAL LETTER M WITH ACUTE
+1E40; C; 1E41; # LATIN CAPITAL LETTER M WITH DOT ABOVE
+1E42; C; 1E43; # LATIN CAPITAL LETTER M WITH DOT BELOW
+1E44; C; 1E45; # LATIN CAPITAL LETTER N WITH DOT ABOVE
+1E46; C; 1E47; # LATIN CAPITAL LETTER N WITH DOT BELOW
+1E48; C; 1E49; # LATIN CAPITAL LETTER N WITH LINE BELOW
+1E4A; C; 1E4B; # LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
+1E4C; C; 1E4D; # LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
+1E4E; C; 1E4F; # LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
+1E50; C; 1E51; # LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
+1E52; C; 1E53; # LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
+1E54; C; 1E55; # LATIN CAPITAL LETTER P WITH ACUTE
+1E56; C; 1E57; # LATIN CAPITAL LETTER P WITH DOT ABOVE
+1E58; C; 1E59; # LATIN CAPITAL LETTER R WITH DOT ABOVE
+1E5A; C; 1E5B; # LATIN CAPITAL LETTER R WITH DOT BELOW
+1E5C; C; 1E5D; # LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
+1E5E; C; 1E5F; # LATIN CAPITAL LETTER R WITH LINE BELOW
+1E60; C; 1E61; # LATIN CAPITAL LETTER S WITH DOT ABOVE
+1E62; C; 1E63; # LATIN CAPITAL LETTER S WITH DOT BELOW
+1E64; C; 1E65; # LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
+1E66; C; 1E67; # LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
+1E68; C; 1E69; # LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
+1E6A; C; 1E6B; # LATIN CAPITAL LETTER T WITH DOT ABOVE
+1E6C; C; 1E6D; # LATIN CAPITAL LETTER T WITH DOT BELOW
+1E6E; C; 1E6F; # LATIN CAPITAL LETTER T WITH LINE BELOW
+1E70; C; 1E71; # LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
+1E72; C; 1E73; # LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
+1E74; C; 1E75; # LATIN CAPITAL LETTER U WITH TILDE BELOW
+1E76; C; 1E77; # LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
+1E78; C; 1E79; # LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
+1E7A; C; 1E7B; # LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
+1E7C; C; 1E7D; # LATIN CAPITAL LETTER V WITH TILDE
+1E7E; C; 1E7F; # LATIN CAPITAL LETTER V WITH DOT BELOW
+1E80; C; 1E81; # LATIN CAPITAL LETTER W WITH GRAVE
+1E82; C; 1E83; # LATIN CAPITAL LETTER W WITH ACUTE
+1E84; C; 1E85; # LATIN CAPITAL LETTER W WITH DIAERESIS
+1E86; C; 1E87; # LATIN CAPITAL LETTER W WITH DOT ABOVE
+1E88; C; 1E89; # LATIN CAPITAL LETTER W WITH DOT BELOW
+1E8A; C; 1E8B; # LATIN CAPITAL LETTER X WITH DOT ABOVE
+1E8C; C; 1E8D; # LATIN CAPITAL LETTER X WITH DIAERESIS
+1E8E; C; 1E8F; # LATIN CAPITAL LETTER Y WITH DOT ABOVE
+1E90; C; 1E91; # LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
+1E92; C; 1E93; # LATIN CAPITAL LETTER Z WITH DOT BELOW
+1E94; C; 1E95; # LATIN CAPITAL LETTER Z WITH LINE BELOW
+1E96; F; 0068 0331; # LATIN SMALL LETTER H WITH LINE BELOW
+1E97; F; 0074 0308; # LATIN SMALL LETTER T WITH DIAERESIS
+1E98; F; 0077 030A; # LATIN SMALL LETTER W WITH RING ABOVE
+1E99; F; 0079 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
+1E9A; F; 0061 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
+1E9B; C; 1E61; # LATIN SMALL LETTER LONG S WITH DOT ABOVE
+1E9E; F; 0073 0073; # LATIN CAPITAL LETTER SHARP S
+1E9E; S; 00DF; # LATIN CAPITAL LETTER SHARP S
+1EA0; C; 1EA1; # LATIN CAPITAL LETTER A WITH DOT BELOW
+1EA2; C; 1EA3; # LATIN CAPITAL LETTER A WITH HOOK ABOVE
+1EA4; C; 1EA5; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
+1EA6; C; 1EA7; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
+1EA8; C; 1EA9; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+1EAA; C; 1EAB; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
+1EAC; C; 1EAD; # LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+1EAE; C; 1EAF; # LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
+1EB0; C; 1EB1; # LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
+1EB2; C; 1EB3; # LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
+1EB4; C; 1EB5; # LATIN CAPITAL LETTER A WITH BREVE AND TILDE
+1EB6; C; 1EB7; # LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
+1EB8; C; 1EB9; # LATIN CAPITAL LETTER E WITH DOT BELOW
+1EBA; C; 1EBB; # LATIN CAPITAL LETTER E WITH HOOK ABOVE
+1EBC; C; 1EBD; # LATIN CAPITAL LETTER E WITH TILDE
+1EBE; C; 1EBF; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
+1EC0; C; 1EC1; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
+1EC2; C; 1EC3; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+1EC4; C; 1EC5; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
+1EC6; C; 1EC7; # LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+1EC8; C; 1EC9; # LATIN CAPITAL LETTER I WITH HOOK ABOVE
+1ECA; C; 1ECB; # LATIN CAPITAL LETTER I WITH DOT BELOW
+1ECC; C; 1ECD; # LATIN CAPITAL LETTER O WITH DOT BELOW
+1ECE; C; 1ECF; # LATIN CAPITAL LETTER O WITH HOOK ABOVE
+1ED0; C; 1ED1; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+1ED2; C; 1ED3; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
+1ED4; C; 1ED5; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+1ED6; C; 1ED7; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
+1ED8; C; 1ED9; # LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+1EDA; C; 1EDB; # LATIN CAPITAL LETTER O WITH HORN AND ACUTE
+1EDC; C; 1EDD; # LATIN CAPITAL LETTER O WITH HORN AND GRAVE
+1EDE; C; 1EDF; # LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
+1EE0; C; 1EE1; # LATIN CAPITAL LETTER O WITH HORN AND TILDE
+1EE2; C; 1EE3; # LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
+1EE4; C; 1EE5; # LATIN CAPITAL LETTER U WITH DOT BELOW
+1EE6; C; 1EE7; # LATIN CAPITAL LETTER U WITH HOOK ABOVE
+1EE8; C; 1EE9; # LATIN CAPITAL LETTER U WITH HORN AND ACUTE
+1EEA; C; 1EEB; # LATIN CAPITAL LETTER U WITH HORN AND GRAVE
+1EEC; C; 1EED; # LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
+1EEE; C; 1EEF; # LATIN CAPITAL LETTER U WITH HORN AND TILDE
+1EF0; C; 1EF1; # LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
+1EF2; C; 1EF3; # LATIN CAPITAL LETTER Y WITH GRAVE
+1EF4; C; 1EF5; # LATIN CAPITAL LETTER Y WITH DOT BELOW
+1EF6; C; 1EF7; # LATIN CAPITAL LETTER Y WITH HOOK ABOVE
+1EF8; C; 1EF9; # LATIN CAPITAL LETTER Y WITH TILDE
+1EFA; C; 1EFB; # LATIN CAPITAL LETTER MIDDLE-WELSH LL
+1EFC; C; 1EFD; # LATIN CAPITAL LETTER MIDDLE-WELSH V
+1EFE; C; 1EFF; # LATIN CAPITAL LETTER Y WITH LOOP
+1F08; C; 1F00; # GREEK CAPITAL LETTER ALPHA WITH PSILI
+1F09; C; 1F01; # GREEK CAPITAL LETTER ALPHA WITH DASIA
+1F0A; C; 1F02; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+1F0B; C; 1F03; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+1F0C; C; 1F04; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+1F0D; C; 1F05; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+1F0E; C; 1F06; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+1F0F; C; 1F07; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+1F18; C; 1F10; # GREEK CAPITAL LETTER EPSILON WITH PSILI
+1F19; C; 1F11; # GREEK CAPITAL LETTER EPSILON WITH DASIA
+1F1A; C; 1F12; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+1F1B; C; 1F13; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+1F1C; C; 1F14; # GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+1F1D; C; 1F15; # GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+1F28; C; 1F20; # GREEK CAPITAL LETTER ETA WITH PSILI
+1F29; C; 1F21; # GREEK CAPITAL LETTER ETA WITH DASIA
+1F2A; C; 1F22; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+1F2B; C; 1F23; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+1F2C; C; 1F24; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+1F2D; C; 1F25; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+1F2E; C; 1F26; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+1F2F; C; 1F27; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+1F38; C; 1F30; # GREEK CAPITAL LETTER IOTA WITH PSILI
+1F39; C; 1F31; # GREEK CAPITAL LETTER IOTA WITH DASIA
+1F3A; C; 1F32; # GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+1F3B; C; 1F33; # GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+1F3C; C; 1F34; # GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+1F3D; C; 1F35; # GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+1F3E; C; 1F36; # GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+1F3F; C; 1F37; # GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+1F48; C; 1F40; # GREEK CAPITAL LETTER OMICRON WITH PSILI
+1F49; C; 1F41; # GREEK CAPITAL LETTER OMICRON WITH DASIA
+1F4A; C; 1F42; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+1F4B; C; 1F43; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+1F4C; C; 1F44; # GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+1F4D; C; 1F45; # GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+1F50; F; 03C5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
+1F52; F; 03C5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
+1F54; F; 03C5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
+1F56; F; 03C5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
+1F59; C; 1F51; # GREEK CAPITAL LETTER UPSILON WITH DASIA
+1F5B; C; 1F53; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+1F5D; C; 1F55; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+1F5F; C; 1F57; # GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+1F68; C; 1F60; # GREEK CAPITAL LETTER OMEGA WITH PSILI
+1F69; C; 1F61; # GREEK CAPITAL LETTER OMEGA WITH DASIA
+1F6A; C; 1F62; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+1F6B; C; 1F63; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+1F6C; C; 1F64; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+1F6D; C; 1F65; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+1F6E; C; 1F66; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+1F6F; C; 1F67; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+1F80; F; 1F00 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+1F81; F; 1F01 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+1F82; F; 1F02 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F83; F; 1F03 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F84; F; 1F04 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F85; F; 1F05 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F86; F; 1F06 03B9; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F87; F; 1F07 03B9; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F88; F; 1F00 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+1F88; S; 1F80; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+1F89; F; 1F01 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+1F89; S; 1F81; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+1F8A; F; 1F02 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F8A; S; 1F82; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F8B; F; 1F03 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F8B; S; 1F83; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F8C; F; 1F04 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F8C; S; 1F84; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F8D; F; 1F05 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F8D; S; 1F85; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F8E; F; 1F06 03B9; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F8E; S; 1F86; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F8F; F; 1F07 03B9; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F8F; S; 1F87; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F90; F; 1F20 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+1F91; F; 1F21 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+1F92; F; 1F22 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1F93; F; 1F23 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1F94; F; 1F24 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1F95; F; 1F25 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1F96; F; 1F26 03B9; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1F97; F; 1F27 03B9; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1F98; F; 1F20 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+1F98; S; 1F90; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+1F99; F; 1F21 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+1F99; S; 1F91; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+1F9A; F; 1F22 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F9A; S; 1F92; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1F9B; F; 1F23 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F9B; S; 1F93; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1F9C; F; 1F24 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F9C; S; 1F94; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1F9D; F; 1F25 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F9D; S; 1F95; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1F9E; F; 1F26 03B9; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F9E; S; 1F96; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1F9F; F; 1F27 03B9; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1F9F; S; 1F97; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FA0; F; 1F60 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+1FA1; F; 1F61 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+1FA2; F; 1F62 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+1FA3; F; 1F63 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+1FA4; F; 1F64 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+1FA5; F; 1F65 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+1FA6; F; 1F66 03B9; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+1FA7; F; 1F67 03B9; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+1FA8; F; 1F60 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+1FA8; S; 1FA0; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+1FA9; F; 1F61 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+1FA9; S; 1FA1; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+1FAA; F; 1F62 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1FAA; S; 1FA2; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+1FAB; F; 1F63 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1FAB; S; 1FA3; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+1FAC; F; 1F64 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1FAC; S; 1FA4; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+1FAD; F; 1F65 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1FAD; S; 1FA5; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+1FAE; F; 1F66 03B9; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1FAE; S; 1FA6; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+1FAF; F; 1F67 03B9; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FAF; S; 1FA7; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+1FB2; F; 1F70 03B9; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
+1FB3; F; 03B1 03B9; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+1FB4; F; 03AC 03B9; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+1FB6; F; 03B1 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+1FB7; F; 03B1 0342 03B9; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FB8; C; 1FB0; # GREEK CAPITAL LETTER ALPHA WITH VRACHY
+1FB9; C; 1FB1; # GREEK CAPITAL LETTER ALPHA WITH MACRON
+1FBA; C; 1F70; # GREEK CAPITAL LETTER ALPHA WITH VARIA
+1FBB; C; 1F71; # GREEK CAPITAL LETTER ALPHA WITH OXIA
+1FBC; F; 03B1 03B9; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FBC; S; 1FB3; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+1FBE; C; 03B9; # GREEK PROSGEGRAMMENI
+1FC2; F; 1F74 03B9; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
+1FC3; F; 03B7 03B9; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+1FC4; F; 03AE 03B9; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+1FC6; F; 03B7 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
+1FC7; F; 03B7 0342 03B9; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FC8; C; 1F72; # GREEK CAPITAL LETTER EPSILON WITH VARIA
+1FC9; C; 1F73; # GREEK CAPITAL LETTER EPSILON WITH OXIA
+1FCA; C; 1F74; # GREEK CAPITAL LETTER ETA WITH VARIA
+1FCB; C; 1F75; # GREEK CAPITAL LETTER ETA WITH OXIA
+1FCC; F; 03B7 03B9; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FCC; S; 1FC3; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+1FD2; F; 03B9 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+1FD3; F; 03B9 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+1FD6; F; 03B9 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
+1FD7; F; 03B9 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+1FD8; C; 1FD0; # GREEK CAPITAL LETTER IOTA WITH VRACHY
+1FD9; C; 1FD1; # GREEK CAPITAL LETTER IOTA WITH MACRON
+1FDA; C; 1F76; # GREEK CAPITAL LETTER IOTA WITH VARIA
+1FDB; C; 1F77; # GREEK CAPITAL LETTER IOTA WITH OXIA
+1FE2; F; 03C5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+1FE3; F; 03C5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+1FE4; F; 03C1 0313; # GREEK SMALL LETTER RHO WITH PSILI
+1FE6; F; 03C5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
+1FE7; F; 03C5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+1FE8; C; 1FE0; # GREEK CAPITAL LETTER UPSILON WITH VRACHY
+1FE9; C; 1FE1; # GREEK CAPITAL LETTER UPSILON WITH MACRON
+1FEA; C; 1F7A; # GREEK CAPITAL LETTER UPSILON WITH VARIA
+1FEB; C; 1F7B; # GREEK CAPITAL LETTER UPSILON WITH OXIA
+1FEC; C; 1FE5; # GREEK CAPITAL LETTER RHO WITH DASIA
+1FF2; F; 1F7C 03B9; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
+1FF3; F; 03C9 03B9; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+1FF4; F; 03CE 03B9; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+1FF6; F; 03C9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+1FF7; F; 03C9 0342 03B9; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
+1FF8; C; 1F78; # GREEK CAPITAL LETTER OMICRON WITH VARIA
+1FF9; C; 1F79; # GREEK CAPITAL LETTER OMICRON WITH OXIA
+1FFA; C; 1F7C; # GREEK CAPITAL LETTER OMEGA WITH VARIA
+1FFB; C; 1F7D; # GREEK CAPITAL LETTER OMEGA WITH OXIA
+1FFC; F; 03C9 03B9; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+1FFC; S; 1FF3; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+2126; C; 03C9; # OHM SIGN
+212A; C; 006B; # KELVIN SIGN
+212B; C; 00E5; # ANGSTROM SIGN
+2132; C; 214E; # TURNED CAPITAL F
+2160; C; 2170; # ROMAN NUMERAL ONE
+2161; C; 2171; # ROMAN NUMERAL TWO
+2162; C; 2172; # ROMAN NUMERAL THREE
+2163; C; 2173; # ROMAN NUMERAL FOUR
+2164; C; 2174; # ROMAN NUMERAL FIVE
+2165; C; 2175; # ROMAN NUMERAL SIX
+2166; C; 2176; # ROMAN NUMERAL SEVEN
+2167; C; 2177; # ROMAN NUMERAL EIGHT
+2168; C; 2178; # ROMAN NUMERAL NINE
+2169; C; 2179; # ROMAN NUMERAL TEN
+216A; C; 217A; # ROMAN NUMERAL ELEVEN
+216B; C; 217B; # ROMAN NUMERAL TWELVE
+216C; C; 217C; # ROMAN NUMERAL FIFTY
+216D; C; 217D; # ROMAN NUMERAL ONE HUNDRED
+216E; C; 217E; # ROMAN NUMERAL FIVE HUNDRED
+216F; C; 217F; # ROMAN NUMERAL ONE THOUSAND
+2183; C; 2184; # ROMAN NUMERAL REVERSED ONE HUNDRED
+24B6; C; 24D0; # CIRCLED LATIN CAPITAL LETTER A
+24B7; C; 24D1; # CIRCLED LATIN CAPITAL LETTER B
+24B8; C; 24D2; # CIRCLED LATIN CAPITAL LETTER C
+24B9; C; 24D3; # CIRCLED LATIN CAPITAL LETTER D
+24BA; C; 24D4; # CIRCLED LATIN CAPITAL LETTER E
+24BB; C; 24D5; # CIRCLED LATIN CAPITAL LETTER F
+24BC; C; 24D6; # CIRCLED LATIN CAPITAL LETTER G
+24BD; C; 24D7; # CIRCLED LATIN CAPITAL LETTER H
+24BE; C; 24D8; # CIRCLED LATIN CAPITAL LETTER I
+24BF; C; 24D9; # CIRCLED LATIN CAPITAL LETTER J
+24C0; C; 24DA; # CIRCLED LATIN CAPITAL LETTER K
+24C1; C; 24DB; # CIRCLED LATIN CAPITAL LETTER L
+24C2; C; 24DC; # CIRCLED LATIN CAPITAL LETTER M
+24C3; C; 24DD; # CIRCLED LATIN CAPITAL LETTER N
+24C4; C; 24DE; # CIRCLED LATIN CAPITAL LETTER O
+24C5; C; 24DF; # CIRCLED LATIN CAPITAL LETTER P
+24C6; C; 24E0; # CIRCLED LATIN CAPITAL LETTER Q
+24C7; C; 24E1; # CIRCLED LATIN CAPITAL LETTER R
+24C8; C; 24E2; # CIRCLED LATIN CAPITAL LETTER S
+24C9; C; 24E3; # CIRCLED LATIN CAPITAL LETTER T
+24CA; C; 24E4; # CIRCLED LATIN CAPITAL LETTER U
+24CB; C; 24E5; # CIRCLED LATIN CAPITAL LETTER V
+24CC; C; 24E6; # CIRCLED LATIN CAPITAL LETTER W
+24CD; C; 24E7; # CIRCLED LATIN CAPITAL LETTER X
+24CE; C; 24E8; # CIRCLED LATIN CAPITAL LETTER Y
+24CF; C; 24E9; # CIRCLED LATIN CAPITAL LETTER Z
+2C00; C; 2C30; # GLAGOLITIC CAPITAL LETTER AZU
+2C01; C; 2C31; # GLAGOLITIC CAPITAL LETTER BUKY
+2C02; C; 2C32; # GLAGOLITIC CAPITAL LETTER VEDE
+2C03; C; 2C33; # GLAGOLITIC CAPITAL LETTER GLAGOLI
+2C04; C; 2C34; # GLAGOLITIC CAPITAL LETTER DOBRO
+2C05; C; 2C35; # GLAGOLITIC CAPITAL LETTER YESTU
+2C06; C; 2C36; # GLAGOLITIC CAPITAL LETTER ZHIVETE
+2C07; C; 2C37; # GLAGOLITIC CAPITAL LETTER DZELO
+2C08; C; 2C38; # GLAGOLITIC CAPITAL LETTER ZEMLJA
+2C09; C; 2C39; # GLAGOLITIC CAPITAL LETTER IZHE
+2C0A; C; 2C3A; # GLAGOLITIC CAPITAL LETTER INITIAL IZHE
+2C0B; C; 2C3B; # GLAGOLITIC CAPITAL LETTER I
+2C0C; C; 2C3C; # GLAGOLITIC CAPITAL LETTER DJERVI
+2C0D; C; 2C3D; # GLAGOLITIC CAPITAL LETTER KAKO
+2C0E; C; 2C3E; # GLAGOLITIC CAPITAL LETTER LJUDIJE
+2C0F; C; 2C3F; # GLAGOLITIC CAPITAL LETTER MYSLITE
+2C10; C; 2C40; # GLAGOLITIC CAPITAL LETTER NASHI
+2C11; C; 2C41; # GLAGOLITIC CAPITAL LETTER ONU
+2C12; C; 2C42; # GLAGOLITIC CAPITAL LETTER POKOJI
+2C13; C; 2C43; # GLAGOLITIC CAPITAL LETTER RITSI
+2C14; C; 2C44; # GLAGOLITIC CAPITAL LETTER SLOVO
+2C15; C; 2C45; # GLAGOLITIC CAPITAL LETTER TVRIDO
+2C16; C; 2C46; # GLAGOLITIC CAPITAL LETTER UKU
+2C17; C; 2C47; # GLAGOLITIC CAPITAL LETTER FRITU
+2C18; C; 2C48; # GLAGOLITIC CAPITAL LETTER HERU
+2C19; C; 2C49; # GLAGOLITIC CAPITAL LETTER OTU
+2C1A; C; 2C4A; # GLAGOLITIC CAPITAL LETTER PE
+2C1B; C; 2C4B; # GLAGOLITIC CAPITAL LETTER SHTA
+2C1C; C; 2C4C; # GLAGOLITIC CAPITAL LETTER TSI
+2C1D; C; 2C4D; # GLAGOLITIC CAPITAL LETTER CHRIVI
+2C1E; C; 2C4E; # GLAGOLITIC CAPITAL LETTER SHA
+2C1F; C; 2C4F; # GLAGOLITIC CAPITAL LETTER YERU
+2C20; C; 2C50; # GLAGOLITIC CAPITAL LETTER YERI
+2C21; C; 2C51; # GLAGOLITIC CAPITAL LETTER YATI
+2C22; C; 2C52; # GLAGOLITIC CAPITAL LETTER SPIDERY HA
+2C23; C; 2C53; # GLAGOLITIC CAPITAL LETTER YU
+2C24; C; 2C54; # GLAGOLITIC CAPITAL LETTER SMALL YUS
+2C25; C; 2C55; # GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
+2C26; C; 2C56; # GLAGOLITIC CAPITAL LETTER YO
+2C27; C; 2C57; # GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
+2C28; C; 2C58; # GLAGOLITIC CAPITAL LETTER BIG YUS
+2C29; C; 2C59; # GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
+2C2A; C; 2C5A; # GLAGOLITIC CAPITAL LETTER FITA
+2C2B; C; 2C5B; # GLAGOLITIC CAPITAL LETTER IZHITSA
+2C2C; C; 2C5C; # GLAGOLITIC CAPITAL LETTER SHTAPIC
+2C2D; C; 2C5D; # GLAGOLITIC CAPITAL LETTER TROKUTASTI A
+2C2E; C; 2C5E; # GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
+2C2F; C; 2C5F; # GLAGOLITIC CAPITAL LETTER CAUDATE CHRIVI
+2C60; C; 2C61; # LATIN CAPITAL LETTER L WITH DOUBLE BAR
+2C62; C; 026B; # LATIN CAPITAL LETTER L WITH MIDDLE TILDE
+2C63; C; 1D7D; # LATIN CAPITAL LETTER P WITH STROKE
+2C64; C; 027D; # LATIN CAPITAL LETTER R WITH TAIL
+2C67; C; 2C68; # LATIN CAPITAL LETTER H WITH DESCENDER
+2C69; C; 2C6A; # LATIN CAPITAL LETTER K WITH DESCENDER
+2C6B; C; 2C6C; # LATIN CAPITAL LETTER Z WITH DESCENDER
+2C6D; C; 0251; # LATIN CAPITAL LETTER ALPHA
+2C6E; C; 0271; # LATIN CAPITAL LETTER M WITH HOOK
+2C6F; C; 0250; # LATIN CAPITAL LETTER TURNED A
+2C70; C; 0252; # LATIN CAPITAL LETTER TURNED ALPHA
+2C72; C; 2C73; # LATIN CAPITAL LETTER W WITH HOOK
+2C75; C; 2C76; # LATIN CAPITAL LETTER HALF H
+2C7E; C; 023F; # LATIN CAPITAL LETTER S WITH SWASH TAIL
+2C7F; C; 0240; # LATIN CAPITAL LETTER Z WITH SWASH TAIL
+2C80; C; 2C81; # COPTIC CAPITAL LETTER ALFA
+2C82; C; 2C83; # COPTIC CAPITAL LETTER VIDA
+2C84; C; 2C85; # COPTIC CAPITAL LETTER GAMMA
+2C86; C; 2C87; # COPTIC CAPITAL LETTER DALDA
+2C88; C; 2C89; # COPTIC CAPITAL LETTER EIE
+2C8A; C; 2C8B; # COPTIC CAPITAL LETTER SOU
+2C8C; C; 2C8D; # COPTIC CAPITAL LETTER ZATA
+2C8E; C; 2C8F; # COPTIC CAPITAL LETTER HATE
+2C90; C; 2C91; # COPTIC CAPITAL LETTER THETHE
+2C92; C; 2C93; # COPTIC CAPITAL LETTER IAUDA
+2C94; C; 2C95; # COPTIC CAPITAL LETTER KAPA
+2C96; C; 2C97; # COPTIC CAPITAL LETTER LAULA
+2C98; C; 2C99; # COPTIC CAPITAL LETTER MI
+2C9A; C; 2C9B; # COPTIC CAPITAL LETTER NI
+2C9C; C; 2C9D; # COPTIC CAPITAL LETTER KSI
+2C9E; C; 2C9F; # COPTIC CAPITAL LETTER O
+2CA0; C; 2CA1; # COPTIC CAPITAL LETTER PI
+2CA2; C; 2CA3; # COPTIC CAPITAL LETTER RO
+2CA4; C; 2CA5; # COPTIC CAPITAL LETTER SIMA
+2CA6; C; 2CA7; # COPTIC CAPITAL LETTER TAU
+2CA8; C; 2CA9; # COPTIC CAPITAL LETTER UA
+2CAA; C; 2CAB; # COPTIC CAPITAL LETTER FI
+2CAC; C; 2CAD; # COPTIC CAPITAL LETTER KHI
+2CAE; C; 2CAF; # COPTIC CAPITAL LETTER PSI
+2CB0; C; 2CB1; # COPTIC CAPITAL LETTER OOU
+2CB2; C; 2CB3; # COPTIC CAPITAL LETTER DIALECT-P ALEF
+2CB4; C; 2CB5; # COPTIC CAPITAL LETTER OLD COPTIC AIN
+2CB6; C; 2CB7; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
+2CB8; C; 2CB9; # COPTIC CAPITAL LETTER DIALECT-P KAPA
+2CBA; C; 2CBB; # COPTIC CAPITAL LETTER DIALECT-P NI
+2CBC; C; 2CBD; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
+2CBE; C; 2CBF; # COPTIC CAPITAL LETTER OLD COPTIC OOU
+2CC0; C; 2CC1; # COPTIC CAPITAL LETTER SAMPI
+2CC2; C; 2CC3; # COPTIC CAPITAL LETTER CROSSED SHEI
+2CC4; C; 2CC5; # COPTIC CAPITAL LETTER OLD COPTIC SHEI
+2CC6; C; 2CC7; # COPTIC CAPITAL LETTER OLD COPTIC ESH
+2CC8; C; 2CC9; # COPTIC CAPITAL LETTER AKHMIMIC KHEI
+2CCA; C; 2CCB; # COPTIC CAPITAL LETTER DIALECT-P HORI
+2CCC; C; 2CCD; # COPTIC CAPITAL LETTER OLD COPTIC HORI
+2CCE; C; 2CCF; # COPTIC CAPITAL LETTER OLD COPTIC HA
+2CD0; C; 2CD1; # COPTIC CAPITAL LETTER L-SHAPED HA
+2CD2; C; 2CD3; # COPTIC CAPITAL LETTER OLD COPTIC HEI
+2CD4; C; 2CD5; # COPTIC CAPITAL LETTER OLD COPTIC HAT
+2CD6; C; 2CD7; # COPTIC CAPITAL LETTER OLD COPTIC GANGIA
+2CD8; C; 2CD9; # COPTIC CAPITAL LETTER OLD COPTIC DJA
+2CDA; C; 2CDB; # COPTIC CAPITAL LETTER OLD COPTIC SHIMA
+2CDC; C; 2CDD; # COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
+2CDE; C; 2CDF; # COPTIC CAPITAL LETTER OLD NUBIAN NGI
+2CE0; C; 2CE1; # COPTIC CAPITAL LETTER OLD NUBIAN NYI
+2CE2; C; 2CE3; # COPTIC CAPITAL LETTER OLD NUBIAN WAU
+2CEB; C; 2CEC; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
+2CED; C; 2CEE; # COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
+2CF2; C; 2CF3; # COPTIC CAPITAL LETTER BOHAIRIC KHEI
+A640; C; A641; # CYRILLIC CAPITAL LETTER ZEMLYA
+A642; C; A643; # CYRILLIC CAPITAL LETTER DZELO
+A644; C; A645; # CYRILLIC CAPITAL LETTER REVERSED DZE
+A646; C; A647; # CYRILLIC CAPITAL LETTER IOTA
+A648; C; A649; # CYRILLIC CAPITAL LETTER DJERV
+A64A; C; A64B; # CYRILLIC CAPITAL LETTER MONOGRAPH UK
+A64C; C; A64D; # CYRILLIC CAPITAL LETTER BROAD OMEGA
+A64E; C; A64F; # CYRILLIC CAPITAL LETTER NEUTRAL YER
+A650; C; A651; # CYRILLIC CAPITAL LETTER YERU WITH BACK YER
+A652; C; A653; # CYRILLIC CAPITAL LETTER IOTIFIED YAT
+A654; C; A655; # CYRILLIC CAPITAL LETTER REVERSED YU
+A656; C; A657; # CYRILLIC CAPITAL LETTER IOTIFIED A
+A658; C; A659; # CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
+A65A; C; A65B; # CYRILLIC CAPITAL LETTER BLENDED YUS
+A65C; C; A65D; # CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
+A65E; C; A65F; # CYRILLIC CAPITAL LETTER YN
+A660; C; A661; # CYRILLIC CAPITAL LETTER REVERSED TSE
+A662; C; A663; # CYRILLIC CAPITAL LETTER SOFT DE
+A664; C; A665; # CYRILLIC CAPITAL LETTER SOFT EL
+A666; C; A667; # CYRILLIC CAPITAL LETTER SOFT EM
+A668; C; A669; # CYRILLIC CAPITAL LETTER MONOCULAR O
+A66A; C; A66B; # CYRILLIC CAPITAL LETTER BINOCULAR O
+A66C; C; A66D; # CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
+A680; C; A681; # CYRILLIC CAPITAL LETTER DWE
+A682; C; A683; # CYRILLIC CAPITAL LETTER DZWE
+A684; C; A685; # CYRILLIC CAPITAL LETTER ZHWE
+A686; C; A687; # CYRILLIC CAPITAL LETTER CCHE
+A688; C; A689; # CYRILLIC CAPITAL LETTER DZZE
+A68A; C; A68B; # CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
+A68C; C; A68D; # CYRILLIC CAPITAL LETTER TWE
+A68E; C; A68F; # CYRILLIC CAPITAL LETTER TSWE
+A690; C; A691; # CYRILLIC CAPITAL LETTER TSSE
+A692; C; A693; # CYRILLIC CAPITAL LETTER TCHE
+A694; C; A695; # CYRILLIC CAPITAL LETTER HWE
+A696; C; A697; # CYRILLIC CAPITAL LETTER SHWE
+A698; C; A699; # CYRILLIC CAPITAL LETTER DOUBLE O
+A69A; C; A69B; # CYRILLIC CAPITAL LETTER CROSSED O
+A722; C; A723; # LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
+A724; C; A725; # LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
+A726; C; A727; # LATIN CAPITAL LETTER HENG
+A728; C; A729; # LATIN CAPITAL LETTER TZ
+A72A; C; A72B; # LATIN CAPITAL LETTER TRESILLO
+A72C; C; A72D; # LATIN CAPITAL LETTER CUATRILLO
+A72E; C; A72F; # LATIN CAPITAL LETTER CUATRILLO WITH COMMA
+A732; C; A733; # LATIN CAPITAL LETTER AA
+A734; C; A735; # LATIN CAPITAL LETTER AO
+A736; C; A737; # LATIN CAPITAL LETTER AU
+A738; C; A739; # LATIN CAPITAL LETTER AV
+A73A; C; A73B; # LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
+A73C; C; A73D; # LATIN CAPITAL LETTER AY
+A73E; C; A73F; # LATIN CAPITAL LETTER REVERSED C WITH DOT
+A740; C; A741; # LATIN CAPITAL LETTER K WITH STROKE
+A742; C; A743; # LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
+A744; C; A745; # LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
+A746; C; A747; # LATIN CAPITAL LETTER BROKEN L
+A748; C; A749; # LATIN CAPITAL LETTER L WITH HIGH STROKE
+A74A; C; A74B; # LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
+A74C; C; A74D; # LATIN CAPITAL LETTER O WITH LOOP
+A74E; C; A74F; # LATIN CAPITAL LETTER OO
+A750; C; A751; # LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
+A752; C; A753; # LATIN CAPITAL LETTER P WITH FLOURISH
+A754; C; A755; # LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
+A756; C; A757; # LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
+A758; C; A759; # LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
+A75A; C; A75B; # LATIN CAPITAL LETTER R ROTUNDA
+A75C; C; A75D; # LATIN CAPITAL LETTER RUM ROTUNDA
+A75E; C; A75F; # LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
+A760; C; A761; # LATIN CAPITAL LETTER VY
+A762; C; A763; # LATIN CAPITAL LETTER VISIGOTHIC Z
+A764; C; A765; # LATIN CAPITAL LETTER THORN WITH STROKE
+A766; C; A767; # LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
+A768; C; A769; # LATIN CAPITAL LETTER VEND
+A76A; C; A76B; # LATIN CAPITAL LETTER ET
+A76C; C; A76D; # LATIN CAPITAL LETTER IS
+A76E; C; A76F; # LATIN CAPITAL LETTER CON
+A779; C; A77A; # LATIN CAPITAL LETTER INSULAR D
+A77B; C; A77C; # LATIN CAPITAL LETTER INSULAR F
+A77D; C; 1D79; # LATIN CAPITAL LETTER INSULAR G
+A77E; C; A77F; # LATIN CAPITAL LETTER TURNED INSULAR G
+A780; C; A781; # LATIN CAPITAL LETTER TURNED L
+A782; C; A783; # LATIN CAPITAL LETTER INSULAR R
+A784; C; A785; # LATIN CAPITAL LETTER INSULAR S
+A786; C; A787; # LATIN CAPITAL LETTER INSULAR T
+A78B; C; A78C; # LATIN CAPITAL LETTER SALTILLO
+A78D; C; 0265; # LATIN CAPITAL LETTER TURNED H
+A790; C; A791; # LATIN CAPITAL LETTER N WITH DESCENDER
+A792; C; A793; # LATIN CAPITAL LETTER C WITH BAR
+A796; C; A797; # LATIN CAPITAL LETTER B WITH FLOURISH
+A798; C; A799; # LATIN CAPITAL LETTER F WITH STROKE
+A79A; C; A79B; # LATIN CAPITAL LETTER VOLAPUK AE
+A79C; C; A79D; # LATIN CAPITAL LETTER VOLAPUK OE
+A79E; C; A79F; # LATIN CAPITAL LETTER VOLAPUK UE
+A7A0; C; A7A1; # LATIN CAPITAL LETTER G WITH OBLIQUE STROKE
+A7A2; C; A7A3; # LATIN CAPITAL LETTER K WITH OBLIQUE STROKE
+A7A4; C; A7A5; # LATIN CAPITAL LETTER N WITH OBLIQUE STROKE
+A7A6; C; A7A7; # LATIN CAPITAL LETTER R WITH OBLIQUE STROKE
+A7A8; C; A7A9; # LATIN CAPITAL LETTER S WITH OBLIQUE STROKE
+A7AA; C; 0266; # LATIN CAPITAL LETTER H WITH HOOK
+A7AB; C; 025C; # LATIN CAPITAL LETTER REVERSED OPEN E
+A7AC; C; 0261; # LATIN CAPITAL LETTER SCRIPT G
+A7AD; C; 026C; # LATIN CAPITAL LETTER L WITH BELT
+A7AE; C; 026A; # LATIN CAPITAL LETTER SMALL CAPITAL I
+A7B0; C; 029E; # LATIN CAPITAL LETTER TURNED K
+A7B1; C; 0287; # LATIN CAPITAL LETTER TURNED T
+A7B2; C; 029D; # LATIN CAPITAL LETTER J WITH CROSSED-TAIL
+A7B3; C; AB53; # LATIN CAPITAL LETTER CHI
+A7B4; C; A7B5; # LATIN CAPITAL LETTER BETA
+A7B6; C; A7B7; # LATIN CAPITAL LETTER OMEGA
+A7B8; C; A7B9; # LATIN CAPITAL LETTER U WITH STROKE
+A7BA; C; A7BB; # LATIN CAPITAL LETTER GLOTTAL A
+A7BC; C; A7BD; # LATIN CAPITAL LETTER GLOTTAL I
+A7BE; C; A7BF; # LATIN CAPITAL LETTER GLOTTAL U
+A7C0; C; A7C1; # LATIN CAPITAL LETTER OLD POLISH O
+A7C2; C; A7C3; # LATIN CAPITAL LETTER ANGLICANA W
+A7C4; C; A794; # LATIN CAPITAL LETTER C WITH PALATAL HOOK
+A7C5; C; 0282; # LATIN CAPITAL LETTER S WITH HOOK
+A7C6; C; 1D8E; # LATIN CAPITAL LETTER Z WITH PALATAL HOOK
+A7C7; C; A7C8; # LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY
+A7C9; C; A7CA; # LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY
+A7D0; C; A7D1; # LATIN CAPITAL LETTER CLOSED INSULAR G
+A7D6; C; A7D7; # LATIN CAPITAL LETTER MIDDLE SCOTS S
+A7D8; C; A7D9; # LATIN CAPITAL LETTER SIGMOID S
+A7F5; C; A7F6; # LATIN CAPITAL LETTER REVERSED HALF H
+AB70; C; 13A0; # CHEROKEE SMALL LETTER A
+AB71; C; 13A1; # CHEROKEE SMALL LETTER E
+AB72; C; 13A2; # CHEROKEE SMALL LETTER I
+AB73; C; 13A3; # CHEROKEE SMALL LETTER O
+AB74; C; 13A4; # CHEROKEE SMALL LETTER U
+AB75; C; 13A5; # CHEROKEE SMALL LETTER V
+AB76; C; 13A6; # CHEROKEE SMALL LETTER GA
+AB77; C; 13A7; # CHEROKEE SMALL LETTER KA
+AB78; C; 13A8; # CHEROKEE SMALL LETTER GE
+AB79; C; 13A9; # CHEROKEE SMALL LETTER GI
+AB7A; C; 13AA; # CHEROKEE SMALL LETTER GO
+AB7B; C; 13AB; # CHEROKEE SMALL LETTER GU
+AB7C; C; 13AC; # CHEROKEE SMALL LETTER GV
+AB7D; C; 13AD; # CHEROKEE SMALL LETTER HA
+AB7E; C; 13AE; # CHEROKEE SMALL LETTER HE
+AB7F; C; 13AF; # CHEROKEE SMALL LETTER HI
+AB80; C; 13B0; # CHEROKEE SMALL LETTER HO
+AB81; C; 13B1; # CHEROKEE SMALL LETTER HU
+AB82; C; 13B2; # CHEROKEE SMALL LETTER HV
+AB83; C; 13B3; # CHEROKEE SMALL LETTER LA
+AB84; C; 13B4; # CHEROKEE SMALL LETTER LE
+AB85; C; 13B5; # CHEROKEE SMALL LETTER LI
+AB86; C; 13B6; # CHEROKEE SMALL LETTER LO
+AB87; C; 13B7; # CHEROKEE SMALL LETTER LU
+AB88; C; 13B8; # CHEROKEE SMALL LETTER LV
+AB89; C; 13B9; # CHEROKEE SMALL LETTER MA
+AB8A; C; 13BA; # CHEROKEE SMALL LETTER ME
+AB8B; C; 13BB; # CHEROKEE SMALL LETTER MI
+AB8C; C; 13BC; # CHEROKEE SMALL LETTER MO
+AB8D; C; 13BD; # CHEROKEE SMALL LETTER MU
+AB8E; C; 13BE; # CHEROKEE SMALL LETTER NA
+AB8F; C; 13BF; # CHEROKEE SMALL LETTER HNA
+AB90; C; 13C0; # CHEROKEE SMALL LETTER NAH
+AB91; C; 13C1; # CHEROKEE SMALL LETTER NE
+AB92; C; 13C2; # CHEROKEE SMALL LETTER NI
+AB93; C; 13C3; # CHEROKEE SMALL LETTER NO
+AB94; C; 13C4; # CHEROKEE SMALL LETTER NU
+AB95; C; 13C5; # CHEROKEE SMALL LETTER NV
+AB96; C; 13C6; # CHEROKEE SMALL LETTER QUA
+AB97; C; 13C7; # CHEROKEE SMALL LETTER QUE
+AB98; C; 13C8; # CHEROKEE SMALL LETTER QUI
+AB99; C; 13C9; # CHEROKEE SMALL LETTER QUO
+AB9A; C; 13CA; # CHEROKEE SMALL LETTER QUU
+AB9B; C; 13CB; # CHEROKEE SMALL LETTER QUV
+AB9C; C; 13CC; # CHEROKEE SMALL LETTER SA
+AB9D; C; 13CD; # CHEROKEE SMALL LETTER S
+AB9E; C; 13CE; # CHEROKEE SMALL LETTER SE
+AB9F; C; 13CF; # CHEROKEE SMALL LETTER SI
+ABA0; C; 13D0; # CHEROKEE SMALL LETTER SO
+ABA1; C; 13D1; # CHEROKEE SMALL LETTER SU
+ABA2; C; 13D2; # CHEROKEE SMALL LETTER SV
+ABA3; C; 13D3; # CHEROKEE SMALL LETTER DA
+ABA4; C; 13D4; # CHEROKEE SMALL LETTER TA
+ABA5; C; 13D5; # CHEROKEE SMALL LETTER DE
+ABA6; C; 13D6; # CHEROKEE SMALL LETTER TE
+ABA7; C; 13D7; # CHEROKEE SMALL LETTER DI
+ABA8; C; 13D8; # CHEROKEE SMALL LETTER TI
+ABA9; C; 13D9; # CHEROKEE SMALL LETTER DO
+ABAA; C; 13DA; # CHEROKEE SMALL LETTER DU
+ABAB; C; 13DB; # CHEROKEE SMALL LETTER DV
+ABAC; C; 13DC; # CHEROKEE SMALL LETTER DLA
+ABAD; C; 13DD; # CHEROKEE SMALL LETTER TLA
+ABAE; C; 13DE; # CHEROKEE SMALL LETTER TLE
+ABAF; C; 13DF; # CHEROKEE SMALL LETTER TLI
+ABB0; C; 13E0; # CHEROKEE SMALL LETTER TLO
+ABB1; C; 13E1; # CHEROKEE SMALL LETTER TLU
+ABB2; C; 13E2; # CHEROKEE SMALL LETTER TLV
+ABB3; C; 13E3; # CHEROKEE SMALL LETTER TSA
+ABB4; C; 13E4; # CHEROKEE SMALL LETTER TSE
+ABB5; C; 13E5; # CHEROKEE SMALL LETTER TSI
+ABB6; C; 13E6; # CHEROKEE SMALL LETTER TSO
+ABB7; C; 13E7; # CHEROKEE SMALL LETTER TSU
+ABB8; C; 13E8; # CHEROKEE SMALL LETTER TSV
+ABB9; C; 13E9; # CHEROKEE SMALL LETTER WA
+ABBA; C; 13EA; # CHEROKEE SMALL LETTER WE
+ABBB; C; 13EB; # CHEROKEE SMALL LETTER WI
+ABBC; C; 13EC; # CHEROKEE SMALL LETTER WO
+ABBD; C; 13ED; # CHEROKEE SMALL LETTER WU
+ABBE; C; 13EE; # CHEROKEE SMALL LETTER WV
+ABBF; C; 13EF; # CHEROKEE SMALL LETTER YA
+FB00; F; 0066 0066; # LATIN SMALL LIGATURE FF
+FB01; F; 0066 0069; # LATIN SMALL LIGATURE FI
+FB02; F; 0066 006C; # LATIN SMALL LIGATURE FL
+FB03; F; 0066 0066 0069; # LATIN SMALL LIGATURE FFI
+FB04; F; 0066 0066 006C; # LATIN SMALL LIGATURE FFL
+FB05; F; 0073 0074; # LATIN SMALL LIGATURE LONG S T
+FB06; F; 0073 0074; # LATIN SMALL LIGATURE ST
+FB13; F; 0574 0576; # ARMENIAN SMALL LIGATURE MEN NOW
+FB14; F; 0574 0565; # ARMENIAN SMALL LIGATURE MEN ECH
+FB15; F; 0574 056B; # ARMENIAN SMALL LIGATURE MEN INI
+FB16; F; 057E 0576; # ARMENIAN SMALL LIGATURE VEW NOW
+FB17; F; 0574 056D; # ARMENIAN SMALL LIGATURE MEN XEH
+FF21; C; FF41; # FULLWIDTH LATIN CAPITAL LETTER A
+FF22; C; FF42; # FULLWIDTH LATIN CAPITAL LETTER B
+FF23; C; FF43; # FULLWIDTH LATIN CAPITAL LETTER C
+FF24; C; FF44; # FULLWIDTH LATIN CAPITAL LETTER D
+FF25; C; FF45; # FULLWIDTH LATIN CAPITAL LETTER E
+FF26; C; FF46; # FULLWIDTH LATIN CAPITAL LETTER F
+FF27; C; FF47; # FULLWIDTH LATIN CAPITAL LETTER G
+FF28; C; FF48; # FULLWIDTH LATIN CAPITAL LETTER H
+FF29; C; FF49; # FULLWIDTH LATIN CAPITAL LETTER I
+FF2A; C; FF4A; # FULLWIDTH LATIN CAPITAL LETTER J
+FF2B; C; FF4B; # FULLWIDTH LATIN CAPITAL LETTER K
+FF2C; C; FF4C; # FULLWIDTH LATIN CAPITAL LETTER L
+FF2D; C; FF4D; # FULLWIDTH LATIN CAPITAL LETTER M
+FF2E; C; FF4E; # FULLWIDTH LATIN CAPITAL LETTER N
+FF2F; C; FF4F; # FULLWIDTH LATIN CAPITAL LETTER O
+FF30; C; FF50; # FULLWIDTH LATIN CAPITAL LETTER P
+FF31; C; FF51; # FULLWIDTH LATIN CAPITAL LETTER Q
+FF32; C; FF52; # FULLWIDTH LATIN CAPITAL LETTER R
+FF33; C; FF53; # FULLWIDTH LATIN CAPITAL LETTER S
+FF34; C; FF54; # FULLWIDTH LATIN CAPITAL LETTER T
+FF35; C; FF55; # FULLWIDTH LATIN CAPITAL LETTER U
+FF36; C; FF56; # FULLWIDTH LATIN CAPITAL LETTER V
+FF37; C; FF57; # FULLWIDTH LATIN CAPITAL LETTER W
+FF38; C; FF58; # FULLWIDTH LATIN CAPITAL LETTER X
+FF39; C; FF59; # FULLWIDTH LATIN CAPITAL LETTER Y
+FF3A; C; FF5A; # FULLWIDTH LATIN CAPITAL LETTER Z
+10400; C; 10428; # DESERET CAPITAL LETTER LONG I
+10401; C; 10429; # DESERET CAPITAL LETTER LONG E
+10402; C; 1042A; # DESERET CAPITAL LETTER LONG A
+10403; C; 1042B; # DESERET CAPITAL LETTER LONG AH
+10404; C; 1042C; # DESERET CAPITAL LETTER LONG O
+10405; C; 1042D; # DESERET CAPITAL LETTER LONG OO
+10406; C; 1042E; # DESERET CAPITAL LETTER SHORT I
+10407; C; 1042F; # DESERET CAPITAL LETTER SHORT E
+10408; C; 10430; # DESERET CAPITAL LETTER SHORT A
+10409; C; 10431; # DESERET CAPITAL LETTER SHORT AH
+1040A; C; 10432; # DESERET CAPITAL LETTER SHORT O
+1040B; C; 10433; # DESERET CAPITAL LETTER SHORT OO
+1040C; C; 10434; # DESERET CAPITAL LETTER AY
+1040D; C; 10435; # DESERET CAPITAL LETTER OW
+1040E; C; 10436; # DESERET CAPITAL LETTER WU
+1040F; C; 10437; # DESERET CAPITAL LETTER YEE
+10410; C; 10438; # DESERET CAPITAL LETTER H
+10411; C; 10439; # DESERET CAPITAL LETTER PEE
+10412; C; 1043A; # DESERET CAPITAL LETTER BEE
+10413; C; 1043B; # DESERET CAPITAL LETTER TEE
+10414; C; 1043C; # DESERET CAPITAL LETTER DEE
+10415; C; 1043D; # DESERET CAPITAL LETTER CHEE
+10416; C; 1043E; # DESERET CAPITAL LETTER JEE
+10417; C; 1043F; # DESERET CAPITAL LETTER KAY
+10418; C; 10440; # DESERET CAPITAL LETTER GAY
+10419; C; 10441; # DESERET CAPITAL LETTER EF
+1041A; C; 10442; # DESERET CAPITAL LETTER VEE
+1041B; C; 10443; # DESERET CAPITAL LETTER ETH
+1041C; C; 10444; # DESERET CAPITAL LETTER THEE
+1041D; C; 10445; # DESERET CAPITAL LETTER ES
+1041E; C; 10446; # DESERET CAPITAL LETTER ZEE
+1041F; C; 10447; # DESERET CAPITAL LETTER ESH
+10420; C; 10448; # DESERET CAPITAL LETTER ZHEE
+10421; C; 10449; # DESERET CAPITAL LETTER ER
+10422; C; 1044A; # DESERET CAPITAL LETTER EL
+10423; C; 1044B; # DESERET CAPITAL LETTER EM
+10424; C; 1044C; # DESERET CAPITAL LETTER EN
+10425; C; 1044D; # DESERET CAPITAL LETTER ENG
+10426; C; 1044E; # DESERET CAPITAL LETTER OI
+10427; C; 1044F; # DESERET CAPITAL LETTER EW
+104B0; C; 104D8; # OSAGE CAPITAL LETTER A
+104B1; C; 104D9; # OSAGE CAPITAL LETTER AI
+104B2; C; 104DA; # OSAGE CAPITAL LETTER AIN
+104B3; C; 104DB; # OSAGE CAPITAL LETTER AH
+104B4; C; 104DC; # OSAGE CAPITAL LETTER BRA
+104B5; C; 104DD; # OSAGE CAPITAL LETTER CHA
+104B6; C; 104DE; # OSAGE CAPITAL LETTER EHCHA
+104B7; C; 104DF; # OSAGE CAPITAL LETTER E
+104B8; C; 104E0; # OSAGE CAPITAL LETTER EIN
+104B9; C; 104E1; # OSAGE CAPITAL LETTER HA
+104BA; C; 104E2; # OSAGE CAPITAL LETTER HYA
+104BB; C; 104E3; # OSAGE CAPITAL LETTER I
+104BC; C; 104E4; # OSAGE CAPITAL LETTER KA
+104BD; C; 104E5; # OSAGE CAPITAL LETTER EHKA
+104BE; C; 104E6; # OSAGE CAPITAL LETTER KYA
+104BF; C; 104E7; # OSAGE CAPITAL LETTER LA
+104C0; C; 104E8; # OSAGE CAPITAL LETTER MA
+104C1; C; 104E9; # OSAGE CAPITAL LETTER NA
+104C2; C; 104EA; # OSAGE CAPITAL LETTER O
+104C3; C; 104EB; # OSAGE CAPITAL LETTER OIN
+104C4; C; 104EC; # OSAGE CAPITAL LETTER PA
+104C5; C; 104ED; # OSAGE CAPITAL LETTER EHPA
+104C6; C; 104EE; # OSAGE CAPITAL LETTER SA
+104C7; C; 104EF; # OSAGE CAPITAL LETTER SHA
+104C8; C; 104F0; # OSAGE CAPITAL LETTER TA
+104C9; C; 104F1; # OSAGE CAPITAL LETTER EHTA
+104CA; C; 104F2; # OSAGE CAPITAL LETTER TSA
+104CB; C; 104F3; # OSAGE CAPITAL LETTER EHTSA
+104CC; C; 104F4; # OSAGE CAPITAL LETTER TSHA
+104CD; C; 104F5; # OSAGE CAPITAL LETTER DHA
+104CE; C; 104F6; # OSAGE CAPITAL LETTER U
+104CF; C; 104F7; # OSAGE CAPITAL LETTER WA
+104D0; C; 104F8; # OSAGE CAPITAL LETTER KHA
+104D1; C; 104F9; # OSAGE CAPITAL LETTER GHA
+104D2; C; 104FA; # OSAGE CAPITAL LETTER ZA
+104D3; C; 104FB; # OSAGE CAPITAL LETTER ZHA
+10570; C; 10597; # VITHKUQI CAPITAL LETTER A
+10571; C; 10598; # VITHKUQI CAPITAL LETTER BBE
+10572; C; 10599; # VITHKUQI CAPITAL LETTER BE
+10573; C; 1059A; # VITHKUQI CAPITAL LETTER CE
+10574; C; 1059B; # VITHKUQI CAPITAL LETTER CHE
+10575; C; 1059C; # VITHKUQI CAPITAL LETTER DE
+10576; C; 1059D; # VITHKUQI CAPITAL LETTER DHE
+10577; C; 1059E; # VITHKUQI CAPITAL LETTER EI
+10578; C; 1059F; # VITHKUQI CAPITAL LETTER E
+10579; C; 105A0; # VITHKUQI CAPITAL LETTER FE
+1057A; C; 105A1; # VITHKUQI CAPITAL LETTER GA
+1057C; C; 105A3; # VITHKUQI CAPITAL LETTER HA
+1057D; C; 105A4; # VITHKUQI CAPITAL LETTER HHA
+1057E; C; 105A5; # VITHKUQI CAPITAL LETTER I
+1057F; C; 105A6; # VITHKUQI CAPITAL LETTER IJE
+10580; C; 105A7; # VITHKUQI CAPITAL LETTER JE
+10581; C; 105A8; # VITHKUQI CAPITAL LETTER KA
+10582; C; 105A9; # VITHKUQI CAPITAL LETTER LA
+10583; C; 105AA; # VITHKUQI CAPITAL LETTER LLA
+10584; C; 105AB; # VITHKUQI CAPITAL LETTER ME
+10585; C; 105AC; # VITHKUQI CAPITAL LETTER NE
+10586; C; 105AD; # VITHKUQI CAPITAL LETTER NJE
+10587; C; 105AE; # VITHKUQI CAPITAL LETTER O
+10588; C; 105AF; # VITHKUQI CAPITAL LETTER PE
+10589; C; 105B0; # VITHKUQI CAPITAL LETTER QA
+1058A; C; 105B1; # VITHKUQI CAPITAL LETTER RE
+1058C; C; 105B3; # VITHKUQI CAPITAL LETTER SE
+1058D; C; 105B4; # VITHKUQI CAPITAL LETTER SHE
+1058E; C; 105B5; # VITHKUQI CAPITAL LETTER TE
+1058F; C; 105B6; # VITHKUQI CAPITAL LETTER THE
+10590; C; 105B7; # VITHKUQI CAPITAL LETTER U
+10591; C; 105B8; # VITHKUQI CAPITAL LETTER VE
+10592; C; 105B9; # VITHKUQI CAPITAL LETTER XE
+10594; C; 105BB; # VITHKUQI CAPITAL LETTER Y
+10595; C; 105BC; # VITHKUQI CAPITAL LETTER ZE
+10C80; C; 10CC0; # OLD HUNGARIAN CAPITAL LETTER A
+10C81; C; 10CC1; # OLD HUNGARIAN CAPITAL LETTER AA
+10C82; C; 10CC2; # OLD HUNGARIAN CAPITAL LETTER EB
+10C83; C; 10CC3; # OLD HUNGARIAN CAPITAL LETTER AMB
+10C84; C; 10CC4; # OLD HUNGARIAN CAPITAL LETTER EC
+10C85; C; 10CC5; # OLD HUNGARIAN CAPITAL LETTER ENC
+10C86; C; 10CC6; # OLD HUNGARIAN CAPITAL LETTER ECS
+10C87; C; 10CC7; # OLD HUNGARIAN CAPITAL LETTER ED
+10C88; C; 10CC8; # OLD HUNGARIAN CAPITAL LETTER AND
+10C89; C; 10CC9; # OLD HUNGARIAN CAPITAL LETTER E
+10C8A; C; 10CCA; # OLD HUNGARIAN CAPITAL LETTER CLOSE E
+10C8B; C; 10CCB; # OLD HUNGARIAN CAPITAL LETTER EE
+10C8C; C; 10CCC; # OLD HUNGARIAN CAPITAL LETTER EF
+10C8D; C; 10CCD; # OLD HUNGARIAN CAPITAL LETTER EG
+10C8E; C; 10CCE; # OLD HUNGARIAN CAPITAL LETTER EGY
+10C8F; C; 10CCF; # OLD HUNGARIAN CAPITAL LETTER EH
+10C90; C; 10CD0; # OLD HUNGARIAN CAPITAL LETTER I
+10C91; C; 10CD1; # OLD HUNGARIAN CAPITAL LETTER II
+10C92; C; 10CD2; # OLD HUNGARIAN CAPITAL LETTER EJ
+10C93; C; 10CD3; # OLD HUNGARIAN CAPITAL LETTER EK
+10C94; C; 10CD4; # OLD HUNGARIAN CAPITAL LETTER AK
+10C95; C; 10CD5; # OLD HUNGARIAN CAPITAL LETTER UNK
+10C96; C; 10CD6; # OLD HUNGARIAN CAPITAL LETTER EL
+10C97; C; 10CD7; # OLD HUNGARIAN CAPITAL LETTER ELY
+10C98; C; 10CD8; # OLD HUNGARIAN CAPITAL LETTER EM
+10C99; C; 10CD9; # OLD HUNGARIAN CAPITAL LETTER EN
+10C9A; C; 10CDA; # OLD HUNGARIAN CAPITAL LETTER ENY
+10C9B; C; 10CDB; # OLD HUNGARIAN CAPITAL LETTER O
+10C9C; C; 10CDC; # OLD HUNGARIAN CAPITAL LETTER OO
+10C9D; C; 10CDD; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE
+10C9E; C; 10CDE; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE
+10C9F; C; 10CDF; # OLD HUNGARIAN CAPITAL LETTER OEE
+10CA0; C; 10CE0; # OLD HUNGARIAN CAPITAL LETTER EP
+10CA1; C; 10CE1; # OLD HUNGARIAN CAPITAL LETTER EMP
+10CA2; C; 10CE2; # OLD HUNGARIAN CAPITAL LETTER ER
+10CA3; C; 10CE3; # OLD HUNGARIAN CAPITAL LETTER SHORT ER
+10CA4; C; 10CE4; # OLD HUNGARIAN CAPITAL LETTER ES
+10CA5; C; 10CE5; # OLD HUNGARIAN CAPITAL LETTER ESZ
+10CA6; C; 10CE6; # OLD HUNGARIAN CAPITAL LETTER ET
+10CA7; C; 10CE7; # OLD HUNGARIAN CAPITAL LETTER ENT
+10CA8; C; 10CE8; # OLD HUNGARIAN CAPITAL LETTER ETY
+10CA9; C; 10CE9; # OLD HUNGARIAN CAPITAL LETTER ECH
+10CAA; C; 10CEA; # OLD HUNGARIAN CAPITAL LETTER U
+10CAB; C; 10CEB; # OLD HUNGARIAN CAPITAL LETTER UU
+10CAC; C; 10CEC; # OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE
+10CAD; C; 10CED; # OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE
+10CAE; C; 10CEE; # OLD HUNGARIAN CAPITAL LETTER EV
+10CAF; C; 10CEF; # OLD HUNGARIAN CAPITAL LETTER EZ
+10CB0; C; 10CF0; # OLD HUNGARIAN CAPITAL LETTER EZS
+10CB1; C; 10CF1; # OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN
+10CB2; C; 10CF2; # OLD HUNGARIAN CAPITAL LETTER US
+118A0; C; 118C0; # WARANG CITI CAPITAL LETTER NGAA
+118A1; C; 118C1; # WARANG CITI CAPITAL LETTER A
+118A2; C; 118C2; # WARANG CITI CAPITAL LETTER WI
+118A3; C; 118C3; # WARANG CITI CAPITAL LETTER YU
+118A4; C; 118C4; # WARANG CITI CAPITAL LETTER YA
+118A5; C; 118C5; # WARANG CITI CAPITAL LETTER YO
+118A6; C; 118C6; # WARANG CITI CAPITAL LETTER II
+118A7; C; 118C7; # WARANG CITI CAPITAL LETTER UU
+118A8; C; 118C8; # WARANG CITI CAPITAL LETTER E
+118A9; C; 118C9; # WARANG CITI CAPITAL LETTER O
+118AA; C; 118CA; # WARANG CITI CAPITAL LETTER ANG
+118AB; C; 118CB; # WARANG CITI CAPITAL LETTER GA
+118AC; C; 118CC; # WARANG CITI CAPITAL LETTER KO
+118AD; C; 118CD; # WARANG CITI CAPITAL LETTER ENY
+118AE; C; 118CE; # WARANG CITI CAPITAL LETTER YUJ
+118AF; C; 118CF; # WARANG CITI CAPITAL LETTER UC
+118B0; C; 118D0; # WARANG CITI CAPITAL LETTER ENN
+118B1; C; 118D1; # WARANG CITI CAPITAL LETTER ODD
+118B2; C; 118D2; # WARANG CITI CAPITAL LETTER TTE
+118B3; C; 118D3; # WARANG CITI CAPITAL LETTER NUNG
+118B4; C; 118D4; # WARANG CITI CAPITAL LETTER DA
+118B5; C; 118D5; # WARANG CITI CAPITAL LETTER AT
+118B6; C; 118D6; # WARANG CITI CAPITAL LETTER AM
+118B7; C; 118D7; # WARANG CITI CAPITAL LETTER BU
+118B8; C; 118D8; # WARANG CITI CAPITAL LETTER PU
+118B9; C; 118D9; # WARANG CITI CAPITAL LETTER HIYO
+118BA; C; 118DA; # WARANG CITI CAPITAL LETTER HOLO
+118BB; C; 118DB; # WARANG CITI CAPITAL LETTER HORR
+118BC; C; 118DC; # WARANG CITI CAPITAL LETTER HAR
+118BD; C; 118DD; # WARANG CITI CAPITAL LETTER SSUU
+118BE; C; 118DE; # WARANG CITI CAPITAL LETTER SII
+118BF; C; 118DF; # WARANG CITI CAPITAL LETTER VIYO
+16E40; C; 16E60; # MEDEFAIDRIN CAPITAL LETTER M
+16E41; C; 16E61; # MEDEFAIDRIN CAPITAL LETTER S
+16E42; C; 16E62; # MEDEFAIDRIN CAPITAL LETTER V
+16E43; C; 16E63; # MEDEFAIDRIN CAPITAL LETTER W
+16E44; C; 16E64; # MEDEFAIDRIN CAPITAL LETTER ATIU
+16E45; C; 16E65; # MEDEFAIDRIN CAPITAL LETTER Z
+16E46; C; 16E66; # MEDEFAIDRIN CAPITAL LETTER KP
+16E47; C; 16E67; # MEDEFAIDRIN CAPITAL LETTER P
+16E48; C; 16E68; # MEDEFAIDRIN CAPITAL LETTER T
+16E49; C; 16E69; # MEDEFAIDRIN CAPITAL LETTER G
+16E4A; C; 16E6A; # MEDEFAIDRIN CAPITAL LETTER F
+16E4B; C; 16E6B; # MEDEFAIDRIN CAPITAL LETTER I
+16E4C; C; 16E6C; # MEDEFAIDRIN CAPITAL LETTER K
+16E4D; C; 16E6D; # MEDEFAIDRIN CAPITAL LETTER A
+16E4E; C; 16E6E; # MEDEFAIDRIN CAPITAL LETTER J
+16E4F; C; 16E6F; # MEDEFAIDRIN CAPITAL LETTER E
+16E50; C; 16E70; # MEDEFAIDRIN CAPITAL LETTER B
+16E51; C; 16E71; # MEDEFAIDRIN CAPITAL LETTER C
+16E52; C; 16E72; # MEDEFAIDRIN CAPITAL LETTER U
+16E53; C; 16E73; # MEDEFAIDRIN CAPITAL LETTER YU
+16E54; C; 16E74; # MEDEFAIDRIN CAPITAL LETTER L
+16E55; C; 16E75; # MEDEFAIDRIN CAPITAL LETTER Q
+16E56; C; 16E76; # MEDEFAIDRIN CAPITAL LETTER HP
+16E57; C; 16E77; # MEDEFAIDRIN CAPITAL LETTER NY
+16E58; C; 16E78; # MEDEFAIDRIN CAPITAL LETTER X
+16E59; C; 16E79; # MEDEFAIDRIN CAPITAL LETTER D
+16E5A; C; 16E7A; # MEDEFAIDRIN CAPITAL LETTER OE
+16E5B; C; 16E7B; # MEDEFAIDRIN CAPITAL LETTER N
+16E5C; C; 16E7C; # MEDEFAIDRIN CAPITAL LETTER R
+16E5D; C; 16E7D; # MEDEFAIDRIN CAPITAL LETTER O
+16E5E; C; 16E7E; # MEDEFAIDRIN CAPITAL LETTER AI
+16E5F; C; 16E7F; # MEDEFAIDRIN CAPITAL LETTER Y
+1E900; C; 1E922; # ADLAM CAPITAL LETTER ALIF
+1E901; C; 1E923; # ADLAM CAPITAL LETTER DAALI
+1E902; C; 1E924; # ADLAM CAPITAL LETTER LAAM
+1E903; C; 1E925; # ADLAM CAPITAL LETTER MIIM
+1E904; C; 1E926; # ADLAM CAPITAL LETTER BA
+1E905; C; 1E927; # ADLAM CAPITAL LETTER SINNYIIYHE
+1E906; C; 1E928; # ADLAM CAPITAL LETTER PE
+1E907; C; 1E929; # ADLAM CAPITAL LETTER BHE
+1E908; C; 1E92A; # ADLAM CAPITAL LETTER RA
+1E909; C; 1E92B; # ADLAM CAPITAL LETTER E
+1E90A; C; 1E92C; # ADLAM CAPITAL LETTER FA
+1E90B; C; 1E92D; # ADLAM CAPITAL LETTER I
+1E90C; C; 1E92E; # ADLAM CAPITAL LETTER O
+1E90D; C; 1E92F; # ADLAM CAPITAL LETTER DHA
+1E90E; C; 1E930; # ADLAM CAPITAL LETTER YHE
+1E90F; C; 1E931; # ADLAM CAPITAL LETTER WAW
+1E910; C; 1E932; # ADLAM CAPITAL LETTER NUN
+1E911; C; 1E933; # ADLAM CAPITAL LETTER KAF
+1E912; C; 1E934; # ADLAM CAPITAL LETTER YA
+1E913; C; 1E935; # ADLAM CAPITAL LETTER U
+1E914; C; 1E936; # ADLAM CAPITAL LETTER JIIM
+1E915; C; 1E937; # ADLAM CAPITAL LETTER CHI
+1E916; C; 1E938; # ADLAM CAPITAL LETTER HA
+1E917; C; 1E939; # ADLAM CAPITAL LETTER QAAF
+1E918; C; 1E93A; # ADLAM CAPITAL LETTER GA
+1E919; C; 1E93B; # ADLAM CAPITAL LETTER NYA
+1E91A; C; 1E93C; # ADLAM CAPITAL LETTER TU
+1E91B; C; 1E93D; # ADLAM CAPITAL LETTER NHA
+1E91C; C; 1E93E; # ADLAM CAPITAL LETTER VA
+1E91D; C; 1E93F; # ADLAM CAPITAL LETTER KHA
+1E91E; C; 1E940; # ADLAM CAPITAL LETTER GBE
+1E91F; C; 1E941; # ADLAM CAPITAL LETTER ZAL
+1E920; C; 1E942; # ADLAM CAPITAL LETTER KPO
+1E921; C; 1E943; # ADLAM CAPITAL LETTER SHA
+#
+# EOF
diff --git a/pkgs/markdown/tool/common_mark_stats.json b/pkgs/markdown/tool/common_mark_stats.json
index be58d4a..1de59bb 100644
--- a/pkgs/markdown/tool/common_mark_stats.json
+++ b/pkgs/markdown/tool/common_mark_stats.json
@@ -244,7 +244,7 @@
},
"Entity and numeric character references": {
"25": "loose",
- "26": "loose",
+ "26": "strict",
"27": "loose",
"28": "loose",
"29": "strict",
@@ -252,12 +252,12 @@
"31": "strict",
"32": "fail",
"33": "fail",
- "34": "fail",
+ "34": "strict",
"35": "strict",
"36": "strict",
- "37": "loose",
- "38": "loose",
- "39": "loose",
+ "37": "strict",
+ "38": "strict",
+ "39": "strict",
"40": "loose",
"41": "strict"
},
@@ -333,7 +333,7 @@
"168": "strict",
"169": "strict",
"170": "strict",
- "171": "loose",
+ "171": "strict",
"172": "strict",
"173": "strict",
"174": "loose",
@@ -352,7 +352,7 @@
"187": "strict",
"188": "loose",
"189": "strict",
- "190": "loose",
+ "190": "strict",
"191": "loose"
},
"Images": {
@@ -484,7 +484,7 @@
"536": "strict",
"537": "strict",
"538": "strict",
- "539": "fail",
+ "539": "strict",
"540": "strict",
"541": "strict",
"542": "strict",
@@ -610,26 +610,26 @@
},
"Raw HTML": {
"612": "strict",
- "613": "fail",
+ "613": "strict",
"614": "strict",
"615": "strict",
"616": "strict",
"617": "strict",
- "618": "fail",
+ "618": "loose",
"619": "loose",
- "620": "fail",
- "621": "fail",
+ "620": "loose",
+ "621": "strict",
"622": "strict",
- "623": "fail",
- "624": "loose",
+ "623": "loose",
+ "624": "strict",
"625": "strict",
"626": "strict",
"627": "strict",
"628": "strict",
- "629": "loose",
+ "629": "strict",
"630": "strict",
"631": "strict",
- "632": "fail"
+ "632": "loose"
},
"Setext headings": {
"80": "strict",
diff --git a/pkgs/markdown/tool/common_mark_stats.txt b/pkgs/markdown/tool/common_mark_stats.txt
index 023259f..3afa53c 100644
--- a/pkgs/markdown/tool/common_mark_stats.txt
+++ b/pkgs/markdown/tool/common_mark_stats.txt
@@ -5,7 +5,7 @@
23 of 25 – 92.0% Block quotes
22 of 22 – 100.0% Code spans
130 of 131 – 99.2% Emphasis and strong emphasis
- 14 of 17 – 82.4% Entity and numeric character references
+ 15 of 17 – 88.2% Entity and numeric character references
28 of 29 – 96.6% Fenced code blocks
15 of 15 – 100.0% Hard line breaks
44 of 44 – 100.0% HTML blocks
@@ -13,16 +13,16 @@
11 of 12 – 91.7% Indented code blocks
1 of 1 – 100.0% Inlines
20 of 27 – 74.1% Link reference definitions
- 84 of 90 – 93.3% Links
+ 85 of 90 – 94.4% Links
45 of 48 – 93.8% List items
22 of 26 – 84.6% Lists
8 of 8 – 100.0% Paragraphs
1 of 1 – 100.0% Precedence
- 15 of 21 – 71.4% Raw HTML
+ 21 of 21 – 100.0% Raw HTML
26 of 27 – 96.3% Setext headings
2 of 2 – 100.0% Soft line breaks
11 of 11 – 100.0% Tabs
3 of 3 – 100.0% Textual content
19 of 19 – 100.0% Thematic breaks
- 614 of 652 – 94.2% TOTAL
- 547 of 614 – 89.1% TOTAL Strict
+ 622 of 652 – 95.4% TOTAL
+ 559 of 622 – 89.9% TOTAL Strict
diff --git a/pkgs/markdown/tool/dartdoc_compare.dart b/pkgs/markdown/tool/dartdoc_compare.dart
index e0195ba..37be7fb 100644
--- a/pkgs/markdown/tool/dartdoc_compare.dart
+++ b/pkgs/markdown/tool/dartdoc_compare.dart
@@ -27,7 +27,6 @@
)
..addFlag(
_sdk,
- defaultsTo: false,
negatable: false,
help: 'Is the package the SDK?',
)
@@ -121,7 +120,7 @@
}
final out = Directory.systemTemp
.createTempSync('dartdoc-compare-${markdownRef}__');
- final cmd = 'dart';
+ const cmd = 'dart';
final args = [dartdocBin, '--output=${out.path}'];
if (sdk) {
@@ -146,12 +145,14 @@
// make modifiable copy
dartdocPubspec = jsonDecode(jsonEncode(dartdocPubspec)) as Map;
+ final dependencies = dartdocPubspec['dependencies'] as Map;
+
if (markdownRef == 'local') {
- dartdocPubspec['dependencies']['markdown'] = {
+ dependencies['markdown'] = {
'path': markdownPath,
};
} else {
- dartdocPubspec['dependencies']['markdown'] = {
+ dependencies['markdown'] = {
'git': {
'url': 'git://github.com/dart-lang/markdown.git',
'ref': markdownRef
diff --git a/pkgs/markdown/tool/entities.json b/pkgs/markdown/tool/entities.json
new file mode 100644
index 0000000..557170b
--- /dev/null
+++ b/pkgs/markdown/tool/entities.json
@@ -0,0 +1,2233 @@
+{
+ "Æ": { "codepoints": [198], "characters": "\u00C6" },
+ "Æ": { "codepoints": [198], "characters": "\u00C6" },
+ "&": { "codepoints": [38], "characters": "\u0026" },
+ "&": { "codepoints": [38], "characters": "\u0026" },
+ "Á": { "codepoints": [193], "characters": "\u00C1" },
+ "Á": { "codepoints": [193], "characters": "\u00C1" },
+ "Ă": { "codepoints": [258], "characters": "\u0102" },
+ "Â": { "codepoints": [194], "characters": "\u00C2" },
+ "Â": { "codepoints": [194], "characters": "\u00C2" },
+ "А": { "codepoints": [1040], "characters": "\u0410" },
+ "𝔄": { "codepoints": [120068], "characters": "\uD835\uDD04" },
+ "À": { "codepoints": [192], "characters": "\u00C0" },
+ "À": { "codepoints": [192], "characters": "\u00C0" },
+ "Α": { "codepoints": [913], "characters": "\u0391" },
+ "Ā": { "codepoints": [256], "characters": "\u0100" },
+ "⩓": { "codepoints": [10835], "characters": "\u2A53" },
+ "Ą": { "codepoints": [260], "characters": "\u0104" },
+ "𝔸": { "codepoints": [120120], "characters": "\uD835\uDD38" },
+ "⁡": { "codepoints": [8289], "characters": "\u2061" },
+ "Å": { "codepoints": [197], "characters": "\u00C5" },
+ "Å": { "codepoints": [197], "characters": "\u00C5" },
+ "𝒜": { "codepoints": [119964], "characters": "\uD835\uDC9C" },
+ "≔": { "codepoints": [8788], "characters": "\u2254" },
+ "Ã": { "codepoints": [195], "characters": "\u00C3" },
+ "Ã": { "codepoints": [195], "characters": "\u00C3" },
+ "Ä": { "codepoints": [196], "characters": "\u00C4" },
+ "Ä": { "codepoints": [196], "characters": "\u00C4" },
+ "∖": { "codepoints": [8726], "characters": "\u2216" },
+ "⫧": { "codepoints": [10983], "characters": "\u2AE7" },
+ "⌆": { "codepoints": [8966], "characters": "\u2306" },
+ "Б": { "codepoints": [1041], "characters": "\u0411" },
+ "∵": { "codepoints": [8757], "characters": "\u2235" },
+ "ℬ": { "codepoints": [8492], "characters": "\u212C" },
+ "Β": { "codepoints": [914], "characters": "\u0392" },
+ "𝔅": { "codepoints": [120069], "characters": "\uD835\uDD05" },
+ "𝔹": { "codepoints": [120121], "characters": "\uD835\uDD39" },
+ "˘": { "codepoints": [728], "characters": "\u02D8" },
+ "ℬ": { "codepoints": [8492], "characters": "\u212C" },
+ "≎": { "codepoints": [8782], "characters": "\u224E" },
+ "Ч": { "codepoints": [1063], "characters": "\u0427" },
+ "©": { "codepoints": [169], "characters": "\u00A9" },
+ "©": { "codepoints": [169], "characters": "\u00A9" },
+ "Ć": { "codepoints": [262], "characters": "\u0106" },
+ "⋒": { "codepoints": [8914], "characters": "\u22D2" },
+ "ⅅ": { "codepoints": [8517], "characters": "\u2145" },
+ "ℭ": { "codepoints": [8493], "characters": "\u212D" },
+ "Č": { "codepoints": [268], "characters": "\u010C" },
+ "Ç": { "codepoints": [199], "characters": "\u00C7" },
+ "Ç": { "codepoints": [199], "characters": "\u00C7" },
+ "Ĉ": { "codepoints": [264], "characters": "\u0108" },
+ "∰": { "codepoints": [8752], "characters": "\u2230" },
+ "Ċ": { "codepoints": [266], "characters": "\u010A" },
+ "¸": { "codepoints": [184], "characters": "\u00B8" },
+ "·": { "codepoints": [183], "characters": "\u00B7" },
+ "ℭ": { "codepoints": [8493], "characters": "\u212D" },
+ "Χ": { "codepoints": [935], "characters": "\u03A7" },
+ "⊙": { "codepoints": [8857], "characters": "\u2299" },
+ "⊖": { "codepoints": [8854], "characters": "\u2296" },
+ "⊕": { "codepoints": [8853], "characters": "\u2295" },
+ "⊗": { "codepoints": [8855], "characters": "\u2297" },
+ "∲": { "codepoints": [8754], "characters": "\u2232" },
+ "”": { "codepoints": [8221], "characters": "\u201D" },
+ "’": { "codepoints": [8217], "characters": "\u2019" },
+ "∷": { "codepoints": [8759], "characters": "\u2237" },
+ "⩴": { "codepoints": [10868], "characters": "\u2A74" },
+ "≡": { "codepoints": [8801], "characters": "\u2261" },
+ "∯": { "codepoints": [8751], "characters": "\u222F" },
+ "∮": { "codepoints": [8750], "characters": "\u222E" },
+ "ℂ": { "codepoints": [8450], "characters": "\u2102" },
+ "∐": { "codepoints": [8720], "characters": "\u2210" },
+ "∳": { "codepoints": [8755], "characters": "\u2233" },
+ "⨯": { "codepoints": [10799], "characters": "\u2A2F" },
+ "𝒞": { "codepoints": [119966], "characters": "\uD835\uDC9E" },
+ "⋓": { "codepoints": [8915], "characters": "\u22D3" },
+ "≍": { "codepoints": [8781], "characters": "\u224D" },
+ "ⅅ": { "codepoints": [8517], "characters": "\u2145" },
+ "⤑": { "codepoints": [10513], "characters": "\u2911" },
+ "Ђ": { "codepoints": [1026], "characters": "\u0402" },
+ "Ѕ": { "codepoints": [1029], "characters": "\u0405" },
+ "Џ": { "codepoints": [1039], "characters": "\u040F" },
+ "‡": { "codepoints": [8225], "characters": "\u2021" },
+ "↡": { "codepoints": [8609], "characters": "\u21A1" },
+ "⫤": { "codepoints": [10980], "characters": "\u2AE4" },
+ "Ď": { "codepoints": [270], "characters": "\u010E" },
+ "Д": { "codepoints": [1044], "characters": "\u0414" },
+ "∇": { "codepoints": [8711], "characters": "\u2207" },
+ "Δ": { "codepoints": [916], "characters": "\u0394" },
+ "𝔇": { "codepoints": [120071], "characters": "\uD835\uDD07" },
+ "´": { "codepoints": [180], "characters": "\u00B4" },
+ "˙": { "codepoints": [729], "characters": "\u02D9" },
+ "˝": { "codepoints": [733], "characters": "\u02DD" },
+ "`": { "codepoints": [96], "characters": "\u0060" },
+ "˜": { "codepoints": [732], "characters": "\u02DC" },
+ "⋄": { "codepoints": [8900], "characters": "\u22C4" },
+ "ⅆ": { "codepoints": [8518], "characters": "\u2146" },
+ "𝔻": { "codepoints": [120123], "characters": "\uD835\uDD3B" },
+ "¨": { "codepoints": [168], "characters": "\u00A8" },
+ "⃜": { "codepoints": [8412], "characters": "\u20DC" },
+ "≐": { "codepoints": [8784], "characters": "\u2250" },
+ "∯": { "codepoints": [8751], "characters": "\u222F" },
+ "¨": { "codepoints": [168], "characters": "\u00A8" },
+ "⇓": { "codepoints": [8659], "characters": "\u21D3" },
+ "⇐": { "codepoints": [8656], "characters": "\u21D0" },
+ "⇔": { "codepoints": [8660], "characters": "\u21D4" },
+ "⫤": { "codepoints": [10980], "characters": "\u2AE4" },
+ "⟸": { "codepoints": [10232], "characters": "\u27F8" },
+ "⟺": { "codepoints": [10234], "characters": "\u27FA" },
+ "⟹": { "codepoints": [10233], "characters": "\u27F9" },
+ "⇒": { "codepoints": [8658], "characters": "\u21D2" },
+ "⊨": { "codepoints": [8872], "characters": "\u22A8" },
+ "⇑": { "codepoints": [8657], "characters": "\u21D1" },
+ "⇕": { "codepoints": [8661], "characters": "\u21D5" },
+ "∥": { "codepoints": [8741], "characters": "\u2225" },
+ "↓": { "codepoints": [8595], "characters": "\u2193" },
+ "⤓": { "codepoints": [10515], "characters": "\u2913" },
+ "⇵": { "codepoints": [8693], "characters": "\u21F5" },
+ "̑": { "codepoints": [785], "characters": "\u0311" },
+ "⥐": { "codepoints": [10576], "characters": "\u2950" },
+ "⥞": { "codepoints": [10590], "characters": "\u295E" },
+ "↽": { "codepoints": [8637], "characters": "\u21BD" },
+ "⥖": { "codepoints": [10582], "characters": "\u2956" },
+ "⥟": { "codepoints": [10591], "characters": "\u295F" },
+ "⇁": { "codepoints": [8641], "characters": "\u21C1" },
+ "⥗": { "codepoints": [10583], "characters": "\u2957" },
+ "⊤": { "codepoints": [8868], "characters": "\u22A4" },
+ "↧": { "codepoints": [8615], "characters": "\u21A7" },
+ "⇓": { "codepoints": [8659], "characters": "\u21D3" },
+ "𝒟": { "codepoints": [119967], "characters": "\uD835\uDC9F" },
+ "Đ": { "codepoints": [272], "characters": "\u0110" },
+ "Ŋ": { "codepoints": [330], "characters": "\u014A" },
+ "Ð": { "codepoints": [208], "characters": "\u00D0" },
+ "Ð": { "codepoints": [208], "characters": "\u00D0" },
+ "É": { "codepoints": [201], "characters": "\u00C9" },
+ "É": { "codepoints": [201], "characters": "\u00C9" },
+ "Ě": { "codepoints": [282], "characters": "\u011A" },
+ "Ê": { "codepoints": [202], "characters": "\u00CA" },
+ "Ê": { "codepoints": [202], "characters": "\u00CA" },
+ "Э": { "codepoints": [1069], "characters": "\u042D" },
+ "Ė": { "codepoints": [278], "characters": "\u0116" },
+ "𝔈": { "codepoints": [120072], "characters": "\uD835\uDD08" },
+ "È": { "codepoints": [200], "characters": "\u00C8" },
+ "È": { "codepoints": [200], "characters": "\u00C8" },
+ "∈": { "codepoints": [8712], "characters": "\u2208" },
+ "Ē": { "codepoints": [274], "characters": "\u0112" },
+ "◻": { "codepoints": [9723], "characters": "\u25FB" },
+ "▫": { "codepoints": [9643], "characters": "\u25AB" },
+ "Ę": { "codepoints": [280], "characters": "\u0118" },
+ "𝔼": { "codepoints": [120124], "characters": "\uD835\uDD3C" },
+ "Ε": { "codepoints": [917], "characters": "\u0395" },
+ "⩵": { "codepoints": [10869], "characters": "\u2A75" },
+ "≂": { "codepoints": [8770], "characters": "\u2242" },
+ "⇌": { "codepoints": [8652], "characters": "\u21CC" },
+ "ℰ": { "codepoints": [8496], "characters": "\u2130" },
+ "⩳": { "codepoints": [10867], "characters": "\u2A73" },
+ "Η": { "codepoints": [919], "characters": "\u0397" },
+ "Ë": { "codepoints": [203], "characters": "\u00CB" },
+ "Ë": { "codepoints": [203], "characters": "\u00CB" },
+ "∃": { "codepoints": [8707], "characters": "\u2203" },
+ "ⅇ": { "codepoints": [8519], "characters": "\u2147" },
+ "Ф": { "codepoints": [1060], "characters": "\u0424" },
+ "𝔉": { "codepoints": [120073], "characters": "\uD835\uDD09" },
+ "◼": { "codepoints": [9724], "characters": "\u25FC" },
+ "▪": { "codepoints": [9642], "characters": "\u25AA" },
+ "𝔽": { "codepoints": [120125], "characters": "\uD835\uDD3D" },
+ "∀": { "codepoints": [8704], "characters": "\u2200" },
+ "ℱ": { "codepoints": [8497], "characters": "\u2131" },
+ "ℱ": { "codepoints": [8497], "characters": "\u2131" },
+ "Ѓ": { "codepoints": [1027], "characters": "\u0403" },
+ ">": { "codepoints": [62], "characters": "\u003E" },
+ ">": { "codepoints": [62], "characters": "\u003E" },
+ "Γ": { "codepoints": [915], "characters": "\u0393" },
+ "Ϝ": { "codepoints": [988], "characters": "\u03DC" },
+ "Ğ": { "codepoints": [286], "characters": "\u011E" },
+ "Ģ": { "codepoints": [290], "characters": "\u0122" },
+ "Ĝ": { "codepoints": [284], "characters": "\u011C" },
+ "Г": { "codepoints": [1043], "characters": "\u0413" },
+ "Ġ": { "codepoints": [288], "characters": "\u0120" },
+ "𝔊": { "codepoints": [120074], "characters": "\uD835\uDD0A" },
+ "⋙": { "codepoints": [8921], "characters": "\u22D9" },
+ "𝔾": { "codepoints": [120126], "characters": "\uD835\uDD3E" },
+ "≥": { "codepoints": [8805], "characters": "\u2265" },
+ "⋛": { "codepoints": [8923], "characters": "\u22DB" },
+ "≧": { "codepoints": [8807], "characters": "\u2267" },
+ "⪢": { "codepoints": [10914], "characters": "\u2AA2" },
+ "≷": { "codepoints": [8823], "characters": "\u2277" },
+ "⩾": { "codepoints": [10878], "characters": "\u2A7E" },
+ "≳": { "codepoints": [8819], "characters": "\u2273" },
+ "𝒢": { "codepoints": [119970], "characters": "\uD835\uDCA2" },
+ "≫": { "codepoints": [8811], "characters": "\u226B" },
+ "Ъ": { "codepoints": [1066], "characters": "\u042A" },
+ "ˇ": { "codepoints": [711], "characters": "\u02C7" },
+ "^": { "codepoints": [94], "characters": "\u005E" },
+ "Ĥ": { "codepoints": [292], "characters": "\u0124" },
+ "ℌ": { "codepoints": [8460], "characters": "\u210C" },
+ "ℋ": { "codepoints": [8459], "characters": "\u210B" },
+ "ℍ": { "codepoints": [8461], "characters": "\u210D" },
+ "─": { "codepoints": [9472], "characters": "\u2500" },
+ "ℋ": { "codepoints": [8459], "characters": "\u210B" },
+ "Ħ": { "codepoints": [294], "characters": "\u0126" },
+ "≎": { "codepoints": [8782], "characters": "\u224E" },
+ "≏": { "codepoints": [8783], "characters": "\u224F" },
+ "Е": { "codepoints": [1045], "characters": "\u0415" },
+ "IJ": { "codepoints": [306], "characters": "\u0132" },
+ "Ё": { "codepoints": [1025], "characters": "\u0401" },
+ "Í": { "codepoints": [205], "characters": "\u00CD" },
+ "Í": { "codepoints": [205], "characters": "\u00CD" },
+ "Î": { "codepoints": [206], "characters": "\u00CE" },
+ "Î": { "codepoints": [206], "characters": "\u00CE" },
+ "И": { "codepoints": [1048], "characters": "\u0418" },
+ "İ": { "codepoints": [304], "characters": "\u0130" },
+ "ℑ": { "codepoints": [8465], "characters": "\u2111" },
+ "Ì": { "codepoints": [204], "characters": "\u00CC" },
+ "Ì": { "codepoints": [204], "characters": "\u00CC" },
+ "ℑ": { "codepoints": [8465], "characters": "\u2111" },
+ "Ī": { "codepoints": [298], "characters": "\u012A" },
+ "ⅈ": { "codepoints": [8520], "characters": "\u2148" },
+ "⇒": { "codepoints": [8658], "characters": "\u21D2" },
+ "∬": { "codepoints": [8748], "characters": "\u222C" },
+ "∫": { "codepoints": [8747], "characters": "\u222B" },
+ "⋂": { "codepoints": [8898], "characters": "\u22C2" },
+ "⁣": { "codepoints": [8291], "characters": "\u2063" },
+ "⁢": { "codepoints": [8290], "characters": "\u2062" },
+ "Į": { "codepoints": [302], "characters": "\u012E" },
+ "𝕀": { "codepoints": [120128], "characters": "\uD835\uDD40" },
+ "Ι": { "codepoints": [921], "characters": "\u0399" },
+ "ℐ": { "codepoints": [8464], "characters": "\u2110" },
+ "Ĩ": { "codepoints": [296], "characters": "\u0128" },
+ "І": { "codepoints": [1030], "characters": "\u0406" },
+ "Ï": { "codepoints": [207], "characters": "\u00CF" },
+ "Ï": { "codepoints": [207], "characters": "\u00CF" },
+ "Ĵ": { "codepoints": [308], "characters": "\u0134" },
+ "Й": { "codepoints": [1049], "characters": "\u0419" },
+ "𝔍": { "codepoints": [120077], "characters": "\uD835\uDD0D" },
+ "𝕁": { "codepoints": [120129], "characters": "\uD835\uDD41" },
+ "𝒥": { "codepoints": [119973], "characters": "\uD835\uDCA5" },
+ "Ј": { "codepoints": [1032], "characters": "\u0408" },
+ "Є": { "codepoints": [1028], "characters": "\u0404" },
+ "Х": { "codepoints": [1061], "characters": "\u0425" },
+ "Ќ": { "codepoints": [1036], "characters": "\u040C" },
+ "Κ": { "codepoints": [922], "characters": "\u039A" },
+ "Ķ": { "codepoints": [310], "characters": "\u0136" },
+ "К": { "codepoints": [1050], "characters": "\u041A" },
+ "𝔎": { "codepoints": [120078], "characters": "\uD835\uDD0E" },
+ "𝕂": { "codepoints": [120130], "characters": "\uD835\uDD42" },
+ "𝒦": { "codepoints": [119974], "characters": "\uD835\uDCA6" },
+ "Љ": { "codepoints": [1033], "characters": "\u0409" },
+ "<": { "codepoints": [60], "characters": "\u003C" },
+ "<": { "codepoints": [60], "characters": "\u003C" },
+ "Ĺ": { "codepoints": [313], "characters": "\u0139" },
+ "Λ": { "codepoints": [923], "characters": "\u039B" },
+ "⟪": { "codepoints": [10218], "characters": "\u27EA" },
+ "ℒ": { "codepoints": [8466], "characters": "\u2112" },
+ "↞": { "codepoints": [8606], "characters": "\u219E" },
+ "Ľ": { "codepoints": [317], "characters": "\u013D" },
+ "Ļ": { "codepoints": [315], "characters": "\u013B" },
+ "Л": { "codepoints": [1051], "characters": "\u041B" },
+ "⟨": { "codepoints": [10216], "characters": "\u27E8" },
+ "←": { "codepoints": [8592], "characters": "\u2190" },
+ "⇤": { "codepoints": [8676], "characters": "\u21E4" },
+ "⇆": { "codepoints": [8646], "characters": "\u21C6" },
+ "⌈": { "codepoints": [8968], "characters": "\u2308" },
+ "⟦": { "codepoints": [10214], "characters": "\u27E6" },
+ "⥡": { "codepoints": [10593], "characters": "\u2961" },
+ "⇃": { "codepoints": [8643], "characters": "\u21C3" },
+ "⥙": { "codepoints": [10585], "characters": "\u2959" },
+ "⌊": { "codepoints": [8970], "characters": "\u230A" },
+ "↔": { "codepoints": [8596], "characters": "\u2194" },
+ "⥎": { "codepoints": [10574], "characters": "\u294E" },
+ "⊣": { "codepoints": [8867], "characters": "\u22A3" },
+ "↤": { "codepoints": [8612], "characters": "\u21A4" },
+ "⥚": { "codepoints": [10586], "characters": "\u295A" },
+ "⊲": { "codepoints": [8882], "characters": "\u22B2" },
+ "⧏": { "codepoints": [10703], "characters": "\u29CF" },
+ "⊴": { "codepoints": [8884], "characters": "\u22B4" },
+ "⥑": { "codepoints": [10577], "characters": "\u2951" },
+ "⥠": { "codepoints": [10592], "characters": "\u2960" },
+ "↿": { "codepoints": [8639], "characters": "\u21BF" },
+ "⥘": { "codepoints": [10584], "characters": "\u2958" },
+ "↼": { "codepoints": [8636], "characters": "\u21BC" },
+ "⥒": { "codepoints": [10578], "characters": "\u2952" },
+ "⇐": { "codepoints": [8656], "characters": "\u21D0" },
+ "⇔": { "codepoints": [8660], "characters": "\u21D4" },
+ "⋚": { "codepoints": [8922], "characters": "\u22DA" },
+ "≦": { "codepoints": [8806], "characters": "\u2266" },
+ "≶": { "codepoints": [8822], "characters": "\u2276" },
+ "⪡": { "codepoints": [10913], "characters": "\u2AA1" },
+ "⩽": { "codepoints": [10877], "characters": "\u2A7D" },
+ "≲": { "codepoints": [8818], "characters": "\u2272" },
+ "𝔏": { "codepoints": [120079], "characters": "\uD835\uDD0F" },
+ "⋘": { "codepoints": [8920], "characters": "\u22D8" },
+ "⇚": { "codepoints": [8666], "characters": "\u21DA" },
+ "Ŀ": { "codepoints": [319], "characters": "\u013F" },
+ "⟵": { "codepoints": [10229], "characters": "\u27F5" },
+ "⟷": { "codepoints": [10231], "characters": "\u27F7" },
+ "⟶": { "codepoints": [10230], "characters": "\u27F6" },
+ "⟸": { "codepoints": [10232], "characters": "\u27F8" },
+ "⟺": { "codepoints": [10234], "characters": "\u27FA" },
+ "⟹": { "codepoints": [10233], "characters": "\u27F9" },
+ "𝕃": { "codepoints": [120131], "characters": "\uD835\uDD43" },
+ "↙": { "codepoints": [8601], "characters": "\u2199" },
+ "↘": { "codepoints": [8600], "characters": "\u2198" },
+ "ℒ": { "codepoints": [8466], "characters": "\u2112" },
+ "↰": { "codepoints": [8624], "characters": "\u21B0" },
+ "Ł": { "codepoints": [321], "characters": "\u0141" },
+ "≪": { "codepoints": [8810], "characters": "\u226A" },
+ "⤅": { "codepoints": [10501], "characters": "\u2905" },
+ "М": { "codepoints": [1052], "characters": "\u041C" },
+ " ": { "codepoints": [8287], "characters": "\u205F" },
+ "ℳ": { "codepoints": [8499], "characters": "\u2133" },
+ "𝔐": { "codepoints": [120080], "characters": "\uD835\uDD10" },
+ "∓": { "codepoints": [8723], "characters": "\u2213" },
+ "𝕄": { "codepoints": [120132], "characters": "\uD835\uDD44" },
+ "ℳ": { "codepoints": [8499], "characters": "\u2133" },
+ "Μ": { "codepoints": [924], "characters": "\u039C" },
+ "Њ": { "codepoints": [1034], "characters": "\u040A" },
+ "Ń": { "codepoints": [323], "characters": "\u0143" },
+ "Ň": { "codepoints": [327], "characters": "\u0147" },
+ "Ņ": { "codepoints": [325], "characters": "\u0145" },
+ "Н": { "codepoints": [1053], "characters": "\u041D" },
+ "​": { "codepoints": [8203], "characters": "\u200B" },
+ "​": { "codepoints": [8203], "characters": "\u200B" },
+ "​": { "codepoints": [8203], "characters": "\u200B" },
+ "​": { "codepoints": [8203], "characters": "\u200B" },
+ "≫": { "codepoints": [8811], "characters": "\u226B" },
+ "≪": { "codepoints": [8810], "characters": "\u226A" },
+ "
": { "codepoints": [10], "characters": "\u000A" },
+ "𝔑": { "codepoints": [120081], "characters": "\uD835\uDD11" },
+ "⁠": { "codepoints": [8288], "characters": "\u2060" },
+ " ": { "codepoints": [160], "characters": "\u00A0" },
+ "ℕ": { "codepoints": [8469], "characters": "\u2115" },
+ "⫬": { "codepoints": [10988], "characters": "\u2AEC" },
+ "≢": { "codepoints": [8802], "characters": "\u2262" },
+ "≭": { "codepoints": [8813], "characters": "\u226D" },
+ "∦": { "codepoints": [8742], "characters": "\u2226" },
+ "∉": { "codepoints": [8713], "characters": "\u2209" },
+ "≠": { "codepoints": [8800], "characters": "\u2260" },
+ "≂̸": { "codepoints": [8770, 824], "characters": "\u2242\u0338" },
+ "∄": { "codepoints": [8708], "characters": "\u2204" },
+ "≯": { "codepoints": [8815], "characters": "\u226F" },
+ "≱": { "codepoints": [8817], "characters": "\u2271" },
+ "≧̸": { "codepoints": [8807, 824], "characters": "\u2267\u0338" },
+ "≫̸": { "codepoints": [8811, 824], "characters": "\u226B\u0338" },
+ "≹": { "codepoints": [8825], "characters": "\u2279" },
+ "⩾̸": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" },
+ "≵": { "codepoints": [8821], "characters": "\u2275" },
+ "≎̸": { "codepoints": [8782, 824], "characters": "\u224E\u0338" },
+ "≏̸": { "codepoints": [8783, 824], "characters": "\u224F\u0338" },
+ "⋪": { "codepoints": [8938], "characters": "\u22EA" },
+ "⧏̸": { "codepoints": [10703, 824], "characters": "\u29CF\u0338" },
+ "⋬": { "codepoints": [8940], "characters": "\u22EC" },
+ "≮": { "codepoints": [8814], "characters": "\u226E" },
+ "≰": { "codepoints": [8816], "characters": "\u2270" },
+ "≸": { "codepoints": [8824], "characters": "\u2278" },
+ "≪̸": { "codepoints": [8810, 824], "characters": "\u226A\u0338" },
+ "⩽̸": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" },
+ "≴": { "codepoints": [8820], "characters": "\u2274" },
+ "⪢̸": { "codepoints": [10914, 824], "characters": "\u2AA2\u0338" },
+ "⪡̸": { "codepoints": [10913, 824], "characters": "\u2AA1\u0338" },
+ "⊀": { "codepoints": [8832], "characters": "\u2280" },
+ "⪯̸": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" },
+ "⋠": { "codepoints": [8928], "characters": "\u22E0" },
+ "∌": { "codepoints": [8716], "characters": "\u220C" },
+ "⋫": { "codepoints": [8939], "characters": "\u22EB" },
+ "⧐̸": { "codepoints": [10704, 824], "characters": "\u29D0\u0338" },
+ "⋭": { "codepoints": [8941], "characters": "\u22ED" },
+ "⊏̸": { "codepoints": [8847, 824], "characters": "\u228F\u0338" },
+ "⋢": { "codepoints": [8930], "characters": "\u22E2" },
+ "⊐̸": { "codepoints": [8848, 824], "characters": "\u2290\u0338" },
+ "⋣": { "codepoints": [8931], "characters": "\u22E3" },
+ "⊂⃒": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" },
+ "⊈": { "codepoints": [8840], "characters": "\u2288" },
+ "⊁": { "codepoints": [8833], "characters": "\u2281" },
+ "⪰̸": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" },
+ "⋡": { "codepoints": [8929], "characters": "\u22E1" },
+ "≿̸": { "codepoints": [8831, 824], "characters": "\u227F\u0338" },
+ "⊃⃒": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" },
+ "⊉": { "codepoints": [8841], "characters": "\u2289" },
+ "≁": { "codepoints": [8769], "characters": "\u2241" },
+ "≄": { "codepoints": [8772], "characters": "\u2244" },
+ "≇": { "codepoints": [8775], "characters": "\u2247" },
+ "≉": { "codepoints": [8777], "characters": "\u2249" },
+ "∤": { "codepoints": [8740], "characters": "\u2224" },
+ "𝒩": { "codepoints": [119977], "characters": "\uD835\uDCA9" },
+ "Ñ": { "codepoints": [209], "characters": "\u00D1" },
+ "Ñ": { "codepoints": [209], "characters": "\u00D1" },
+ "Ν": { "codepoints": [925], "characters": "\u039D" },
+ "Œ": { "codepoints": [338], "characters": "\u0152" },
+ "Ó": { "codepoints": [211], "characters": "\u00D3" },
+ "Ó": { "codepoints": [211], "characters": "\u00D3" },
+ "Ô": { "codepoints": [212], "characters": "\u00D4" },
+ "Ô": { "codepoints": [212], "characters": "\u00D4" },
+ "О": { "codepoints": [1054], "characters": "\u041E" },
+ "Ő": { "codepoints": [336], "characters": "\u0150" },
+ "𝔒": { "codepoints": [120082], "characters": "\uD835\uDD12" },
+ "Ò": { "codepoints": [210], "characters": "\u00D2" },
+ "Ò": { "codepoints": [210], "characters": "\u00D2" },
+ "Ō": { "codepoints": [332], "characters": "\u014C" },
+ "Ω": { "codepoints": [937], "characters": "\u03A9" },
+ "Ο": { "codepoints": [927], "characters": "\u039F" },
+ "𝕆": { "codepoints": [120134], "characters": "\uD835\uDD46" },
+ "“": { "codepoints": [8220], "characters": "\u201C" },
+ "‘": { "codepoints": [8216], "characters": "\u2018" },
+ "⩔": { "codepoints": [10836], "characters": "\u2A54" },
+ "𝒪": { "codepoints": [119978], "characters": "\uD835\uDCAA" },
+ "Ø": { "codepoints": [216], "characters": "\u00D8" },
+ "Ø": { "codepoints": [216], "characters": "\u00D8" },
+ "Õ": { "codepoints": [213], "characters": "\u00D5" },
+ "Õ": { "codepoints": [213], "characters": "\u00D5" },
+ "⨷": { "codepoints": [10807], "characters": "\u2A37" },
+ "Ö": { "codepoints": [214], "characters": "\u00D6" },
+ "Ö": { "codepoints": [214], "characters": "\u00D6" },
+ "‾": { "codepoints": [8254], "characters": "\u203E" },
+ "⏞": { "codepoints": [9182], "characters": "\u23DE" },
+ "⎴": { "codepoints": [9140], "characters": "\u23B4" },
+ "⏜": { "codepoints": [9180], "characters": "\u23DC" },
+ "∂": { "codepoints": [8706], "characters": "\u2202" },
+ "П": { "codepoints": [1055], "characters": "\u041F" },
+ "𝔓": { "codepoints": [120083], "characters": "\uD835\uDD13" },
+ "Φ": { "codepoints": [934], "characters": "\u03A6" },
+ "Π": { "codepoints": [928], "characters": "\u03A0" },
+ "±": { "codepoints": [177], "characters": "\u00B1" },
+ "ℌ": { "codepoints": [8460], "characters": "\u210C" },
+ "ℙ": { "codepoints": [8473], "characters": "\u2119" },
+ "⪻": { "codepoints": [10939], "characters": "\u2ABB" },
+ "≺": { "codepoints": [8826], "characters": "\u227A" },
+ "⪯": { "codepoints": [10927], "characters": "\u2AAF" },
+ "≼": { "codepoints": [8828], "characters": "\u227C" },
+ "≾": { "codepoints": [8830], "characters": "\u227E" },
+ "″": { "codepoints": [8243], "characters": "\u2033" },
+ "∏": { "codepoints": [8719], "characters": "\u220F" },
+ "∷": { "codepoints": [8759], "characters": "\u2237" },
+ "∝": { "codepoints": [8733], "characters": "\u221D" },
+ "𝒫": { "codepoints": [119979], "characters": "\uD835\uDCAB" },
+ "Ψ": { "codepoints": [936], "characters": "\u03A8" },
+ """: { "codepoints": [34], "characters": "\u0022" },
+ """: { "codepoints": [34], "characters": "\u0022" },
+ "𝔔": { "codepoints": [120084], "characters": "\uD835\uDD14" },
+ "ℚ": { "codepoints": [8474], "characters": "\u211A" },
+ "𝒬": { "codepoints": [119980], "characters": "\uD835\uDCAC" },
+ "⤐": { "codepoints": [10512], "characters": "\u2910" },
+ "®": { "codepoints": [174], "characters": "\u00AE" },
+ "®": { "codepoints": [174], "characters": "\u00AE" },
+ "Ŕ": { "codepoints": [340], "characters": "\u0154" },
+ "⟫": { "codepoints": [10219], "characters": "\u27EB" },
+ "↠": { "codepoints": [8608], "characters": "\u21A0" },
+ "⤖": { "codepoints": [10518], "characters": "\u2916" },
+ "Ř": { "codepoints": [344], "characters": "\u0158" },
+ "Ŗ": { "codepoints": [342], "characters": "\u0156" },
+ "Р": { "codepoints": [1056], "characters": "\u0420" },
+ "ℜ": { "codepoints": [8476], "characters": "\u211C" },
+ "∋": { "codepoints": [8715], "characters": "\u220B" },
+ "⇋": { "codepoints": [8651], "characters": "\u21CB" },
+ "⥯": { "codepoints": [10607], "characters": "\u296F" },
+ "ℜ": { "codepoints": [8476], "characters": "\u211C" },
+ "Ρ": { "codepoints": [929], "characters": "\u03A1" },
+ "⟩": { "codepoints": [10217], "characters": "\u27E9" },
+ "→": { "codepoints": [8594], "characters": "\u2192" },
+ "⇥": { "codepoints": [8677], "characters": "\u21E5" },
+ "⇄": { "codepoints": [8644], "characters": "\u21C4" },
+ "⌉": { "codepoints": [8969], "characters": "\u2309" },
+ "⟧": { "codepoints": [10215], "characters": "\u27E7" },
+ "⥝": { "codepoints": [10589], "characters": "\u295D" },
+ "⇂": { "codepoints": [8642], "characters": "\u21C2" },
+ "⥕": { "codepoints": [10581], "characters": "\u2955" },
+ "⌋": { "codepoints": [8971], "characters": "\u230B" },
+ "⊢": { "codepoints": [8866], "characters": "\u22A2" },
+ "↦": { "codepoints": [8614], "characters": "\u21A6" },
+ "⥛": { "codepoints": [10587], "characters": "\u295B" },
+ "⊳": { "codepoints": [8883], "characters": "\u22B3" },
+ "⧐": { "codepoints": [10704], "characters": "\u29D0" },
+ "⊵": { "codepoints": [8885], "characters": "\u22B5" },
+ "⥏": { "codepoints": [10575], "characters": "\u294F" },
+ "⥜": { "codepoints": [10588], "characters": "\u295C" },
+ "↾": { "codepoints": [8638], "characters": "\u21BE" },
+ "⥔": { "codepoints": [10580], "characters": "\u2954" },
+ "⇀": { "codepoints": [8640], "characters": "\u21C0" },
+ "⥓": { "codepoints": [10579], "characters": "\u2953" },
+ "⇒": { "codepoints": [8658], "characters": "\u21D2" },
+ "ℝ": { "codepoints": [8477], "characters": "\u211D" },
+ "⥰": { "codepoints": [10608], "characters": "\u2970" },
+ "⇛": { "codepoints": [8667], "characters": "\u21DB" },
+ "ℛ": { "codepoints": [8475], "characters": "\u211B" },
+ "↱": { "codepoints": [8625], "characters": "\u21B1" },
+ "⧴": { "codepoints": [10740], "characters": "\u29F4" },
+ "Щ": { "codepoints": [1065], "characters": "\u0429" },
+ "Ш": { "codepoints": [1064], "characters": "\u0428" },
+ "Ь": { "codepoints": [1068], "characters": "\u042C" },
+ "Ś": { "codepoints": [346], "characters": "\u015A" },
+ "⪼": { "codepoints": [10940], "characters": "\u2ABC" },
+ "Š": { "codepoints": [352], "characters": "\u0160" },
+ "Ş": { "codepoints": [350], "characters": "\u015E" },
+ "Ŝ": { "codepoints": [348], "characters": "\u015C" },
+ "С": { "codepoints": [1057], "characters": "\u0421" },
+ "𝔖": { "codepoints": [120086], "characters": "\uD835\uDD16" },
+ "↓": { "codepoints": [8595], "characters": "\u2193" },
+ "←": { "codepoints": [8592], "characters": "\u2190" },
+ "→": { "codepoints": [8594], "characters": "\u2192" },
+ "↑": { "codepoints": [8593], "characters": "\u2191" },
+ "Σ": { "codepoints": [931], "characters": "\u03A3" },
+ "∘": { "codepoints": [8728], "characters": "\u2218" },
+ "𝕊": { "codepoints": [120138], "characters": "\uD835\uDD4A" },
+ "√": { "codepoints": [8730], "characters": "\u221A" },
+ "□": { "codepoints": [9633], "characters": "\u25A1" },
+ "⊓": { "codepoints": [8851], "characters": "\u2293" },
+ "⊏": { "codepoints": [8847], "characters": "\u228F" },
+ "⊑": { "codepoints": [8849], "characters": "\u2291" },
+ "⊐": { "codepoints": [8848], "characters": "\u2290" },
+ "⊒": { "codepoints": [8850], "characters": "\u2292" },
+ "⊔": { "codepoints": [8852], "characters": "\u2294" },
+ "𝒮": { "codepoints": [119982], "characters": "\uD835\uDCAE" },
+ "⋆": { "codepoints": [8902], "characters": "\u22C6" },
+ "⋐": { "codepoints": [8912], "characters": "\u22D0" },
+ "⋐": { "codepoints": [8912], "characters": "\u22D0" },
+ "⊆": { "codepoints": [8838], "characters": "\u2286" },
+ "≻": { "codepoints": [8827], "characters": "\u227B" },
+ "⪰": { "codepoints": [10928], "characters": "\u2AB0" },
+ "≽": { "codepoints": [8829], "characters": "\u227D" },
+ "≿": { "codepoints": [8831], "characters": "\u227F" },
+ "∋": { "codepoints": [8715], "characters": "\u220B" },
+ "∑": { "codepoints": [8721], "characters": "\u2211" },
+ "⋑": { "codepoints": [8913], "characters": "\u22D1" },
+ "⊃": { "codepoints": [8835], "characters": "\u2283" },
+ "⊇": { "codepoints": [8839], "characters": "\u2287" },
+ "⋑": { "codepoints": [8913], "characters": "\u22D1" },
+ "Þ": { "codepoints": [222], "characters": "\u00DE" },
+ "Þ": { "codepoints": [222], "characters": "\u00DE" },
+ "™": { "codepoints": [8482], "characters": "\u2122" },
+ "Ћ": { "codepoints": [1035], "characters": "\u040B" },
+ "Ц": { "codepoints": [1062], "characters": "\u0426" },
+ "	": { "codepoints": [9], "characters": "\u0009" },
+ "Τ": { "codepoints": [932], "characters": "\u03A4" },
+ "Ť": { "codepoints": [356], "characters": "\u0164" },
+ "Ţ": { "codepoints": [354], "characters": "\u0162" },
+ "Т": { "codepoints": [1058], "characters": "\u0422" },
+ "𝔗": { "codepoints": [120087], "characters": "\uD835\uDD17" },
+ "∴": { "codepoints": [8756], "characters": "\u2234" },
+ "Θ": { "codepoints": [920], "characters": "\u0398" },
+ "  ": { "codepoints": [8287, 8202], "characters": "\u205F\u200A" },
+ " ": { "codepoints": [8201], "characters": "\u2009" },
+ "∼": { "codepoints": [8764], "characters": "\u223C" },
+ "≃": { "codepoints": [8771], "characters": "\u2243" },
+ "≅": { "codepoints": [8773], "characters": "\u2245" },
+ "≈": { "codepoints": [8776], "characters": "\u2248" },
+ "𝕋": { "codepoints": [120139], "characters": "\uD835\uDD4B" },
+ "⃛": { "codepoints": [8411], "characters": "\u20DB" },
+ "𝒯": { "codepoints": [119983], "characters": "\uD835\uDCAF" },
+ "Ŧ": { "codepoints": [358], "characters": "\u0166" },
+ "Ú": { "codepoints": [218], "characters": "\u00DA" },
+ "Ú": { "codepoints": [218], "characters": "\u00DA" },
+ "↟": { "codepoints": [8607], "characters": "\u219F" },
+ "⥉": { "codepoints": [10569], "characters": "\u2949" },
+ "Ў": { "codepoints": [1038], "characters": "\u040E" },
+ "Ŭ": { "codepoints": [364], "characters": "\u016C" },
+ "Û": { "codepoints": [219], "characters": "\u00DB" },
+ "Û": { "codepoints": [219], "characters": "\u00DB" },
+ "У": { "codepoints": [1059], "characters": "\u0423" },
+ "Ű": { "codepoints": [368], "characters": "\u0170" },
+ "𝔘": { "codepoints": [120088], "characters": "\uD835\uDD18" },
+ "Ù": { "codepoints": [217], "characters": "\u00D9" },
+ "Ù": { "codepoints": [217], "characters": "\u00D9" },
+ "Ū": { "codepoints": [362], "characters": "\u016A" },
+ "_": { "codepoints": [95], "characters": "\u005F" },
+ "⏟": { "codepoints": [9183], "characters": "\u23DF" },
+ "⎵": { "codepoints": [9141], "characters": "\u23B5" },
+ "⏝": { "codepoints": [9181], "characters": "\u23DD" },
+ "⋃": { "codepoints": [8899], "characters": "\u22C3" },
+ "⊎": { "codepoints": [8846], "characters": "\u228E" },
+ "Ų": { "codepoints": [370], "characters": "\u0172" },
+ "𝕌": { "codepoints": [120140], "characters": "\uD835\uDD4C" },
+ "↑": { "codepoints": [8593], "characters": "\u2191" },
+ "⤒": { "codepoints": [10514], "characters": "\u2912" },
+ "⇅": { "codepoints": [8645], "characters": "\u21C5" },
+ "↕": { "codepoints": [8597], "characters": "\u2195" },
+ "⥮": { "codepoints": [10606], "characters": "\u296E" },
+ "⊥": { "codepoints": [8869], "characters": "\u22A5" },
+ "↥": { "codepoints": [8613], "characters": "\u21A5" },
+ "⇑": { "codepoints": [8657], "characters": "\u21D1" },
+ "⇕": { "codepoints": [8661], "characters": "\u21D5" },
+ "↖": { "codepoints": [8598], "characters": "\u2196" },
+ "↗": { "codepoints": [8599], "characters": "\u2197" },
+ "ϒ": { "codepoints": [978], "characters": "\u03D2" },
+ "Υ": { "codepoints": [933], "characters": "\u03A5" },
+ "Ů": { "codepoints": [366], "characters": "\u016E" },
+ "𝒰": { "codepoints": [119984], "characters": "\uD835\uDCB0" },
+ "Ũ": { "codepoints": [360], "characters": "\u0168" },
+ "Ü": { "codepoints": [220], "characters": "\u00DC" },
+ "Ü": { "codepoints": [220], "characters": "\u00DC" },
+ "⊫": { "codepoints": [8875], "characters": "\u22AB" },
+ "⫫": { "codepoints": [10987], "characters": "\u2AEB" },
+ "В": { "codepoints": [1042], "characters": "\u0412" },
+ "⊩": { "codepoints": [8873], "characters": "\u22A9" },
+ "⫦": { "codepoints": [10982], "characters": "\u2AE6" },
+ "⋁": { "codepoints": [8897], "characters": "\u22C1" },
+ "‖": { "codepoints": [8214], "characters": "\u2016" },
+ "‖": { "codepoints": [8214], "characters": "\u2016" },
+ "∣": { "codepoints": [8739], "characters": "\u2223" },
+ "|": { "codepoints": [124], "characters": "\u007C" },
+ "❘": { "codepoints": [10072], "characters": "\u2758" },
+ "≀": { "codepoints": [8768], "characters": "\u2240" },
+ " ": { "codepoints": [8202], "characters": "\u200A" },
+ "𝔙": { "codepoints": [120089], "characters": "\uD835\uDD19" },
+ "𝕍": { "codepoints": [120141], "characters": "\uD835\uDD4D" },
+ "𝒱": { "codepoints": [119985], "characters": "\uD835\uDCB1" },
+ "⊪": { "codepoints": [8874], "characters": "\u22AA" },
+ "Ŵ": { "codepoints": [372], "characters": "\u0174" },
+ "⋀": { "codepoints": [8896], "characters": "\u22C0" },
+ "𝔚": { "codepoints": [120090], "characters": "\uD835\uDD1A" },
+ "𝕎": { "codepoints": [120142], "characters": "\uD835\uDD4E" },
+ "𝒲": { "codepoints": [119986], "characters": "\uD835\uDCB2" },
+ "𝔛": { "codepoints": [120091], "characters": "\uD835\uDD1B" },
+ "Ξ": { "codepoints": [926], "characters": "\u039E" },
+ "𝕏": { "codepoints": [120143], "characters": "\uD835\uDD4F" },
+ "𝒳": { "codepoints": [119987], "characters": "\uD835\uDCB3" },
+ "Я": { "codepoints": [1071], "characters": "\u042F" },
+ "Ї": { "codepoints": [1031], "characters": "\u0407" },
+ "Ю": { "codepoints": [1070], "characters": "\u042E" },
+ "Ý": { "codepoints": [221], "characters": "\u00DD" },
+ "Ý": { "codepoints": [221], "characters": "\u00DD" },
+ "Ŷ": { "codepoints": [374], "characters": "\u0176" },
+ "Ы": { "codepoints": [1067], "characters": "\u042B" },
+ "𝔜": { "codepoints": [120092], "characters": "\uD835\uDD1C" },
+ "𝕐": { "codepoints": [120144], "characters": "\uD835\uDD50" },
+ "𝒴": { "codepoints": [119988], "characters": "\uD835\uDCB4" },
+ "Ÿ": { "codepoints": [376], "characters": "\u0178" },
+ "Ж": { "codepoints": [1046], "characters": "\u0416" },
+ "Ź": { "codepoints": [377], "characters": "\u0179" },
+ "Ž": { "codepoints": [381], "characters": "\u017D" },
+ "З": { "codepoints": [1047], "characters": "\u0417" },
+ "Ż": { "codepoints": [379], "characters": "\u017B" },
+ "​": { "codepoints": [8203], "characters": "\u200B" },
+ "Ζ": { "codepoints": [918], "characters": "\u0396" },
+ "ℨ": { "codepoints": [8488], "characters": "\u2128" },
+ "ℤ": { "codepoints": [8484], "characters": "\u2124" },
+ "𝒵": { "codepoints": [119989], "characters": "\uD835\uDCB5" },
+ "á": { "codepoints": [225], "characters": "\u00E1" },
+ "á": { "codepoints": [225], "characters": "\u00E1" },
+ "ă": { "codepoints": [259], "characters": "\u0103" },
+ "∾": { "codepoints": [8766], "characters": "\u223E" },
+ "∾̳": { "codepoints": [8766, 819], "characters": "\u223E\u0333" },
+ "∿": { "codepoints": [8767], "characters": "\u223F" },
+ "â": { "codepoints": [226], "characters": "\u00E2" },
+ "â": { "codepoints": [226], "characters": "\u00E2" },
+ "´": { "codepoints": [180], "characters": "\u00B4" },
+ "´": { "codepoints": [180], "characters": "\u00B4" },
+ "а": { "codepoints": [1072], "characters": "\u0430" },
+ "æ": { "codepoints": [230], "characters": "\u00E6" },
+ "æ": { "codepoints": [230], "characters": "\u00E6" },
+ "⁡": { "codepoints": [8289], "characters": "\u2061" },
+ "𝔞": { "codepoints": [120094], "characters": "\uD835\uDD1E" },
+ "à": { "codepoints": [224], "characters": "\u00E0" },
+ "à": { "codepoints": [224], "characters": "\u00E0" },
+ "ℵ": { "codepoints": [8501], "characters": "\u2135" },
+ "ℵ": { "codepoints": [8501], "characters": "\u2135" },
+ "α": { "codepoints": [945], "characters": "\u03B1" },
+ "ā": { "codepoints": [257], "characters": "\u0101" },
+ "⨿": { "codepoints": [10815], "characters": "\u2A3F" },
+ "&": { "codepoints": [38], "characters": "\u0026" },
+ "&": { "codepoints": [38], "characters": "\u0026" },
+ "∧": { "codepoints": [8743], "characters": "\u2227" },
+ "⩕": { "codepoints": [10837], "characters": "\u2A55" },
+ "⩜": { "codepoints": [10844], "characters": "\u2A5C" },
+ "⩘": { "codepoints": [10840], "characters": "\u2A58" },
+ "⩚": { "codepoints": [10842], "characters": "\u2A5A" },
+ "∠": { "codepoints": [8736], "characters": "\u2220" },
+ "⦤": { "codepoints": [10660], "characters": "\u29A4" },
+ "∠": { "codepoints": [8736], "characters": "\u2220" },
+ "∡": { "codepoints": [8737], "characters": "\u2221" },
+ "⦨": { "codepoints": [10664], "characters": "\u29A8" },
+ "⦩": { "codepoints": [10665], "characters": "\u29A9" },
+ "⦪": { "codepoints": [10666], "characters": "\u29AA" },
+ "⦫": { "codepoints": [10667], "characters": "\u29AB" },
+ "⦬": { "codepoints": [10668], "characters": "\u29AC" },
+ "⦭": { "codepoints": [10669], "characters": "\u29AD" },
+ "⦮": { "codepoints": [10670], "characters": "\u29AE" },
+ "⦯": { "codepoints": [10671], "characters": "\u29AF" },
+ "∟": { "codepoints": [8735], "characters": "\u221F" },
+ "⊾": { "codepoints": [8894], "characters": "\u22BE" },
+ "⦝": { "codepoints": [10653], "characters": "\u299D" },
+ "∢": { "codepoints": [8738], "characters": "\u2222" },
+ "Å": { "codepoints": [197], "characters": "\u00C5" },
+ "⍼": { "codepoints": [9084], "characters": "\u237C" },
+ "ą": { "codepoints": [261], "characters": "\u0105" },
+ "𝕒": { "codepoints": [120146], "characters": "\uD835\uDD52" },
+ "≈": { "codepoints": [8776], "characters": "\u2248" },
+ "⩰": { "codepoints": [10864], "characters": "\u2A70" },
+ "⩯": { "codepoints": [10863], "characters": "\u2A6F" },
+ "≊": { "codepoints": [8778], "characters": "\u224A" },
+ "≋": { "codepoints": [8779], "characters": "\u224B" },
+ "'": { "codepoints": [39], "characters": "\u0027" },
+ "≈": { "codepoints": [8776], "characters": "\u2248" },
+ "≊": { "codepoints": [8778], "characters": "\u224A" },
+ "å": { "codepoints": [229], "characters": "\u00E5" },
+ "å": { "codepoints": [229], "characters": "\u00E5" },
+ "𝒶": { "codepoints": [119990], "characters": "\uD835\uDCB6" },
+ "*": { "codepoints": [42], "characters": "\u002A" },
+ "≈": { "codepoints": [8776], "characters": "\u2248" },
+ "≍": { "codepoints": [8781], "characters": "\u224D" },
+ "ã": { "codepoints": [227], "characters": "\u00E3" },
+ "ã": { "codepoints": [227], "characters": "\u00E3" },
+ "ä": { "codepoints": [228], "characters": "\u00E4" },
+ "ä": { "codepoints": [228], "characters": "\u00E4" },
+ "∳": { "codepoints": [8755], "characters": "\u2233" },
+ "⨑": { "codepoints": [10769], "characters": "\u2A11" },
+ "⫭": { "codepoints": [10989], "characters": "\u2AED" },
+ "≌": { "codepoints": [8780], "characters": "\u224C" },
+ "϶": { "codepoints": [1014], "characters": "\u03F6" },
+ "‵": { "codepoints": [8245], "characters": "\u2035" },
+ "∽": { "codepoints": [8765], "characters": "\u223D" },
+ "⋍": { "codepoints": [8909], "characters": "\u22CD" },
+ "⊽": { "codepoints": [8893], "characters": "\u22BD" },
+ "⌅": { "codepoints": [8965], "characters": "\u2305" },
+ "⌅": { "codepoints": [8965], "characters": "\u2305" },
+ "⎵": { "codepoints": [9141], "characters": "\u23B5" },
+ "⎶": { "codepoints": [9142], "characters": "\u23B6" },
+ "≌": { "codepoints": [8780], "characters": "\u224C" },
+ "б": { "codepoints": [1073], "characters": "\u0431" },
+ "„": { "codepoints": [8222], "characters": "\u201E" },
+ "∵": { "codepoints": [8757], "characters": "\u2235" },
+ "∵": { "codepoints": [8757], "characters": "\u2235" },
+ "⦰": { "codepoints": [10672], "characters": "\u29B0" },
+ "϶": { "codepoints": [1014], "characters": "\u03F6" },
+ "ℬ": { "codepoints": [8492], "characters": "\u212C" },
+ "β": { "codepoints": [946], "characters": "\u03B2" },
+ "ℶ": { "codepoints": [8502], "characters": "\u2136" },
+ "≬": { "codepoints": [8812], "characters": "\u226C" },
+ "𝔟": { "codepoints": [120095], "characters": "\uD835\uDD1F" },
+ "⋂": { "codepoints": [8898], "characters": "\u22C2" },
+ "◯": { "codepoints": [9711], "characters": "\u25EF" },
+ "⋃": { "codepoints": [8899], "characters": "\u22C3" },
+ "⨀": { "codepoints": [10752], "characters": "\u2A00" },
+ "⨁": { "codepoints": [10753], "characters": "\u2A01" },
+ "⨂": { "codepoints": [10754], "characters": "\u2A02" },
+ "⨆": { "codepoints": [10758], "characters": "\u2A06" },
+ "★": { "codepoints": [9733], "characters": "\u2605" },
+ "▽": { "codepoints": [9661], "characters": "\u25BD" },
+ "△": { "codepoints": [9651], "characters": "\u25B3" },
+ "⨄": { "codepoints": [10756], "characters": "\u2A04" },
+ "⋁": { "codepoints": [8897], "characters": "\u22C1" },
+ "⋀": { "codepoints": [8896], "characters": "\u22C0" },
+ "⤍": { "codepoints": [10509], "characters": "\u290D" },
+ "⧫": { "codepoints": [10731], "characters": "\u29EB" },
+ "▪": { "codepoints": [9642], "characters": "\u25AA" },
+ "▴": { "codepoints": [9652], "characters": "\u25B4" },
+ "▾": { "codepoints": [9662], "characters": "\u25BE" },
+ "◂": { "codepoints": [9666], "characters": "\u25C2" },
+ "▸": { "codepoints": [9656], "characters": "\u25B8" },
+ "␣": { "codepoints": [9251], "characters": "\u2423" },
+ "▒": { "codepoints": [9618], "characters": "\u2592" },
+ "░": { "codepoints": [9617], "characters": "\u2591" },
+ "▓": { "codepoints": [9619], "characters": "\u2593" },
+ "█": { "codepoints": [9608], "characters": "\u2588" },
+ "=⃥": { "codepoints": [61, 8421], "characters": "\u003D\u20E5" },
+ "≡⃥": { "codepoints": [8801, 8421], "characters": "\u2261\u20E5" },
+ "⌐": { "codepoints": [8976], "characters": "\u2310" },
+ "𝕓": { "codepoints": [120147], "characters": "\uD835\uDD53" },
+ "⊥": { "codepoints": [8869], "characters": "\u22A5" },
+ "⊥": { "codepoints": [8869], "characters": "\u22A5" },
+ "⋈": { "codepoints": [8904], "characters": "\u22C8" },
+ "╗": { "codepoints": [9559], "characters": "\u2557" },
+ "╔": { "codepoints": [9556], "characters": "\u2554" },
+ "╖": { "codepoints": [9558], "characters": "\u2556" },
+ "╓": { "codepoints": [9555], "characters": "\u2553" },
+ "═": { "codepoints": [9552], "characters": "\u2550" },
+ "╦": { "codepoints": [9574], "characters": "\u2566" },
+ "╩": { "codepoints": [9577], "characters": "\u2569" },
+ "╤": { "codepoints": [9572], "characters": "\u2564" },
+ "╧": { "codepoints": [9575], "characters": "\u2567" },
+ "╝": { "codepoints": [9565], "characters": "\u255D" },
+ "╚": { "codepoints": [9562], "characters": "\u255A" },
+ "╜": { "codepoints": [9564], "characters": "\u255C" },
+ "╙": { "codepoints": [9561], "characters": "\u2559" },
+ "║": { "codepoints": [9553], "characters": "\u2551" },
+ "╬": { "codepoints": [9580], "characters": "\u256C" },
+ "╣": { "codepoints": [9571], "characters": "\u2563" },
+ "╠": { "codepoints": [9568], "characters": "\u2560" },
+ "╫": { "codepoints": [9579], "characters": "\u256B" },
+ "╢": { "codepoints": [9570], "characters": "\u2562" },
+ "╟": { "codepoints": [9567], "characters": "\u255F" },
+ "⧉": { "codepoints": [10697], "characters": "\u29C9" },
+ "╕": { "codepoints": [9557], "characters": "\u2555" },
+ "╒": { "codepoints": [9554], "characters": "\u2552" },
+ "┐": { "codepoints": [9488], "characters": "\u2510" },
+ "┌": { "codepoints": [9484], "characters": "\u250C" },
+ "─": { "codepoints": [9472], "characters": "\u2500" },
+ "╥": { "codepoints": [9573], "characters": "\u2565" },
+ "╨": { "codepoints": [9576], "characters": "\u2568" },
+ "┬": { "codepoints": [9516], "characters": "\u252C" },
+ "┴": { "codepoints": [9524], "characters": "\u2534" },
+ "⊟": { "codepoints": [8863], "characters": "\u229F" },
+ "⊞": { "codepoints": [8862], "characters": "\u229E" },
+ "⊠": { "codepoints": [8864], "characters": "\u22A0" },
+ "╛": { "codepoints": [9563], "characters": "\u255B" },
+ "╘": { "codepoints": [9560], "characters": "\u2558" },
+ "┘": { "codepoints": [9496], "characters": "\u2518" },
+ "└": { "codepoints": [9492], "characters": "\u2514" },
+ "│": { "codepoints": [9474], "characters": "\u2502" },
+ "╪": { "codepoints": [9578], "characters": "\u256A" },
+ "╡": { "codepoints": [9569], "characters": "\u2561" },
+ "╞": { "codepoints": [9566], "characters": "\u255E" },
+ "┼": { "codepoints": [9532], "characters": "\u253C" },
+ "┤": { "codepoints": [9508], "characters": "\u2524" },
+ "├": { "codepoints": [9500], "characters": "\u251C" },
+ "‵": { "codepoints": [8245], "characters": "\u2035" },
+ "˘": { "codepoints": [728], "characters": "\u02D8" },
+ "¦": { "codepoints": [166], "characters": "\u00A6" },
+ "¦": { "codepoints": [166], "characters": "\u00A6" },
+ "𝒷": { "codepoints": [119991], "characters": "\uD835\uDCB7" },
+ "⁏": { "codepoints": [8271], "characters": "\u204F" },
+ "∽": { "codepoints": [8765], "characters": "\u223D" },
+ "⋍": { "codepoints": [8909], "characters": "\u22CD" },
+ "\": { "codepoints": [92], "characters": "\u005C" },
+ "⧅": { "codepoints": [10693], "characters": "\u29C5" },
+ "⟈": { "codepoints": [10184], "characters": "\u27C8" },
+ "•": { "codepoints": [8226], "characters": "\u2022" },
+ "•": { "codepoints": [8226], "characters": "\u2022" },
+ "≎": { "codepoints": [8782], "characters": "\u224E" },
+ "⪮": { "codepoints": [10926], "characters": "\u2AAE" },
+ "≏": { "codepoints": [8783], "characters": "\u224F" },
+ "≏": { "codepoints": [8783], "characters": "\u224F" },
+ "ć": { "codepoints": [263], "characters": "\u0107" },
+ "∩": { "codepoints": [8745], "characters": "\u2229" },
+ "⩄": { "codepoints": [10820], "characters": "\u2A44" },
+ "⩉": { "codepoints": [10825], "characters": "\u2A49" },
+ "⩋": { "codepoints": [10827], "characters": "\u2A4B" },
+ "⩇": { "codepoints": [10823], "characters": "\u2A47" },
+ "⩀": { "codepoints": [10816], "characters": "\u2A40" },
+ "∩︀": { "codepoints": [8745, 65024], "characters": "\u2229\uFE00" },
+ "⁁": { "codepoints": [8257], "characters": "\u2041" },
+ "ˇ": { "codepoints": [711], "characters": "\u02C7" },
+ "⩍": { "codepoints": [10829], "characters": "\u2A4D" },
+ "č": { "codepoints": [269], "characters": "\u010D" },
+ "ç": { "codepoints": [231], "characters": "\u00E7" },
+ "ç": { "codepoints": [231], "characters": "\u00E7" },
+ "ĉ": { "codepoints": [265], "characters": "\u0109" },
+ "⩌": { "codepoints": [10828], "characters": "\u2A4C" },
+ "⩐": { "codepoints": [10832], "characters": "\u2A50" },
+ "ċ": { "codepoints": [267], "characters": "\u010B" },
+ "¸": { "codepoints": [184], "characters": "\u00B8" },
+ "¸": { "codepoints": [184], "characters": "\u00B8" },
+ "⦲": { "codepoints": [10674], "characters": "\u29B2" },
+ "¢": { "codepoints": [162], "characters": "\u00A2" },
+ "¢": { "codepoints": [162], "characters": "\u00A2" },
+ "·": { "codepoints": [183], "characters": "\u00B7" },
+ "𝔠": { "codepoints": [120096], "characters": "\uD835\uDD20" },
+ "ч": { "codepoints": [1095], "characters": "\u0447" },
+ "✓": { "codepoints": [10003], "characters": "\u2713" },
+ "✓": { "codepoints": [10003], "characters": "\u2713" },
+ "χ": { "codepoints": [967], "characters": "\u03C7" },
+ "○": { "codepoints": [9675], "characters": "\u25CB" },
+ "⧃": { "codepoints": [10691], "characters": "\u29C3" },
+ "ˆ": { "codepoints": [710], "characters": "\u02C6" },
+ "≗": { "codepoints": [8791], "characters": "\u2257" },
+ "↺": { "codepoints": [8634], "characters": "\u21BA" },
+ "↻": { "codepoints": [8635], "characters": "\u21BB" },
+ "®": { "codepoints": [174], "characters": "\u00AE" },
+ "Ⓢ": { "codepoints": [9416], "characters": "\u24C8" },
+ "⊛": { "codepoints": [8859], "characters": "\u229B" },
+ "⊚": { "codepoints": [8858], "characters": "\u229A" },
+ "⊝": { "codepoints": [8861], "characters": "\u229D" },
+ "≗": { "codepoints": [8791], "characters": "\u2257" },
+ "⨐": { "codepoints": [10768], "characters": "\u2A10" },
+ "⫯": { "codepoints": [10991], "characters": "\u2AEF" },
+ "⧂": { "codepoints": [10690], "characters": "\u29C2" },
+ "♣": { "codepoints": [9827], "characters": "\u2663" },
+ "♣": { "codepoints": [9827], "characters": "\u2663" },
+ ":": { "codepoints": [58], "characters": "\u003A" },
+ "≔": { "codepoints": [8788], "characters": "\u2254" },
+ "≔": { "codepoints": [8788], "characters": "\u2254" },
+ ",": { "codepoints": [44], "characters": "\u002C" },
+ "@": { "codepoints": [64], "characters": "\u0040" },
+ "∁": { "codepoints": [8705], "characters": "\u2201" },
+ "∘": { "codepoints": [8728], "characters": "\u2218" },
+ "∁": { "codepoints": [8705], "characters": "\u2201" },
+ "ℂ": { "codepoints": [8450], "characters": "\u2102" },
+ "≅": { "codepoints": [8773], "characters": "\u2245" },
+ "⩭": { "codepoints": [10861], "characters": "\u2A6D" },
+ "∮": { "codepoints": [8750], "characters": "\u222E" },
+ "𝕔": { "codepoints": [120148], "characters": "\uD835\uDD54" },
+ "∐": { "codepoints": [8720], "characters": "\u2210" },
+ "©": { "codepoints": [169], "characters": "\u00A9" },
+ "©": { "codepoints": [169], "characters": "\u00A9" },
+ "℗": { "codepoints": [8471], "characters": "\u2117" },
+ "↵": { "codepoints": [8629], "characters": "\u21B5" },
+ "✗": { "codepoints": [10007], "characters": "\u2717" },
+ "𝒸": { "codepoints": [119992], "characters": "\uD835\uDCB8" },
+ "⫏": { "codepoints": [10959], "characters": "\u2ACF" },
+ "⫑": { "codepoints": [10961], "characters": "\u2AD1" },
+ "⫐": { "codepoints": [10960], "characters": "\u2AD0" },
+ "⫒": { "codepoints": [10962], "characters": "\u2AD2" },
+ "⋯": { "codepoints": [8943], "characters": "\u22EF" },
+ "⤸": { "codepoints": [10552], "characters": "\u2938" },
+ "⤵": { "codepoints": [10549], "characters": "\u2935" },
+ "⋞": { "codepoints": [8926], "characters": "\u22DE" },
+ "⋟": { "codepoints": [8927], "characters": "\u22DF" },
+ "↶": { "codepoints": [8630], "characters": "\u21B6" },
+ "⤽": { "codepoints": [10557], "characters": "\u293D" },
+ "∪": { "codepoints": [8746], "characters": "\u222A" },
+ "⩈": { "codepoints": [10824], "characters": "\u2A48" },
+ "⩆": { "codepoints": [10822], "characters": "\u2A46" },
+ "⩊": { "codepoints": [10826], "characters": "\u2A4A" },
+ "⊍": { "codepoints": [8845], "characters": "\u228D" },
+ "⩅": { "codepoints": [10821], "characters": "\u2A45" },
+ "∪︀": { "codepoints": [8746, 65024], "characters": "\u222A\uFE00" },
+ "↷": { "codepoints": [8631], "characters": "\u21B7" },
+ "⤼": { "codepoints": [10556], "characters": "\u293C" },
+ "⋞": { "codepoints": [8926], "characters": "\u22DE" },
+ "⋟": { "codepoints": [8927], "characters": "\u22DF" },
+ "⋎": { "codepoints": [8910], "characters": "\u22CE" },
+ "⋏": { "codepoints": [8911], "characters": "\u22CF" },
+ "¤": { "codepoints": [164], "characters": "\u00A4" },
+ "¤": { "codepoints": [164], "characters": "\u00A4" },
+ "↶": { "codepoints": [8630], "characters": "\u21B6" },
+ "↷": { "codepoints": [8631], "characters": "\u21B7" },
+ "⋎": { "codepoints": [8910], "characters": "\u22CE" },
+ "⋏": { "codepoints": [8911], "characters": "\u22CF" },
+ "∲": { "codepoints": [8754], "characters": "\u2232" },
+ "∱": { "codepoints": [8753], "characters": "\u2231" },
+ "⌭": { "codepoints": [9005], "characters": "\u232D" },
+ "⇓": { "codepoints": [8659], "characters": "\u21D3" },
+ "⥥": { "codepoints": [10597], "characters": "\u2965" },
+ "†": { "codepoints": [8224], "characters": "\u2020" },
+ "ℸ": { "codepoints": [8504], "characters": "\u2138" },
+ "↓": { "codepoints": [8595], "characters": "\u2193" },
+ "‐": { "codepoints": [8208], "characters": "\u2010" },
+ "⊣": { "codepoints": [8867], "characters": "\u22A3" },
+ "⤏": { "codepoints": [10511], "characters": "\u290F" },
+ "˝": { "codepoints": [733], "characters": "\u02DD" },
+ "ď": { "codepoints": [271], "characters": "\u010F" },
+ "д": { "codepoints": [1076], "characters": "\u0434" },
+ "ⅆ": { "codepoints": [8518], "characters": "\u2146" },
+ "‡": { "codepoints": [8225], "characters": "\u2021" },
+ "⇊": { "codepoints": [8650], "characters": "\u21CA" },
+ "⩷": { "codepoints": [10871], "characters": "\u2A77" },
+ "°": { "codepoints": [176], "characters": "\u00B0" },
+ "°": { "codepoints": [176], "characters": "\u00B0" },
+ "δ": { "codepoints": [948], "characters": "\u03B4" },
+ "⦱": { "codepoints": [10673], "characters": "\u29B1" },
+ "⥿": { "codepoints": [10623], "characters": "\u297F" },
+ "𝔡": { "codepoints": [120097], "characters": "\uD835\uDD21" },
+ "⇃": { "codepoints": [8643], "characters": "\u21C3" },
+ "⇂": { "codepoints": [8642], "characters": "\u21C2" },
+ "⋄": { "codepoints": [8900], "characters": "\u22C4" },
+ "⋄": { "codepoints": [8900], "characters": "\u22C4" },
+ "♦": { "codepoints": [9830], "characters": "\u2666" },
+ "♦": { "codepoints": [9830], "characters": "\u2666" },
+ "¨": { "codepoints": [168], "characters": "\u00A8" },
+ "ϝ": { "codepoints": [989], "characters": "\u03DD" },
+ "⋲": { "codepoints": [8946], "characters": "\u22F2" },
+ "÷": { "codepoints": [247], "characters": "\u00F7" },
+ "÷": { "codepoints": [247], "characters": "\u00F7" },
+ "÷": { "codepoints": [247], "characters": "\u00F7" },
+ "⋇": { "codepoints": [8903], "characters": "\u22C7" },
+ "⋇": { "codepoints": [8903], "characters": "\u22C7" },
+ "ђ": { "codepoints": [1106], "characters": "\u0452" },
+ "⌞": { "codepoints": [8990], "characters": "\u231E" },
+ "⌍": { "codepoints": [8973], "characters": "\u230D" },
+ "$": { "codepoints": [36], "characters": "\u0024" },
+ "𝕕": { "codepoints": [120149], "characters": "\uD835\uDD55" },
+ "˙": { "codepoints": [729], "characters": "\u02D9" },
+ "≐": { "codepoints": [8784], "characters": "\u2250" },
+ "≑": { "codepoints": [8785], "characters": "\u2251" },
+ "∸": { "codepoints": [8760], "characters": "\u2238" },
+ "∔": { "codepoints": [8724], "characters": "\u2214" },
+ "⊡": { "codepoints": [8865], "characters": "\u22A1" },
+ "⌆": { "codepoints": [8966], "characters": "\u2306" },
+ "↓": { "codepoints": [8595], "characters": "\u2193" },
+ "⇊": { "codepoints": [8650], "characters": "\u21CA" },
+ "⇃": { "codepoints": [8643], "characters": "\u21C3" },
+ "⇂": { "codepoints": [8642], "characters": "\u21C2" },
+ "⤐": { "codepoints": [10512], "characters": "\u2910" },
+ "⌟": { "codepoints": [8991], "characters": "\u231F" },
+ "⌌": { "codepoints": [8972], "characters": "\u230C" },
+ "𝒹": { "codepoints": [119993], "characters": "\uD835\uDCB9" },
+ "ѕ": { "codepoints": [1109], "characters": "\u0455" },
+ "⧶": { "codepoints": [10742], "characters": "\u29F6" },
+ "đ": { "codepoints": [273], "characters": "\u0111" },
+ "⋱": { "codepoints": [8945], "characters": "\u22F1" },
+ "▿": { "codepoints": [9663], "characters": "\u25BF" },
+ "▾": { "codepoints": [9662], "characters": "\u25BE" },
+ "⇵": { "codepoints": [8693], "characters": "\u21F5" },
+ "⥯": { "codepoints": [10607], "characters": "\u296F" },
+ "⦦": { "codepoints": [10662], "characters": "\u29A6" },
+ "џ": { "codepoints": [1119], "characters": "\u045F" },
+ "⟿": { "codepoints": [10239], "characters": "\u27FF" },
+ "⩷": { "codepoints": [10871], "characters": "\u2A77" },
+ "≑": { "codepoints": [8785], "characters": "\u2251" },
+ "é": { "codepoints": [233], "characters": "\u00E9" },
+ "é": { "codepoints": [233], "characters": "\u00E9" },
+ "⩮": { "codepoints": [10862], "characters": "\u2A6E" },
+ "ě": { "codepoints": [283], "characters": "\u011B" },
+ "≖": { "codepoints": [8790], "characters": "\u2256" },
+ "ê": { "codepoints": [234], "characters": "\u00EA" },
+ "ê": { "codepoints": [234], "characters": "\u00EA" },
+ "≕": { "codepoints": [8789], "characters": "\u2255" },
+ "э": { "codepoints": [1101], "characters": "\u044D" },
+ "ė": { "codepoints": [279], "characters": "\u0117" },
+ "ⅇ": { "codepoints": [8519], "characters": "\u2147" },
+ "≒": { "codepoints": [8786], "characters": "\u2252" },
+ "𝔢": { "codepoints": [120098], "characters": "\uD835\uDD22" },
+ "⪚": { "codepoints": [10906], "characters": "\u2A9A" },
+ "è": { "codepoints": [232], "characters": "\u00E8" },
+ "è": { "codepoints": [232], "characters": "\u00E8" },
+ "⪖": { "codepoints": [10902], "characters": "\u2A96" },
+ "⪘": { "codepoints": [10904], "characters": "\u2A98" },
+ "⪙": { "codepoints": [10905], "characters": "\u2A99" },
+ "⏧": { "codepoints": [9191], "characters": "\u23E7" },
+ "ℓ": { "codepoints": [8467], "characters": "\u2113" },
+ "⪕": { "codepoints": [10901], "characters": "\u2A95" },
+ "⪗": { "codepoints": [10903], "characters": "\u2A97" },
+ "ē": { "codepoints": [275], "characters": "\u0113" },
+ "∅": { "codepoints": [8709], "characters": "\u2205" },
+ "∅": { "codepoints": [8709], "characters": "\u2205" },
+ "∅": { "codepoints": [8709], "characters": "\u2205" },
+ " ": { "codepoints": [8196], "characters": "\u2004" },
+ " ": { "codepoints": [8197], "characters": "\u2005" },
+ " ": { "codepoints": [8195], "characters": "\u2003" },
+ "ŋ": { "codepoints": [331], "characters": "\u014B" },
+ " ": { "codepoints": [8194], "characters": "\u2002" },
+ "ę": { "codepoints": [281], "characters": "\u0119" },
+ "𝕖": { "codepoints": [120150], "characters": "\uD835\uDD56" },
+ "⋕": { "codepoints": [8917], "characters": "\u22D5" },
+ "⧣": { "codepoints": [10723], "characters": "\u29E3" },
+ "⩱": { "codepoints": [10865], "characters": "\u2A71" },
+ "ε": { "codepoints": [949], "characters": "\u03B5" },
+ "ε": { "codepoints": [949], "characters": "\u03B5" },
+ "ϵ": { "codepoints": [1013], "characters": "\u03F5" },
+ "≖": { "codepoints": [8790], "characters": "\u2256" },
+ "≕": { "codepoints": [8789], "characters": "\u2255" },
+ "≂": { "codepoints": [8770], "characters": "\u2242" },
+ "⪖": { "codepoints": [10902], "characters": "\u2A96" },
+ "⪕": { "codepoints": [10901], "characters": "\u2A95" },
+ "=": { "codepoints": [61], "characters": "\u003D" },
+ "≟": { "codepoints": [8799], "characters": "\u225F" },
+ "≡": { "codepoints": [8801], "characters": "\u2261" },
+ "⩸": { "codepoints": [10872], "characters": "\u2A78" },
+ "⧥": { "codepoints": [10725], "characters": "\u29E5" },
+ "≓": { "codepoints": [8787], "characters": "\u2253" },
+ "⥱": { "codepoints": [10609], "characters": "\u2971" },
+ "ℯ": { "codepoints": [8495], "characters": "\u212F" },
+ "≐": { "codepoints": [8784], "characters": "\u2250" },
+ "≂": { "codepoints": [8770], "characters": "\u2242" },
+ "η": { "codepoints": [951], "characters": "\u03B7" },
+ "ð": { "codepoints": [240], "characters": "\u00F0" },
+ "ð": { "codepoints": [240], "characters": "\u00F0" },
+ "ë": { "codepoints": [235], "characters": "\u00EB" },
+ "ë": { "codepoints": [235], "characters": "\u00EB" },
+ "€": { "codepoints": [8364], "characters": "\u20AC" },
+ "!": { "codepoints": [33], "characters": "\u0021" },
+ "∃": { "codepoints": [8707], "characters": "\u2203" },
+ "ℰ": { "codepoints": [8496], "characters": "\u2130" },
+ "ⅇ": { "codepoints": [8519], "characters": "\u2147" },
+ "≒": { "codepoints": [8786], "characters": "\u2252" },
+ "ф": { "codepoints": [1092], "characters": "\u0444" },
+ "♀": { "codepoints": [9792], "characters": "\u2640" },
+ "ffi": { "codepoints": [64259], "characters": "\uFB03" },
+ "ff": { "codepoints": [64256], "characters": "\uFB00" },
+ "ffl": { "codepoints": [64260], "characters": "\uFB04" },
+ "𝔣": { "codepoints": [120099], "characters": "\uD835\uDD23" },
+ "fi": { "codepoints": [64257], "characters": "\uFB01" },
+ "fj": { "codepoints": [102, 106], "characters": "\u0066\u006A" },
+ "♭": { "codepoints": [9837], "characters": "\u266D" },
+ "fl": { "codepoints": [64258], "characters": "\uFB02" },
+ "▱": { "codepoints": [9649], "characters": "\u25B1" },
+ "ƒ": { "codepoints": [402], "characters": "\u0192" },
+ "𝕗": { "codepoints": [120151], "characters": "\uD835\uDD57" },
+ "∀": { "codepoints": [8704], "characters": "\u2200" },
+ "⋔": { "codepoints": [8916], "characters": "\u22D4" },
+ "⫙": { "codepoints": [10969], "characters": "\u2AD9" },
+ "⨍": { "codepoints": [10765], "characters": "\u2A0D" },
+ "½": { "codepoints": [189], "characters": "\u00BD" },
+ "½": { "codepoints": [189], "characters": "\u00BD" },
+ "⅓": { "codepoints": [8531], "characters": "\u2153" },
+ "¼": { "codepoints": [188], "characters": "\u00BC" },
+ "¼": { "codepoints": [188], "characters": "\u00BC" },
+ "⅕": { "codepoints": [8533], "characters": "\u2155" },
+ "⅙": { "codepoints": [8537], "characters": "\u2159" },
+ "⅛": { "codepoints": [8539], "characters": "\u215B" },
+ "⅔": { "codepoints": [8532], "characters": "\u2154" },
+ "⅖": { "codepoints": [8534], "characters": "\u2156" },
+ "¾": { "codepoints": [190], "characters": "\u00BE" },
+ "¾": { "codepoints": [190], "characters": "\u00BE" },
+ "⅗": { "codepoints": [8535], "characters": "\u2157" },
+ "⅜": { "codepoints": [8540], "characters": "\u215C" },
+ "⅘": { "codepoints": [8536], "characters": "\u2158" },
+ "⅚": { "codepoints": [8538], "characters": "\u215A" },
+ "⅝": { "codepoints": [8541], "characters": "\u215D" },
+ "⅞": { "codepoints": [8542], "characters": "\u215E" },
+ "⁄": { "codepoints": [8260], "characters": "\u2044" },
+ "⌢": { "codepoints": [8994], "characters": "\u2322" },
+ "𝒻": { "codepoints": [119995], "characters": "\uD835\uDCBB" },
+ "≧": { "codepoints": [8807], "characters": "\u2267" },
+ "⪌": { "codepoints": [10892], "characters": "\u2A8C" },
+ "ǵ": { "codepoints": [501], "characters": "\u01F5" },
+ "γ": { "codepoints": [947], "characters": "\u03B3" },
+ "ϝ": { "codepoints": [989], "characters": "\u03DD" },
+ "⪆": { "codepoints": [10886], "characters": "\u2A86" },
+ "ğ": { "codepoints": [287], "characters": "\u011F" },
+ "ĝ": { "codepoints": [285], "characters": "\u011D" },
+ "г": { "codepoints": [1075], "characters": "\u0433" },
+ "ġ": { "codepoints": [289], "characters": "\u0121" },
+ "≥": { "codepoints": [8805], "characters": "\u2265" },
+ "⋛": { "codepoints": [8923], "characters": "\u22DB" },
+ "≥": { "codepoints": [8805], "characters": "\u2265" },
+ "≧": { "codepoints": [8807], "characters": "\u2267" },
+ "⩾": { "codepoints": [10878], "characters": "\u2A7E" },
+ "⩾": { "codepoints": [10878], "characters": "\u2A7E" },
+ "⪩": { "codepoints": [10921], "characters": "\u2AA9" },
+ "⪀": { "codepoints": [10880], "characters": "\u2A80" },
+ "⪂": { "codepoints": [10882], "characters": "\u2A82" },
+ "⪄": { "codepoints": [10884], "characters": "\u2A84" },
+ "⋛︀": { "codepoints": [8923, 65024], "characters": "\u22DB\uFE00" },
+ "⪔": { "codepoints": [10900], "characters": "\u2A94" },
+ "𝔤": { "codepoints": [120100], "characters": "\uD835\uDD24" },
+ "≫": { "codepoints": [8811], "characters": "\u226B" },
+ "⋙": { "codepoints": [8921], "characters": "\u22D9" },
+ "ℷ": { "codepoints": [8503], "characters": "\u2137" },
+ "ѓ": { "codepoints": [1107], "characters": "\u0453" },
+ "≷": { "codepoints": [8823], "characters": "\u2277" },
+ "⪒": { "codepoints": [10898], "characters": "\u2A92" },
+ "⪥": { "codepoints": [10917], "characters": "\u2AA5" },
+ "⪤": { "codepoints": [10916], "characters": "\u2AA4" },
+ "≩": { "codepoints": [8809], "characters": "\u2269" },
+ "⪊": { "codepoints": [10890], "characters": "\u2A8A" },
+ "⪊": { "codepoints": [10890], "characters": "\u2A8A" },
+ "⪈": { "codepoints": [10888], "characters": "\u2A88" },
+ "⪈": { "codepoints": [10888], "characters": "\u2A88" },
+ "≩": { "codepoints": [8809], "characters": "\u2269" },
+ "⋧": { "codepoints": [8935], "characters": "\u22E7" },
+ "𝕘": { "codepoints": [120152], "characters": "\uD835\uDD58" },
+ "`": { "codepoints": [96], "characters": "\u0060" },
+ "ℊ": { "codepoints": [8458], "characters": "\u210A" },
+ "≳": { "codepoints": [8819], "characters": "\u2273" },
+ "⪎": { "codepoints": [10894], "characters": "\u2A8E" },
+ "⪐": { "codepoints": [10896], "characters": "\u2A90" },
+ ">": { "codepoints": [62], "characters": "\u003E" },
+ ">": { "codepoints": [62], "characters": "\u003E" },
+ "⪧": { "codepoints": [10919], "characters": "\u2AA7" },
+ "⩺": { "codepoints": [10874], "characters": "\u2A7A" },
+ "⋗": { "codepoints": [8919], "characters": "\u22D7" },
+ "⦕": { "codepoints": [10645], "characters": "\u2995" },
+ "⩼": { "codepoints": [10876], "characters": "\u2A7C" },
+ "⪆": { "codepoints": [10886], "characters": "\u2A86" },
+ "⥸": { "codepoints": [10616], "characters": "\u2978" },
+ "⋗": { "codepoints": [8919], "characters": "\u22D7" },
+ "⋛": { "codepoints": [8923], "characters": "\u22DB" },
+ "⪌": { "codepoints": [10892], "characters": "\u2A8C" },
+ "≷": { "codepoints": [8823], "characters": "\u2277" },
+ "≳": { "codepoints": [8819], "characters": "\u2273" },
+ "≩︀": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" },
+ "≩︀": { "codepoints": [8809, 65024], "characters": "\u2269\uFE00" },
+ "⇔": { "codepoints": [8660], "characters": "\u21D4" },
+ " ": { "codepoints": [8202], "characters": "\u200A" },
+ "½": { "codepoints": [189], "characters": "\u00BD" },
+ "ℋ": { "codepoints": [8459], "characters": "\u210B" },
+ "ъ": { "codepoints": [1098], "characters": "\u044A" },
+ "↔": { "codepoints": [8596], "characters": "\u2194" },
+ "⥈": { "codepoints": [10568], "characters": "\u2948" },
+ "↭": { "codepoints": [8621], "characters": "\u21AD" },
+ "ℏ": { "codepoints": [8463], "characters": "\u210F" },
+ "ĥ": { "codepoints": [293], "characters": "\u0125" },
+ "♥": { "codepoints": [9829], "characters": "\u2665" },
+ "♥": { "codepoints": [9829], "characters": "\u2665" },
+ "…": { "codepoints": [8230], "characters": "\u2026" },
+ "⊹": { "codepoints": [8889], "characters": "\u22B9" },
+ "𝔥": { "codepoints": [120101], "characters": "\uD835\uDD25" },
+ "⤥": { "codepoints": [10533], "characters": "\u2925" },
+ "⤦": { "codepoints": [10534], "characters": "\u2926" },
+ "⇿": { "codepoints": [8703], "characters": "\u21FF" },
+ "∻": { "codepoints": [8763], "characters": "\u223B" },
+ "↩": { "codepoints": [8617], "characters": "\u21A9" },
+ "↪": { "codepoints": [8618], "characters": "\u21AA" },
+ "𝕙": { "codepoints": [120153], "characters": "\uD835\uDD59" },
+ "―": { "codepoints": [8213], "characters": "\u2015" },
+ "𝒽": { "codepoints": [119997], "characters": "\uD835\uDCBD" },
+ "ℏ": { "codepoints": [8463], "characters": "\u210F" },
+ "ħ": { "codepoints": [295], "characters": "\u0127" },
+ "⁃": { "codepoints": [8259], "characters": "\u2043" },
+ "‐": { "codepoints": [8208], "characters": "\u2010" },
+ "í": { "codepoints": [237], "characters": "\u00ED" },
+ "í": { "codepoints": [237], "characters": "\u00ED" },
+ "⁣": { "codepoints": [8291], "characters": "\u2063" },
+ "î": { "codepoints": [238], "characters": "\u00EE" },
+ "î": { "codepoints": [238], "characters": "\u00EE" },
+ "и": { "codepoints": [1080], "characters": "\u0438" },
+ "е": { "codepoints": [1077], "characters": "\u0435" },
+ "¡": { "codepoints": [161], "characters": "\u00A1" },
+ "¡": { "codepoints": [161], "characters": "\u00A1" },
+ "⇔": { "codepoints": [8660], "characters": "\u21D4" },
+ "𝔦": { "codepoints": [120102], "characters": "\uD835\uDD26" },
+ "ì": { "codepoints": [236], "characters": "\u00EC" },
+ "ì": { "codepoints": [236], "characters": "\u00EC" },
+ "ⅈ": { "codepoints": [8520], "characters": "\u2148" },
+ "⨌": { "codepoints": [10764], "characters": "\u2A0C" },
+ "∭": { "codepoints": [8749], "characters": "\u222D" },
+ "⧜": { "codepoints": [10716], "characters": "\u29DC" },
+ "℩": { "codepoints": [8489], "characters": "\u2129" },
+ "ij": { "codepoints": [307], "characters": "\u0133" },
+ "ī": { "codepoints": [299], "characters": "\u012B" },
+ "ℑ": { "codepoints": [8465], "characters": "\u2111" },
+ "ℐ": { "codepoints": [8464], "characters": "\u2110" },
+ "ℑ": { "codepoints": [8465], "characters": "\u2111" },
+ "ı": { "codepoints": [305], "characters": "\u0131" },
+ "⊷": { "codepoints": [8887], "characters": "\u22B7" },
+ "Ƶ": { "codepoints": [437], "characters": "\u01B5" },
+ "∈": { "codepoints": [8712], "characters": "\u2208" },
+ "℅": { "codepoints": [8453], "characters": "\u2105" },
+ "∞": { "codepoints": [8734], "characters": "\u221E" },
+ "⧝": { "codepoints": [10717], "characters": "\u29DD" },
+ "ı": { "codepoints": [305], "characters": "\u0131" },
+ "∫": { "codepoints": [8747], "characters": "\u222B" },
+ "⊺": { "codepoints": [8890], "characters": "\u22BA" },
+ "ℤ": { "codepoints": [8484], "characters": "\u2124" },
+ "⊺": { "codepoints": [8890], "characters": "\u22BA" },
+ "⨗": { "codepoints": [10775], "characters": "\u2A17" },
+ "⨼": { "codepoints": [10812], "characters": "\u2A3C" },
+ "ё": { "codepoints": [1105], "characters": "\u0451" },
+ "į": { "codepoints": [303], "characters": "\u012F" },
+ "𝕚": { "codepoints": [120154], "characters": "\uD835\uDD5A" },
+ "ι": { "codepoints": [953], "characters": "\u03B9" },
+ "⨼": { "codepoints": [10812], "characters": "\u2A3C" },
+ "¿": { "codepoints": [191], "characters": "\u00BF" },
+ "¿": { "codepoints": [191], "characters": "\u00BF" },
+ "𝒾": { "codepoints": [119998], "characters": "\uD835\uDCBE" },
+ "∈": { "codepoints": [8712], "characters": "\u2208" },
+ "⋹": { "codepoints": [8953], "characters": "\u22F9" },
+ "⋵": { "codepoints": [8949], "characters": "\u22F5" },
+ "⋴": { "codepoints": [8948], "characters": "\u22F4" },
+ "⋳": { "codepoints": [8947], "characters": "\u22F3" },
+ "∈": { "codepoints": [8712], "characters": "\u2208" },
+ "⁢": { "codepoints": [8290], "characters": "\u2062" },
+ "ĩ": { "codepoints": [297], "characters": "\u0129" },
+ "і": { "codepoints": [1110], "characters": "\u0456" },
+ "ï": { "codepoints": [239], "characters": "\u00EF" },
+ "ï": { "codepoints": [239], "characters": "\u00EF" },
+ "ĵ": { "codepoints": [309], "characters": "\u0135" },
+ "й": { "codepoints": [1081], "characters": "\u0439" },
+ "𝔧": { "codepoints": [120103], "characters": "\uD835\uDD27" },
+ "ȷ": { "codepoints": [567], "characters": "\u0237" },
+ "𝕛": { "codepoints": [120155], "characters": "\uD835\uDD5B" },
+ "𝒿": { "codepoints": [119999], "characters": "\uD835\uDCBF" },
+ "ј": { "codepoints": [1112], "characters": "\u0458" },
+ "є": { "codepoints": [1108], "characters": "\u0454" },
+ "κ": { "codepoints": [954], "characters": "\u03BA" },
+ "ϰ": { "codepoints": [1008], "characters": "\u03F0" },
+ "ķ": { "codepoints": [311], "characters": "\u0137" },
+ "к": { "codepoints": [1082], "characters": "\u043A" },
+ "𝔨": { "codepoints": [120104], "characters": "\uD835\uDD28" },
+ "ĸ": { "codepoints": [312], "characters": "\u0138" },
+ "х": { "codepoints": [1093], "characters": "\u0445" },
+ "ќ": { "codepoints": [1116], "characters": "\u045C" },
+ "𝕜": { "codepoints": [120156], "characters": "\uD835\uDD5C" },
+ "𝓀": { "codepoints": [120000], "characters": "\uD835\uDCC0" },
+ "⇚": { "codepoints": [8666], "characters": "\u21DA" },
+ "⇐": { "codepoints": [8656], "characters": "\u21D0" },
+ "⤛": { "codepoints": [10523], "characters": "\u291B" },
+ "⤎": { "codepoints": [10510], "characters": "\u290E" },
+ "≦": { "codepoints": [8806], "characters": "\u2266" },
+ "⪋": { "codepoints": [10891], "characters": "\u2A8B" },
+ "⥢": { "codepoints": [10594], "characters": "\u2962" },
+ "ĺ": { "codepoints": [314], "characters": "\u013A" },
+ "⦴": { "codepoints": [10676], "characters": "\u29B4" },
+ "ℒ": { "codepoints": [8466], "characters": "\u2112" },
+ "λ": { "codepoints": [955], "characters": "\u03BB" },
+ "⟨": { "codepoints": [10216], "characters": "\u27E8" },
+ "⦑": { "codepoints": [10641], "characters": "\u2991" },
+ "⟨": { "codepoints": [10216], "characters": "\u27E8" },
+ "⪅": { "codepoints": [10885], "characters": "\u2A85" },
+ "«": { "codepoints": [171], "characters": "\u00AB" },
+ "«": { "codepoints": [171], "characters": "\u00AB" },
+ "←": { "codepoints": [8592], "characters": "\u2190" },
+ "⇤": { "codepoints": [8676], "characters": "\u21E4" },
+ "⤟": { "codepoints": [10527], "characters": "\u291F" },
+ "⤝": { "codepoints": [10525], "characters": "\u291D" },
+ "↩": { "codepoints": [8617], "characters": "\u21A9" },
+ "↫": { "codepoints": [8619], "characters": "\u21AB" },
+ "⤹": { "codepoints": [10553], "characters": "\u2939" },
+ "⥳": { "codepoints": [10611], "characters": "\u2973" },
+ "↢": { "codepoints": [8610], "characters": "\u21A2" },
+ "⪫": { "codepoints": [10923], "characters": "\u2AAB" },
+ "⤙": { "codepoints": [10521], "characters": "\u2919" },
+ "⪭": { "codepoints": [10925], "characters": "\u2AAD" },
+ "⪭︀": { "codepoints": [10925, 65024], "characters": "\u2AAD\uFE00" },
+ "⤌": { "codepoints": [10508], "characters": "\u290C" },
+ "❲": { "codepoints": [10098], "characters": "\u2772" },
+ "{": { "codepoints": [123], "characters": "\u007B" },
+ "[": { "codepoints": [91], "characters": "\u005B" },
+ "⦋": { "codepoints": [10635], "characters": "\u298B" },
+ "⦏": { "codepoints": [10639], "characters": "\u298F" },
+ "⦍": { "codepoints": [10637], "characters": "\u298D" },
+ "ľ": { "codepoints": [318], "characters": "\u013E" },
+ "ļ": { "codepoints": [316], "characters": "\u013C" },
+ "⌈": { "codepoints": [8968], "characters": "\u2308" },
+ "{": { "codepoints": [123], "characters": "\u007B" },
+ "л": { "codepoints": [1083], "characters": "\u043B" },
+ "⤶": { "codepoints": [10550], "characters": "\u2936" },
+ "“": { "codepoints": [8220], "characters": "\u201C" },
+ "„": { "codepoints": [8222], "characters": "\u201E" },
+ "⥧": { "codepoints": [10599], "characters": "\u2967" },
+ "⥋": { "codepoints": [10571], "characters": "\u294B" },
+ "↲": { "codepoints": [8626], "characters": "\u21B2" },
+ "≤": { "codepoints": [8804], "characters": "\u2264" },
+ "←": { "codepoints": [8592], "characters": "\u2190" },
+ "↢": { "codepoints": [8610], "characters": "\u21A2" },
+ "↽": { "codepoints": [8637], "characters": "\u21BD" },
+ "↼": { "codepoints": [8636], "characters": "\u21BC" },
+ "⇇": { "codepoints": [8647], "characters": "\u21C7" },
+ "↔": { "codepoints": [8596], "characters": "\u2194" },
+ "⇆": { "codepoints": [8646], "characters": "\u21C6" },
+ "⇋": { "codepoints": [8651], "characters": "\u21CB" },
+ "↭": { "codepoints": [8621], "characters": "\u21AD" },
+ "⋋": { "codepoints": [8907], "characters": "\u22CB" },
+ "⋚": { "codepoints": [8922], "characters": "\u22DA" },
+ "≤": { "codepoints": [8804], "characters": "\u2264" },
+ "≦": { "codepoints": [8806], "characters": "\u2266" },
+ "⩽": { "codepoints": [10877], "characters": "\u2A7D" },
+ "⩽": { "codepoints": [10877], "characters": "\u2A7D" },
+ "⪨": { "codepoints": [10920], "characters": "\u2AA8" },
+ "⩿": { "codepoints": [10879], "characters": "\u2A7F" },
+ "⪁": { "codepoints": [10881], "characters": "\u2A81" },
+ "⪃": { "codepoints": [10883], "characters": "\u2A83" },
+ "⋚︀": { "codepoints": [8922, 65024], "characters": "\u22DA\uFE00" },
+ "⪓": { "codepoints": [10899], "characters": "\u2A93" },
+ "⪅": { "codepoints": [10885], "characters": "\u2A85" },
+ "⋖": { "codepoints": [8918], "characters": "\u22D6" },
+ "⋚": { "codepoints": [8922], "characters": "\u22DA" },
+ "⪋": { "codepoints": [10891], "characters": "\u2A8B" },
+ "≶": { "codepoints": [8822], "characters": "\u2276" },
+ "≲": { "codepoints": [8818], "characters": "\u2272" },
+ "⥼": { "codepoints": [10620], "characters": "\u297C" },
+ "⌊": { "codepoints": [8970], "characters": "\u230A" },
+ "𝔩": { "codepoints": [120105], "characters": "\uD835\uDD29" },
+ "≶": { "codepoints": [8822], "characters": "\u2276" },
+ "⪑": { "codepoints": [10897], "characters": "\u2A91" },
+ "↽": { "codepoints": [8637], "characters": "\u21BD" },
+ "↼": { "codepoints": [8636], "characters": "\u21BC" },
+ "⥪": { "codepoints": [10602], "characters": "\u296A" },
+ "▄": { "codepoints": [9604], "characters": "\u2584" },
+ "љ": { "codepoints": [1113], "characters": "\u0459" },
+ "≪": { "codepoints": [8810], "characters": "\u226A" },
+ "⇇": { "codepoints": [8647], "characters": "\u21C7" },
+ "⌞": { "codepoints": [8990], "characters": "\u231E" },
+ "⥫": { "codepoints": [10603], "characters": "\u296B" },
+ "◺": { "codepoints": [9722], "characters": "\u25FA" },
+ "ŀ": { "codepoints": [320], "characters": "\u0140" },
+ "⎰": { "codepoints": [9136], "characters": "\u23B0" },
+ "⎰": { "codepoints": [9136], "characters": "\u23B0" },
+ "≨": { "codepoints": [8808], "characters": "\u2268" },
+ "⪉": { "codepoints": [10889], "characters": "\u2A89" },
+ "⪉": { "codepoints": [10889], "characters": "\u2A89" },
+ "⪇": { "codepoints": [10887], "characters": "\u2A87" },
+ "⪇": { "codepoints": [10887], "characters": "\u2A87" },
+ "≨": { "codepoints": [8808], "characters": "\u2268" },
+ "⋦": { "codepoints": [8934], "characters": "\u22E6" },
+ "⟬": { "codepoints": [10220], "characters": "\u27EC" },
+ "⇽": { "codepoints": [8701], "characters": "\u21FD" },
+ "⟦": { "codepoints": [10214], "characters": "\u27E6" },
+ "⟵": { "codepoints": [10229], "characters": "\u27F5" },
+ "⟷": { "codepoints": [10231], "characters": "\u27F7" },
+ "⟼": { "codepoints": [10236], "characters": "\u27FC" },
+ "⟶": { "codepoints": [10230], "characters": "\u27F6" },
+ "↫": { "codepoints": [8619], "characters": "\u21AB" },
+ "↬": { "codepoints": [8620], "characters": "\u21AC" },
+ "⦅": { "codepoints": [10629], "characters": "\u2985" },
+ "𝕝": { "codepoints": [120157], "characters": "\uD835\uDD5D" },
+ "⨭": { "codepoints": [10797], "characters": "\u2A2D" },
+ "⨴": { "codepoints": [10804], "characters": "\u2A34" },
+ "∗": { "codepoints": [8727], "characters": "\u2217" },
+ "_": { "codepoints": [95], "characters": "\u005F" },
+ "◊": { "codepoints": [9674], "characters": "\u25CA" },
+ "◊": { "codepoints": [9674], "characters": "\u25CA" },
+ "⧫": { "codepoints": [10731], "characters": "\u29EB" },
+ "(": { "codepoints": [40], "characters": "\u0028" },
+ "⦓": { "codepoints": [10643], "characters": "\u2993" },
+ "⇆": { "codepoints": [8646], "characters": "\u21C6" },
+ "⌟": { "codepoints": [8991], "characters": "\u231F" },
+ "⇋": { "codepoints": [8651], "characters": "\u21CB" },
+ "⥭": { "codepoints": [10605], "characters": "\u296D" },
+ "‎": { "codepoints": [8206], "characters": "\u200E" },
+ "⊿": { "codepoints": [8895], "characters": "\u22BF" },
+ "‹": { "codepoints": [8249], "characters": "\u2039" },
+ "𝓁": { "codepoints": [120001], "characters": "\uD835\uDCC1" },
+ "↰": { "codepoints": [8624], "characters": "\u21B0" },
+ "≲": { "codepoints": [8818], "characters": "\u2272" },
+ "⪍": { "codepoints": [10893], "characters": "\u2A8D" },
+ "⪏": { "codepoints": [10895], "characters": "\u2A8F" },
+ "[": { "codepoints": [91], "characters": "\u005B" },
+ "‘": { "codepoints": [8216], "characters": "\u2018" },
+ "‚": { "codepoints": [8218], "characters": "\u201A" },
+ "ł": { "codepoints": [322], "characters": "\u0142" },
+ "<": { "codepoints": [60], "characters": "\u003C" },
+ "<": { "codepoints": [60], "characters": "\u003C" },
+ "⪦": { "codepoints": [10918], "characters": "\u2AA6" },
+ "⩹": { "codepoints": [10873], "characters": "\u2A79" },
+ "⋖": { "codepoints": [8918], "characters": "\u22D6" },
+ "⋋": { "codepoints": [8907], "characters": "\u22CB" },
+ "⋉": { "codepoints": [8905], "characters": "\u22C9" },
+ "⥶": { "codepoints": [10614], "characters": "\u2976" },
+ "⩻": { "codepoints": [10875], "characters": "\u2A7B" },
+ "⦖": { "codepoints": [10646], "characters": "\u2996" },
+ "◃": { "codepoints": [9667], "characters": "\u25C3" },
+ "⊴": { "codepoints": [8884], "characters": "\u22B4" },
+ "◂": { "codepoints": [9666], "characters": "\u25C2" },
+ "⥊": { "codepoints": [10570], "characters": "\u294A" },
+ "⥦": { "codepoints": [10598], "characters": "\u2966" },
+ "≨︀": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" },
+ "≨︀": { "codepoints": [8808, 65024], "characters": "\u2268\uFE00" },
+ "∺": { "codepoints": [8762], "characters": "\u223A" },
+ "¯": { "codepoints": [175], "characters": "\u00AF" },
+ "¯": { "codepoints": [175], "characters": "\u00AF" },
+ "♂": { "codepoints": [9794], "characters": "\u2642" },
+ "✠": { "codepoints": [10016], "characters": "\u2720" },
+ "✠": { "codepoints": [10016], "characters": "\u2720" },
+ "↦": { "codepoints": [8614], "characters": "\u21A6" },
+ "↦": { "codepoints": [8614], "characters": "\u21A6" },
+ "↧": { "codepoints": [8615], "characters": "\u21A7" },
+ "↤": { "codepoints": [8612], "characters": "\u21A4" },
+ "↥": { "codepoints": [8613], "characters": "\u21A5" },
+ "▮": { "codepoints": [9646], "characters": "\u25AE" },
+ "⨩": { "codepoints": [10793], "characters": "\u2A29" },
+ "м": { "codepoints": [1084], "characters": "\u043C" },
+ "—": { "codepoints": [8212], "characters": "\u2014" },
+ "∡": { "codepoints": [8737], "characters": "\u2221" },
+ "𝔪": { "codepoints": [120106], "characters": "\uD835\uDD2A" },
+ "℧": { "codepoints": [8487], "characters": "\u2127" },
+ "µ": { "codepoints": [181], "characters": "\u00B5" },
+ "µ": { "codepoints": [181], "characters": "\u00B5" },
+ "∣": { "codepoints": [8739], "characters": "\u2223" },
+ "*": { "codepoints": [42], "characters": "\u002A" },
+ "⫰": { "codepoints": [10992], "characters": "\u2AF0" },
+ "·": { "codepoints": [183], "characters": "\u00B7" },
+ "·": { "codepoints": [183], "characters": "\u00B7" },
+ "−": { "codepoints": [8722], "characters": "\u2212" },
+ "⊟": { "codepoints": [8863], "characters": "\u229F" },
+ "∸": { "codepoints": [8760], "characters": "\u2238" },
+ "⨪": { "codepoints": [10794], "characters": "\u2A2A" },
+ "⫛": { "codepoints": [10971], "characters": "\u2ADB" },
+ "…": { "codepoints": [8230], "characters": "\u2026" },
+ "∓": { "codepoints": [8723], "characters": "\u2213" },
+ "⊧": { "codepoints": [8871], "characters": "\u22A7" },
+ "𝕞": { "codepoints": [120158], "characters": "\uD835\uDD5E" },
+ "∓": { "codepoints": [8723], "characters": "\u2213" },
+ "𝓂": { "codepoints": [120002], "characters": "\uD835\uDCC2" },
+ "∾": { "codepoints": [8766], "characters": "\u223E" },
+ "μ": { "codepoints": [956], "characters": "\u03BC" },
+ "⊸": { "codepoints": [8888], "characters": "\u22B8" },
+ "⊸": { "codepoints": [8888], "characters": "\u22B8" },
+ "⋙̸": { "codepoints": [8921, 824], "characters": "\u22D9\u0338" },
+ "≫⃒": { "codepoints": [8811, 8402], "characters": "\u226B\u20D2" },
+ "≫̸": { "codepoints": [8811, 824], "characters": "\u226B\u0338" },
+ "⇍": { "codepoints": [8653], "characters": "\u21CD" },
+ "⇎": { "codepoints": [8654], "characters": "\u21CE" },
+ "⋘̸": { "codepoints": [8920, 824], "characters": "\u22D8\u0338" },
+ "≪⃒": { "codepoints": [8810, 8402], "characters": "\u226A\u20D2" },
+ "≪̸": { "codepoints": [8810, 824], "characters": "\u226A\u0338" },
+ "⇏": { "codepoints": [8655], "characters": "\u21CF" },
+ "⊯": { "codepoints": [8879], "characters": "\u22AF" },
+ "⊮": { "codepoints": [8878], "characters": "\u22AE" },
+ "∇": { "codepoints": [8711], "characters": "\u2207" },
+ "ń": { "codepoints": [324], "characters": "\u0144" },
+ "∠⃒": { "codepoints": [8736, 8402], "characters": "\u2220\u20D2" },
+ "≉": { "codepoints": [8777], "characters": "\u2249" },
+ "⩰̸": { "codepoints": [10864, 824], "characters": "\u2A70\u0338" },
+ "≋̸": { "codepoints": [8779, 824], "characters": "\u224B\u0338" },
+ "ʼn": { "codepoints": [329], "characters": "\u0149" },
+ "≉": { "codepoints": [8777], "characters": "\u2249" },
+ "♮": { "codepoints": [9838], "characters": "\u266E" },
+ "♮": { "codepoints": [9838], "characters": "\u266E" },
+ "ℕ": { "codepoints": [8469], "characters": "\u2115" },
+ " ": { "codepoints": [160], "characters": "\u00A0" },
+ " ": { "codepoints": [160], "characters": "\u00A0" },
+ "≎̸": { "codepoints": [8782, 824], "characters": "\u224E\u0338" },
+ "≏̸": { "codepoints": [8783, 824], "characters": "\u224F\u0338" },
+ "⩃": { "codepoints": [10819], "characters": "\u2A43" },
+ "ň": { "codepoints": [328], "characters": "\u0148" },
+ "ņ": { "codepoints": [326], "characters": "\u0146" },
+ "≇": { "codepoints": [8775], "characters": "\u2247" },
+ "⩭̸": { "codepoints": [10861, 824], "characters": "\u2A6D\u0338" },
+ "⩂": { "codepoints": [10818], "characters": "\u2A42" },
+ "н": { "codepoints": [1085], "characters": "\u043D" },
+ "–": { "codepoints": [8211], "characters": "\u2013" },
+ "≠": { "codepoints": [8800], "characters": "\u2260" },
+ "⇗": { "codepoints": [8663], "characters": "\u21D7" },
+ "⤤": { "codepoints": [10532], "characters": "\u2924" },
+ "↗": { "codepoints": [8599], "characters": "\u2197" },
+ "↗": { "codepoints": [8599], "characters": "\u2197" },
+ "≐̸": { "codepoints": [8784, 824], "characters": "\u2250\u0338" },
+ "≢": { "codepoints": [8802], "characters": "\u2262" },
+ "⤨": { "codepoints": [10536], "characters": "\u2928" },
+ "≂̸": { "codepoints": [8770, 824], "characters": "\u2242\u0338" },
+ "∄": { "codepoints": [8708], "characters": "\u2204" },
+ "∄": { "codepoints": [8708], "characters": "\u2204" },
+ "𝔫": { "codepoints": [120107], "characters": "\uD835\uDD2B" },
+ "≧̸": { "codepoints": [8807, 824], "characters": "\u2267\u0338" },
+ "≱": { "codepoints": [8817], "characters": "\u2271" },
+ "≱": { "codepoints": [8817], "characters": "\u2271" },
+ "≧̸": { "codepoints": [8807, 824], "characters": "\u2267\u0338" },
+ "⩾̸": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" },
+ "⩾̸": { "codepoints": [10878, 824], "characters": "\u2A7E\u0338" },
+ "≵": { "codepoints": [8821], "characters": "\u2275" },
+ "≯": { "codepoints": [8815], "characters": "\u226F" },
+ "≯": { "codepoints": [8815], "characters": "\u226F" },
+ "⇎": { "codepoints": [8654], "characters": "\u21CE" },
+ "↮": { "codepoints": [8622], "characters": "\u21AE" },
+ "⫲": { "codepoints": [10994], "characters": "\u2AF2" },
+ "∋": { "codepoints": [8715], "characters": "\u220B" },
+ "⋼": { "codepoints": [8956], "characters": "\u22FC" },
+ "⋺": { "codepoints": [8954], "characters": "\u22FA" },
+ "∋": { "codepoints": [8715], "characters": "\u220B" },
+ "њ": { "codepoints": [1114], "characters": "\u045A" },
+ "⇍": { "codepoints": [8653], "characters": "\u21CD" },
+ "≦̸": { "codepoints": [8806, 824], "characters": "\u2266\u0338" },
+ "↚": { "codepoints": [8602], "characters": "\u219A" },
+ "‥": { "codepoints": [8229], "characters": "\u2025" },
+ "≰": { "codepoints": [8816], "characters": "\u2270" },
+ "↚": { "codepoints": [8602], "characters": "\u219A" },
+ "↮": { "codepoints": [8622], "characters": "\u21AE" },
+ "≰": { "codepoints": [8816], "characters": "\u2270" },
+ "≦̸": { "codepoints": [8806, 824], "characters": "\u2266\u0338" },
+ "⩽̸": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" },
+ "⩽̸": { "codepoints": [10877, 824], "characters": "\u2A7D\u0338" },
+ "≮": { "codepoints": [8814], "characters": "\u226E" },
+ "≴": { "codepoints": [8820], "characters": "\u2274" },
+ "≮": { "codepoints": [8814], "characters": "\u226E" },
+ "⋪": { "codepoints": [8938], "characters": "\u22EA" },
+ "⋬": { "codepoints": [8940], "characters": "\u22EC" },
+ "∤": { "codepoints": [8740], "characters": "\u2224" },
+ "𝕟": { "codepoints": [120159], "characters": "\uD835\uDD5F" },
+ "¬": { "codepoints": [172], "characters": "\u00AC" },
+ "¬": { "codepoints": [172], "characters": "\u00AC" },
+ "∉": { "codepoints": [8713], "characters": "\u2209" },
+ "⋹̸": { "codepoints": [8953, 824], "characters": "\u22F9\u0338" },
+ "⋵̸": { "codepoints": [8949, 824], "characters": "\u22F5\u0338" },
+ "∉": { "codepoints": [8713], "characters": "\u2209" },
+ "⋷": { "codepoints": [8951], "characters": "\u22F7" },
+ "⋶": { "codepoints": [8950], "characters": "\u22F6" },
+ "∌": { "codepoints": [8716], "characters": "\u220C" },
+ "∌": { "codepoints": [8716], "characters": "\u220C" },
+ "⋾": { "codepoints": [8958], "characters": "\u22FE" },
+ "⋽": { "codepoints": [8957], "characters": "\u22FD" },
+ "∦": { "codepoints": [8742], "characters": "\u2226" },
+ "∦": { "codepoints": [8742], "characters": "\u2226" },
+ "⫽⃥": { "codepoints": [11005, 8421], "characters": "\u2AFD\u20E5" },
+ "∂̸": { "codepoints": [8706, 824], "characters": "\u2202\u0338" },
+ "⨔": { "codepoints": [10772], "characters": "\u2A14" },
+ "⊀": { "codepoints": [8832], "characters": "\u2280" },
+ "⋠": { "codepoints": [8928], "characters": "\u22E0" },
+ "⪯̸": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" },
+ "⊀": { "codepoints": [8832], "characters": "\u2280" },
+ "⪯̸": { "codepoints": [10927, 824], "characters": "\u2AAF\u0338" },
+ "⇏": { "codepoints": [8655], "characters": "\u21CF" },
+ "↛": { "codepoints": [8603], "characters": "\u219B" },
+ "⤳̸": { "codepoints": [10547, 824], "characters": "\u2933\u0338" },
+ "↝̸": { "codepoints": [8605, 824], "characters": "\u219D\u0338" },
+ "↛": { "codepoints": [8603], "characters": "\u219B" },
+ "⋫": { "codepoints": [8939], "characters": "\u22EB" },
+ "⋭": { "codepoints": [8941], "characters": "\u22ED" },
+ "⊁": { "codepoints": [8833], "characters": "\u2281" },
+ "⋡": { "codepoints": [8929], "characters": "\u22E1" },
+ "⪰̸": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" },
+ "𝓃": { "codepoints": [120003], "characters": "\uD835\uDCC3" },
+ "∤": { "codepoints": [8740], "characters": "\u2224" },
+ "∦": { "codepoints": [8742], "characters": "\u2226" },
+ "≁": { "codepoints": [8769], "characters": "\u2241" },
+ "≄": { "codepoints": [8772], "characters": "\u2244" },
+ "≄": { "codepoints": [8772], "characters": "\u2244" },
+ "∤": { "codepoints": [8740], "characters": "\u2224" },
+ "∦": { "codepoints": [8742], "characters": "\u2226" },
+ "⋢": { "codepoints": [8930], "characters": "\u22E2" },
+ "⋣": { "codepoints": [8931], "characters": "\u22E3" },
+ "⊄": { "codepoints": [8836], "characters": "\u2284" },
+ "⫅̸": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" },
+ "⊈": { "codepoints": [8840], "characters": "\u2288" },
+ "⊂⃒": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" },
+ "⊈": { "codepoints": [8840], "characters": "\u2288" },
+ "⫅̸": { "codepoints": [10949, 824], "characters": "\u2AC5\u0338" },
+ "⊁": { "codepoints": [8833], "characters": "\u2281" },
+ "⪰̸": { "codepoints": [10928, 824], "characters": "\u2AB0\u0338" },
+ "⊅": { "codepoints": [8837], "characters": "\u2285" },
+ "⫆̸": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" },
+ "⊉": { "codepoints": [8841], "characters": "\u2289" },
+ "⊃⃒": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" },
+ "⊉": { "codepoints": [8841], "characters": "\u2289" },
+ "⫆̸": { "codepoints": [10950, 824], "characters": "\u2AC6\u0338" },
+ "≹": { "codepoints": [8825], "characters": "\u2279" },
+ "ñ": { "codepoints": [241], "characters": "\u00F1" },
+ "ñ": { "codepoints": [241], "characters": "\u00F1" },
+ "≸": { "codepoints": [8824], "characters": "\u2278" },
+ "⋪": { "codepoints": [8938], "characters": "\u22EA" },
+ "⋬": { "codepoints": [8940], "characters": "\u22EC" },
+ "⋫": { "codepoints": [8939], "characters": "\u22EB" },
+ "⋭": { "codepoints": [8941], "characters": "\u22ED" },
+ "ν": { "codepoints": [957], "characters": "\u03BD" },
+ "#": { "codepoints": [35], "characters": "\u0023" },
+ "№": { "codepoints": [8470], "characters": "\u2116" },
+ " ": { "codepoints": [8199], "characters": "\u2007" },
+ "⊭": { "codepoints": [8877], "characters": "\u22AD" },
+ "⤄": { "codepoints": [10500], "characters": "\u2904" },
+ "≍⃒": { "codepoints": [8781, 8402], "characters": "\u224D\u20D2" },
+ "⊬": { "codepoints": [8876], "characters": "\u22AC" },
+ "≥⃒": { "codepoints": [8805, 8402], "characters": "\u2265\u20D2" },
+ ">⃒": { "codepoints": [62, 8402], "characters": "\u003E\u20D2" },
+ "⧞": { "codepoints": [10718], "characters": "\u29DE" },
+ "⤂": { "codepoints": [10498], "characters": "\u2902" },
+ "≤⃒": { "codepoints": [8804, 8402], "characters": "\u2264\u20D2" },
+ "<⃒": { "codepoints": [60, 8402], "characters": "\u003C\u20D2" },
+ "⊴⃒": { "codepoints": [8884, 8402], "characters": "\u22B4\u20D2" },
+ "⤃": { "codepoints": [10499], "characters": "\u2903" },
+ "⊵⃒": { "codepoints": [8885, 8402], "characters": "\u22B5\u20D2" },
+ "∼⃒": { "codepoints": [8764, 8402], "characters": "\u223C\u20D2" },
+ "⇖": { "codepoints": [8662], "characters": "\u21D6" },
+ "⤣": { "codepoints": [10531], "characters": "\u2923" },
+ "↖": { "codepoints": [8598], "characters": "\u2196" },
+ "↖": { "codepoints": [8598], "characters": "\u2196" },
+ "⤧": { "codepoints": [10535], "characters": "\u2927" },
+ "Ⓢ": { "codepoints": [9416], "characters": "\u24C8" },
+ "ó": { "codepoints": [243], "characters": "\u00F3" },
+ "ó": { "codepoints": [243], "characters": "\u00F3" },
+ "⊛": { "codepoints": [8859], "characters": "\u229B" },
+ "⊚": { "codepoints": [8858], "characters": "\u229A" },
+ "ô": { "codepoints": [244], "characters": "\u00F4" },
+ "ô": { "codepoints": [244], "characters": "\u00F4" },
+ "о": { "codepoints": [1086], "characters": "\u043E" },
+ "⊝": { "codepoints": [8861], "characters": "\u229D" },
+ "ő": { "codepoints": [337], "characters": "\u0151" },
+ "⨸": { "codepoints": [10808], "characters": "\u2A38" },
+ "⊙": { "codepoints": [8857], "characters": "\u2299" },
+ "⦼": { "codepoints": [10684], "characters": "\u29BC" },
+ "œ": { "codepoints": [339], "characters": "\u0153" },
+ "⦿": { "codepoints": [10687], "characters": "\u29BF" },
+ "𝔬": { "codepoints": [120108], "characters": "\uD835\uDD2C" },
+ "˛": { "codepoints": [731], "characters": "\u02DB" },
+ "ò": { "codepoints": [242], "characters": "\u00F2" },
+ "ò": { "codepoints": [242], "characters": "\u00F2" },
+ "⧁": { "codepoints": [10689], "characters": "\u29C1" },
+ "⦵": { "codepoints": [10677], "characters": "\u29B5" },
+ "Ω": { "codepoints": [937], "characters": "\u03A9" },
+ "∮": { "codepoints": [8750], "characters": "\u222E" },
+ "↺": { "codepoints": [8634], "characters": "\u21BA" },
+ "⦾": { "codepoints": [10686], "characters": "\u29BE" },
+ "⦻": { "codepoints": [10683], "characters": "\u29BB" },
+ "‾": { "codepoints": [8254], "characters": "\u203E" },
+ "⧀": { "codepoints": [10688], "characters": "\u29C0" },
+ "ō": { "codepoints": [333], "characters": "\u014D" },
+ "ω": { "codepoints": [969], "characters": "\u03C9" },
+ "ο": { "codepoints": [959], "characters": "\u03BF" },
+ "⦶": { "codepoints": [10678], "characters": "\u29B6" },
+ "⊖": { "codepoints": [8854], "characters": "\u2296" },
+ "𝕠": { "codepoints": [120160], "characters": "\uD835\uDD60" },
+ "⦷": { "codepoints": [10679], "characters": "\u29B7" },
+ "⦹": { "codepoints": [10681], "characters": "\u29B9" },
+ "⊕": { "codepoints": [8853], "characters": "\u2295" },
+ "∨": { "codepoints": [8744], "characters": "\u2228" },
+ "↻": { "codepoints": [8635], "characters": "\u21BB" },
+ "⩝": { "codepoints": [10845], "characters": "\u2A5D" },
+ "ℴ": { "codepoints": [8500], "characters": "\u2134" },
+ "ℴ": { "codepoints": [8500], "characters": "\u2134" },
+ "ª": { "codepoints": [170], "characters": "\u00AA" },
+ "ª": { "codepoints": [170], "characters": "\u00AA" },
+ "º": { "codepoints": [186], "characters": "\u00BA" },
+ "º": { "codepoints": [186], "characters": "\u00BA" },
+ "⊶": { "codepoints": [8886], "characters": "\u22B6" },
+ "⩖": { "codepoints": [10838], "characters": "\u2A56" },
+ "⩗": { "codepoints": [10839], "characters": "\u2A57" },
+ "⩛": { "codepoints": [10843], "characters": "\u2A5B" },
+ "ℴ": { "codepoints": [8500], "characters": "\u2134" },
+ "ø": { "codepoints": [248], "characters": "\u00F8" },
+ "ø": { "codepoints": [248], "characters": "\u00F8" },
+ "⊘": { "codepoints": [8856], "characters": "\u2298" },
+ "õ": { "codepoints": [245], "characters": "\u00F5" },
+ "õ": { "codepoints": [245], "characters": "\u00F5" },
+ "⊗": { "codepoints": [8855], "characters": "\u2297" },
+ "⨶": { "codepoints": [10806], "characters": "\u2A36" },
+ "ö": { "codepoints": [246], "characters": "\u00F6" },
+ "ö": { "codepoints": [246], "characters": "\u00F6" },
+ "⌽": { "codepoints": [9021], "characters": "\u233D" },
+ "∥": { "codepoints": [8741], "characters": "\u2225" },
+ "¶": { "codepoints": [182], "characters": "\u00B6" },
+ "¶": { "codepoints": [182], "characters": "\u00B6" },
+ "∥": { "codepoints": [8741], "characters": "\u2225" },
+ "⫳": { "codepoints": [10995], "characters": "\u2AF3" },
+ "⫽": { "codepoints": [11005], "characters": "\u2AFD" },
+ "∂": { "codepoints": [8706], "characters": "\u2202" },
+ "п": { "codepoints": [1087], "characters": "\u043F" },
+ "%": { "codepoints": [37], "characters": "\u0025" },
+ ".": { "codepoints": [46], "characters": "\u002E" },
+ "‰": { "codepoints": [8240], "characters": "\u2030" },
+ "⊥": { "codepoints": [8869], "characters": "\u22A5" },
+ "‱": { "codepoints": [8241], "characters": "\u2031" },
+ "𝔭": { "codepoints": [120109], "characters": "\uD835\uDD2D" },
+ "φ": { "codepoints": [966], "characters": "\u03C6" },
+ "ϕ": { "codepoints": [981], "characters": "\u03D5" },
+ "ℳ": { "codepoints": [8499], "characters": "\u2133" },
+ "☎": { "codepoints": [9742], "characters": "\u260E" },
+ "π": { "codepoints": [960], "characters": "\u03C0" },
+ "⋔": { "codepoints": [8916], "characters": "\u22D4" },
+ "ϖ": { "codepoints": [982], "characters": "\u03D6" },
+ "ℏ": { "codepoints": [8463], "characters": "\u210F" },
+ "ℎ": { "codepoints": [8462], "characters": "\u210E" },
+ "ℏ": { "codepoints": [8463], "characters": "\u210F" },
+ "+": { "codepoints": [43], "characters": "\u002B" },
+ "⨣": { "codepoints": [10787], "characters": "\u2A23" },
+ "⊞": { "codepoints": [8862], "characters": "\u229E" },
+ "⨢": { "codepoints": [10786], "characters": "\u2A22" },
+ "∔": { "codepoints": [8724], "characters": "\u2214" },
+ "⨥": { "codepoints": [10789], "characters": "\u2A25" },
+ "⩲": { "codepoints": [10866], "characters": "\u2A72" },
+ "±": { "codepoints": [177], "characters": "\u00B1" },
+ "±": { "codepoints": [177], "characters": "\u00B1" },
+ "⨦": { "codepoints": [10790], "characters": "\u2A26" },
+ "⨧": { "codepoints": [10791], "characters": "\u2A27" },
+ "±": { "codepoints": [177], "characters": "\u00B1" },
+ "⨕": { "codepoints": [10773], "characters": "\u2A15" },
+ "𝕡": { "codepoints": [120161], "characters": "\uD835\uDD61" },
+ "£": { "codepoints": [163], "characters": "\u00A3" },
+ "£": { "codepoints": [163], "characters": "\u00A3" },
+ "≺": { "codepoints": [8826], "characters": "\u227A" },
+ "⪳": { "codepoints": [10931], "characters": "\u2AB3" },
+ "⪷": { "codepoints": [10935], "characters": "\u2AB7" },
+ "≼": { "codepoints": [8828], "characters": "\u227C" },
+ "⪯": { "codepoints": [10927], "characters": "\u2AAF" },
+ "≺": { "codepoints": [8826], "characters": "\u227A" },
+ "⪷": { "codepoints": [10935], "characters": "\u2AB7" },
+ "≼": { "codepoints": [8828], "characters": "\u227C" },
+ "⪯": { "codepoints": [10927], "characters": "\u2AAF" },
+ "⪹": { "codepoints": [10937], "characters": "\u2AB9" },
+ "⪵": { "codepoints": [10933], "characters": "\u2AB5" },
+ "⋨": { "codepoints": [8936], "characters": "\u22E8" },
+ "≾": { "codepoints": [8830], "characters": "\u227E" },
+ "′": { "codepoints": [8242], "characters": "\u2032" },
+ "ℙ": { "codepoints": [8473], "characters": "\u2119" },
+ "⪵": { "codepoints": [10933], "characters": "\u2AB5" },
+ "⪹": { "codepoints": [10937], "characters": "\u2AB9" },
+ "⋨": { "codepoints": [8936], "characters": "\u22E8" },
+ "∏": { "codepoints": [8719], "characters": "\u220F" },
+ "⌮": { "codepoints": [9006], "characters": "\u232E" },
+ "⌒": { "codepoints": [8978], "characters": "\u2312" },
+ "⌓": { "codepoints": [8979], "characters": "\u2313" },
+ "∝": { "codepoints": [8733], "characters": "\u221D" },
+ "∝": { "codepoints": [8733], "characters": "\u221D" },
+ "≾": { "codepoints": [8830], "characters": "\u227E" },
+ "⊰": { "codepoints": [8880], "characters": "\u22B0" },
+ "𝓅": { "codepoints": [120005], "characters": "\uD835\uDCC5" },
+ "ψ": { "codepoints": [968], "characters": "\u03C8" },
+ " ": { "codepoints": [8200], "characters": "\u2008" },
+ "𝔮": { "codepoints": [120110], "characters": "\uD835\uDD2E" },
+ "⨌": { "codepoints": [10764], "characters": "\u2A0C" },
+ "𝕢": { "codepoints": [120162], "characters": "\uD835\uDD62" },
+ "⁗": { "codepoints": [8279], "characters": "\u2057" },
+ "𝓆": { "codepoints": [120006], "characters": "\uD835\uDCC6" },
+ "ℍ": { "codepoints": [8461], "characters": "\u210D" },
+ "⨖": { "codepoints": [10774], "characters": "\u2A16" },
+ "?": { "codepoints": [63], "characters": "\u003F" },
+ "≟": { "codepoints": [8799], "characters": "\u225F" },
+ """: { "codepoints": [34], "characters": "\u0022" },
+ """: { "codepoints": [34], "characters": "\u0022" },
+ "⇛": { "codepoints": [8667], "characters": "\u21DB" },
+ "⇒": { "codepoints": [8658], "characters": "\u21D2" },
+ "⤜": { "codepoints": [10524], "characters": "\u291C" },
+ "⤏": { "codepoints": [10511], "characters": "\u290F" },
+ "⥤": { "codepoints": [10596], "characters": "\u2964" },
+ "∽̱": { "codepoints": [8765, 817], "characters": "\u223D\u0331" },
+ "ŕ": { "codepoints": [341], "characters": "\u0155" },
+ "√": { "codepoints": [8730], "characters": "\u221A" },
+ "⦳": { "codepoints": [10675], "characters": "\u29B3" },
+ "⟩": { "codepoints": [10217], "characters": "\u27E9" },
+ "⦒": { "codepoints": [10642], "characters": "\u2992" },
+ "⦥": { "codepoints": [10661], "characters": "\u29A5" },
+ "⟩": { "codepoints": [10217], "characters": "\u27E9" },
+ "»": { "codepoints": [187], "characters": "\u00BB" },
+ "»": { "codepoints": [187], "characters": "\u00BB" },
+ "→": { "codepoints": [8594], "characters": "\u2192" },
+ "⥵": { "codepoints": [10613], "characters": "\u2975" },
+ "⇥": { "codepoints": [8677], "characters": "\u21E5" },
+ "⤠": { "codepoints": [10528], "characters": "\u2920" },
+ "⤳": { "codepoints": [10547], "characters": "\u2933" },
+ "⤞": { "codepoints": [10526], "characters": "\u291E" },
+ "↪": { "codepoints": [8618], "characters": "\u21AA" },
+ "↬": { "codepoints": [8620], "characters": "\u21AC" },
+ "⥅": { "codepoints": [10565], "characters": "\u2945" },
+ "⥴": { "codepoints": [10612], "characters": "\u2974" },
+ "↣": { "codepoints": [8611], "characters": "\u21A3" },
+ "↝": { "codepoints": [8605], "characters": "\u219D" },
+ "⤚": { "codepoints": [10522], "characters": "\u291A" },
+ "∶": { "codepoints": [8758], "characters": "\u2236" },
+ "ℚ": { "codepoints": [8474], "characters": "\u211A" },
+ "⤍": { "codepoints": [10509], "characters": "\u290D" },
+ "❳": { "codepoints": [10099], "characters": "\u2773" },
+ "}": { "codepoints": [125], "characters": "\u007D" },
+ "]": { "codepoints": [93], "characters": "\u005D" },
+ "⦌": { "codepoints": [10636], "characters": "\u298C" },
+ "⦎": { "codepoints": [10638], "characters": "\u298E" },
+ "⦐": { "codepoints": [10640], "characters": "\u2990" },
+ "ř": { "codepoints": [345], "characters": "\u0159" },
+ "ŗ": { "codepoints": [343], "characters": "\u0157" },
+ "⌉": { "codepoints": [8969], "characters": "\u2309" },
+ "}": { "codepoints": [125], "characters": "\u007D" },
+ "р": { "codepoints": [1088], "characters": "\u0440" },
+ "⤷": { "codepoints": [10551], "characters": "\u2937" },
+ "⥩": { "codepoints": [10601], "characters": "\u2969" },
+ "”": { "codepoints": [8221], "characters": "\u201D" },
+ "”": { "codepoints": [8221], "characters": "\u201D" },
+ "↳": { "codepoints": [8627], "characters": "\u21B3" },
+ "ℜ": { "codepoints": [8476], "characters": "\u211C" },
+ "ℛ": { "codepoints": [8475], "characters": "\u211B" },
+ "ℜ": { "codepoints": [8476], "characters": "\u211C" },
+ "ℝ": { "codepoints": [8477], "characters": "\u211D" },
+ "▭": { "codepoints": [9645], "characters": "\u25AD" },
+ "®": { "codepoints": [174], "characters": "\u00AE" },
+ "®": { "codepoints": [174], "characters": "\u00AE" },
+ "⥽": { "codepoints": [10621], "characters": "\u297D" },
+ "⌋": { "codepoints": [8971], "characters": "\u230B" },
+ "𝔯": { "codepoints": [120111], "characters": "\uD835\uDD2F" },
+ "⇁": { "codepoints": [8641], "characters": "\u21C1" },
+ "⇀": { "codepoints": [8640], "characters": "\u21C0" },
+ "⥬": { "codepoints": [10604], "characters": "\u296C" },
+ "ρ": { "codepoints": [961], "characters": "\u03C1" },
+ "ϱ": { "codepoints": [1009], "characters": "\u03F1" },
+ "→": { "codepoints": [8594], "characters": "\u2192" },
+ "↣": { "codepoints": [8611], "characters": "\u21A3" },
+ "⇁": { "codepoints": [8641], "characters": "\u21C1" },
+ "⇀": { "codepoints": [8640], "characters": "\u21C0" },
+ "⇄": { "codepoints": [8644], "characters": "\u21C4" },
+ "⇌": { "codepoints": [8652], "characters": "\u21CC" },
+ "⇉": { "codepoints": [8649], "characters": "\u21C9" },
+ "↝": { "codepoints": [8605], "characters": "\u219D" },
+ "⋌": { "codepoints": [8908], "characters": "\u22CC" },
+ "˚": { "codepoints": [730], "characters": "\u02DA" },
+ "≓": { "codepoints": [8787], "characters": "\u2253" },
+ "⇄": { "codepoints": [8644], "characters": "\u21C4" },
+ "⇌": { "codepoints": [8652], "characters": "\u21CC" },
+ "‏": { "codepoints": [8207], "characters": "\u200F" },
+ "⎱": { "codepoints": [9137], "characters": "\u23B1" },
+ "⎱": { "codepoints": [9137], "characters": "\u23B1" },
+ "⫮": { "codepoints": [10990], "characters": "\u2AEE" },
+ "⟭": { "codepoints": [10221], "characters": "\u27ED" },
+ "⇾": { "codepoints": [8702], "characters": "\u21FE" },
+ "⟧": { "codepoints": [10215], "characters": "\u27E7" },
+ "⦆": { "codepoints": [10630], "characters": "\u2986" },
+ "𝕣": { "codepoints": [120163], "characters": "\uD835\uDD63" },
+ "⨮": { "codepoints": [10798], "characters": "\u2A2E" },
+ "⨵": { "codepoints": [10805], "characters": "\u2A35" },
+ ")": { "codepoints": [41], "characters": "\u0029" },
+ "⦔": { "codepoints": [10644], "characters": "\u2994" },
+ "⨒": { "codepoints": [10770], "characters": "\u2A12" },
+ "⇉": { "codepoints": [8649], "characters": "\u21C9" },
+ "›": { "codepoints": [8250], "characters": "\u203A" },
+ "𝓇": { "codepoints": [120007], "characters": "\uD835\uDCC7" },
+ "↱": { "codepoints": [8625], "characters": "\u21B1" },
+ "]": { "codepoints": [93], "characters": "\u005D" },
+ "’": { "codepoints": [8217], "characters": "\u2019" },
+ "’": { "codepoints": [8217], "characters": "\u2019" },
+ "⋌": { "codepoints": [8908], "characters": "\u22CC" },
+ "⋊": { "codepoints": [8906], "characters": "\u22CA" },
+ "▹": { "codepoints": [9657], "characters": "\u25B9" },
+ "⊵": { "codepoints": [8885], "characters": "\u22B5" },
+ "▸": { "codepoints": [9656], "characters": "\u25B8" },
+ "⧎": { "codepoints": [10702], "characters": "\u29CE" },
+ "⥨": { "codepoints": [10600], "characters": "\u2968" },
+ "℞": { "codepoints": [8478], "characters": "\u211E" },
+ "ś": { "codepoints": [347], "characters": "\u015B" },
+ "‚": { "codepoints": [8218], "characters": "\u201A" },
+ "≻": { "codepoints": [8827], "characters": "\u227B" },
+ "⪴": { "codepoints": [10932], "characters": "\u2AB4" },
+ "⪸": { "codepoints": [10936], "characters": "\u2AB8" },
+ "š": { "codepoints": [353], "characters": "\u0161" },
+ "≽": { "codepoints": [8829], "characters": "\u227D" },
+ "⪰": { "codepoints": [10928], "characters": "\u2AB0" },
+ "ş": { "codepoints": [351], "characters": "\u015F" },
+ "ŝ": { "codepoints": [349], "characters": "\u015D" },
+ "⪶": { "codepoints": [10934], "characters": "\u2AB6" },
+ "⪺": { "codepoints": [10938], "characters": "\u2ABA" },
+ "⋩": { "codepoints": [8937], "characters": "\u22E9" },
+ "⨓": { "codepoints": [10771], "characters": "\u2A13" },
+ "≿": { "codepoints": [8831], "characters": "\u227F" },
+ "с": { "codepoints": [1089], "characters": "\u0441" },
+ "⋅": { "codepoints": [8901], "characters": "\u22C5" },
+ "⊡": { "codepoints": [8865], "characters": "\u22A1" },
+ "⩦": { "codepoints": [10854], "characters": "\u2A66" },
+ "⇘": { "codepoints": [8664], "characters": "\u21D8" },
+ "⤥": { "codepoints": [10533], "characters": "\u2925" },
+ "↘": { "codepoints": [8600], "characters": "\u2198" },
+ "↘": { "codepoints": [8600], "characters": "\u2198" },
+ "§": { "codepoints": [167], "characters": "\u00A7" },
+ "§": { "codepoints": [167], "characters": "\u00A7" },
+ ";": { "codepoints": [59], "characters": "\u003B" },
+ "⤩": { "codepoints": [10537], "characters": "\u2929" },
+ "∖": { "codepoints": [8726], "characters": "\u2216" },
+ "∖": { "codepoints": [8726], "characters": "\u2216" },
+ "✶": { "codepoints": [10038], "characters": "\u2736" },
+ "𝔰": { "codepoints": [120112], "characters": "\uD835\uDD30" },
+ "⌢": { "codepoints": [8994], "characters": "\u2322" },
+ "♯": { "codepoints": [9839], "characters": "\u266F" },
+ "щ": { "codepoints": [1097], "characters": "\u0449" },
+ "ш": { "codepoints": [1096], "characters": "\u0448" },
+ "∣": { "codepoints": [8739], "characters": "\u2223" },
+ "∥": { "codepoints": [8741], "characters": "\u2225" },
+ "­": { "codepoints": [173], "characters": "\u00AD" },
+ "­": { "codepoints": [173], "characters": "\u00AD" },
+ "σ": { "codepoints": [963], "characters": "\u03C3" },
+ "ς": { "codepoints": [962], "characters": "\u03C2" },
+ "ς": { "codepoints": [962], "characters": "\u03C2" },
+ "∼": { "codepoints": [8764], "characters": "\u223C" },
+ "⩪": { "codepoints": [10858], "characters": "\u2A6A" },
+ "≃": { "codepoints": [8771], "characters": "\u2243" },
+ "≃": { "codepoints": [8771], "characters": "\u2243" },
+ "⪞": { "codepoints": [10910], "characters": "\u2A9E" },
+ "⪠": { "codepoints": [10912], "characters": "\u2AA0" },
+ "⪝": { "codepoints": [10909], "characters": "\u2A9D" },
+ "⪟": { "codepoints": [10911], "characters": "\u2A9F" },
+ "≆": { "codepoints": [8774], "characters": "\u2246" },
+ "⨤": { "codepoints": [10788], "characters": "\u2A24" },
+ "⥲": { "codepoints": [10610], "characters": "\u2972" },
+ "←": { "codepoints": [8592], "characters": "\u2190" },
+ "∖": { "codepoints": [8726], "characters": "\u2216" },
+ "⨳": { "codepoints": [10803], "characters": "\u2A33" },
+ "⧤": { "codepoints": [10724], "characters": "\u29E4" },
+ "∣": { "codepoints": [8739], "characters": "\u2223" },
+ "⌣": { "codepoints": [8995], "characters": "\u2323" },
+ "⪪": { "codepoints": [10922], "characters": "\u2AAA" },
+ "⪬": { "codepoints": [10924], "characters": "\u2AAC" },
+ "⪬︀": { "codepoints": [10924, 65024], "characters": "\u2AAC\uFE00" },
+ "ь": { "codepoints": [1100], "characters": "\u044C" },
+ "/": { "codepoints": [47], "characters": "\u002F" },
+ "⧄": { "codepoints": [10692], "characters": "\u29C4" },
+ "⌿": { "codepoints": [9023], "characters": "\u233F" },
+ "𝕤": { "codepoints": [120164], "characters": "\uD835\uDD64" },
+ "♠": { "codepoints": [9824], "characters": "\u2660" },
+ "♠": { "codepoints": [9824], "characters": "\u2660" },
+ "∥": { "codepoints": [8741], "characters": "\u2225" },
+ "⊓": { "codepoints": [8851], "characters": "\u2293" },
+ "⊓︀": { "codepoints": [8851, 65024], "characters": "\u2293\uFE00" },
+ "⊔": { "codepoints": [8852], "characters": "\u2294" },
+ "⊔︀": { "codepoints": [8852, 65024], "characters": "\u2294\uFE00" },
+ "⊏": { "codepoints": [8847], "characters": "\u228F" },
+ "⊑": { "codepoints": [8849], "characters": "\u2291" },
+ "⊏": { "codepoints": [8847], "characters": "\u228F" },
+ "⊑": { "codepoints": [8849], "characters": "\u2291" },
+ "⊐": { "codepoints": [8848], "characters": "\u2290" },
+ "⊒": { "codepoints": [8850], "characters": "\u2292" },
+ "⊐": { "codepoints": [8848], "characters": "\u2290" },
+ "⊒": { "codepoints": [8850], "characters": "\u2292" },
+ "□": { "codepoints": [9633], "characters": "\u25A1" },
+ "□": { "codepoints": [9633], "characters": "\u25A1" },
+ "▪": { "codepoints": [9642], "characters": "\u25AA" },
+ "▪": { "codepoints": [9642], "characters": "\u25AA" },
+ "→": { "codepoints": [8594], "characters": "\u2192" },
+ "𝓈": { "codepoints": [120008], "characters": "\uD835\uDCC8" },
+ "∖": { "codepoints": [8726], "characters": "\u2216" },
+ "⌣": { "codepoints": [8995], "characters": "\u2323" },
+ "⋆": { "codepoints": [8902], "characters": "\u22C6" },
+ "☆": { "codepoints": [9734], "characters": "\u2606" },
+ "★": { "codepoints": [9733], "characters": "\u2605" },
+ "ϵ": { "codepoints": [1013], "characters": "\u03F5" },
+ "ϕ": { "codepoints": [981], "characters": "\u03D5" },
+ "¯": { "codepoints": [175], "characters": "\u00AF" },
+ "⊂": { "codepoints": [8834], "characters": "\u2282" },
+ "⫅": { "codepoints": [10949], "characters": "\u2AC5" },
+ "⪽": { "codepoints": [10941], "characters": "\u2ABD" },
+ "⊆": { "codepoints": [8838], "characters": "\u2286" },
+ "⫃": { "codepoints": [10947], "characters": "\u2AC3" },
+ "⫁": { "codepoints": [10945], "characters": "\u2AC1" },
+ "⫋": { "codepoints": [10955], "characters": "\u2ACB" },
+ "⊊": { "codepoints": [8842], "characters": "\u228A" },
+ "⪿": { "codepoints": [10943], "characters": "\u2ABF" },
+ "⥹": { "codepoints": [10617], "characters": "\u2979" },
+ "⊂": { "codepoints": [8834], "characters": "\u2282" },
+ "⊆": { "codepoints": [8838], "characters": "\u2286" },
+ "⫅": { "codepoints": [10949], "characters": "\u2AC5" },
+ "⊊": { "codepoints": [8842], "characters": "\u228A" },
+ "⫋": { "codepoints": [10955], "characters": "\u2ACB" },
+ "⫇": { "codepoints": [10951], "characters": "\u2AC7" },
+ "⫕": { "codepoints": [10965], "characters": "\u2AD5" },
+ "⫓": { "codepoints": [10963], "characters": "\u2AD3" },
+ "≻": { "codepoints": [8827], "characters": "\u227B" },
+ "⪸": { "codepoints": [10936], "characters": "\u2AB8" },
+ "≽": { "codepoints": [8829], "characters": "\u227D" },
+ "⪰": { "codepoints": [10928], "characters": "\u2AB0" },
+ "⪺": { "codepoints": [10938], "characters": "\u2ABA" },
+ "⪶": { "codepoints": [10934], "characters": "\u2AB6" },
+ "⋩": { "codepoints": [8937], "characters": "\u22E9" },
+ "≿": { "codepoints": [8831], "characters": "\u227F" },
+ "∑": { "codepoints": [8721], "characters": "\u2211" },
+ "♪": { "codepoints": [9834], "characters": "\u266A" },
+ "¹": { "codepoints": [185], "characters": "\u00B9" },
+ "¹": { "codepoints": [185], "characters": "\u00B9" },
+ "²": { "codepoints": [178], "characters": "\u00B2" },
+ "²": { "codepoints": [178], "characters": "\u00B2" },
+ "³": { "codepoints": [179], "characters": "\u00B3" },
+ "³": { "codepoints": [179], "characters": "\u00B3" },
+ "⊃": { "codepoints": [8835], "characters": "\u2283" },
+ "⫆": { "codepoints": [10950], "characters": "\u2AC6" },
+ "⪾": { "codepoints": [10942], "characters": "\u2ABE" },
+ "⫘": { "codepoints": [10968], "characters": "\u2AD8" },
+ "⊇": { "codepoints": [8839], "characters": "\u2287" },
+ "⫄": { "codepoints": [10948], "characters": "\u2AC4" },
+ "⟉": { "codepoints": [10185], "characters": "\u27C9" },
+ "⫗": { "codepoints": [10967], "characters": "\u2AD7" },
+ "⥻": { "codepoints": [10619], "characters": "\u297B" },
+ "⫂": { "codepoints": [10946], "characters": "\u2AC2" },
+ "⫌": { "codepoints": [10956], "characters": "\u2ACC" },
+ "⊋": { "codepoints": [8843], "characters": "\u228B" },
+ "⫀": { "codepoints": [10944], "characters": "\u2AC0" },
+ "⊃": { "codepoints": [8835], "characters": "\u2283" },
+ "⊇": { "codepoints": [8839], "characters": "\u2287" },
+ "⫆": { "codepoints": [10950], "characters": "\u2AC6" },
+ "⊋": { "codepoints": [8843], "characters": "\u228B" },
+ "⫌": { "codepoints": [10956], "characters": "\u2ACC" },
+ "⫈": { "codepoints": [10952], "characters": "\u2AC8" },
+ "⫔": { "codepoints": [10964], "characters": "\u2AD4" },
+ "⫖": { "codepoints": [10966], "characters": "\u2AD6" },
+ "⇙": { "codepoints": [8665], "characters": "\u21D9" },
+ "⤦": { "codepoints": [10534], "characters": "\u2926" },
+ "↙": { "codepoints": [8601], "characters": "\u2199" },
+ "↙": { "codepoints": [8601], "characters": "\u2199" },
+ "⤪": { "codepoints": [10538], "characters": "\u292A" },
+ "ß": { "codepoints": [223], "characters": "\u00DF" },
+ "ß": { "codepoints": [223], "characters": "\u00DF" },
+ "⌖": { "codepoints": [8982], "characters": "\u2316" },
+ "τ": { "codepoints": [964], "characters": "\u03C4" },
+ "⎴": { "codepoints": [9140], "characters": "\u23B4" },
+ "ť": { "codepoints": [357], "characters": "\u0165" },
+ "ţ": { "codepoints": [355], "characters": "\u0163" },
+ "т": { "codepoints": [1090], "characters": "\u0442" },
+ "⃛": { "codepoints": [8411], "characters": "\u20DB" },
+ "⌕": { "codepoints": [8981], "characters": "\u2315" },
+ "𝔱": { "codepoints": [120113], "characters": "\uD835\uDD31" },
+ "∴": { "codepoints": [8756], "characters": "\u2234" },
+ "∴": { "codepoints": [8756], "characters": "\u2234" },
+ "θ": { "codepoints": [952], "characters": "\u03B8" },
+ "ϑ": { "codepoints": [977], "characters": "\u03D1" },
+ "ϑ": { "codepoints": [977], "characters": "\u03D1" },
+ "≈": { "codepoints": [8776], "characters": "\u2248" },
+ "∼": { "codepoints": [8764], "characters": "\u223C" },
+ " ": { "codepoints": [8201], "characters": "\u2009" },
+ "≈": { "codepoints": [8776], "characters": "\u2248" },
+ "∼": { "codepoints": [8764], "characters": "\u223C" },
+ "þ": { "codepoints": [254], "characters": "\u00FE" },
+ "þ": { "codepoints": [254], "characters": "\u00FE" },
+ "˜": { "codepoints": [732], "characters": "\u02DC" },
+ "×": { "codepoints": [215], "characters": "\u00D7" },
+ "×": { "codepoints": [215], "characters": "\u00D7" },
+ "⊠": { "codepoints": [8864], "characters": "\u22A0" },
+ "⨱": { "codepoints": [10801], "characters": "\u2A31" },
+ "⨰": { "codepoints": [10800], "characters": "\u2A30" },
+ "∭": { "codepoints": [8749], "characters": "\u222D" },
+ "⤨": { "codepoints": [10536], "characters": "\u2928" },
+ "⊤": { "codepoints": [8868], "characters": "\u22A4" },
+ "⌶": { "codepoints": [9014], "characters": "\u2336" },
+ "⫱": { "codepoints": [10993], "characters": "\u2AF1" },
+ "𝕥": { "codepoints": [120165], "characters": "\uD835\uDD65" },
+ "⫚": { "codepoints": [10970], "characters": "\u2ADA" },
+ "⤩": { "codepoints": [10537], "characters": "\u2929" },
+ "‴": { "codepoints": [8244], "characters": "\u2034" },
+ "™": { "codepoints": [8482], "characters": "\u2122" },
+ "▵": { "codepoints": [9653], "characters": "\u25B5" },
+ "▿": { "codepoints": [9663], "characters": "\u25BF" },
+ "◃": { "codepoints": [9667], "characters": "\u25C3" },
+ "⊴": { "codepoints": [8884], "characters": "\u22B4" },
+ "≜": { "codepoints": [8796], "characters": "\u225C" },
+ "▹": { "codepoints": [9657], "characters": "\u25B9" },
+ "⊵": { "codepoints": [8885], "characters": "\u22B5" },
+ "◬": { "codepoints": [9708], "characters": "\u25EC" },
+ "≜": { "codepoints": [8796], "characters": "\u225C" },
+ "⨺": { "codepoints": [10810], "characters": "\u2A3A" },
+ "⨹": { "codepoints": [10809], "characters": "\u2A39" },
+ "⧍": { "codepoints": [10701], "characters": "\u29CD" },
+ "⨻": { "codepoints": [10811], "characters": "\u2A3B" },
+ "⏢": { "codepoints": [9186], "characters": "\u23E2" },
+ "𝓉": { "codepoints": [120009], "characters": "\uD835\uDCC9" },
+ "ц": { "codepoints": [1094], "characters": "\u0446" },
+ "ћ": { "codepoints": [1115], "characters": "\u045B" },
+ "ŧ": { "codepoints": [359], "characters": "\u0167" },
+ "≬": { "codepoints": [8812], "characters": "\u226C" },
+ "↞": { "codepoints": [8606], "characters": "\u219E" },
+ "↠": { "codepoints": [8608], "characters": "\u21A0" },
+ "⇑": { "codepoints": [8657], "characters": "\u21D1" },
+ "⥣": { "codepoints": [10595], "characters": "\u2963" },
+ "ú": { "codepoints": [250], "characters": "\u00FA" },
+ "ú": { "codepoints": [250], "characters": "\u00FA" },
+ "↑": { "codepoints": [8593], "characters": "\u2191" },
+ "ў": { "codepoints": [1118], "characters": "\u045E" },
+ "ŭ": { "codepoints": [365], "characters": "\u016D" },
+ "û": { "codepoints": [251], "characters": "\u00FB" },
+ "û": { "codepoints": [251], "characters": "\u00FB" },
+ "у": { "codepoints": [1091], "characters": "\u0443" },
+ "⇅": { "codepoints": [8645], "characters": "\u21C5" },
+ "ű": { "codepoints": [369], "characters": "\u0171" },
+ "⥮": { "codepoints": [10606], "characters": "\u296E" },
+ "⥾": { "codepoints": [10622], "characters": "\u297E" },
+ "𝔲": { "codepoints": [120114], "characters": "\uD835\uDD32" },
+ "ù": { "codepoints": [249], "characters": "\u00F9" },
+ "ù": { "codepoints": [249], "characters": "\u00F9" },
+ "↿": { "codepoints": [8639], "characters": "\u21BF" },
+ "↾": { "codepoints": [8638], "characters": "\u21BE" },
+ "▀": { "codepoints": [9600], "characters": "\u2580" },
+ "⌜": { "codepoints": [8988], "characters": "\u231C" },
+ "⌜": { "codepoints": [8988], "characters": "\u231C" },
+ "⌏": { "codepoints": [8975], "characters": "\u230F" },
+ "◸": { "codepoints": [9720], "characters": "\u25F8" },
+ "ū": { "codepoints": [363], "characters": "\u016B" },
+ "¨": { "codepoints": [168], "characters": "\u00A8" },
+ "¨": { "codepoints": [168], "characters": "\u00A8" },
+ "ų": { "codepoints": [371], "characters": "\u0173" },
+ "𝕦": { "codepoints": [120166], "characters": "\uD835\uDD66" },
+ "↑": { "codepoints": [8593], "characters": "\u2191" },
+ "↕": { "codepoints": [8597], "characters": "\u2195" },
+ "↿": { "codepoints": [8639], "characters": "\u21BF" },
+ "↾": { "codepoints": [8638], "characters": "\u21BE" },
+ "⊎": { "codepoints": [8846], "characters": "\u228E" },
+ "υ": { "codepoints": [965], "characters": "\u03C5" },
+ "ϒ": { "codepoints": [978], "characters": "\u03D2" },
+ "υ": { "codepoints": [965], "characters": "\u03C5" },
+ "⇈": { "codepoints": [8648], "characters": "\u21C8" },
+ "⌝": { "codepoints": [8989], "characters": "\u231D" },
+ "⌝": { "codepoints": [8989], "characters": "\u231D" },
+ "⌎": { "codepoints": [8974], "characters": "\u230E" },
+ "ů": { "codepoints": [367], "characters": "\u016F" },
+ "◹": { "codepoints": [9721], "characters": "\u25F9" },
+ "𝓊": { "codepoints": [120010], "characters": "\uD835\uDCCA" },
+ "⋰": { "codepoints": [8944], "characters": "\u22F0" },
+ "ũ": { "codepoints": [361], "characters": "\u0169" },
+ "▵": { "codepoints": [9653], "characters": "\u25B5" },
+ "▴": { "codepoints": [9652], "characters": "\u25B4" },
+ "⇈": { "codepoints": [8648], "characters": "\u21C8" },
+ "ü": { "codepoints": [252], "characters": "\u00FC" },
+ "ü": { "codepoints": [252], "characters": "\u00FC" },
+ "⦧": { "codepoints": [10663], "characters": "\u29A7" },
+ "⇕": { "codepoints": [8661], "characters": "\u21D5" },
+ "⫨": { "codepoints": [10984], "characters": "\u2AE8" },
+ "⫩": { "codepoints": [10985], "characters": "\u2AE9" },
+ "⊨": { "codepoints": [8872], "characters": "\u22A8" },
+ "⦜": { "codepoints": [10652], "characters": "\u299C" },
+ "ϵ": { "codepoints": [1013], "characters": "\u03F5" },
+ "ϰ": { "codepoints": [1008], "characters": "\u03F0" },
+ "∅": { "codepoints": [8709], "characters": "\u2205" },
+ "ϕ": { "codepoints": [981], "characters": "\u03D5" },
+ "ϖ": { "codepoints": [982], "characters": "\u03D6" },
+ "∝": { "codepoints": [8733], "characters": "\u221D" },
+ "↕": { "codepoints": [8597], "characters": "\u2195" },
+ "ϱ": { "codepoints": [1009], "characters": "\u03F1" },
+ "ς": { "codepoints": [962], "characters": "\u03C2" },
+ "⊊︀": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" },
+ "⫋︀": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" },
+ "⊋︀": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" },
+ "⫌︀": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" },
+ "ϑ": { "codepoints": [977], "characters": "\u03D1" },
+ "⊲": { "codepoints": [8882], "characters": "\u22B2" },
+ "⊳": { "codepoints": [8883], "characters": "\u22B3" },
+ "в": { "codepoints": [1074], "characters": "\u0432" },
+ "⊢": { "codepoints": [8866], "characters": "\u22A2" },
+ "∨": { "codepoints": [8744], "characters": "\u2228" },
+ "⊻": { "codepoints": [8891], "characters": "\u22BB" },
+ "≚": { "codepoints": [8794], "characters": "\u225A" },
+ "⋮": { "codepoints": [8942], "characters": "\u22EE" },
+ "|": { "codepoints": [124], "characters": "\u007C" },
+ "|": { "codepoints": [124], "characters": "\u007C" },
+ "𝔳": { "codepoints": [120115], "characters": "\uD835\uDD33" },
+ "⊲": { "codepoints": [8882], "characters": "\u22B2" },
+ "⊂⃒": { "codepoints": [8834, 8402], "characters": "\u2282\u20D2" },
+ "⊃⃒": { "codepoints": [8835, 8402], "characters": "\u2283\u20D2" },
+ "𝕧": { "codepoints": [120167], "characters": "\uD835\uDD67" },
+ "∝": { "codepoints": [8733], "characters": "\u221D" },
+ "⊳": { "codepoints": [8883], "characters": "\u22B3" },
+ "𝓋": { "codepoints": [120011], "characters": "\uD835\uDCCB" },
+ "⫋︀": { "codepoints": [10955, 65024], "characters": "\u2ACB\uFE00" },
+ "⊊︀": { "codepoints": [8842, 65024], "characters": "\u228A\uFE00" },
+ "⫌︀": { "codepoints": [10956, 65024], "characters": "\u2ACC\uFE00" },
+ "⊋︀": { "codepoints": [8843, 65024], "characters": "\u228B\uFE00" },
+ "⦚": { "codepoints": [10650], "characters": "\u299A" },
+ "ŵ": { "codepoints": [373], "characters": "\u0175" },
+ "⩟": { "codepoints": [10847], "characters": "\u2A5F" },
+ "∧": { "codepoints": [8743], "characters": "\u2227" },
+ "≙": { "codepoints": [8793], "characters": "\u2259" },
+ "℘": { "codepoints": [8472], "characters": "\u2118" },
+ "𝔴": { "codepoints": [120116], "characters": "\uD835\uDD34" },
+ "𝕨": { "codepoints": [120168], "characters": "\uD835\uDD68" },
+ "℘": { "codepoints": [8472], "characters": "\u2118" },
+ "≀": { "codepoints": [8768], "characters": "\u2240" },
+ "≀": { "codepoints": [8768], "characters": "\u2240" },
+ "𝓌": { "codepoints": [120012], "characters": "\uD835\uDCCC" },
+ "⋂": { "codepoints": [8898], "characters": "\u22C2" },
+ "◯": { "codepoints": [9711], "characters": "\u25EF" },
+ "⋃": { "codepoints": [8899], "characters": "\u22C3" },
+ "▽": { "codepoints": [9661], "characters": "\u25BD" },
+ "𝔵": { "codepoints": [120117], "characters": "\uD835\uDD35" },
+ "⟺": { "codepoints": [10234], "characters": "\u27FA" },
+ "⟷": { "codepoints": [10231], "characters": "\u27F7" },
+ "ξ": { "codepoints": [958], "characters": "\u03BE" },
+ "⟸": { "codepoints": [10232], "characters": "\u27F8" },
+ "⟵": { "codepoints": [10229], "characters": "\u27F5" },
+ "⟼": { "codepoints": [10236], "characters": "\u27FC" },
+ "⋻": { "codepoints": [8955], "characters": "\u22FB" },
+ "⨀": { "codepoints": [10752], "characters": "\u2A00" },
+ "𝕩": { "codepoints": [120169], "characters": "\uD835\uDD69" },
+ "⨁": { "codepoints": [10753], "characters": "\u2A01" },
+ "⨂": { "codepoints": [10754], "characters": "\u2A02" },
+ "⟹": { "codepoints": [10233], "characters": "\u27F9" },
+ "⟶": { "codepoints": [10230], "characters": "\u27F6" },
+ "𝓍": { "codepoints": [120013], "characters": "\uD835\uDCCD" },
+ "⨆": { "codepoints": [10758], "characters": "\u2A06" },
+ "⨄": { "codepoints": [10756], "characters": "\u2A04" },
+ "△": { "codepoints": [9651], "characters": "\u25B3" },
+ "⋁": { "codepoints": [8897], "characters": "\u22C1" },
+ "⋀": { "codepoints": [8896], "characters": "\u22C0" },
+ "ý": { "codepoints": [253], "characters": "\u00FD" },
+ "ý": { "codepoints": [253], "characters": "\u00FD" },
+ "я": { "codepoints": [1103], "characters": "\u044F" },
+ "ŷ": { "codepoints": [375], "characters": "\u0177" },
+ "ы": { "codepoints": [1099], "characters": "\u044B" },
+ "¥": { "codepoints": [165], "characters": "\u00A5" },
+ "¥": { "codepoints": [165], "characters": "\u00A5" },
+ "𝔶": { "codepoints": [120118], "characters": "\uD835\uDD36" },
+ "ї": { "codepoints": [1111], "characters": "\u0457" },
+ "𝕪": { "codepoints": [120170], "characters": "\uD835\uDD6A" },
+ "𝓎": { "codepoints": [120014], "characters": "\uD835\uDCCE" },
+ "ю": { "codepoints": [1102], "characters": "\u044E" },
+ "ÿ": { "codepoints": [255], "characters": "\u00FF" },
+ "ÿ": { "codepoints": [255], "characters": "\u00FF" },
+ "ź": { "codepoints": [378], "characters": "\u017A" },
+ "ž": { "codepoints": [382], "characters": "\u017E" },
+ "з": { "codepoints": [1079], "characters": "\u0437" },
+ "ż": { "codepoints": [380], "characters": "\u017C" },
+ "ℨ": { "codepoints": [8488], "characters": "\u2128" },
+ "ζ": { "codepoints": [950], "characters": "\u03B6" },
+ "𝔷": { "codepoints": [120119], "characters": "\uD835\uDD37" },
+ "ж": { "codepoints": [1078], "characters": "\u0436" },
+ "⇝": { "codepoints": [8669], "characters": "\u21DD" },
+ "𝕫": { "codepoints": [120171], "characters": "\uD835\uDD6B" },
+ "𝓏": { "codepoints": [120015], "characters": "\uD835\uDCCF" },
+ "‍": { "codepoints": [8205], "characters": "\u200D" },
+ "‌": { "codepoints": [8204], "characters": "\u200C" }
+}
diff --git a/pkgs/markdown/tool/expected_output.dart b/pkgs/markdown/tool/expected_output.dart
index 30d8fe9..b50adb0 100644
--- a/pkgs/markdown/tool/expected_output.dart
+++ b/pkgs/markdown/tool/expected_output.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
-import 'dart:isolate';
import 'package:path/path.dart' as p;
@@ -35,14 +34,14 @@
description = 'line ${i + 1}: $description';
}
- var input = '';
+ final input = StringBuffer();
while (!lines[i].startsWith('<<<')) {
- input += '${lines[i++]}\n';
+ input.writeln(lines[i++]);
}
- var expectedOutput = '';
+ final expectedOutput = StringBuffer();
while (++i < lines.length && !lines[i].startsWith('>>>')) {
- expectedOutput += '${lines[i]}\n';
+ expectedOutput.writeln(lines[i]);
}
final dataCase = DataCase(
@@ -51,8 +50,8 @@
front_matter: frontMatter.toString(),
description: description,
skip: skip,
- input: input,
- expectedOutput: expectedOutput,
+ input: input.toString(),
+ expectedOutput: expectedOutput.toString(),
);
yield dataCase;
}
@@ -116,16 +115,12 @@
/// }
/// }
/// ```
-Stream<DataCase> dataCasesUnder({
+Iterable<DataCase> dataCasesUnder({
required String testDirectory,
String extension = 'unit',
bool recursive = true,
-}) async* {
- final packageUri = Uri.parse('package:markdown/markdown.dart');
- final isolateUri = await Isolate.resolvePackageUri(packageUri);
- final markdownLibRoot = p.dirname(isolateUri!.toFilePath());
- final directory =
- p.joinAll([p.dirname(markdownLibRoot), 'test', testDirectory]);
+}) sync* {
+ final directory = p.join(p.current, 'test', testDirectory);
for (final dataCase in _dataCases(
directory: directory,
extension: extension,
diff --git a/pkgs/markdown/tool/gfm_stats.json b/pkgs/markdown/tool/gfm_stats.json
index ffbe9bd..1460d3e 100644
--- a/pkgs/markdown/tool/gfm_stats.json
+++ b/pkgs/markdown/tool/gfm_stats.json
@@ -34,24 +34,24 @@
"613": "strict",
"614": "strict",
"615": "strict",
- "616": "fail",
+ "616": "strict",
"617": "strict",
"618": "strict",
- "619": "fail",
+ "619": "strict",
"620": "strict"
},
"Autolinks (extension)": {
"621": "strict",
"622": "strict",
"623": "strict",
- "624": "fail",
+ "624": "strict",
"625": "strict",
"626": "loose",
"627": "strict",
"628": "strict",
- "629": "fail",
- "630": "fail",
- "631": "fail"
+ "629": "strict",
+ "630": "strict",
+ "631": "strict"
},
"Backslash escapes": {
"308": "loose",
@@ -260,7 +260,7 @@
},
"Entity and numeric character references": {
"321": "loose",
- "322": "loose",
+ "322": "strict",
"323": "loose",
"324": "loose",
"325": "strict",
@@ -268,12 +268,12 @@
"327": "strict",
"328": "fail",
"329": "fail",
- "330": "fail",
+ "330": "strict",
"331": "strict",
"332": "strict",
- "333": "loose",
- "334": "loose",
- "335": "loose",
+ "333": "strict",
+ "334": "strict",
+ "335": "strict",
"336": "loose",
"337": "strict"
},
@@ -367,7 +367,7 @@
"156": "strict",
"157": "loose",
"158": "strict",
- "159": "loose",
+ "159": "strict",
"160": "loose"
},
"Images": {
@@ -623,26 +623,26 @@
},
"Raw HTML": {
"632": "strict",
- "633": "fail",
+ "633": "strict",
"634": "strict",
"635": "strict",
"636": "strict",
"637": "strict",
- "638": "fail",
+ "638": "loose",
"639": "loose",
- "640": "fail",
- "641": "fail",
+ "640": "loose",
+ "641": "strict",
"642": "strict",
- "643": "fail",
- "644": "loose",
+ "643": "loose",
+ "644": "strict",
"645": "strict",
"646": "strict",
"647": "strict",
"648": "strict",
- "649": "loose",
+ "649": "strict",
"650": "strict",
"651": "strict",
- "652": "fail"
+ "652": "loose"
},
"Setext headings": {
"50": "strict",
@@ -682,14 +682,14 @@
"492": "strict"
},
"Tables (extension)": {
- "198": "loose",
- "199": "fail",
- "200": "loose",
- "201": "loose",
- "202": "loose",
- "203": "loose",
- "204": "loose",
- "205": "loose"
+ "198": "strict",
+ "199": "strict",
+ "200": "strict",
+ "201": "strict",
+ "202": "strict",
+ "203": "strict",
+ "204": "strict",
+ "205": "strict"
},
"Tabs": {
"1": "strict",
diff --git a/pkgs/markdown/tool/gfm_stats.txt b/pkgs/markdown/tool/gfm_stats.txt
index b82976e..c455a49 100644
--- a/pkgs/markdown/tool/gfm_stats.txt
+++ b/pkgs/markdown/tool/gfm_stats.txt
@@ -1,13 +1,13 @@
17 of 18 – 94.4% ATX headings
- 17 of 19 – 89.5% Autolinks
- 7 of 11 – 63.6% Autolinks (extension)
+ 19 of 19 – 100.0% Autolinks
+ 11 of 11 – 100.0% Autolinks (extension)
12 of 13 – 92.3% Backslash escapes
1 of 1 – 100.0% Blank lines
23 of 25 – 92.0% Block quotes
22 of 22 – 100.0% Code spans
0 of 1 – 0.0% Disallowed Raw HTML (extension)
130 of 131 – 99.2% Emphasis and strong emphasis
- 14 of 17 – 82.4% Entity and numeric character references
+ 15 of 17 – 88.2% Entity and numeric character references
28 of 29 – 96.6% Fenced code blocks
15 of 15 – 100.0% Hard line breaks
43 of 43 – 100.0% HTML blocks
@@ -20,13 +20,13 @@
22 of 26 – 84.6% Lists
8 of 8 – 100.0% Paragraphs
1 of 1 – 100.0% Precedence
- 15 of 21 – 71.4% Raw HTML
+ 21 of 21 – 100.0% Raw HTML
26 of 27 – 96.3% Setext headings
2 of 2 – 100.0% Soft line breaks
2 of 2 – 100.0% Strikethrough (extension)
- 7 of 8 – 87.5% Tables (extension)
+ 8 of 8 – 100.0% Tables (extension)
11 of 11 – 100.0% Tabs
3 of 3 – 100.0% Textual content
19 of 19 – 100.0% Thematic breaks
- 626 of 671 – 93.3% TOTAL
- 551 of 626 – 88.0% TOTAL Strict
+ 640 of 671 – 95.4% TOTAL
+ 575 of 640 – 89.8% TOTAL Strict
diff --git a/pkgs/markdown/tool/stats.dart b/pkgs/markdown/tool/stats.dart
index a212e6c..4f952bb 100644
--- a/pkgs/markdown/tool/stats.dart
+++ b/pkgs/markdown/tool/stats.dart
@@ -27,30 +27,26 @@
)
..addFlag(
'raw',
- defaultsTo: false,
help: 'raw JSON format',
negatable: false,
)
..addFlag(
'update-files',
- defaultsTo: false,
help: 'Update stats files in $toolDir',
negatable: false,
)
..addFlag(
'verbose',
- defaultsTo: false,
help: 'Print details for failures and errors.',
negatable: false,
)
..addFlag(
'verbose-loose',
- defaultsTo: false,
help: 'Print details for "loose" matches.',
negatable: false,
)
..addOption('flavor', allowed: _configs.map((c) => c.prefix))
- ..addFlag('help', defaultsTo: false, negatable: false);
+ ..addFlag('help', negatable: false);
ArgResults options;
@@ -140,6 +136,7 @@
e,
verboseFail: verbose,
verboseLooseMatch: verboseLooseMatch,
+ extensions: e.extensions,
);
units.add(DataCase(
@@ -153,7 +150,7 @@
final nestedMap = scores.putIfAbsent(
entry.key,
- () => SplayTreeMap<int, CompareLevel>(),
+ SplayTreeMap<int, CompareLevel>.new,
);
nestedMap[e.example] = result.compareLevel;
}
@@ -220,9 +217,10 @@
sink = stdout;
}
- final encoder = const JsonEncoder.withIndent(' ', _convert);
+ const encoder = JsonEncoder.withIndent(' ', _convert);
try {
sink.writeln(encoder.convert(scores));
+ // ignore: avoid_catching_errors
} on JsonUnsupportedObjectError catch (e) {
stderr.writeln(e.cause);
stderr.writeln(e.unsupportedObject.runtimeType);
diff --git a/pkgs/markdown/tool/stats_lib.dart b/pkgs/markdown/tool/stats_lib.dart
index 125b34e..c1298f1 100644
--- a/pkgs/markdown/tool/stats_lib.dart
+++ b/pkgs/markdown/tool/stats_lib.dart
@@ -8,7 +8,14 @@
import 'package:html/dom.dart' show Element;
import 'package:html/parser.dart' show parseFragment;
-import 'package:markdown/markdown.dart' show markdownToHtml, ExtensionSet;
+import 'package:markdown/markdown.dart'
+ show
+ markdownToHtml,
+ InlineSyntax,
+ BlockSyntax,
+ AutolinkExtensionSyntax,
+ StrikethroughSyntax,
+ TableSyntax;
import 'package:path/path.dart' as p;
import '../test/util.dart';
@@ -54,19 +61,16 @@
static final Config commonMarkConfig = Config._(
'common_mark',
'http://spec.commonmark.org/0.28/',
- null,
);
static final Config gfmConfig = Config._(
'gfm',
'https://github.github.com/gfm/',
- ExtensionSet.gitHubFlavored,
);
final String prefix;
final String baseUrl;
- final ExtensionSet? extensionSet;
- Config._(this.prefix, this.baseUrl, this.extensionSet);
+ Config._(this.prefix, this.baseUrl);
}
class CommonMarkTestCase {
@@ -76,6 +80,7 @@
final String html;
final int startLine;
final int endLine;
+ final Set<String> extensions;
CommonMarkTestCase(
this.example,
@@ -84,6 +89,7 @@
this.endLine,
this.markdown,
this.html,
+ this.extensions,
);
factory CommonMarkTestCase.fromJson(Map<String, dynamic> json) {
@@ -94,6 +100,9 @@
json['end_line'] as int,
json['markdown'] as String /*!*/,
json['html'] as String,
+ json['extensions'] == null
+ ? const {}
+ : Set.from(json['extensions'] as List),
);
}
@@ -117,11 +126,37 @@
bool throwOnError = false,
bool verboseFail = false,
bool verboseLooseMatch = false,
+ Set<String> extensions = const {},
}) {
String output;
+ final inlineSyntaxes = <InlineSyntax>[];
+ final blockSyntaxes = <BlockSyntax>[];
+
+ for (final extension in extensions) {
+ switch (extension) {
+ case 'autolink':
+ inlineSyntaxes.add(AutolinkExtensionSyntax());
+ break;
+ case 'strikethrough':
+ inlineSyntaxes.add(StrikethroughSyntax());
+ break;
+ case 'table':
+ blockSyntaxes.add(const TableSyntax());
+ break;
+ case 'tagfilter':
+ // TODO(Zhiguang): https://github.com/dart-lang/markdown/pull/447
+ break;
+ default:
+ throw UnimplementedError('Unimplemented extension "$extension"');
+ }
+ }
+
try {
- output =
- markdownToHtml(testCase.markdown, extensionSet: config.extensionSet);
+ output = markdownToHtml(
+ testCase.markdown,
+ inlineSyntaxes: inlineSyntaxes,
+ blockSyntaxes: blockSyntaxes,
+ );
} catch (err, stackTrace) {
if (throwOnError) {
rethrow;
diff --git a/pkgs/markdown/tool/update_blns.dart b/pkgs/markdown/tool/update_blns.dart
index b48b8a7..e2b5c62 100644
--- a/pkgs/markdown/tool/update_blns.dart
+++ b/pkgs/markdown/tool/update_blns.dart
@@ -1,23 +1,14 @@
import 'dart:async';
-import 'dart:convert';
import 'dart:io';
-final _blnsJsonRawUrl =
+import 'update_shared.dart';
+
+const _blnsJsonRawUrl =
'https://github.com/minimaxir/big-list-of-naughty-strings/raw/master/blns.json';
-final _blnsFilePath = 'test/blns.dart';
+const _blnsFilePath = 'test/blns.dart';
Future<void> main() async {
- final client = HttpClient();
- List<String> json;
- try {
- final request = await client.getUrl(Uri.parse(_blnsJsonRawUrl));
- final response = await request.close();
- final source =
- await response.cast<List<int>>().transform(utf8.decoder).join('');
- json = (jsonDecode(source) as List).cast<String>();
- } finally {
- client.close();
- }
+ final json = (await downloadJson(_blnsJsonRawUrl) as List).cast<String>();
final blnsContent = StringBuffer('''
// GENERATED FILE. DO NOT EDIT.
//
diff --git a/pkgs/markdown/tool/update_case_folding.dart b/pkgs/markdown/tool/update_case_folding.dart
new file mode 100644
index 0000000..e53f70b
--- /dev/null
+++ b/pkgs/markdown/tool/update_case_folding.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+
+// Generates and updates unicode case folding map.
+// Here only extract status C + F capital letters.
+void main() {
+ // Downloaded from http://www.unicode.org/Public/14.0.0/ucd/CaseFolding.txt
+ final file = File('${p.current}/tool/case_folding.txt');
+
+ final result = <String, String>{};
+
+ for (final line in file.readAsLinesSync()) {
+ if (line.startsWith('#') ||
+ line.trim().isEmpty ||
+ !line.contains('CAPITAL LETTER')) {
+ continue;
+ }
+
+ final content = line.substring(0, line.indexOf('#'));
+ final match =
+ RegExp(r'([0-9A-F]{1,6});\s+[CF];\s+(.+);').firstMatch(content);
+ if (match == null) {
+ continue;
+ }
+
+ final key = String.fromCharCode(int.parse(match[1]!, radix: 16));
+ final value = match[2]!.split(RegExp('[ ]+')).map((e) {
+ return String.fromCharCode(int.parse(e, radix: 16));
+ }).join();
+ result[key] = value;
+ }
+
+ final outputPath = '${p.current}/lib/src/assets/case_folding.dart';
+ final stringMap = const JsonEncoder.withIndent(' ').convert(result);
+ final output = '''
+// Generated file. do not edit.
+//
+// Source: tool/case_folding.txt
+// Script: tool/update_case_folding.dart
+// ignore_for_file: prefer_single_quotes
+
+const caseFoldingMap = $stringMap;
+''';
+ File(outputPath).writeAsStringSync(output);
+}
diff --git a/pkgs/markdown/tool/update_emojis.dart b/pkgs/markdown/tool/update_emojis.dart
index 6b11e7a..dad59c7 100644
--- a/pkgs/markdown/tool/update_emojis.dart
+++ b/pkgs/markdown/tool/update_emojis.dart
@@ -3,25 +3,23 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:convert';
import 'dart:io';
+import 'update_shared.dart';
+
// update_github_emojis.dart now generates the emoji list using the GitHub API
// to retrieve the emoji list. It uses this emoji source as a source to keep
// binary compatibility with the Unicode sequences for each emoji found here.
-final _emojisJsonRawUrl =
+const _emojisJsonRawUrl =
'https://raw.githubusercontent.com/muan/emojilib/v2.4.0/emojis.json';
-final _emojisFilePath = 'lib/src/legacy_emojis.dart';
+const _emojisFilePath = 'lib/src/legacy_emojis.dart';
Future<void> main() async {
- final client = HttpClient();
- final request = await client.getUrl(Uri.parse(_emojisJsonRawUrl));
- final response = await request.close();
- final json = jsonDecode(
- await response.cast<List<int>>().transform(utf8.decoder).join(''))
- .map((String alias, dynamic info) =>
- MapEntry(alias, info.cast<String, dynamic>()))
- .cast<String, Map<String, dynamic>>();
+ final json =
+ (await downloadJson(_emojisJsonRawUrl) as Map<String, dynamic>).map(
+ (String alias, dynamic info) =>
+ MapEntry(alias, info as Map<String, dynamic>),
+ );
final emojisContent = StringBuffer('''
// GENERATED FILE. DO NOT EDIT.
//
@@ -35,7 +33,7 @@
final ignored = <String>[];
// Dump in sorted order now to facilitate comparison with new GitHub emoji.
final sortedKeys = json.keys.toList()..sort();
- for (final String alias in sortedKeys) {
+ for (final alias in sortedKeys) {
final info = json[alias] as Map<String, dynamic>;
if (info['char'] != null) {
emojisContent.writeln(" '$alias': '${info['char']}',");
@@ -50,5 +48,4 @@
'emoji recognized by the markdown package, execute `update_github_emojis.dart`.\n');
print('Wrote data to $_emojisFilePath for $emojiCount emoji, '
'ignoring ${ignored.length}: ${ignored.join(', ')}.');
- exit(0);
}
diff --git a/pkgs/markdown/tool/update_entities.dart b/pkgs/markdown/tool/update_entities.dart
new file mode 100644
index 0000000..2026ebc
--- /dev/null
+++ b/pkgs/markdown/tool/update_entities.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+import 'package:path/path.dart' as p;
+
+/// Generates and updates HTML entities.
+void main() {
+ // Original file: https://html.spec.whatwg.org/entities.json
+ final file = File('${p.current}/tool/entities.json');
+ final json = file.readAsStringSync();
+ final map = Map<String, Map<String, dynamic>>.from(jsonDecode(json) as Map);
+
+ final result = <String, String>{};
+ for (var name in map.keys) {
+ if (name.endsWith(';')) {
+ final value = map[name]!['characters'] as String;
+ result[name] = value;
+ }
+ }
+
+ final outputPath = '${p.current}/lib/src/assets/html_entities.dart';
+ final stringMap = const JsonEncoder.withIndent(' ')
+ .convert(result)
+ .replaceAll(r'"$"', r'r"$"')
+ .replaceAll(r'"\\"', r'r"\"');
+ final output = '''
+// Generated file. do not edit.
+//
+// Source: tool/entities.json
+// Script: tool/update_entities.dart
+// ignore_for_file: prefer_single_quotes
+
+const htmlEntitiesMap = $stringMap;
+''';
+ File(outputPath).writeAsStringSync(output);
+}
diff --git a/pkgs/markdown/tool/update_github_emojis.dart b/pkgs/markdown/tool/update_github_emojis.dart
index 5431d31..d5af661 100644
--- a/pkgs/markdown/tool/update_github_emojis.dart
+++ b/pkgs/markdown/tool/update_github_emojis.dart
@@ -3,13 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'dart:convert';
import 'dart:io';
import 'package:args/args.dart';
-
import 'package:markdown/src/legacy_emojis.dart' as legacy;
+import 'update_shared.dart';
+
/// Regular expression to match GitHub emoji API output filenames.
RegExp gitHubEmojiApiPattern =
RegExp(r'^[\ \t]+"(.*?)".*unicode\/([A-Fa-f0-9\-]+)\.png');
@@ -26,11 +26,11 @@
/// The 'cricket' emoji changes from `🏏` to `🦗`, legacy available as 'cricket_game'.
/// (if the -g flag us used to force using the GitHub Unicode sequences for the
/// emoji then additionally the 'email' emoji changes from '✉️' to '📧').
-final _emojisJsonRawUrl = 'https://api.github.com/emojis';
-final _emojisFilePath = 'lib/src/emojis.dart';
+const _emojisJsonRawUrl = 'https://api.github.com/emojis';
+const _emojisFilePath = 'lib/src/emojis.dart';
/// Reference to emoji map within legacy_emojis.dart
-final legacyEmojis = legacy.emojis;
+const legacyEmojis = legacy.emojis;
/// AUTO GENERATED by [reconcile_emojis.dart] - this only needed to be done ONCE
/// during the reconciliation process with the legacy emoji.
@@ -140,7 +140,7 @@
const zeroWidthJoiner = 0x200D;
try {
- final String? rawHexList = gitHubEmojiUnicodeFromFilenamePattern
+ final rawHexList = gitHubEmojiUnicodeFromFilenamePattern
.firstMatch(emojiFilename)
?.group(1);
if (rawHexList == null) {
@@ -183,7 +183,7 @@
} catch (e) {
print(
'Invalid/Non-Conformant emoji filename encountered "$emojiFilename"!');
- return (errorSpecialReplacement);
+ return errorSpecialReplacement;
}
}
@@ -215,22 +215,24 @@
try {
results = parser.parse(args);
} catch (e) {
+ print(e);
printUsage(parser);
- exit(0);
+ return;
}
if (results['help'] as bool) {
printUsage(parser);
- exit(0);
+ return;
}
var totalEmojiWithDifferentUnicodeSequences = 0;
final useLegacyUnicodeSequences = !(results['useGitHubUnicodes'] as bool);
final visualizeUnicodeDiffs = results['visualizeDifferentUnicodes'] as bool;
- final dumpMarkdownShortCodes =
- (results['dumpMarkdownShortCodes'].toLowerCase() == 'plain');
- final dumpMarkdownToolTipShortCodes =
- (results['dumpMarkdownShortCodes'].toLowerCase() == 'tooltip');
+
+ final shortCodes =
+ (results['dumpMarkdownShortCodes'] as String).toLowerCase();
+ final dumpMarkdownShortCodes = shortCodes == 'plain';
+ final dumpMarkdownToolTipShortCodes = shortCodes == 'tooltip';
if (!useLegacyUnicodeSequences) {
// Issue warning of the implications of using full GitHub emjoi Unicode sequences.
@@ -240,14 +242,13 @@
print(
'The following emoji have different Unicode sequences from those of legacy versions:');
}
- final client = HttpClient();
- final request = await client.getUrl(Uri.parse(_emojisJsonRawUrl));
- final response = await request.close();
- final shortcodeToEmoji = jsonDecode(
- await response.cast<List<int>>().transform(utf8.decoder).join(''))
- .map((String alias, dynamic filename) => MapEntry(
- alias, parseGitHubFilenameIntoUnicodeString(filename as String)))
- .cast<String, String>() as Map<String, String>;
+ final shortcodeToEmoji =
+ (await downloadJson(_emojisJsonRawUrl) as Map<String, dynamic>).map(
+ (String alias, dynamic filename) => MapEntry(
+ alias,
+ parseGitHubFilenameIntoUnicodeString(filename as String),
+ ),
+ );
// Now before we proceed we need to 'mix in' any legacy emoji alias shortcodes that
// are missing from the GitHub emoji list.
@@ -271,8 +272,8 @@
final errored = <String>[];
// Dump in sorted order now to facilitate comparison with new GitHub emoji.
final sortedKeys = shortcodeToEmoji.keys.toList()..sort();
- for (final String shortCodeAlias in sortedKeys) {
- String emojiUnicode = shortcodeToEmoji[shortCodeAlias]!;
+ for (final shortCodeAlias in sortedKeys) {
+ var emojiUnicode = shortcodeToEmoji[shortCodeAlias]!;
if (useLegacyUnicodeSequences &&
legacyEmojis.containsKey(shortCodeAlias) &&
shortCodeAlias != 'cricket' &&
@@ -312,14 +313,13 @@
// is being captured, so we exit now to exclude the summary
// report from being included in the emoji markdown we have
// been outputing.
- exit(0);
+ return;
}
print('''Wrote data to $_emojisFilePath for $emojiCount emoji,
$totalEmojiWithDifferentUnicodeSequences emoji's Unicode sequences differ from legacy versions${!visualizeUnicodeDiffs ? " (run with -v flag to visualize)" : ""},
ignoring ${ignored.length}: ${ignored.join(', ')},
errored: ${errored.length} ${errored.join(', ')}.''');
- exit(0);
}
void printUsage(ArgParser parser) {
diff --git a/pkgs/markdown/tool/update_shared.dart b/pkgs/markdown/tool/update_shared.dart
new file mode 100644
index 0000000..6992cd5
--- /dev/null
+++ b/pkgs/markdown/tool/update_shared.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+Future<Object?> downloadJson(String uri) async {
+ final client = HttpClient();
+ try {
+ final request = await client.getUrl(Uri.parse(uri));
+ final response = await request.close();
+
+ return response
+ .transform(utf8.decoder)
+ .transform(const JsonDecoder())
+ .single;
+ } finally {
+ client.close();
+ }
+}