diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..d8d6143
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,22 @@
+name: CI
+
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+
+jobs:
+  test:
+    name: Nim ${{ matrix.nim }}
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        # xxx trim to on use latest in each branch eg 1.0.10, 1.2.8 etc
+        nim: [1.0.0, 1.0.2, 1.0.4, 1.0.10, 1.2.0, 1.2.2, 1.2.4, 1.2.6, 1.2.8, 1.4.0, 1.4.2, 1.4.4]
+    steps:
+    - uses: actions/checkout@v2
+    - name: Run Tests
+      run: |
+        docker pull nimlang/nim:${{ matrix.nim }}
+        docker run --rm -v `pwd`:/usr/src/app -w /usr/src/app nimlang/nim:${{ matrix.nim }} /bin/bash -c "nimble install -y; nimble test"
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 62f5efb..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-services:
-  - docker
-env:
-  - NIM=0.19.6
-  - NIM=0.20.0
-  - NIM=0.20.2
-  - NIM=1.0.0
-  - NIM=1.0.2
-  - NIM=1.0.4
-  - NIM=1.2.0
-  - NIM=1.2.2
-  - NIM=1.2.4
-  - NIM=1.2.6
-before_install:
-  - docker pull nimlang/nim:$NIM
-script:
-  - docker run --rm -v `pwd`:/usr/src/app -w /usr/src/app nimlang/nim:$NIM /bin/bash -c "nimble install -y; nimble test"
-notifications:
-  email:
-    on_failure: never
-    on_success: never
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 50cac3a..cfeb30e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,28 @@
+v0.19.0
+==================
+
+* Adds support for unbounded lookaround assertions
+* Fix: parsing `{n,m}` repetitions is less strict;
+  `{}`, `{abc}`, etc are parsed as characters. This is
+  closer to PCRE, but it won't allow error prone instances
+  such as missing brackets: `{123`.
+* Fix: double repetitions: `**`, `++`, `*+`, `???`, `{n}*`, `{n}+`,
+  and other combinations are no longer allowed. The `++` PCRE hack
+  is not allowed, as it won't work the same way anyway.
+
+v0.18.0
+==================
+
+* Adds `escapeRe(string): string` function
+* Removed `unicodeplus` dependency
+
+v0.17.1
+==================
+
+* Fix: regression related to repetitions,
+  and lonely assertions; issue #83
+* Fix: make it compile with ARC; thanks to @timotheecour
+
 v0.17.0
 ==================
 
@@ -64,7 +89,7 @@ v0.13
 ==================
 
 * Add `groupFirstCapture`, `groupLastCapture`, and
-  `group(1): seq[string]` (thaks to @xmonader)
+  `group(1): seq[string]` (thanks to @xmonader)
 * Add Nim 1.0.0 to CI
 * Drop Nim 0.18 support
 * Fix nested captures with repetition range; issue #46
diff --git a/README.md b/README.md
index 0c3862a..59dadb0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Regex
 
-[![Build Status](https://img.shields.io/travis/nitely/nim-regex/master.svg?style=flat-square)](https://travis-ci.org/nitely/nim-regex)
+[![Build Status](https://img.shields.io/github/workflow/status/nitely/nim-regex/CI/master?style=flat-square)](https://github.com/nitely/nim-regex/actions?query=workflow%3ACI)
 [![licence](https://img.shields.io/github/license/nitely/nim-regex.svg?style=flat-square)](https://raw.githubusercontent.com/nitely/nim-regex/master/LICENSE)
 
 A library for parsing, compiling, and executing regular expressions.
@@ -34,6 +34,10 @@ Nim +0.19.0
 nimble test
 ```
 
+## Debugging
+
+Compile with `-d:regexDotDir:.` to generate [dot files](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) of the regexes (NFAs) within the nim file. A dot file can be viewed in [Graphviz](https://dreampuf.github.io/GraphvizOnline/). Requires Nim +1.2.
+
 ## LICENSE
 
 MIT
diff --git a/bench/bench.nim b/bench/bench.nim
index 8de4d9b..b38d135 100644
--- a/bench/bench.nim
+++ b/bench/bench.nim
@@ -27,6 +27,13 @@ benchRelative(regex_sol, m):
     discard regex.match(text, pattern4, m2)
   doNotOptimizeAway(m2)
 
+benchRelative(regex_macro_sol, m):
+  var d: bool
+  for i in 0 ..< m:
+    regex.match text, regex.rex"\w*sol\w*":
+      d = true
+  doNotOptimizeAway(d)
+
 var dummyTextNums = """650-253-0001"""
 
 var pattern_nums = re.re"^[0-9]+-[0-9]+-[0-9]+$"
@@ -45,6 +52,13 @@ benchRelative(regex_nums, m):
     discard regex.match(dummyTextNums, n_pattern_nums, m2)
   doNotOptimizeAway(m2)
 
+benchRelative(regex_macro_nums, m):
+  var d: bool
+  for i in 0 ..< m:
+    regex.match text, regex.rex"[0-9]+-[0-9]+-[0-9]+":
+      d = true
+  doNotOptimizeAway(d)
+
 var pattern_nums2 = re.re"^[0-9]+..*$"
 
 bench(re_nums2, m):
@@ -61,15 +75,22 @@ benchRelative(regex_nums2, m):
     discard regex.match(dummyTextNums, n_pattern_nums2, m3)
   doNotOptimizeAway(m3)
 
-var lits_find_re = re.re"do|re|mi|fa|sol"
-
-bench(re_lits_find, m):
-  var d: int
+benchRelative(regex_macro_nums2, m):
+  var d: bool
   for i in 0 ..< m:
-    d = re.find(text, lits_find_re)
+    regex.match text, regex.rex"[0-9]+..*":
+      d = true
   doNotOptimizeAway(d)
 
 when false:  # XXX remove
+  var lits_find_re = re.re"do|re|mi|fa|sol"
+
+  bench(re_lits_find, m):
+    var d: int
+    for i in 0 ..< m:
+      d = re.find(text, lits_find_re)
+    doNotOptimizeAway(d)
+
   const lits_find = regex.re"do|re|mi|fa|sol"
 
   benchRelative(regex_lits_find, m):
@@ -92,7 +113,7 @@ bench(re_email_find_all, m):
 
 const email_find_all = regex.re"[\w\.+-]+@[\w\.-]+\.[\w\.-]+"
 
-benchRelative(email_find_all, m):
+benchRelative(regex_email_find_all, m):
   var d = 0
   for i in 0 ..< m:
     for _ in regex.findAll(bench_text, email_find_all):
@@ -112,7 +133,7 @@ bench(re_uri_find_all, m):
 
 const uri_find_all = regex.re"[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?"
 
-benchRelative(uri_find_all, m):
+benchRelative(regex_uri_find_all, m):
   var d = 0
   for i in 0 ..< m:
     for _ in regex.findAll(bench_text, uri_find_all):
@@ -132,7 +153,7 @@ bench(re_ip_find_all, m):
 
 const ip_find_all = regex.re"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])"
 
-benchRelative(ip_find_all, m):
+benchRelative(regex_ip_find_all, m):
   var d = 0
   for i in 0 ..< m:
     for _ in regex.findAll(bench_text, ip_find_all):
diff --git a/debian/changelog b/debian/changelog
index 92bdf1d..ae56b85 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+nim-regex (0.19.0+git20220308.1.a37b8f2-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Fri, 01 Apr 2022 05:22:19 -0000
+
 nim-regex (0.17.0+ds-2) unstable; urgency=medium
 
   * Added some sanity to the package.
diff --git a/docs/dochack.js b/docs/dochack.js
new file mode 100644
index 0000000..fcc691f
--- /dev/null
+++ b/docs/dochack.js
@@ -0,0 +1,1955 @@
+/* Generated by the Nim Compiler v1.5.1 */
+var framePtr = null;
+var excHandler = 0;
+var lastJSError = null;
+var NTI536870915 = {size: 0, kind: 18, base: null, node: null, finalizer: null};
+var NTI402653734 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093812 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093811 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093810 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093809 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093808 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093807 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093806 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093805 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093804 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093803 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093802 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093801 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093800 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093799 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093798 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093797 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093796 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093795 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093794 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093793 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093792 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093791 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093790 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093698 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093742 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093741 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093861 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093858 = {size: 0,kind: 25,base: null,node: null,finalizer: null};
+var NTI520093857 = {size: 0, kind: 18, base: null, node: null, finalizer: null};
+var NTI520093788 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093860 = {size: 0, kind: 18, base: null, node: null, finalizer: null};
+var NTI520093789 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093730 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093729 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093835 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093732 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093731 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093834 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093833 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093740 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093739 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093832 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093831 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093734 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093733 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093830 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093837 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093736 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093735 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093836 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI33554454 = {size: 0,kind: 31,base: null,node: null,finalizer: null};
+var NTI520093840 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093738 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093737 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI33554464 = {size: 0,kind: 1,base: null,node: null,finalizer: null};
+var NTI520093711 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093710 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093718 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093717 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093716 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093715 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520093712 = {size: 0, kind: 14, base: null, node: null, finalizer: null};
+var NTI520093829 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093828 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093827 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI520093714 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI520093713 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI520094115 = {size: 0,kind: 24,base: null,node: null,finalizer: null};
+var NTI33555108 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI33555112 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI33555071 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI33555149 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI33554437 = {size: 0,kind: 28,base: null,node: null,finalizer: null};
+var NTI33554438 = {size: 0,kind: 29,base: null,node: null,finalizer: null};
+var NTI33555148 = {size: 0,kind: 22,base: null,node: null,finalizer: null};
+var NTI33555096 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI33555097 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI33555104 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NTI33555106 = {size: 0, kind: 17, base: null, node: null, finalizer: null};
+var NNI33555106 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI33555106.node = NNI33555106;
+var NNI33555104 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI33555104.node = NNI33555104;
+var NNI33555097 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI33555097.node = NNI33555097;
+NTI33555148.base = NTI33555096;
+NTI33555149.base = NTI33555096;
+var NNI33555096 = {kind: 2, len: 5, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI33555148, name: "parent", sons: null}, 
+{kind: 1, offset: "name", len: 0, typ: NTI33554438, name: "name", sons: null}, 
+{kind: 1, offset: "message", len: 0, typ: NTI33554437, name: "msg", sons: null}, 
+{kind: 1, offset: "trace", len: 0, typ: NTI33554437, name: "trace", sons: null}, 
+{kind: 1, offset: "up", len: 0, typ: NTI33555149, name: "up", sons: null}]};
+NTI33555096.node = NNI33555096;
+var NNI33555071 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI33555071.node = NNI33555071;
+NTI33555096.base = NTI33555071;
+NTI33555097.base = NTI33555096;
+NTI33555104.base = NTI33555097;
+NTI33555106.base = NTI33555104;
+var NNI33555112 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI33555112.node = NNI33555112;
+NTI33555112.base = NTI33555097;
+var NNI33555108 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI33555108.node = NNI33555108;
+NTI33555108.base = NTI33555097;
+NTI520093827.base = NTI520093713;
+NTI520093828.base = NTI520093713;
+NTI520093829.base = NTI520093713;
+var NNI520093712 = {kind: 2, offset: 0, typ: null, name: null, len: 12, sons: {"1": {kind: 1, offset: 1, typ: NTI520093712, name: "ElementNode", len: 0, sons: null}, 
+"2": {kind: 1, offset: 2, typ: NTI520093712, name: "AttributeNode", len: 0, sons: null}, 
+"3": {kind: 1, offset: 3, typ: NTI520093712, name: "TextNode", len: 0, sons: null}, 
+"4": {kind: 1, offset: 4, typ: NTI520093712, name: "CDATANode", len: 0, sons: null}, 
+"5": {kind: 1, offset: 5, typ: NTI520093712, name: "EntityRefNode", len: 0, sons: null}, 
+"6": {kind: 1, offset: 6, typ: NTI520093712, name: "EntityNode", len: 0, sons: null}, 
+"7": {kind: 1, offset: 7, typ: NTI520093712, name: "ProcessingInstructionNode", len: 0, sons: null}, 
+"8": {kind: 1, offset: 8, typ: NTI520093712, name: "CommentNode", len: 0, sons: null}, 
+"9": {kind: 1, offset: 9, typ: NTI520093712, name: "DocumentNode", len: 0, sons: null}, 
+"10": {kind: 1, offset: 10, typ: NTI520093712, name: "DocumentTypeNode", len: 0, sons: null}, 
+"11": {kind: 1, offset: 11, typ: NTI520093712, name: "DocumentFragmentNode", len: 0, sons: null}, 
+"12": {kind: 1, offset: 12, typ: NTI520093712, name: "NotationNode", len: 0, sons: null}}};
+NTI520093712.node = NNI520093712;
+var NNI520093711 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []};
+NTI520093711.node = NNI520093711;
+NTI520093711.base = NTI33555071;
+NTI520093710.base = NTI520093711;
+NTI520093840.base = NTI520093717;
+var NNI520093738 = {kind: 2, len: 10, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "acceptCharset", len: 0, typ: NTI33554438, name: "acceptCharset", sons: null}, 
+{kind: 1, offset: "action", len: 0, typ: NTI33554438, name: "action", sons: null}, 
+{kind: 1, offset: "autocomplete", len: 0, typ: NTI33554438, name: "autocomplete", sons: null}, 
+{kind: 1, offset: "elements", len: 0, typ: NTI520093840, name: "elements", sons: null}, 
+{kind: 1, offset: "encoding", len: 0, typ: NTI33554438, name: "encoding", sons: null}, 
+{kind: 1, offset: "enctype", len: 0, typ: NTI33554438, name: "enctype", sons: null}, 
+{kind: 1, offset: "length", len: 0, typ: NTI33554454, name: "length", sons: null}, 
+{kind: 1, offset: "method", len: 0, typ: NTI33554438, name: "method", sons: null}, 
+{kind: 1, offset: "noValidate", len: 0, typ: NTI33554464, name: "noValidate", sons: null}, 
+{kind: 1, offset: "target", len: 0, typ: NTI33554438, name: "target", sons: null}]};
+NTI520093738.node = NNI520093738;
+NTI520093738.base = NTI520093718;
+NTI520093737.base = NTI520093738;
+var NNI520093736 = {kind: 2, len: 5, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "defaultSelected", len: 0, typ: NTI33554464, name: "defaultSelected", sons: null}, 
+{kind: 1, offset: "selected", len: 0, typ: NTI33554464, name: "selected", sons: null}, 
+{kind: 1, offset: "selectedIndex", len: 0, typ: NTI33554454, name: "selectedIndex", sons: null}, 
+{kind: 1, offset: "text", len: 0, typ: NTI33554438, name: "text", sons: null}, 
+{kind: 1, offset: "value", len: 0, typ: NTI33554438, name: "value", sons: null}]};
+NTI520093736.node = NNI520093736;
+NTI520093736.base = NTI520093718;
+NTI520093735.base = NTI520093736;
+NTI520093836.base = NTI520093735;
+NTI520093837.base = NTI520093735;
+var NNI520093718 = {kind: 2, len: 20, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "className", len: 0, typ: NTI33554438, name: "className", sons: null}, 
+{kind: 1, offset: "classList", len: 0, typ: NTI520093710, name: "classList", sons: null}, 
+{kind: 1, offset: "checked", len: 0, typ: NTI33554464, name: "checked", sons: null}, 
+{kind: 1, offset: "defaultChecked", len: 0, typ: NTI33554464, name: "defaultChecked", sons: null}, 
+{kind: 1, offset: "defaultValue", len: 0, typ: NTI33554438, name: "defaultValue", sons: null}, 
+{kind: 1, offset: "disabled", len: 0, typ: NTI33554464, name: "disabled", sons: null}, 
+{kind: 1, offset: "form", len: 0, typ: NTI520093737, name: "form", sons: null}, 
+{kind: 1, offset: "name", len: 0, typ: NTI33554438, name: "name", sons: null}, 
+{kind: 1, offset: "readOnly", len: 0, typ: NTI33554464, name: "readOnly", sons: null}, 
+{kind: 1, offset: "options", len: 0, typ: NTI520093836, name: "options", sons: null}, 
+{kind: 1, offset: "selectedOptions", len: 0, typ: NTI520093837, name: "selectedOptions", sons: null}, 
+{kind: 1, offset: "clientWidth", len: 0, typ: NTI33554454, name: "clientWidth", sons: null}, 
+{kind: 1, offset: "clientHeight", len: 0, typ: NTI33554454, name: "clientHeight", sons: null}, 
+{kind: 1, offset: "contentEditable", len: 0, typ: NTI33554438, name: "contentEditable", sons: null}, 
+{kind: 1, offset: "isContentEditable", len: 0, typ: NTI33554464, name: "isContentEditable", sons: null}, 
+{kind: 1, offset: "dir", len: 0, typ: NTI33554438, name: "dir", sons: null}, 
+{kind: 1, offset: "offsetHeight", len: 0, typ: NTI33554454, name: "offsetHeight", sons: null}, 
+{kind: 1, offset: "offsetWidth", len: 0, typ: NTI33554454, name: "offsetWidth", sons: null}, 
+{kind: 1, offset: "offsetLeft", len: 0, typ: NTI33554454, name: "offsetLeft", sons: null}, 
+{kind: 1, offset: "offsetTop", len: 0, typ: NTI33554454, name: "offsetTop", sons: null}]};
+NTI520093718.node = NNI520093718;
+NTI520093718.base = NTI520093714;
+NTI520093717.base = NTI520093718;
+var NNI520093734 = {kind: 2, len: 3, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "text", len: 0, typ: NTI33554438, name: "text", sons: null}, 
+{kind: 1, offset: "x", len: 0, typ: NTI33554454, name: "x", sons: null}, 
+{kind: 1, offset: "y", len: 0, typ: NTI33554454, name: "y", sons: null}]};
+NTI520093734.node = NNI520093734;
+NTI520093734.base = NTI520093718;
+NTI520093733.base = NTI520093734;
+NTI520093830.base = NTI520093733;
+NTI520093831.base = NTI520093737;
+var NNI520093740 = {kind: 2, len: 8, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "border", len: 0, typ: NTI33554454, name: "border", sons: null}, 
+{kind: 1, offset: "complete", len: 0, typ: NTI33554464, name: "complete", sons: null}, 
+{kind: 1, offset: "height", len: 0, typ: NTI33554454, name: "height", sons: null}, 
+{kind: 1, offset: "hspace", len: 0, typ: NTI33554454, name: "hspace", sons: null}, 
+{kind: 1, offset: "lowsrc", len: 0, typ: NTI33554438, name: "lowsrc", sons: null}, 
+{kind: 1, offset: "src", len: 0, typ: NTI33554438, name: "src", sons: null}, 
+{kind: 1, offset: "vspace", len: 0, typ: NTI33554454, name: "vspace", sons: null}, 
+{kind: 1, offset: "width", len: 0, typ: NTI33554454, name: "width", sons: null}]};
+NTI520093740.node = NNI520093740;
+NTI520093740.base = NTI520093718;
+NTI520093739.base = NTI520093740;
+NTI520093832.base = NTI520093739;
+NTI520093833.base = NTI520093717;
+var NNI520093732 = {kind: 2, len: 6, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "height", len: 0, typ: NTI33554454, name: "height", sons: null}, 
+{kind: 1, offset: "hspace", len: 0, typ: NTI33554454, name: "hspace", sons: null}, 
+{kind: 1, offset: "src", len: 0, typ: NTI33554438, name: "src", sons: null}, 
+{kind: 1, offset: "width", len: 0, typ: NTI33554454, name: "width", sons: null}, 
+{kind: 1, offset: "type", len: 0, typ: NTI33554438, name: "type", sons: null}, 
+{kind: 1, offset: "vspace", len: 0, typ: NTI33554454, name: "vspace", sons: null}]};
+NTI520093732.node = NNI520093732;
+NTI520093732.base = NTI520093718;
+NTI520093731.base = NTI520093732;
+NTI520093834.base = NTI520093731;
+var NNI520093730 = {kind: 2, len: 4, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "target", len: 0, typ: NTI33554438, name: "target", sons: null}, 
+{kind: 1, offset: "text", len: 0, typ: NTI33554438, name: "text", sons: null}, 
+{kind: 1, offset: "x", len: 0, typ: NTI33554454, name: "x", sons: null}, 
+{kind: 1, offset: "y", len: 0, typ: NTI33554454, name: "y", sons: null}]};
+NTI520093730.node = NNI520093730;
+NTI520093730.base = NTI520093718;
+NTI520093729.base = NTI520093730;
+NTI520093835.base = NTI520093729;
+var NNI520093857 = {kind: 1, offset: "then", len: 0, typ: NTI520093858, name: "then", sons: null};
+NTI520093857.node = NNI520093857;
+NTI520093788.base = NTI520093857;
+var NNI520093860 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "ready", len: 0, typ: NTI520093788, name: "ready", sons: null}, 
+{kind: 1, offset: "onloadingdone", len: 0, typ: NTI520093861, name: "onloadingdone", sons: null}]};
+NTI520093860.node = NNI520093860;
+NTI520093789.base = NTI520093860;
+var NNI520093716 = {kind: 2, len: 23, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "activeElement", len: 0, typ: NTI520093717, name: "activeElement", sons: null}, 
+{kind: 1, offset: "documentElement", len: 0, typ: NTI520093717, name: "documentElement", sons: null}, 
+{kind: 1, offset: "alinkColor", len: 0, typ: NTI33554438, name: "alinkColor", sons: null}, 
+{kind: 1, offset: "bgColor", len: 0, typ: NTI33554438, name: "bgColor", sons: null}, 
+{kind: 1, offset: "body", len: 0, typ: NTI520093717, name: "body", sons: null}, 
+{kind: 1, offset: "charset", len: 0, typ: NTI33554438, name: "charset", sons: null}, 
+{kind: 1, offset: "cookie", len: 0, typ: NTI33554438, name: "cookie", sons: null}, 
+{kind: 1, offset: "defaultCharset", len: 0, typ: NTI33554438, name: "defaultCharset", sons: null}, 
+{kind: 1, offset: "fgColor", len: 0, typ: NTI33554438, name: "fgColor", sons: null}, 
+{kind: 1, offset: "head", len: 0, typ: NTI520093717, name: "head", sons: null}, 
+{kind: 1, offset: "lastModified", len: 0, typ: NTI33554438, name: "lastModified", sons: null}, 
+{kind: 1, offset: "linkColor", len: 0, typ: NTI33554438, name: "linkColor", sons: null}, 
+{kind: 1, offset: "referrer", len: 0, typ: NTI33554438, name: "referrer", sons: null}, 
+{kind: 1, offset: "title", len: 0, typ: NTI33554438, name: "title", sons: null}, 
+{kind: 1, offset: "URL", len: 0, typ: NTI33554438, name: "URL", sons: null}, 
+{kind: 1, offset: "vlinkColor", len: 0, typ: NTI33554438, name: "vlinkColor", sons: null}, 
+{kind: 1, offset: "anchors", len: 0, typ: NTI520093830, name: "anchors", sons: null}, 
+{kind: 1, offset: "forms", len: 0, typ: NTI520093831, name: "forms", sons: null}, 
+{kind: 1, offset: "images", len: 0, typ: NTI520093832, name: "images", sons: null}, 
+{kind: 1, offset: "applets", len: 0, typ: NTI520093833, name: "applets", sons: null}, 
+{kind: 1, offset: "embeds", len: 0, typ: NTI520093834, name: "embeds", sons: null}, 
+{kind: 1, offset: "links", len: 0, typ: NTI520093835, name: "links", sons: null}, 
+{kind: 1, offset: "fonts", len: 0, typ: NTI520093789, name: "fonts", sons: null}]};
+NTI520093716.node = NNI520093716;
+NTI520093716.base = NTI520093714;
+NTI520093715.base = NTI520093716;
+var NNI520093742 = {kind: 2, len: 368, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "alignContent", len: 0, typ: NTI33554438, name: "alignContent", sons: null}, 
+{kind: 1, offset: "alignItems", len: 0, typ: NTI33554438, name: "alignItems", sons: null}, 
+{kind: 1, offset: "alignSelf", len: 0, typ: NTI33554438, name: "alignSelf", sons: null}, 
+{kind: 1, offset: "all", len: 0, typ: NTI33554438, name: "all", sons: null}, 
+{kind: 1, offset: "animation", len: 0, typ: NTI33554438, name: "animation", sons: null}, 
+{kind: 1, offset: "animationDelay", len: 0, typ: NTI33554438, name: "animationDelay", sons: null}, 
+{kind: 1, offset: "animationDirection", len: 0, typ: NTI33554438, name: "animationDirection", sons: null}, 
+{kind: 1, offset: "animationDuration", len: 0, typ: NTI33554438, name: "animationDuration", sons: null}, 
+{kind: 1, offset: "animationFillMode", len: 0, typ: NTI33554438, name: "animationFillMode", sons: null}, 
+{kind: 1, offset: "animationIterationCount", len: 0, typ: NTI33554438, name: "animationIterationCount", sons: null}, 
+{kind: 1, offset: "animationName", len: 0, typ: NTI33554438, name: "animationName", sons: null}, 
+{kind: 1, offset: "animationPlayState", len: 0, typ: NTI33554438, name: "animationPlayState", sons: null}, 
+{kind: 1, offset: "animationTimingFunction", len: 0, typ: NTI33554438, name: "animationTimingFunction", sons: null}, 
+{kind: 1, offset: "backdropFilter", len: 0, typ: NTI33554438, name: "backdropFilter", sons: null}, 
+{kind: 1, offset: "backfaceVisibility", len: 0, typ: NTI33554438, name: "backfaceVisibility", sons: null}, 
+{kind: 1, offset: "background", len: 0, typ: NTI33554438, name: "background", sons: null}, 
+{kind: 1, offset: "backgroundAttachment", len: 0, typ: NTI33554438, name: "backgroundAttachment", sons: null}, 
+{kind: 1, offset: "backgroundBlendMode", len: 0, typ: NTI33554438, name: "backgroundBlendMode", sons: null}, 
+{kind: 1, offset: "backgroundClip", len: 0, typ: NTI33554438, name: "backgroundClip", sons: null}, 
+{kind: 1, offset: "backgroundColor", len: 0, typ: NTI33554438, name: "backgroundColor", sons: null}, 
+{kind: 1, offset: "backgroundImage", len: 0, typ: NTI33554438, name: "backgroundImage", sons: null}, 
+{kind: 1, offset: "backgroundOrigin", len: 0, typ: NTI33554438, name: "backgroundOrigin", sons: null}, 
+{kind: 1, offset: "backgroundPosition", len: 0, typ: NTI33554438, name: "backgroundPosition", sons: null}, 
+{kind: 1, offset: "backgroundRepeat", len: 0, typ: NTI33554438, name: "backgroundRepeat", sons: null}, 
+{kind: 1, offset: "backgroundSize", len: 0, typ: NTI33554438, name: "backgroundSize", sons: null}, 
+{kind: 1, offset: "blockSize", len: 0, typ: NTI33554438, name: "blockSize", sons: null}, 
+{kind: 1, offset: "border", len: 0, typ: NTI33554438, name: "border", sons: null}, 
+{kind: 1, offset: "borderBlock", len: 0, typ: NTI33554438, name: "borderBlock", sons: null}, 
+{kind: 1, offset: "borderBlockColor", len: 0, typ: NTI33554438, name: "borderBlockColor", sons: null}, 
+{kind: 1, offset: "borderBlockEnd", len: 0, typ: NTI33554438, name: "borderBlockEnd", sons: null}, 
+{kind: 1, offset: "borderBlockEndColor", len: 0, typ: NTI33554438, name: "borderBlockEndColor", sons: null}, 
+{kind: 1, offset: "borderBlockEndStyle", len: 0, typ: NTI33554438, name: "borderBlockEndStyle", sons: null}, 
+{kind: 1, offset: "borderBlockEndWidth", len: 0, typ: NTI33554438, name: "borderBlockEndWidth", sons: null}, 
+{kind: 1, offset: "borderBlockStart", len: 0, typ: NTI33554438, name: "borderBlockStart", sons: null}, 
+{kind: 1, offset: "borderBlockStartColor", len: 0, typ: NTI33554438, name: "borderBlockStartColor", sons: null}, 
+{kind: 1, offset: "borderBlockStartStyle", len: 0, typ: NTI33554438, name: "borderBlockStartStyle", sons: null}, 
+{kind: 1, offset: "borderBlockStartWidth", len: 0, typ: NTI33554438, name: "borderBlockStartWidth", sons: null}, 
+{kind: 1, offset: "borderBlockStyle", len: 0, typ: NTI33554438, name: "borderBlockStyle", sons: null}, 
+{kind: 1, offset: "borderBlockWidth", len: 0, typ: NTI33554438, name: "borderBlockWidth", sons: null}, 
+{kind: 1, offset: "borderBottom", len: 0, typ: NTI33554438, name: "borderBottom", sons: null}, 
+{kind: 1, offset: "borderBottomColor", len: 0, typ: NTI33554438, name: "borderBottomColor", sons: null}, 
+{kind: 1, offset: "borderBottomLeftRadius", len: 0, typ: NTI33554438, name: "borderBottomLeftRadius", sons: null}, 
+{kind: 1, offset: "borderBottomRightRadius", len: 0, typ: NTI33554438, name: "borderBottomRightRadius", sons: null}, 
+{kind: 1, offset: "borderBottomStyle", len: 0, typ: NTI33554438, name: "borderBottomStyle", sons: null}, 
+{kind: 1, offset: "borderBottomWidth", len: 0, typ: NTI33554438, name: "borderBottomWidth", sons: null}, 
+{kind: 1, offset: "borderCollapse", len: 0, typ: NTI33554438, name: "borderCollapse", sons: null}, 
+{kind: 1, offset: "borderColor", len: 0, typ: NTI33554438, name: "borderColor", sons: null}, 
+{kind: 1, offset: "borderEndEndRadius", len: 0, typ: NTI33554438, name: "borderEndEndRadius", sons: null}, 
+{kind: 1, offset: "borderEndStartRadius", len: 0, typ: NTI33554438, name: "borderEndStartRadius", sons: null}, 
+{kind: 1, offset: "borderImage", len: 0, typ: NTI33554438, name: "borderImage", sons: null}, 
+{kind: 1, offset: "borderImageOutset", len: 0, typ: NTI33554438, name: "borderImageOutset", sons: null}, 
+{kind: 1, offset: "borderImageRepeat", len: 0, typ: NTI33554438, name: "borderImageRepeat", sons: null}, 
+{kind: 1, offset: "borderImageSlice", len: 0, typ: NTI33554438, name: "borderImageSlice", sons: null}, 
+{kind: 1, offset: "borderImageSource", len: 0, typ: NTI33554438, name: "borderImageSource", sons: null}, 
+{kind: 1, offset: "borderImageWidth", len: 0, typ: NTI33554438, name: "borderImageWidth", sons: null}, 
+{kind: 1, offset: "borderInline", len: 0, typ: NTI33554438, name: "borderInline", sons: null}, 
+{kind: 1, offset: "borderInlineColor", len: 0, typ: NTI33554438, name: "borderInlineColor", sons: null}, 
+{kind: 1, offset: "borderInlineEnd", len: 0, typ: NTI33554438, name: "borderInlineEnd", sons: null}, 
+{kind: 1, offset: "borderInlineEndColor", len: 0, typ: NTI33554438, name: "borderInlineEndColor", sons: null}, 
+{kind: 1, offset: "borderInlineEndStyle", len: 0, typ: NTI33554438, name: "borderInlineEndStyle", sons: null}, 
+{kind: 1, offset: "borderInlineEndWidth", len: 0, typ: NTI33554438, name: "borderInlineEndWidth", sons: null}, 
+{kind: 1, offset: "borderInlineStart", len: 0, typ: NTI33554438, name: "borderInlineStart", sons: null}, 
+{kind: 1, offset: "borderInlineStartColor", len: 0, typ: NTI33554438, name: "borderInlineStartColor", sons: null}, 
+{kind: 1, offset: "borderInlineStartStyle", len: 0, typ: NTI33554438, name: "borderInlineStartStyle", sons: null}, 
+{kind: 1, offset: "borderInlineStartWidth", len: 0, typ: NTI33554438, name: "borderInlineStartWidth", sons: null}, 
+{kind: 1, offset: "borderInlineStyle", len: 0, typ: NTI33554438, name: "borderInlineStyle", sons: null}, 
+{kind: 1, offset: "borderInlineWidth", len: 0, typ: NTI33554438, name: "borderInlineWidth", sons: null}, 
+{kind: 1, offset: "borderLeft", len: 0, typ: NTI33554438, name: "borderLeft", sons: null}, 
+{kind: 1, offset: "borderLeftColor", len: 0, typ: NTI33554438, name: "borderLeftColor", sons: null}, 
+{kind: 1, offset: "borderLeftStyle", len: 0, typ: NTI33554438, name: "borderLeftStyle", sons: null}, 
+{kind: 1, offset: "borderLeftWidth", len: 0, typ: NTI33554438, name: "borderLeftWidth", sons: null}, 
+{kind: 1, offset: "borderRadius", len: 0, typ: NTI33554438, name: "borderRadius", sons: null}, 
+{kind: 1, offset: "borderRight", len: 0, typ: NTI33554438, name: "borderRight", sons: null}, 
+{kind: 1, offset: "borderRightColor", len: 0, typ: NTI33554438, name: "borderRightColor", sons: null}, 
+{kind: 1, offset: "borderRightStyle", len: 0, typ: NTI33554438, name: "borderRightStyle", sons: null}, 
+{kind: 1, offset: "borderRightWidth", len: 0, typ: NTI33554438, name: "borderRightWidth", sons: null}, 
+{kind: 1, offset: "borderSpacing", len: 0, typ: NTI33554438, name: "borderSpacing", sons: null}, 
+{kind: 1, offset: "borderStartEndRadius", len: 0, typ: NTI33554438, name: "borderStartEndRadius", sons: null}, 
+{kind: 1, offset: "borderStartStartRadius", len: 0, typ: NTI33554438, name: "borderStartStartRadius", sons: null}, 
+{kind: 1, offset: "borderStyle", len: 0, typ: NTI33554438, name: "borderStyle", sons: null}, 
+{kind: 1, offset: "borderTop", len: 0, typ: NTI33554438, name: "borderTop", sons: null}, 
+{kind: 1, offset: "borderTopColor", len: 0, typ: NTI33554438, name: "borderTopColor", sons: null}, 
+{kind: 1, offset: "borderTopLeftRadius", len: 0, typ: NTI33554438, name: "borderTopLeftRadius", sons: null}, 
+{kind: 1, offset: "borderTopRightRadius", len: 0, typ: NTI33554438, name: "borderTopRightRadius", sons: null}, 
+{kind: 1, offset: "borderTopStyle", len: 0, typ: NTI33554438, name: "borderTopStyle", sons: null}, 
+{kind: 1, offset: "borderTopWidth", len: 0, typ: NTI33554438, name: "borderTopWidth", sons: null}, 
+{kind: 1, offset: "borderWidth", len: 0, typ: NTI33554438, name: "borderWidth", sons: null}, 
+{kind: 1, offset: "bottom", len: 0, typ: NTI33554438, name: "bottom", sons: null}, 
+{kind: 1, offset: "boxDecorationBreak", len: 0, typ: NTI33554438, name: "boxDecorationBreak", sons: null}, 
+{kind: 1, offset: "boxShadow", len: 0, typ: NTI33554438, name: "boxShadow", sons: null}, 
+{kind: 1, offset: "boxSizing", len: 0, typ: NTI33554438, name: "boxSizing", sons: null}, 
+{kind: 1, offset: "breakAfter", len: 0, typ: NTI33554438, name: "breakAfter", sons: null}, 
+{kind: 1, offset: "breakBefore", len: 0, typ: NTI33554438, name: "breakBefore", sons: null}, 
+{kind: 1, offset: "breakInside", len: 0, typ: NTI33554438, name: "breakInside", sons: null}, 
+{kind: 1, offset: "captionSide", len: 0, typ: NTI33554438, name: "captionSide", sons: null}, 
+{kind: 1, offset: "caretColor", len: 0, typ: NTI33554438, name: "caretColor", sons: null}, 
+{kind: 1, offset: "clear", len: 0, typ: NTI33554438, name: "clear", sons: null}, 
+{kind: 1, offset: "clip", len: 0, typ: NTI33554438, name: "clip", sons: null}, 
+{kind: 1, offset: "clipPath", len: 0, typ: NTI33554438, name: "clipPath", sons: null}, 
+{kind: 1, offset: "color", len: 0, typ: NTI33554438, name: "color", sons: null}, 
+{kind: 1, offset: "colorAdjust", len: 0, typ: NTI33554438, name: "colorAdjust", sons: null}, 
+{kind: 1, offset: "columnCount", len: 0, typ: NTI33554438, name: "columnCount", sons: null}, 
+{kind: 1, offset: "columnFill", len: 0, typ: NTI33554438, name: "columnFill", sons: null}, 
+{kind: 1, offset: "columnGap", len: 0, typ: NTI33554438, name: "columnGap", sons: null}, 
+{kind: 1, offset: "columnRule", len: 0, typ: NTI33554438, name: "columnRule", sons: null}, 
+{kind: 1, offset: "columnRuleColor", len: 0, typ: NTI33554438, name: "columnRuleColor", sons: null}, 
+{kind: 1, offset: "columnRuleStyle", len: 0, typ: NTI33554438, name: "columnRuleStyle", sons: null}, 
+{kind: 1, offset: "columnRuleWidth", len: 0, typ: NTI33554438, name: "columnRuleWidth", sons: null}, 
+{kind: 1, offset: "columnSpan", len: 0, typ: NTI33554438, name: "columnSpan", sons: null}, 
+{kind: 1, offset: "columnWidth", len: 0, typ: NTI33554438, name: "columnWidth", sons: null}, 
+{kind: 1, offset: "columns", len: 0, typ: NTI33554438, name: "columns", sons: null}, 
+{kind: 1, offset: "contain", len: 0, typ: NTI33554438, name: "contain", sons: null}, 
+{kind: 1, offset: "content", len: 0, typ: NTI33554438, name: "content", sons: null}, 
+{kind: 1, offset: "counterIncrement", len: 0, typ: NTI33554438, name: "counterIncrement", sons: null}, 
+{kind: 1, offset: "counterReset", len: 0, typ: NTI33554438, name: "counterReset", sons: null}, 
+{kind: 1, offset: "counterSet", len: 0, typ: NTI33554438, name: "counterSet", sons: null}, 
+{kind: 1, offset: "cursor", len: 0, typ: NTI33554438, name: "cursor", sons: null}, 
+{kind: 1, offset: "direction", len: 0, typ: NTI33554438, name: "direction", sons: null}, 
+{kind: 1, offset: "display", len: 0, typ: NTI33554438, name: "display", sons: null}, 
+{kind: 1, offset: "emptyCells", len: 0, typ: NTI33554438, name: "emptyCells", sons: null}, 
+{kind: 1, offset: "filter", len: 0, typ: NTI33554438, name: "filter", sons: null}, 
+{kind: 1, offset: "flex", len: 0, typ: NTI33554438, name: "flex", sons: null}, 
+{kind: 1, offset: "flexBasis", len: 0, typ: NTI33554438, name: "flexBasis", sons: null}, 
+{kind: 1, offset: "flexDirection", len: 0, typ: NTI33554438, name: "flexDirection", sons: null}, 
+{kind: 1, offset: "flexFlow", len: 0, typ: NTI33554438, name: "flexFlow", sons: null}, 
+{kind: 1, offset: "flexGrow", len: 0, typ: NTI33554438, name: "flexGrow", sons: null}, 
+{kind: 1, offset: "flexShrink", len: 0, typ: NTI33554438, name: "flexShrink", sons: null}, 
+{kind: 1, offset: "flexWrap", len: 0, typ: NTI33554438, name: "flexWrap", sons: null}, 
+{kind: 1, offset: "cssFloat", len: 0, typ: NTI33554438, name: "cssFloat", sons: null}, 
+{kind: 1, offset: "font", len: 0, typ: NTI33554438, name: "font", sons: null}, 
+{kind: 1, offset: "fontFamily", len: 0, typ: NTI33554438, name: "fontFamily", sons: null}, 
+{kind: 1, offset: "fontFeatureSettings", len: 0, typ: NTI33554438, name: "fontFeatureSettings", sons: null}, 
+{kind: 1, offset: "fontKerning", len: 0, typ: NTI33554438, name: "fontKerning", sons: null}, 
+{kind: 1, offset: "fontLanguageOverride", len: 0, typ: NTI33554438, name: "fontLanguageOverride", sons: null}, 
+{kind: 1, offset: "fontOpticalSizing", len: 0, typ: NTI33554438, name: "fontOpticalSizing", sons: null}, 
+{kind: 1, offset: "fontSize", len: 0, typ: NTI33554438, name: "fontSize", sons: null}, 
+{kind: 1, offset: "fontSizeAdjust", len: 0, typ: NTI33554438, name: "fontSizeAdjust", sons: null}, 
+{kind: 1, offset: "fontStretch", len: 0, typ: NTI33554438, name: "fontStretch", sons: null}, 
+{kind: 1, offset: "fontStyle", len: 0, typ: NTI33554438, name: "fontStyle", sons: null}, 
+{kind: 1, offset: "fontSynthesis", len: 0, typ: NTI33554438, name: "fontSynthesis", sons: null}, 
+{kind: 1, offset: "fontVariant", len: 0, typ: NTI33554438, name: "fontVariant", sons: null}, 
+{kind: 1, offset: "fontVariantAlternates", len: 0, typ: NTI33554438, name: "fontVariantAlternates", sons: null}, 
+{kind: 1, offset: "fontVariantCaps", len: 0, typ: NTI33554438, name: "fontVariantCaps", sons: null}, 
+{kind: 1, offset: "fontVariantEastAsian", len: 0, typ: NTI33554438, name: "fontVariantEastAsian", sons: null}, 
+{kind: 1, offset: "fontVariantLigatures", len: 0, typ: NTI33554438, name: "fontVariantLigatures", sons: null}, 
+{kind: 1, offset: "fontVariantNumeric", len: 0, typ: NTI33554438, name: "fontVariantNumeric", sons: null}, 
+{kind: 1, offset: "fontVariantPosition", len: 0, typ: NTI33554438, name: "fontVariantPosition", sons: null}, 
+{kind: 1, offset: "fontVariationSettings", len: 0, typ: NTI33554438, name: "fontVariationSettings", sons: null}, 
+{kind: 1, offset: "fontWeight", len: 0, typ: NTI33554438, name: "fontWeight", sons: null}, 
+{kind: 1, offset: "gap", len: 0, typ: NTI33554438, name: "gap", sons: null}, 
+{kind: 1, offset: "grid", len: 0, typ: NTI33554438, name: "grid", sons: null}, 
+{kind: 1, offset: "gridArea", len: 0, typ: NTI33554438, name: "gridArea", sons: null}, 
+{kind: 1, offset: "gridAutoColumns", len: 0, typ: NTI33554438, name: "gridAutoColumns", sons: null}, 
+{kind: 1, offset: "gridAutoFlow", len: 0, typ: NTI33554438, name: "gridAutoFlow", sons: null}, 
+{kind: 1, offset: "gridAutoRows", len: 0, typ: NTI33554438, name: "gridAutoRows", sons: null}, 
+{kind: 1, offset: "gridColumn", len: 0, typ: NTI33554438, name: "gridColumn", sons: null}, 
+{kind: 1, offset: "gridColumnEnd", len: 0, typ: NTI33554438, name: "gridColumnEnd", sons: null}, 
+{kind: 1, offset: "gridColumnStart", len: 0, typ: NTI33554438, name: "gridColumnStart", sons: null}, 
+{kind: 1, offset: "gridRow", len: 0, typ: NTI33554438, name: "gridRow", sons: null}, 
+{kind: 1, offset: "gridRowEnd", len: 0, typ: NTI33554438, name: "gridRowEnd", sons: null}, 
+{kind: 1, offset: "gridRowStart", len: 0, typ: NTI33554438, name: "gridRowStart", sons: null}, 
+{kind: 1, offset: "gridTemplate", len: 0, typ: NTI33554438, name: "gridTemplate", sons: null}, 
+{kind: 1, offset: "gridTemplateAreas", len: 0, typ: NTI33554438, name: "gridTemplateAreas", sons: null}, 
+{kind: 1, offset: "gridTemplateColumns", len: 0, typ: NTI33554438, name: "gridTemplateColumns", sons: null}, 
+{kind: 1, offset: "gridTemplateRows", len: 0, typ: NTI33554438, name: "gridTemplateRows", sons: null}, 
+{kind: 1, offset: "hangingPunctuation", len: 0, typ: NTI33554438, name: "hangingPunctuation", sons: null}, 
+{kind: 1, offset: "height", len: 0, typ: NTI33554438, name: "height", sons: null}, 
+{kind: 1, offset: "hyphens", len: 0, typ: NTI33554438, name: "hyphens", sons: null}, 
+{kind: 1, offset: "imageOrientation", len: 0, typ: NTI33554438, name: "imageOrientation", sons: null}, 
+{kind: 1, offset: "imageRendering", len: 0, typ: NTI33554438, name: "imageRendering", sons: null}, 
+{kind: 1, offset: "inlineSize", len: 0, typ: NTI33554438, name: "inlineSize", sons: null}, 
+{kind: 1, offset: "inset", len: 0, typ: NTI33554438, name: "inset", sons: null}, 
+{kind: 1, offset: "insetBlock", len: 0, typ: NTI33554438, name: "insetBlock", sons: null}, 
+{kind: 1, offset: "insetBlockEnd", len: 0, typ: NTI33554438, name: "insetBlockEnd", sons: null}, 
+{kind: 1, offset: "insetBlockStart", len: 0, typ: NTI33554438, name: "insetBlockStart", sons: null}, 
+{kind: 1, offset: "insetInline", len: 0, typ: NTI33554438, name: "insetInline", sons: null}, 
+{kind: 1, offset: "insetInlineEnd", len: 0, typ: NTI33554438, name: "insetInlineEnd", sons: null}, 
+{kind: 1, offset: "insetInlineStart", len: 0, typ: NTI33554438, name: "insetInlineStart", sons: null}, 
+{kind: 1, offset: "isolation", len: 0, typ: NTI33554438, name: "isolation", sons: null}, 
+{kind: 1, offset: "justifyContent", len: 0, typ: NTI33554438, name: "justifyContent", sons: null}, 
+{kind: 1, offset: "justifyItems", len: 0, typ: NTI33554438, name: "justifyItems", sons: null}, 
+{kind: 1, offset: "justifySelf", len: 0, typ: NTI33554438, name: "justifySelf", sons: null}, 
+{kind: 1, offset: "left", len: 0, typ: NTI33554438, name: "left", sons: null}, 
+{kind: 1, offset: "letterSpacing", len: 0, typ: NTI33554438, name: "letterSpacing", sons: null}, 
+{kind: 1, offset: "lineBreak", len: 0, typ: NTI33554438, name: "lineBreak", sons: null}, 
+{kind: 1, offset: "lineHeight", len: 0, typ: NTI33554438, name: "lineHeight", sons: null}, 
+{kind: 1, offset: "listStyle", len: 0, typ: NTI33554438, name: "listStyle", sons: null}, 
+{kind: 1, offset: "listStyleImage", len: 0, typ: NTI33554438, name: "listStyleImage", sons: null}, 
+{kind: 1, offset: "listStylePosition", len: 0, typ: NTI33554438, name: "listStylePosition", sons: null}, 
+{kind: 1, offset: "listStyleType", len: 0, typ: NTI33554438, name: "listStyleType", sons: null}, 
+{kind: 1, offset: "margin", len: 0, typ: NTI33554438, name: "margin", sons: null}, 
+{kind: 1, offset: "marginBlock", len: 0, typ: NTI33554438, name: "marginBlock", sons: null}, 
+{kind: 1, offset: "marginBlockEnd", len: 0, typ: NTI33554438, name: "marginBlockEnd", sons: null}, 
+{kind: 1, offset: "marginBlockStart", len: 0, typ: NTI33554438, name: "marginBlockStart", sons: null}, 
+{kind: 1, offset: "marginBottom", len: 0, typ: NTI33554438, name: "marginBottom", sons: null}, 
+{kind: 1, offset: "marginInline", len: 0, typ: NTI33554438, name: "marginInline", sons: null}, 
+{kind: 1, offset: "marginInlineEnd", len: 0, typ: NTI33554438, name: "marginInlineEnd", sons: null}, 
+{kind: 1, offset: "marginInlineStart", len: 0, typ: NTI33554438, name: "marginInlineStart", sons: null}, 
+{kind: 1, offset: "marginLeft", len: 0, typ: NTI33554438, name: "marginLeft", sons: null}, 
+{kind: 1, offset: "marginRight", len: 0, typ: NTI33554438, name: "marginRight", sons: null}, 
+{kind: 1, offset: "marginTop", len: 0, typ: NTI33554438, name: "marginTop", sons: null}, 
+{kind: 1, offset: "mask", len: 0, typ: NTI33554438, name: "mask", sons: null}, 
+{kind: 1, offset: "maskBorder", len: 0, typ: NTI33554438, name: "maskBorder", sons: null}, 
+{kind: 1, offset: "maskBorderMode", len: 0, typ: NTI33554438, name: "maskBorderMode", sons: null}, 
+{kind: 1, offset: "maskBorderOutset", len: 0, typ: NTI33554438, name: "maskBorderOutset", sons: null}, 
+{kind: 1, offset: "maskBorderRepeat", len: 0, typ: NTI33554438, name: "maskBorderRepeat", sons: null}, 
+{kind: 1, offset: "maskBorderSlice", len: 0, typ: NTI33554438, name: "maskBorderSlice", sons: null}, 
+{kind: 1, offset: "maskBorderSource", len: 0, typ: NTI33554438, name: "maskBorderSource", sons: null}, 
+{kind: 1, offset: "maskBorderWidth", len: 0, typ: NTI33554438, name: "maskBorderWidth", sons: null}, 
+{kind: 1, offset: "maskClip", len: 0, typ: NTI33554438, name: "maskClip", sons: null}, 
+{kind: 1, offset: "maskComposite", len: 0, typ: NTI33554438, name: "maskComposite", sons: null}, 
+{kind: 1, offset: "maskImage", len: 0, typ: NTI33554438, name: "maskImage", sons: null}, 
+{kind: 1, offset: "maskMode", len: 0, typ: NTI33554438, name: "maskMode", sons: null}, 
+{kind: 1, offset: "maskOrigin", len: 0, typ: NTI33554438, name: "maskOrigin", sons: null}, 
+{kind: 1, offset: "maskPosition", len: 0, typ: NTI33554438, name: "maskPosition", sons: null}, 
+{kind: 1, offset: "maskRepeat", len: 0, typ: NTI33554438, name: "maskRepeat", sons: null}, 
+{kind: 1, offset: "maskSize", len: 0, typ: NTI33554438, name: "maskSize", sons: null}, 
+{kind: 1, offset: "maskType", len: 0, typ: NTI33554438, name: "maskType", sons: null}, 
+{kind: 1, offset: "maxBlockSize", len: 0, typ: NTI33554438, name: "maxBlockSize", sons: null}, 
+{kind: 1, offset: "maxHeight", len: 0, typ: NTI33554438, name: "maxHeight", sons: null}, 
+{kind: 1, offset: "maxInlineSize", len: 0, typ: NTI33554438, name: "maxInlineSize", sons: null}, 
+{kind: 1, offset: "maxWidth", len: 0, typ: NTI33554438, name: "maxWidth", sons: null}, 
+{kind: 1, offset: "minBlockSize", len: 0, typ: NTI33554438, name: "minBlockSize", sons: null}, 
+{kind: 1, offset: "minHeight", len: 0, typ: NTI33554438, name: "minHeight", sons: null}, 
+{kind: 1, offset: "minInlineSize", len: 0, typ: NTI33554438, name: "minInlineSize", sons: null}, 
+{kind: 1, offset: "minWidth", len: 0, typ: NTI33554438, name: "minWidth", sons: null}, 
+{kind: 1, offset: "mixBlendMode", len: 0, typ: NTI33554438, name: "mixBlendMode", sons: null}, 
+{kind: 1, offset: "objectFit", len: 0, typ: NTI33554438, name: "objectFit", sons: null}, 
+{kind: 1, offset: "objectPosition", len: 0, typ: NTI33554438, name: "objectPosition", sons: null}, 
+{kind: 1, offset: "offset", len: 0, typ: NTI33554438, name: "offset", sons: null}, 
+{kind: 1, offset: "offsetAnchor", len: 0, typ: NTI33554438, name: "offsetAnchor", sons: null}, 
+{kind: 1, offset: "offsetDistance", len: 0, typ: NTI33554438, name: "offsetDistance", sons: null}, 
+{kind: 1, offset: "offsetPath", len: 0, typ: NTI33554438, name: "offsetPath", sons: null}, 
+{kind: 1, offset: "offsetRotate", len: 0, typ: NTI33554438, name: "offsetRotate", sons: null}, 
+{kind: 1, offset: "opacity", len: 0, typ: NTI33554438, name: "opacity", sons: null}, 
+{kind: 1, offset: "order", len: 0, typ: NTI33554438, name: "order", sons: null}, 
+{kind: 1, offset: "orphans", len: 0, typ: NTI33554438, name: "orphans", sons: null}, 
+{kind: 1, offset: "outline", len: 0, typ: NTI33554438, name: "outline", sons: null}, 
+{kind: 1, offset: "outlineColor", len: 0, typ: NTI33554438, name: "outlineColor", sons: null}, 
+{kind: 1, offset: "outlineOffset", len: 0, typ: NTI33554438, name: "outlineOffset", sons: null}, 
+{kind: 1, offset: "outlineStyle", len: 0, typ: NTI33554438, name: "outlineStyle", sons: null}, 
+{kind: 1, offset: "outlineWidth", len: 0, typ: NTI33554438, name: "outlineWidth", sons: null}, 
+{kind: 1, offset: "overflow", len: 0, typ: NTI33554438, name: "overflow", sons: null}, 
+{kind: 1, offset: "overflowAnchor", len: 0, typ: NTI33554438, name: "overflowAnchor", sons: null}, 
+{kind: 1, offset: "overflowBlock", len: 0, typ: NTI33554438, name: "overflowBlock", sons: null}, 
+{kind: 1, offset: "overflowInline", len: 0, typ: NTI33554438, name: "overflowInline", sons: null}, 
+{kind: 1, offset: "overflowWrap", len: 0, typ: NTI33554438, name: "overflowWrap", sons: null}, 
+{kind: 1, offset: "overflowX", len: 0, typ: NTI33554438, name: "overflowX", sons: null}, 
+{kind: 1, offset: "overflowY", len: 0, typ: NTI33554438, name: "overflowY", sons: null}, 
+{kind: 1, offset: "overscrollBehavior", len: 0, typ: NTI33554438, name: "overscrollBehavior", sons: null}, 
+{kind: 1, offset: "overscrollBehaviorBlock", len: 0, typ: NTI33554438, name: "overscrollBehaviorBlock", sons: null}, 
+{kind: 1, offset: "overscrollBehaviorInline", len: 0, typ: NTI33554438, name: "overscrollBehaviorInline", sons: null}, 
+{kind: 1, offset: "overscrollBehaviorX", len: 0, typ: NTI33554438, name: "overscrollBehaviorX", sons: null}, 
+{kind: 1, offset: "overscrollBehaviorY", len: 0, typ: NTI33554438, name: "overscrollBehaviorY", sons: null}, 
+{kind: 1, offset: "padding", len: 0, typ: NTI33554438, name: "padding", sons: null}, 
+{kind: 1, offset: "paddingBlock", len: 0, typ: NTI33554438, name: "paddingBlock", sons: null}, 
+{kind: 1, offset: "paddingBlockEnd", len: 0, typ: NTI33554438, name: "paddingBlockEnd", sons: null}, 
+{kind: 1, offset: "paddingBlockStart", len: 0, typ: NTI33554438, name: "paddingBlockStart", sons: null}, 
+{kind: 1, offset: "paddingBottom", len: 0, typ: NTI33554438, name: "paddingBottom", sons: null}, 
+{kind: 1, offset: "paddingInline", len: 0, typ: NTI33554438, name: "paddingInline", sons: null}, 
+{kind: 1, offset: "paddingInlineEnd", len: 0, typ: NTI33554438, name: "paddingInlineEnd", sons: null}, 
+{kind: 1, offset: "paddingInlineStart", len: 0, typ: NTI33554438, name: "paddingInlineStart", sons: null}, 
+{kind: 1, offset: "paddingLeft", len: 0, typ: NTI33554438, name: "paddingLeft", sons: null}, 
+{kind: 1, offset: "paddingRight", len: 0, typ: NTI33554438, name: "paddingRight", sons: null}, 
+{kind: 1, offset: "paddingTop", len: 0, typ: NTI33554438, name: "paddingTop", sons: null}, 
+{kind: 1, offset: "pageBreakAfter", len: 0, typ: NTI33554438, name: "pageBreakAfter", sons: null}, 
+{kind: 1, offset: "pageBreakBefore", len: 0, typ: NTI33554438, name: "pageBreakBefore", sons: null}, 
+{kind: 1, offset: "pageBreakInside", len: 0, typ: NTI33554438, name: "pageBreakInside", sons: null}, 
+{kind: 1, offset: "paintOrder", len: 0, typ: NTI33554438, name: "paintOrder", sons: null}, 
+{kind: 1, offset: "perspective", len: 0, typ: NTI33554438, name: "perspective", sons: null}, 
+{kind: 1, offset: "perspectiveOrigin", len: 0, typ: NTI33554438, name: "perspectiveOrigin", sons: null}, 
+{kind: 1, offset: "placeContent", len: 0, typ: NTI33554438, name: "placeContent", sons: null}, 
+{kind: 1, offset: "placeItems", len: 0, typ: NTI33554438, name: "placeItems", sons: null}, 
+{kind: 1, offset: "placeSelf", len: 0, typ: NTI33554438, name: "placeSelf", sons: null}, 
+{kind: 1, offset: "pointerEvents", len: 0, typ: NTI33554438, name: "pointerEvents", sons: null}, 
+{kind: 1, offset: "position", len: 0, typ: NTI33554438, name: "position", sons: null}, 
+{kind: 1, offset: "quotes", len: 0, typ: NTI33554438, name: "quotes", sons: null}, 
+{kind: 1, offset: "resize", len: 0, typ: NTI33554438, name: "resize", sons: null}, 
+{kind: 1, offset: "right", len: 0, typ: NTI33554438, name: "right", sons: null}, 
+{kind: 1, offset: "rotate", len: 0, typ: NTI33554438, name: "rotate", sons: null}, 
+{kind: 1, offset: "rowGap", len: 0, typ: NTI33554438, name: "rowGap", sons: null}, 
+{kind: 1, offset: "scale", len: 0, typ: NTI33554438, name: "scale", sons: null}, 
+{kind: 1, offset: "scrollBehavior", len: 0, typ: NTI33554438, name: "scrollBehavior", sons: null}, 
+{kind: 1, offset: "scrollMargin", len: 0, typ: NTI33554438, name: "scrollMargin", sons: null}, 
+{kind: 1, offset: "scrollMarginBlock", len: 0, typ: NTI33554438, name: "scrollMarginBlock", sons: null}, 
+{kind: 1, offset: "scrollMarginBlockEnd", len: 0, typ: NTI33554438, name: "scrollMarginBlockEnd", sons: null}, 
+{kind: 1, offset: "scrollMarginBlockStart", len: 0, typ: NTI33554438, name: "scrollMarginBlockStart", sons: null}, 
+{kind: 1, offset: "scrollMarginBottom", len: 0, typ: NTI33554438, name: "scrollMarginBottom", sons: null}, 
+{kind: 1, offset: "scrollMarginInline", len: 0, typ: NTI33554438, name: "scrollMarginInline", sons: null}, 
+{kind: 1, offset: "scrollMarginInlineEnd", len: 0, typ: NTI33554438, name: "scrollMarginInlineEnd", sons: null}, 
+{kind: 1, offset: "scrollMarginInlineStart", len: 0, typ: NTI33554438, name: "scrollMarginInlineStart", sons: null}, 
+{kind: 1, offset: "scrollMarginLeft", len: 0, typ: NTI33554438, name: "scrollMarginLeft", sons: null}, 
+{kind: 1, offset: "scrollMarginRight", len: 0, typ: NTI33554438, name: "scrollMarginRight", sons: null}, 
+{kind: 1, offset: "scrollMarginTop", len: 0, typ: NTI33554438, name: "scrollMarginTop", sons: null}, 
+{kind: 1, offset: "scrollPadding", len: 0, typ: NTI33554438, name: "scrollPadding", sons: null}, 
+{kind: 1, offset: "scrollPaddingBlock", len: 0, typ: NTI33554438, name: "scrollPaddingBlock", sons: null}, 
+{kind: 1, offset: "scrollPaddingBlockEnd", len: 0, typ: NTI33554438, name: "scrollPaddingBlockEnd", sons: null}, 
+{kind: 1, offset: "scrollPaddingBlockStart", len: 0, typ: NTI33554438, name: "scrollPaddingBlockStart", sons: null}, 
+{kind: 1, offset: "scrollPaddingBottom", len: 0, typ: NTI33554438, name: "scrollPaddingBottom", sons: null}, 
+{kind: 1, offset: "scrollPaddingInline", len: 0, typ: NTI33554438, name: "scrollPaddingInline", sons: null}, 
+{kind: 1, offset: "scrollPaddingInlineEnd", len: 0, typ: NTI33554438, name: "scrollPaddingInlineEnd", sons: null}, 
+{kind: 1, offset: "scrollPaddingInlineStart", len: 0, typ: NTI33554438, name: "scrollPaddingInlineStart", sons: null}, 
+{kind: 1, offset: "scrollPaddingLeft", len: 0, typ: NTI33554438, name: "scrollPaddingLeft", sons: null}, 
+{kind: 1, offset: "scrollPaddingRight", len: 0, typ: NTI33554438, name: "scrollPaddingRight", sons: null}, 
+{kind: 1, offset: "scrollPaddingTop", len: 0, typ: NTI33554438, name: "scrollPaddingTop", sons: null}, 
+{kind: 1, offset: "scrollSnapAlign", len: 0, typ: NTI33554438, name: "scrollSnapAlign", sons: null}, 
+{kind: 1, offset: "scrollSnapStop", len: 0, typ: NTI33554438, name: "scrollSnapStop", sons: null}, 
+{kind: 1, offset: "scrollSnapType", len: 0, typ: NTI33554438, name: "scrollSnapType", sons: null}, 
+{kind: 1, offset: "scrollbar3dLightColor", len: 0, typ: NTI33554438, name: "scrollbar3dLightColor", sons: null}, 
+{kind: 1, offset: "scrollbarArrowColor", len: 0, typ: NTI33554438, name: "scrollbarArrowColor", sons: null}, 
+{kind: 1, offset: "scrollbarBaseColor", len: 0, typ: NTI33554438, name: "scrollbarBaseColor", sons: null}, 
+{kind: 1, offset: "scrollbarColor", len: 0, typ: NTI33554438, name: "scrollbarColor", sons: null}, 
+{kind: 1, offset: "scrollbarDarkshadowColor", len: 0, typ: NTI33554438, name: "scrollbarDarkshadowColor", sons: null}, 
+{kind: 1, offset: "scrollbarFaceColor", len: 0, typ: NTI33554438, name: "scrollbarFaceColor", sons: null}, 
+{kind: 1, offset: "scrollbarHighlightColor", len: 0, typ: NTI33554438, name: "scrollbarHighlightColor", sons: null}, 
+{kind: 1, offset: "scrollbarShadowColor", len: 0, typ: NTI33554438, name: "scrollbarShadowColor", sons: null}, 
+{kind: 1, offset: "scrollbarTrackColor", len: 0, typ: NTI33554438, name: "scrollbarTrackColor", sons: null}, 
+{kind: 1, offset: "scrollbarWidth", len: 0, typ: NTI33554438, name: "scrollbarWidth", sons: null}, 
+{kind: 1, offset: "shapeImageThreshold", len: 0, typ: NTI33554438, name: "shapeImageThreshold", sons: null}, 
+{kind: 1, offset: "shapeMargin", len: 0, typ: NTI33554438, name: "shapeMargin", sons: null}, 
+{kind: 1, offset: "shapeOutside", len: 0, typ: NTI33554438, name: "shapeOutside", sons: null}, 
+{kind: 1, offset: "tabSize", len: 0, typ: NTI33554438, name: "tabSize", sons: null}, 
+{kind: 1, offset: "tableLayout", len: 0, typ: NTI33554438, name: "tableLayout", sons: null}, 
+{kind: 1, offset: "textAlign", len: 0, typ: NTI33554438, name: "textAlign", sons: null}, 
+{kind: 1, offset: "textAlignLast", len: 0, typ: NTI33554438, name: "textAlignLast", sons: null}, 
+{kind: 1, offset: "textCombineUpright", len: 0, typ: NTI33554438, name: "textCombineUpright", sons: null}, 
+{kind: 1, offset: "textDecoration", len: 0, typ: NTI33554438, name: "textDecoration", sons: null}, 
+{kind: 1, offset: "textDecorationColor", len: 0, typ: NTI33554438, name: "textDecorationColor", sons: null}, 
+{kind: 1, offset: "textDecorationLine", len: 0, typ: NTI33554438, name: "textDecorationLine", sons: null}, 
+{kind: 1, offset: "textDecorationSkipInk", len: 0, typ: NTI33554438, name: "textDecorationSkipInk", sons: null}, 
+{kind: 1, offset: "textDecorationStyle", len: 0, typ: NTI33554438, name: "textDecorationStyle", sons: null}, 
+{kind: 1, offset: "textDecorationThickness", len: 0, typ: NTI33554438, name: "textDecorationThickness", sons: null}, 
+{kind: 1, offset: "textEmphasis", len: 0, typ: NTI33554438, name: "textEmphasis", sons: null}, 
+{kind: 1, offset: "textEmphasisColor", len: 0, typ: NTI33554438, name: "textEmphasisColor", sons: null}, 
+{kind: 1, offset: "textEmphasisPosition", len: 0, typ: NTI33554438, name: "textEmphasisPosition", sons: null}, 
+{kind: 1, offset: "textEmphasisStyle", len: 0, typ: NTI33554438, name: "textEmphasisStyle", sons: null}, 
+{kind: 1, offset: "textIndent", len: 0, typ: NTI33554438, name: "textIndent", sons: null}, 
+{kind: 1, offset: "textJustify", len: 0, typ: NTI33554438, name: "textJustify", sons: null}, 
+{kind: 1, offset: "textOrientation", len: 0, typ: NTI33554438, name: "textOrientation", sons: null}, 
+{kind: 1, offset: "textOverflow", len: 0, typ: NTI33554438, name: "textOverflow", sons: null}, 
+{kind: 1, offset: "textRendering", len: 0, typ: NTI33554438, name: "textRendering", sons: null}, 
+{kind: 1, offset: "textShadow", len: 0, typ: NTI33554438, name: "textShadow", sons: null}, 
+{kind: 1, offset: "textTransform", len: 0, typ: NTI33554438, name: "textTransform", sons: null}, 
+{kind: 1, offset: "textUnderlineOffset", len: 0, typ: NTI33554438, name: "textUnderlineOffset", sons: null}, 
+{kind: 1, offset: "textUnderlinePosition", len: 0, typ: NTI33554438, name: "textUnderlinePosition", sons: null}, 
+{kind: 1, offset: "top", len: 0, typ: NTI33554438, name: "top", sons: null}, 
+{kind: 1, offset: "touchAction", len: 0, typ: NTI33554438, name: "touchAction", sons: null}, 
+{kind: 1, offset: "transform", len: 0, typ: NTI33554438, name: "transform", sons: null}, 
+{kind: 1, offset: "transformBox", len: 0, typ: NTI33554438, name: "transformBox", sons: null}, 
+{kind: 1, offset: "transformOrigin", len: 0, typ: NTI33554438, name: "transformOrigin", sons: null}, 
+{kind: 1, offset: "transformStyle", len: 0, typ: NTI33554438, name: "transformStyle", sons: null}, 
+{kind: 1, offset: "transition", len: 0, typ: NTI33554438, name: "transition", sons: null}, 
+{kind: 1, offset: "transitionDelay", len: 0, typ: NTI33554438, name: "transitionDelay", sons: null}, 
+{kind: 1, offset: "transitionDuration", len: 0, typ: NTI33554438, name: "transitionDuration", sons: null}, 
+{kind: 1, offset: "transitionProperty", len: 0, typ: NTI33554438, name: "transitionProperty", sons: null}, 
+{kind: 1, offset: "transitionTimingFunction", len: 0, typ: NTI33554438, name: "transitionTimingFunction", sons: null}, 
+{kind: 1, offset: "translate", len: 0, typ: NTI33554438, name: "translate", sons: null}, 
+{kind: 1, offset: "unicodeBidi", len: 0, typ: NTI33554438, name: "unicodeBidi", sons: null}, 
+{kind: 1, offset: "verticalAlign", len: 0, typ: NTI33554438, name: "verticalAlign", sons: null}, 
+{kind: 1, offset: "visibility", len: 0, typ: NTI33554438, name: "visibility", sons: null}, 
+{kind: 1, offset: "whiteSpace", len: 0, typ: NTI33554438, name: "whiteSpace", sons: null}, 
+{kind: 1, offset: "widows", len: 0, typ: NTI33554438, name: "widows", sons: null}, 
+{kind: 1, offset: "width", len: 0, typ: NTI33554438, name: "width", sons: null}, 
+{kind: 1, offset: "willChange", len: 0, typ: NTI33554438, name: "willChange", sons: null}, 
+{kind: 1, offset: "wordBreak", len: 0, typ: NTI33554438, name: "wordBreak", sons: null}, 
+{kind: 1, offset: "wordSpacing", len: 0, typ: NTI33554438, name: "wordSpacing", sons: null}, 
+{kind: 1, offset: "writingMode", len: 0, typ: NTI33554438, name: "writingMode", sons: null}, 
+{kind: 1, offset: "zIndex", len: 0, typ: NTI33554438, name: "zIndex", sons: null}]};
+NTI520093742.node = NNI520093742;
+NTI520093742.base = NTI33555071;
+NTI520093741.base = NTI520093742;
+var NNI520093714 = {kind: 2, len: 22, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "attributes", len: 0, typ: NTI520093827, name: "attributes", sons: null}, 
+{kind: 1, offset: "childNodes", len: 0, typ: NTI520093828, name: "childNodes", sons: null}, 
+{kind: 1, offset: "children", len: 0, typ: NTI520093829, name: "children", sons: null}, 
+{kind: 1, offset: "data", len: 0, typ: NTI33554438, name: "data", sons: null}, 
+{kind: 1, offset: "firstChild", len: 0, typ: NTI520093713, name: "firstChild", sons: null}, 
+{kind: 1, offset: "lastChild", len: 0, typ: NTI520093713, name: "lastChild", sons: null}, 
+{kind: 1, offset: "nextSibling", len: 0, typ: NTI520093713, name: "nextSibling", sons: null}, 
+{kind: 1, offset: "nodeName", len: 0, typ: NTI33554438, name: "nodeName", sons: null}, 
+{kind: 1, offset: "nodeType", len: 0, typ: NTI520093712, name: "nodeType", sons: null}, 
+{kind: 1, offset: "nodeValue", len: 0, typ: NTI33554438, name: "nodeValue", sons: null}, 
+{kind: 1, offset: "parentNode", len: 0, typ: NTI520093713, name: "parentNode", sons: null}, 
+{kind: 1, offset: "content", len: 0, typ: NTI520093713, name: "content", sons: null}, 
+{kind: 1, offset: "previousSibling", len: 0, typ: NTI520093713, name: "previousSibling", sons: null}, 
+{kind: 1, offset: "ownerDocument", len: 0, typ: NTI520093715, name: "ownerDocument", sons: null}, 
+{kind: 1, offset: "innerHTML", len: 0, typ: NTI33554438, name: "innerHTML", sons: null}, 
+{kind: 1, offset: "outerHTML", len: 0, typ: NTI33554438, name: "outerHTML", sons: null}, 
+{kind: 1, offset: "innerText", len: 0, typ: NTI33554438, name: "innerText", sons: null}, 
+{kind: 1, offset: "textContent", len: 0, typ: NTI33554438, name: "textContent", sons: null}, 
+{kind: 1, offset: "style", len: 0, typ: NTI520093741, name: "style", sons: null}, 
+{kind: 1, offset: "baseURI", len: 0, typ: NTI33554438, name: "baseURI", sons: null}, 
+{kind: 1, offset: "parentElement", len: 0, typ: NTI520093717, name: "parentElement", sons: null}, 
+{kind: 1, offset: "isConnected", len: 0, typ: NTI33554464, name: "isConnected", sons: null}]};
+NTI520093714.node = NNI520093714;
+var NNI520093698 = {kind: 2, len: 23, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "onabort", len: 0, typ: NTI520093790, name: "onabort", sons: null}, 
+{kind: 1, offset: "onblur", len: 0, typ: NTI520093791, name: "onblur", sons: null}, 
+{kind: 1, offset: "onchange", len: 0, typ: NTI520093792, name: "onchange", sons: null}, 
+{kind: 1, offset: "onclick", len: 0, typ: NTI520093793, name: "onclick", sons: null}, 
+{kind: 1, offset: "ondblclick", len: 0, typ: NTI520093794, name: "ondblclick", sons: null}, 
+{kind: 1, offset: "onerror", len: 0, typ: NTI520093795, name: "onerror", sons: null}, 
+{kind: 1, offset: "onfocus", len: 0, typ: NTI520093796, name: "onfocus", sons: null}, 
+{kind: 1, offset: "onkeydown", len: 0, typ: NTI520093797, name: "onkeydown", sons: null}, 
+{kind: 1, offset: "onkeypress", len: 0, typ: NTI520093798, name: "onkeypress", sons: null}, 
+{kind: 1, offset: "onkeyup", len: 0, typ: NTI520093799, name: "onkeyup", sons: null}, 
+{kind: 1, offset: "onload", len: 0, typ: NTI520093800, name: "onload", sons: null}, 
+{kind: 1, offset: "onmousedown", len: 0, typ: NTI520093801, name: "onmousedown", sons: null}, 
+{kind: 1, offset: "onmousemove", len: 0, typ: NTI520093802, name: "onmousemove", sons: null}, 
+{kind: 1, offset: "onmouseout", len: 0, typ: NTI520093803, name: "onmouseout", sons: null}, 
+{kind: 1, offset: "onmouseover", len: 0, typ: NTI520093804, name: "onmouseover", sons: null}, 
+{kind: 1, offset: "onmouseup", len: 0, typ: NTI520093805, name: "onmouseup", sons: null}, 
+{kind: 1, offset: "onreset", len: 0, typ: NTI520093806, name: "onreset", sons: null}, 
+{kind: 1, offset: "onselect", len: 0, typ: NTI520093807, name: "onselect", sons: null}, 
+{kind: 1, offset: "onsubmit", len: 0, typ: NTI520093808, name: "onsubmit", sons: null}, 
+{kind: 1, offset: "onunload", len: 0, typ: NTI520093809, name: "onunload", sons: null}, 
+{kind: 1, offset: "onloadstart", len: 0, typ: NTI520093810, name: "onloadstart", sons: null}, 
+{kind: 1, offset: "onprogress", len: 0, typ: NTI520093811, name: "onprogress", sons: null}, 
+{kind: 1, offset: "onloadend", len: 0, typ: NTI520093812, name: "onloadend", sons: null}]};
+NTI520093698.node = NNI520093698;
+NTI520093698.base = NTI33555071;
+NTI520093714.base = NTI520093698;
+NTI520093713.base = NTI520093714;
+NTI520094115.base = NTI520093713;
+NTI402653734.base = NTI33554438;
+var NNI536870915 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI33554454, name: "Field0", sons: null}, 
+{kind: 1, offset: "Field1", len: 0, typ: NTI33554464, name: "Field1", sons: null}]};
+NTI536870915.node = NNI536870915;
+function makeNimstrLit(c_33556787) {
+      var result = [];
+  for (var i = 0; i < c_33556787.length; ++i) {
+    result[i] = c_33556787.charCodeAt(i);
+  }
+  return result;
+  
+
+  
+}
+function toJSStr(s_33556793) {
+                    var Tmp5;
+            var Tmp7;
+
+  var result_33556794 = null;
+
+    var res_33556828 = newSeq_33556811((s_33556793).length);
+    var i_33556829 = 0;
+    var j_33556830 = 0;
+    L1: do {
+        L2: while (true) {
+        if (!(i_33556829 < (s_33556793).length)) break L2;
+          var c_33556831 = s_33556793[i_33556829];
+          if ((c_33556831 < 128)) {
+          res_33556828[j_33556830] = String.fromCharCode(c_33556831);
+          i_33556829 += 1;
+          }
+          else {
+            var helper_33556843 = newSeq_33556811(0);
+            L3: do {
+                L4: while (true) {
+                if (!true) break L4;
+                  var code_33556844 = c_33556831.toString(16);
+                  if (((code_33556844).length == 1)) {
+                  helper_33556843.push("%0");;
+                  }
+                  else {
+                  helper_33556843.push("%");;
+                  }
+                  
+                  helper_33556843.push(code_33556844);;
+                  i_33556829 += 1;
+                    if (((s_33556793).length <= i_33556829)) Tmp5 = true; else {                      Tmp5 = (s_33556793[i_33556829] < 128);                    }                  if (Tmp5) {
+                  break L3;
+                  }
+                  
+                  c_33556831 = s_33556793[i_33556829];
+                }
+            } while(false);
+++excHandler;
+            Tmp7 = framePtr;
+            try {
+            res_33556828[j_33556830] = decodeURIComponent(helper_33556843.join(""));
+--excHandler;
+} catch (EXC) {
+ var prevJSError = lastJSError;
+ lastJSError = EXC;
+ --excHandler;
+            framePtr = Tmp7;
+            res_33556828[j_33556830] = helper_33556843.join("");
+            lastJSError = prevJSError;
+            } finally {
+            framePtr = Tmp7;
+            }
+          }
+          
+          j_33556830 += 1;
+        }
+    } while(false);
+    if (res_33556828.length < j_33556830) { for (var i=res_33556828.length;i<j_33556830;++i) res_33556828.push(null); }
+               else { res_33556828.length = j_33556830; };
+    result_33556794 = res_33556828.join("");
+
+  return result_33556794;
+
+}
+function raiseException(e_33556654, ename_33556655) {
+    e_33556654.name = ename_33556655;
+    if ((excHandler == 0)) {
+    unhandledException(e_33556654);
+    }
+    
+    throw e_33556654;
+
+  
+}
+function addInt(a_33556926, b_33556927) {
+        var result = a_33556926 + b_33556927;
+    checkOverflowInt(result);
+    return result;
+  
+
+  
+}
+function cstrToNimstr(c_33556790) {
+      var ln = c_33556790.length;
+  var result = new Array(ln);
+  var r = 0;
+  for (var i = 0; i < ln; ++i) {
+    var ch = c_33556790.charCodeAt(i);
+
+    if (ch < 128) {
+      result[r] = ch;
+    }
+    else {
+      if (ch < 2048) {
+        result[r] = (ch >> 6) | 192;
+      }
+      else {
+        if (ch < 55296 || ch >= 57344) {
+          result[r] = (ch >> 12) | 224;
+        }
+        else {
+            ++i;
+            ch = 65536 + (((ch & 1023) << 10) | (c_33556790.charCodeAt(i) & 1023));
+            result[r] = (ch >> 18) | 240;
+            ++r;
+            result[r] = ((ch >> 12) & 63) | 128;
+        }
+        ++r;
+        result[r] = ((ch >> 6) & 63) | 128;
+      }
+      ++r;
+      result[r] = (ch & 63) | 128;
+    }
+    ++r;
+  }
+  return result;
+  
+
+  
+}
+function setConstr() {
+        var result = {};
+    for (var i = 0; i < arguments.length; ++i) {
+      var x = arguments[i];
+      if (typeof(x) == "object") {
+        for (var j = x[0]; j <= x[1]; ++j) {
+          result[j] = true;
+        }
+      } else {
+        result[x] = true;
+      }
+    }
+    return result;
+  
+
+  
+}
+var ConstSet1 = setConstr(17, 16, 4, 18, 27, 19, 23, 22, 21);
+function nimCopy(dest_33557120, src_33557121, ti_33557122) {
+  var result_33557131 = null;
+
+    switch (ti_33557122.kind) {
+    case 21:
+    case 22:
+    case 23:
+    case 5:
+      if (!(isFatPointer_33557111(ti_33557122))) {
+      result_33557131 = src_33557121;
+      }
+      else {
+        result_33557131 = [src_33557121[0], src_33557121[1]];
+      }
+      
+      break;
+    case 19:
+            if (dest_33557120 === null || dest_33557120 === undefined) {
+        dest_33557120 = {};
+      }
+      else {
+        for (var key in dest_33557120) { delete dest_33557120[key]; }
+      }
+      for (var key in src_33557121) { dest_33557120[key] = src_33557121[key]; }
+      result_33557131 = dest_33557120;
+    
+      break;
+    case 18:
+    case 17:
+      if (!((ti_33557122.base == null))) {
+      result_33557131 = nimCopy(dest_33557120, src_33557121, ti_33557122.base);
+      }
+      else {
+      if ((ti_33557122.kind == 17)) {
+      result_33557131 = (dest_33557120 === null || dest_33557120 === undefined) ? {m_type: ti_33557122} : dest_33557120;
+      }
+      else {
+        result_33557131 = (dest_33557120 === null || dest_33557120 === undefined) ? {} : dest_33557120;
+      }
+      }
+      nimCopyAux(result_33557131, src_33557121, ti_33557122.node);
+      break;
+    case 24:
+    case 4:
+    case 27:
+    case 16:
+            if (src_33557121 === null) {
+        result_33557131 = null;
+      }
+      else {
+        if (dest_33557120 === null || dest_33557120 === undefined) {
+          dest_33557120 = new Array(src_33557121.length);
+        }
+        else {
+          dest_33557120.length = src_33557121.length;
+        }
+        result_33557131 = dest_33557120;
+        for (var i = 0; i < src_33557121.length; ++i) {
+          result_33557131[i] = nimCopy(result_33557131[i], src_33557121[i], ti_33557122.base);
+        }
+      }
+    
+      break;
+    case 28:
+            if (src_33557121 !== null) {
+        result_33557131 = src_33557121.slice(0);
+      }
+    
+      break;
+    default: 
+      result_33557131 = src_33557121;
+      break;
+    }
+
+  return result_33557131;
+
+}
+function chckIndx(i_33557164, a_33557165, b_33557166) {
+      var Tmp1;
+
+  var result_33557167 = 0;
+
+  BeforeRet: do {
+      if (!(a_33557165 <= i_33557164)) Tmp1 = false; else {        Tmp1 = (i_33557164 <= b_33557166);      }    if (Tmp1) {
+    result_33557167 = i_33557164;
+    break BeforeRet;
+    }
+    else {
+    raiseIndexError(i_33557164, a_33557165, b_33557166);
+    }
+    
+  } while (false);
+
+  return result_33557167;
+
+}
+function subInt(a_33556930, b_33556931) {
+        var result = a_33556930 - b_33556931;
+    checkOverflowInt(result);
+    return result;
+  
+
+  
+}
+var ConstSet2 = setConstr([65, 90]);
+var ConstSet3 = setConstr(95, 32, 46);
+var ConstSet4 = setConstr(95, 32, 46);
+function mulInt(a_33556934, b_33556935) {
+        var result = a_33556934 * b_33556935;
+    checkOverflowInt(result);
+    return result;
+  
+
+  
+}
+var ConstSet5 = setConstr([97, 122]);
+var ConstSet6 = setConstr([65, 90], [97, 122]);
+var ConstSet7 = setConstr([97, 122]);
+var ConstSet8 = setConstr([65, 90]);
+var ConstSet9 = setConstr([65, 90], [97, 122]);
+function nimMax(a_33556987, b_33556988) {
+    var Tmp1;
+
+  var result_33556989 = 0;
+
+  BeforeRet: do {
+    if ((b_33556988 <= a_33556987)) {
+    Tmp1 = a_33556987;
+    }
+    else {
+    Tmp1 = b_33556988;
+    }
+    
+    result_33556989 = Tmp1;
+    break BeforeRet;
+  } while (false);
+
+  return result_33556989;
+
+}
+function nimMin(a_33556983, b_33556984) {
+    var Tmp1;
+
+  var result_33556985 = 0;
+
+  BeforeRet: do {
+    if ((a_33556983 <= b_33556984)) {
+    Tmp1 = a_33556983;
+    }
+    else {
+    Tmp1 = b_33556984;
+    }
+    
+    result_33556985 = Tmp1;
+    break BeforeRet;
+  } while (false);
+
+  return result_33556985;
+
+}
+function addChar(x_33557235, c_33557236) {
+    x_33557235.push(c_33557236);
+
+  
+}
+if (!Math.trunc) {
+  Math.trunc = function(v) {
+    v = +v;
+    if (!isFinite(v)) return v;
+    return (v - v % 1) || (v < 0 ? -0 : v === 0 ? v : 0);
+  };
+}
+
+var alternative_402653757 = [null];
+function add_33556409(x_33556410, x_33556410_Idx, y_33556411) {
+          if (x_33556410[x_33556410_Idx] === null) { x_33556410[x_33556410_Idx] = []; }
+      var off = x_33556410[x_33556410_Idx].length;
+      x_33556410[x_33556410_Idx].length += y_33556411.length;
+      for (var i = 0; i < y_33556411.length; ++i) {
+        x_33556410[x_33556410_Idx][off+i] = y_33556411.charCodeAt(i);
+      }
+    
+
+  
+}
+function newSeq_33556811(len_33556813) {
+  var result_33556814 = [];
+
+    result_33556814 = new Array(len_33556813); for (var i=0;i<len_33556813;++i) {result_33556814[i]=null;}
+  return result_33556814;
+
+}
+function unhandledException(e_33556650) {
+    var buf_33556651 = [[]];
+    if (!(((e_33556650.message).length == 0))) {
+    buf_33556651[0].push.apply(buf_33556651[0], makeNimstrLit("Error: unhandled exception: "));;
+    buf_33556651[0].push.apply(buf_33556651[0], e_33556650.message);;
+    }
+    else {
+    buf_33556651[0].push.apply(buf_33556651[0], makeNimstrLit("Error: unhandled exception"));;
+    }
+    
+    buf_33556651[0].push.apply(buf_33556651[0], makeNimstrLit(" ["));;
+    add_33556409(buf_33556651, 0, e_33556650.name);
+    buf_33556651[0].push.apply(buf_33556651[0], makeNimstrLit("]\x0A"));;
+    var cbuf_33556652 = toJSStr(buf_33556651[0]);
+    framePtr = null;
+      if (typeof(Error) !== "undefined") {
+    throw new Error(cbuf_33556652);
+  }
+  else {
+    throw cbuf_33556652;
+  }
+  
+
+  
+}
+function raiseOverflow() {
+    raiseException({message: makeNimstrLit("over- or underflow"), parent: null, m_type: NTI33555106, name: null, trace: [], up: null}, "OverflowDefect");
+
+  
+}
+function checkOverflowInt(a_33556924) {
+        if (a_33556924 > 2147483647 || a_33556924 < -2147483648) raiseOverflow();
+  
+
+  
+}
+function isWhitespace_402653490(text_402653491) {
+         return !/[^\s]/.test(text_402653491);
+  
+
+  
+}
+function isWhitespace_402653493(x_402653494) {
+    var Tmp1;
+    var Tmp2;
+
+  var result_402653495 = false;
+
+    if (!(x_402653494.nodeName == "#text")) Tmp2 = false; else {      Tmp2 = isWhitespace_402653490(x_402653494.textContent);    }    if (Tmp2) Tmp1 = true; else {      Tmp1 = (x_402653494.nodeName == "#comment");    }    result_402653495 = Tmp1;
+
+  return result_402653495;
+
+}
+function isFatPointer_33557111(ti_33557112) {
+  var result_33557113 = false;
+
+  BeforeRet: do {
+    result_33557113 = !((ConstSet1[ti_33557112.base.kind] != undefined));
+    break BeforeRet;
+  } while (false);
+
+  return result_33557113;
+
+}
+function nimCopyAux(dest_33557124, src_33557125, n_33557126) {
+    switch (n_33557126.kind) {
+    case 0:
+      break;
+    case 1:
+            dest_33557124[n_33557126.offset] = nimCopy(dest_33557124[n_33557126.offset], src_33557125[n_33557126.offset], n_33557126.typ);
+    
+      break;
+    case 2:
+          for (var i = 0; i < n_33557126.sons.length; i++) {
+      nimCopyAux(dest_33557124, src_33557125, n_33557126.sons[i]);
+    }
+    
+      break;
+    case 3:
+            dest_33557124[n_33557126.offset] = nimCopy(dest_33557124[n_33557126.offset], src_33557125[n_33557126.offset], n_33557126.typ);
+      for (var i = 0; i < n_33557126.sons.length; ++i) {
+        nimCopyAux(dest_33557124, src_33557125, n_33557126.sons[i][1]);
+      }
+    
+      break;
+    }
+
+  
+}
+function raiseIndexError(i_33556741, a_33556742, b_33556743) {
+    var Tmp1;
+
+    if ((b_33556743 < a_33556742)) {
+    Tmp1 = makeNimstrLit("index out of bounds, the container is empty");
+    }
+    else {
+    Tmp1 = (makeNimstrLit("index ") || []).concat(cstrToNimstr((i_33556741)+"") || [],makeNimstrLit(" not in ") || [],cstrToNimstr((a_33556742)+"") || [],makeNimstrLit(" .. ") || [],cstrToNimstr((b_33556743)+"") || []);
+    }
+    
+    raiseException({message: nimCopy(null, Tmp1, NTI33554437), parent: null, m_type: NTI33555112, name: null, trace: [], up: null}, "IndexDefect");
+
+  
+}
+function toToc_402653496(x_402653497, father_402653498) {
+                var Tmp5;
+            var Tmp6;
+            var Tmp7;
+            var Tmp8;
+      var Tmp15;
+
+    if ((x_402653497.nodeName == "UL")) {
+    var f_402653506 = {heading: null, kids: [], sortId: (father_402653498.kids).length, doSort: false};
+    var i_402653507 = 0;
+    L1: do {
+        L2: while (true) {
+        if (!(i_402653507 < x_402653497.childNodes.length)) break L2;
+          var nxt_402653508 = addInt(i_402653507, 1);
+          L3: do {
+              L4: while (true) {
+                if (!(nxt_402653508 < x_402653497.childNodes.length)) Tmp5 = false; else {                  Tmp5 = isWhitespace_402653493(x_402653497.childNodes[nxt_402653508]);                }              if (!Tmp5) break L4;
+                nxt_402653508 = addInt(nxt_402653508, 1);
+              }
+          } while(false);
+            if (!(nxt_402653508 < x_402653497.childNodes.length)) Tmp8 = false; else {              Tmp8 = (x_402653497.childNodes[i_402653507].nodeName == "LI");            }            if (!Tmp8) Tmp7 = false; else {              Tmp7 = (x_402653497.childNodes[i_402653507].childNodes.length == 1);            }            if (!Tmp7) Tmp6 = false; else {              Tmp6 = (x_402653497.childNodes[nxt_402653508].nodeName == "UL");            }          if (Tmp6) {
+          var e_402653520 = {heading: x_402653497.childNodes[i_402653507].childNodes[0], kids: [], sortId: (f_402653506.kids).length, doSort: false};
+          var it_402653521 = x_402653497.childNodes[nxt_402653508];
+          L9: do {
+            var j_402653526 = 0;
+            var colontmp__402653786 = 0;
+            colontmp__402653786 = it_402653521.childNodes.length;
+            var i_402653787 = 0;
+            L10: do {
+                L11: while (true) {
+                if (!(i_402653787 < colontmp__402653786)) break L11;
+                  j_402653526 = i_402653787;
+                  toToc_402653496(it_402653521.childNodes[j_402653526], e_402653520);
+                  i_402653787 = addInt(i_402653787, 1);
+                }
+            } while(false);
+          } while(false);
+          f_402653506.kids.push(e_402653520);;
+          i_402653507 = addInt(nxt_402653508, 1);
+          }
+          else {
+            toToc_402653496(x_402653497.childNodes[i_402653507], f_402653506);
+            i_402653507 = addInt(i_402653507, 1);
+          }
+          
+        }
+    } while(false);
+    father_402653498.kids.push(f_402653506);;
+    }
+    else {
+    if (isWhitespace_402653493(x_402653497)) {
+    }
+    else {
+    if ((x_402653497.nodeName == "LI")) {
+    var idx_402653543 = [];
+    L12: do {
+      var i_402653548 = 0;
+      var colontmp__402653790 = 0;
+      colontmp__402653790 = x_402653497.childNodes.length;
+      var i_402653791 = 0;
+      L13: do {
+          L14: while (true) {
+          if (!(i_402653791 < colontmp__402653790)) break L14;
+            i_402653548 = i_402653791;
+            if (!(isWhitespace_402653493(x_402653497.childNodes[i_402653548]))) {
+            idx_402653543.push(i_402653548);;
+            }
+            
+            i_402653791 = addInt(i_402653791, 1);
+          }
+      } while(false);
+    } while(false);
+      if (!((idx_402653543).length == 2)) Tmp15 = false; else {        Tmp15 = (x_402653497.childNodes[idx_402653543[chckIndx(1, 0, (idx_402653543).length-1)]].nodeName == "UL");      }    if (Tmp15) {
+    var e_402653563 = {heading: x_402653497.childNodes[idx_402653543[chckIndx(0, 0, (idx_402653543).length-1)]], kids: [], sortId: (father_402653498.kids).length, doSort: false};
+    var it_402653564 = x_402653497.childNodes[idx_402653543[chckIndx(1, 0, (idx_402653543).length-1)]];
+    L16: do {
+      var j_402653569 = 0;
+      var colontmp__402653794 = 0;
+      colontmp__402653794 = it_402653564.childNodes.length;
+      var i_402653795 = 0;
+      L17: do {
+          L18: while (true) {
+          if (!(i_402653795 < colontmp__402653794)) break L18;
+            j_402653569 = i_402653795;
+            toToc_402653496(it_402653564.childNodes[j_402653569], e_402653563);
+            i_402653795 = addInt(i_402653795, 1);
+          }
+      } while(false);
+    } while(false);
+    father_402653498.kids.push(e_402653563);;
+    }
+    else {
+      L19: do {
+        var i_402653578 = 0;
+        var colontmp__402653798 = 0;
+        colontmp__402653798 = x_402653497.childNodes.length;
+        var i_402653799 = 0;
+        L20: do {
+            L21: while (true) {
+            if (!(i_402653799 < colontmp__402653798)) break L21;
+              i_402653578 = i_402653799;
+              toToc_402653496(x_402653497.childNodes[i_402653578], father_402653498);
+              i_402653799 = addInt(i_402653799, 1);
+            }
+        } while(false);
+      } while(false);
+    }
+    
+    }
+    else {
+    father_402653498.kids.push({heading: x_402653497, kids: [], sortId: (father_402653498.kids).length, doSort: false});;
+    }
+    }}
+
+  
+}
+function extractItems_402653315(x_402653316, heading_402653317, items_402653318, items_402653318_Idx) {
+      var Tmp1;
+
+  BeforeRet: do {
+    if ((x_402653316 == null)) {
+    break BeforeRet;
+    }
+    
+      if (!!((x_402653316.heading == null))) Tmp1 = false; else {        Tmp1 = (x_402653316.heading.textContent == heading_402653317);      }    if (Tmp1) {
+    L2: do {
+      var i_402653334 = 0;
+      var colontmp__402653804 = 0;
+      colontmp__402653804 = (x_402653316.kids).length;
+      var i_402653805 = 0;
+      L3: do {
+          L4: while (true) {
+          if (!(i_402653805 < colontmp__402653804)) break L4;
+            i_402653334 = i_402653805;
+            items_402653318[items_402653318_Idx].push(x_402653316.kids[chckIndx(i_402653334, 0, (x_402653316.kids).length-1)].heading);;
+            i_402653805 = addInt(i_402653805, 1);
+          }
+      } while(false);
+    } while(false);
+    }
+    else {
+      L5: do {
+        var i_402653346 = 0;
+        var colontmp__402653808 = 0;
+        colontmp__402653808 = (x_402653316.kids).length;
+        var i_402653809 = 0;
+        L6: do {
+            L7: while (true) {
+            if (!(i_402653809 < colontmp__402653808)) break L7;
+              i_402653346 = i_402653809;
+              var it_402653347 = x_402653316.kids[chckIndx(i_402653346, 0, (x_402653316.kids).length-1)];
+              extractItems_402653315(it_402653347, heading_402653317, items_402653318, items_402653318_Idx);
+              i_402653809 = addInt(i_402653809, 1);
+            }
+        } while(false);
+      } while(false);
+    }
+    
+  } while (false);
+
+  
+}
+function tree_402653189(tag_402653190, kids_402653191) {
+  var result_402653192 = null;
+
+    result_402653192 = document.createElement(toJSStr(tag_402653190));
+    L1: do {
+      var k_402653204 = null;
+      var k_402653204_Idx = 0;
+      var i_402653822 = 0;
+      L2: do {
+          L3: while (true) {
+          if (!(i_402653822 < (kids_402653191).length)) break L3;
+            k_402653204 = kids_402653191; k_402653204_Idx = chckIndx(i_402653822, 0, (kids_402653191).length-1);
+            result_402653192.appendChild(k_402653204[k_402653204_Idx]);
+            i_402653822 = addInt(i_402653822, 1);
+          }
+      } while(false);
+    } while(false);
+
+  return result_402653192;
+
+}
+function text_402653242(s_402653243) {
+  var result_402653244 = null;
+
+    result_402653244 = document.createTextNode(s_402653243);
+
+  return result_402653244;
+
+}
+function sysFatal_218103843(message_218103846) {
+    raiseException({message: nimCopy(null, message_218103846, NTI33554437), m_type: NTI33555108, parent: null, name: null, trace: [], up: null}, "AssertionDefect");
+
+  
+}
+function raiseAssert_218103841(msg_218103842) {
+    sysFatal_218103843(msg_218103842);
+
+  
+}
+function failedAssertImpl_218103865(msg_218103866) {
+    raiseAssert_218103841(msg_218103866);
+
+  
+}
+function uncovered_402653626(x_402653627) {
+      var Tmp1;
+    var Tmp2;
+
+  var result_402653628 = null;
+
+  BeforeRet: do {
+      if (!((x_402653627.kids).length == 0)) Tmp1 = false; else {        Tmp1 = !((x_402653627.heading == null));      }    if (Tmp1) {
+    if (!(x_402653627.heading.hasOwnProperty('__karaxMarker__'))) {
+    Tmp2 = x_402653627;
+    }
+    else {
+    Tmp2 = null;
+    }
+    
+    result_402653628 = Tmp2;
+    break BeforeRet;
+    }
+    
+    result_402653628 = {heading: x_402653627.heading, kids: [], sortId: x_402653627.sortId, doSort: x_402653627.doSort};
+    L3: do {
+      var i_402653647 = 0;
+      var colontmp__402653829 = 0;
+      colontmp__402653829 = (x_402653627.kids).length;
+      var i_402653830 = 0;
+      L4: do {
+          L5: while (true) {
+          if (!(i_402653830 < colontmp__402653829)) break L5;
+            i_402653647 = i_402653830;
+            var y_402653648 = uncovered_402653626(x_402653627.kids[chckIndx(i_402653647, 0, (x_402653627.kids).length-1)]);
+            if (!((y_402653648 == null))) {
+            result_402653628.kids.push(y_402653648);;
+            }
+            
+            i_402653830 = addInt(i_402653830, 1);
+          }
+      } while(false);
+    } while(false);
+    if (((result_402653628.kids).length == 0)) {
+    result_402653628 = null;
+    }
+    
+  } while (false);
+
+  return result_402653628;
+
+}
+function mergeTocs_402653660(orig_402653661, news_402653662) {
+  var result_402653663 = null;
+
+    result_402653663 = uncovered_402653626(orig_402653661);
+    if ((result_402653663 == null)) {
+    result_402653663 = news_402653662;
+    }
+    else {
+      L1: do {
+        var i_402653675 = 0;
+        var colontmp__402653825 = 0;
+        colontmp__402653825 = (news_402653662.kids).length;
+        var i_402653826 = 0;
+        L2: do {
+            L3: while (true) {
+            if (!(i_402653826 < colontmp__402653825)) break L3;
+              i_402653675 = i_402653826;
+              result_402653663.kids.push(news_402653662.kids[chckIndx(i_402653675, 0, (news_402653662.kids).length-1)]);;
+              i_402653826 = addInt(i_402653826, 1);
+            }
+        } while(false);
+      } while(false);
+    }
+    
+
+  return result_402653663;
+
+}
+function buildToc_402653680(orig_402653681, types_402653682, procs_402653683) {
+                      var Tmp7;
+
+  var result_402653684 = null;
+
+    var newStuff_402653689 = {heading: null, kids: [], doSort: true, sortId: 0};
+    L1: do {
+      var t_402653712 = null;
+      var t_402653712_Idx = 0;
+      var i_402653817 = 0;
+      var L_402653818 = (types_402653682).length;
+      L2: do {
+          L3: while (true) {
+          if (!(i_402653817 < L_402653818)) break L3;
+            t_402653712 = types_402653682; t_402653712_Idx = chckIndx(i_402653817, 0, (types_402653682).length-1);
+            var c_402653717 = {heading: t_402653712[t_402653712_Idx].cloneNode(true), kids: [], doSort: true, sortId: 0};
+            t_402653712[t_402653712_Idx].__karaxMarker__ = true;
+            L4: do {
+              var p_402653721 = null;
+              var p_402653721_Idx = 0;
+              var i_402653814 = 0;
+              var L_402653815 = (procs_402653683).length;
+              L5: do {
+                  L6: while (true) {
+                  if (!(i_402653814 < L_402653815)) break L6;
+                    p_402653721 = procs_402653683; p_402653721_Idx = chckIndx(i_402653814, 0, (procs_402653683).length-1);
+                    if (!(p_402653721[p_402653721_Idx].hasOwnProperty('__karaxMarker__'))) {
+                    var xx_402653722 = p_402653721[p_402653721_Idx].parentNode.getElementsByClassName("attachedType");
+                      if (!((xx_402653722).length == 1)) Tmp7 = false; else {                        Tmp7 = (xx_402653722[chckIndx(0, 0, (xx_402653722).length-1)].textContent == t_402653712[t_402653712_Idx].textContent);                      }                    if (Tmp7) {
+                    var q_402653726 = tree_402653189(makeNimstrLit("A"), [text_402653242(p_402653721[p_402653721_Idx].title)]);
+                    q_402653726.setAttribute("href", p_402653721[p_402653721_Idx].getAttribute("href"));
+                    c_402653717.kids.push({heading: q_402653726, kids: [], sortId: 0, doSort: false});;
+                    p_402653721[p_402653721_Idx].__karaxMarker__ = true;
+                    }
+                    
+                    }
+                    
+                    i_402653814 = addInt(i_402653814, 1);
+                    if (!(((procs_402653683).length == L_402653815))) {
+                    failedAssertImpl_218103865(makeNimstrLit("iterators.nim(204, 11) `len(a) == L` the length of the seq changed while iterating over it"));
+                    }
+                    
+                  }
+              } while(false);
+            } while(false);
+            newStuff_402653689.kids.push(c_402653717);;
+            i_402653817 = addInt(i_402653817, 1);
+            if (!(((types_402653682).length == L_402653818))) {
+            failedAssertImpl_218103865(makeNimstrLit("iterators.nim(204, 11) `len(a) == L` the length of the seq changed while iterating over it"));
+            }
+            
+          }
+      } while(false);
+    } while(false);
+    result_402653684 = mergeTocs_402653660(orig_402653681, newStuff_402653689);
+
+  return result_402653684;
+
+}
+function add_402653232(parent_402653233, kid_402653234) {
+      var Tmp1;
+        var Tmp2;
+
+      if (!(parent_402653233.nodeName == "TR")) Tmp1 = false; else {        if ((kid_402653234.nodeName == "TD")) Tmp2 = true; else {          Tmp2 = (kid_402653234.nodeName == "TH");        }        Tmp1 = Tmp2;      }    if (Tmp1) {
+    var k_402653235 = document.createElement("TD");
+    k_402653235.appendChild(kid_402653234);
+    parent_402653233.appendChild(k_402653235);
+    }
+    else {
+    parent_402653233.appendChild(kid_402653234);
+    }
+    
+
+  
+}
+function setClass_402653236(e_402653237, value_402653238) {
+    e_402653237.setAttribute("class", toJSStr(value_402653238));
+
+  
+}
+function toHtml_402653357(x_402653358, isRoot_402653359) {
+      var Tmp1;
+    function HEX3Aanonymous_402653377(a_402653378, b_402653379) {
+          var Tmp1;
+
+      var result_402653380 = 0;
+
+      BeforeRet: do {
+          if (!!((a_402653378.heading == null))) Tmp1 = false; else {            Tmp1 = !((b_402653379.heading == null));          }        if (Tmp1) {
+        var x_402653389 = a_402653378.heading.textContent;
+        var y_402653390 = b_402653379.heading.textContent;
+        if ((x_402653389 < y_402653390)) {
+        result_402653380 = -1;
+        break BeforeRet;
+        }
+        
+        if ((y_402653390 < x_402653389)) {
+        result_402653380 = 1;
+        break BeforeRet;
+        }
+        
+        result_402653380 = 0;
+        break BeforeRet;
+        }
+        else {
+          result_402653380 = subInt(a_402653378.sortId, b_402653379.sortId);
+          break BeforeRet;
+        }
+        
+      } while (false);
+
+      return result_402653380;
+
+    }
+
+  var result_402653360 = null;
+
+  BeforeRet: do {
+    if ((x_402653358 == null)) {
+    result_402653360 = null;
+    break BeforeRet;
+    }
+    
+    if (((x_402653358.kids).length == 0)) {
+    if ((x_402653358.heading == null)) {
+    result_402653360 = null;
+    break BeforeRet;
+    }
+    
+    result_402653360 = x_402653358.heading.cloneNode(true);
+    break BeforeRet;
+    }
+    
+    result_402653360 = tree_402653189(makeNimstrLit("DIV"), []);
+      if (!!((x_402653358.heading == null))) Tmp1 = false; else {        Tmp1 = !(x_402653358.heading.hasOwnProperty('__karaxMarker__'));      }    if (Tmp1) {
+    add_402653232(result_402653360, x_402653358.heading.cloneNode(true));
+    }
+    
+    var ul_402653376 = tree_402653189(makeNimstrLit("UL"), []);
+    if (isRoot_402653359) {
+    setClass_402653236(ul_402653376, makeNimstrLit("simple simple-toc"));
+    }
+    else {
+    setClass_402653236(ul_402653376, makeNimstrLit("simple"));
+    }
+    
+    if (x_402653358.doSort) {
+    x_402653358.kids.sort(HEX3Aanonymous_402653377);
+    }
+    
+    L2: do {
+      var k_402653421 = null;
+      var k_402653421_Idx = 0;
+      var i_402653834 = 0;
+      var L_402653835 = (x_402653358.kids).length;
+      L3: do {
+          L4: while (true) {
+          if (!(i_402653834 < L_402653835)) break L4;
+            k_402653421 = x_402653358.kids; k_402653421_Idx = chckIndx(i_402653834, 0, (x_402653358.kids).length-1);
+            var y_402653422 = toHtml_402653357(k_402653421[k_402653421_Idx], false);
+            if (!((y_402653422 == null))) {
+            add_402653232(ul_402653376, tree_402653189(makeNimstrLit("LI"), [y_402653422]));
+            }
+            
+            i_402653834 = addInt(i_402653834, 1);
+            if (!(((x_402653358.kids).length == L_402653835))) {
+            failedAssertImpl_218103865(makeNimstrLit("iterators.nim(204, 11) `len(a) == L` the length of the seq changed while iterating over it"));
+            }
+            
+          }
+      } while(false);
+    } while(false);
+    if (!((ul_402653376.childNodes.length == 0))) {
+    add_402653232(result_402653360, ul_402653376);
+    }
+    
+    if ((result_402653360.childNodes.length == 0)) {
+    result_402653360 = null;
+    }
+    
+  } while (false);
+
+  return result_402653360;
+
+}
+function replaceById_402653247(id_402653248, newTree_402653249) {
+    var x_402653250 = document.getElementById(id_402653248);
+    x_402653250.parentNode.replaceChild(newTree_402653249, x_402653250);
+    newTree_402653249.id = id_402653248;
+
+  
+}
+function togglevis_402653758(d_402653759) {
+        if (d_402653759.style.display == 'none')
+      d_402653759.style.display = 'inline';
+    else
+      d_402653759.style.display = 'none';
+  
+
+  
+}
+function groupBy(value_402653761) {
+    var toc_402653762 = document.getElementById("toc-list");
+    if ((alternative_402653757[0] == null)) {
+    var tt_402653770 = {heading: null, kids: [], sortId: 0, doSort: false};
+    toToc_402653496(toc_402653762, tt_402653770);
+    tt_402653770 = tt_402653770.kids[chckIndx(0, 0, (tt_402653770.kids).length-1)];
+    var types_402653775 = [[]];
+    var procs_402653780 = [[]];
+    extractItems_402653315(tt_402653770, "Types", types_402653775, 0);
+    extractItems_402653315(tt_402653770, "Procs", procs_402653780, 0);
+    extractItems_402653315(tt_402653770, "Converters", procs_402653780, 0);
+    extractItems_402653315(tt_402653770, "Methods", procs_402653780, 0);
+    extractItems_402653315(tt_402653770, "Templates", procs_402653780, 0);
+    extractItems_402653315(tt_402653770, "Macros", procs_402653780, 0);
+    extractItems_402653315(tt_402653770, "Iterators", procs_402653780, 0);
+    var ntoc_402653781 = buildToc_402653680(tt_402653770, types_402653775[0], procs_402653780[0]);
+    var x_402653782 = toHtml_402653357(ntoc_402653781, true);
+    alternative_402653757[0] = tree_402653189(makeNimstrLit("DIV"), [x_402653782]);
+    }
+    
+    if ((value_402653761 == "type")) {
+    replaceById_402653247("tocRoot", alternative_402653757[0]);
+    }
+    else {
+    replaceById_402653247("tocRoot", tree_402653189(makeNimstrLit("DIV"), []));
+    }
+    
+    togglevis_402653758(document.getElementById("toc-list"));
+
+  
+}
+var db_402653837 = [[]];
+var contents_402653838 = [[]];
+var oldtoc_402653986 = [null];
+var timer_402653987 = [null];
+function nsuToLowerAsciiChar(c_553648189) {
+  var result_553648190 = 0;
+
+    if ((ConstSet2[c_553648189] != undefined)) {
+    result_553648190 = (c_553648189 ^ 32);
+    }
+    else {
+      result_553648190 = c_553648189;
+    }
+    
+
+  return result_553648190;
+
+}
+function fuzzyMatch_536870923(pattern_536870924, str_536870925) {
+              var Tmp4;
+              var Tmp5;
+                var Tmp6;
+      var Tmp7;
+        var Tmp8;
+
+  var result_536870928 = {Field0: 0, Field1: false};
+
+    var scoreState_536870929 = -100;
+    var headerMatched_536870930 = false;
+    var unmatchedLeadingCharCount_536870931 = 0;
+    var consecutiveMatchCount_536870932 = 0;
+    var strIndex_536870933 = 0;
+    var patIndex_536870934 = 0;
+    var score_536870935 = 0;
+    L1: do {
+        L2: while (true) {
+        if (!((strIndex_536870933 < (str_536870925).length) && (patIndex_536870934 < (pattern_536870924).length))) break L2;
+          L3: do {
+            var patternChar_536870938 = nsuToLowerAsciiChar(pattern_536870924.charCodeAt(chckIndx(patIndex_536870934, 0, (pattern_536870924).length-1)));
+            var strChar_536870939 = nsuToLowerAsciiChar(str_536870925.charCodeAt(chckIndx(strIndex_536870933, 0, (str_536870925).length-1)));
+            if ((ConstSet3[patternChar_536870938] != undefined)) {
+            patIndex_536870934 = addInt(patIndex_536870934, 1);
+            break L3;
+            }
+            
+            if ((ConstSet4[strChar_536870939] != undefined)) {
+            strIndex_536870933 = addInt(strIndex_536870933, 1);
+            break L3;
+            }
+            
+            if ((!(headerMatched_536870930) && (strChar_536870939 == 58))) {
+            headerMatched_536870930 = true;
+            scoreState_536870929 = -100;
+            score_536870935 = ((Math.floor((5.0000000000000000e-01 * score_536870935)))|0);
+            patIndex_536870934 = 0;
+            strIndex_536870933 = addInt(strIndex_536870933, 1);
+            break L3;
+            }
+            
+            if ((strChar_536870939 == patternChar_536870938)) {
+            switch (scoreState_536870929) {
+            case -100:
+            case 20:
+              scoreState_536870929 = 10;
+              break;
+            case 0:
+              scoreState_536870929 = 5;
+              score_536870935 = addInt(score_536870935, scoreState_536870929);
+              break;
+            case 10:
+            case 5:
+              consecutiveMatchCount_536870932 = addInt(consecutiveMatchCount_536870932, 1);
+              scoreState_536870929 = 5;
+              score_536870935 = addInt(score_536870935, mulInt(5, consecutiveMatchCount_536870932));
+              if ((scoreState_536870929 == 10)) {
+              score_536870935 = addInt(score_536870935, 10);
+              }
+              
+              var onBoundary_536870990 = (patIndex_536870934 == ((pattern_536870924).length-1));
+              if ((!(onBoundary_536870990) && (strIndex_536870933 < ((str_536870925).length-1)))) {
+              var nextPatternChar_536870991 = nsuToLowerAsciiChar(pattern_536870924.charCodeAt(chckIndx(addInt(patIndex_536870934, 1), 0, (pattern_536870924).length-1)));
+              var nextStrChar_536870992 = nsuToLowerAsciiChar(str_536870925.charCodeAt(chckIndx(addInt(strIndex_536870933, 1), 0, (str_536870925).length-1)));
+              if (!!((ConstSet5[nextStrChar_536870992] != undefined))) Tmp4 = false; else {                Tmp4 = !((nextStrChar_536870992 == nextPatternChar_536870991));              }              onBoundary_536870990 = Tmp4;
+              }
+              
+              if (onBoundary_536870990) {
+              scoreState_536870929 = 20;
+              score_536870935 = addInt(score_536870935, scoreState_536870929);
+              }
+              
+              break;
+            case -1:
+            case -3:
+              if (!((ConstSet6[str_536870925.charCodeAt(chckIndx(subInt(strIndex_536870933, 1), 0, (str_536870925).length-1))] != undefined))) Tmp5 = true; else {                if (!(ConstSet7[str_536870925.charCodeAt(chckIndx(subInt(strIndex_536870933, 1), 0, (str_536870925).length-1))] != undefined)) Tmp6 = false; else {                  Tmp6 = (ConstSet8[str_536870925.charCodeAt(chckIndx(strIndex_536870933, 0, (str_536870925).length-1))] != undefined);                }                Tmp5 = Tmp6;              }              var isLeadingChar_536871016 = Tmp5;
+              if (isLeadingChar_536871016) {
+              scoreState_536870929 = 10;
+              }
+              else {
+                scoreState_536870929 = 0;
+                score_536870935 = addInt(score_536870935, scoreState_536870929);
+              }
+              
+              break;
+            }
+            patIndex_536870934 = addInt(patIndex_536870934, 1);
+            }
+            else {
+              switch (scoreState_536870929) {
+              case -100:
+                scoreState_536870929 = -3;
+                score_536870935 = addInt(score_536870935, scoreState_536870929);
+                break;
+              case 5:
+                scoreState_536870929 = -1;
+                score_536870935 = addInt(score_536870935, scoreState_536870929);
+                consecutiveMatchCount_536870932 = 0;
+                break;
+              case -3:
+                if ((unmatchedLeadingCharCount_536870931 < 3)) {
+                scoreState_536870929 = -3;
+                score_536870935 = addInt(score_536870935, scoreState_536870929);
+                }
+                
+                unmatchedLeadingCharCount_536870931 = addInt(unmatchedLeadingCharCount_536870931, 1);
+                break;
+              default: 
+                scoreState_536870929 = -1;
+                score_536870935 = addInt(score_536870935, scoreState_536870929);
+                break;
+              }
+            }
+            
+            strIndex_536870933 = addInt(strIndex_536870933, 1);
+          } while(false);
+        }
+    } while(false);
+      if (!(patIndex_536870934 == (pattern_536870924).length)) Tmp7 = false; else {        if ((strIndex_536870933 == (str_536870925).length)) Tmp8 = true; else {          Tmp8 = !((ConstSet9[str_536870925.charCodeAt(chckIndx(strIndex_536870933, 0, (str_536870925).length-1))] != undefined));        }        Tmp7 = Tmp8;      }    if (Tmp7) {
+    score_536870935 = addInt(score_536870935, 10);
+    }
+    
+    var colontmp__402654047 = nimMax(0, score_536870935);
+    var colontmp__402654048 = (0 < score_536870935);
+    result_536870928 = nimCopy(result_536870928, {Field0: colontmp__402654047, Field1: colontmp__402654048}, NTI536870915);
+
+  return result_536870928;
+
+}
+function escapeCString_402653841(x_402653842, x_402653842_Idx) {
+    var s_402653843 = [];
+    L1: do {
+      var c_402653844 = 0;
+      var i_402654051 = 0;
+      var L_402654052 = (x_402653842[x_402653842_Idx]).length;
+      L2: do {
+          L3: while (true) {
+          if (!(i_402654051 < L_402654052)) break L3;
+            c_402653844 = x_402653842[x_402653842_Idx].charCodeAt(chckIndx(i_402654051, 0, (x_402653842[x_402653842_Idx]).length-1));
+            switch (c_402653844) {
+            case 60:
+              s_402653843.push.apply(s_402653843, makeNimstrLit("&lt;"));;
+              break;
+            case 62:
+              s_402653843.push.apply(s_402653843, makeNimstrLit("&gt;"));;
+              break;
+            default: 
+              addChar(s_402653843, c_402653844);;
+              break;
+            }
+            i_402654051 = addInt(i_402654051, 1);
+          }
+      } while(false);
+    } while(false);
+    x_402653842[x_402653842_Idx] = toJSStr(s_402653843);
+
+  
+}
+function text_402653239(s_402653240) {
+  var result_402653241 = null;
+
+    result_402653241 = document.createTextNode(toJSStr(s_402653240));
+
+  return result_402653241;
+
+}
+function dosearch_402653845(value_402653846) {
+    function HEX3Aanonymous_402653904(a_402653909, b_402653910) {
+      var result_402653915 = 0;
+
+        result_402653915 = subInt(b_402653910["Field1"], a_402653909["Field1"]);
+
+      return result_402653915;
+
+    }
+
+  var result_402653847 = null;
+
+    if (((db_402653837[0]).length == 0)) {
+    var stuff_402653851 = null;
+        var request = new XMLHttpRequest();
+    request.open("GET", "theindex.html", false);
+    request.send(null);
+
+    var doc = document.implementation.createHTMLDocument("theindex");
+    doc.documentElement.innerHTML = request.responseText;
+
+    //parser=new DOMParser();
+    //doc=parser.parseFromString("<html></html>", "text/html");
+
+    stuff_402653851 = doc.documentElement;
+    
+    db_402653837[0] = nimCopy(null, stuff_402653851.getElementsByClassName("reference"), NTI520094115);
+    contents_402653838[0] = nimCopy(null, [], NTI402653734);
+    L1: do {
+      var ahref_402653878 = null;
+      var ahref_402653878_Idx = 0;
+      var i_402654032 = 0;
+      var L_402654033 = (db_402653837[0]).length;
+      L2: do {
+          L3: while (true) {
+          if (!(i_402654032 < L_402654033)) break L3;
+            ahref_402653878 = db_402653837[0]; ahref_402653878_Idx = chckIndx(i_402654032, 0, (db_402653837[0]).length-1);
+            contents_402653838[0].push(ahref_402653878[ahref_402653878_Idx].getAttribute("data-doc-search-tag"));;
+            i_402654032 = addInt(i_402654032, 1);
+            if (!(((db_402653837[0]).length == L_402654033))) {
+            failedAssertImpl_218103865(makeNimstrLit("iterators.nim(204, 11) `len(a) == L` the length of the seq changed while iterating over it"));
+            }
+            
+          }
+      } while(false);
+    } while(false);
+    }
+    
+    var ul_402653883 = tree_402653189(makeNimstrLit("UL"), []);
+    result_402653847 = tree_402653189(makeNimstrLit("DIV"), []);
+    setClass_402653236(result_402653847, makeNimstrLit("search_results"));
+    var matches_402653888 = [];
+    L4: do {
+      var i_402653896 = 0;
+      var colontmp__402654037 = 0;
+      colontmp__402654037 = (db_402653837[0]).length;
+      var i_402654038 = 0;
+      L5: do {
+          L6: while (true) {
+          if (!(i_402654038 < colontmp__402654037)) break L6;
+            i_402653896 = i_402654038;
+            L7: do {
+              var c_402653897 = contents_402653838[0][chckIndx(i_402653896, 0, (contents_402653838[0]).length-1)];
+              if (((c_402653897 == "Examples") || (c_402653897 == "PEG construction"))) {
+              break L7;
+              }
+              
+              var colontmp__402654044 = fuzzyMatch_536870923(value_402653846, c_402653897);
+              var score_402653898 = colontmp__402654044["Field0"];
+              var matched_402653899 = colontmp__402654044["Field1"];
+              if (matched_402653899) {
+              matches_402653888.push({Field0: db_402653837[0][chckIndx(i_402653896, 0, (db_402653837[0]).length-1)], Field1: score_402653898});;
+              }
+              
+            } while(false);
+            i_402654038 = addInt(i_402654038, 1);
+          }
+      } while(false);
+    } while(false);
+    matches_402653888.sort(HEX3Aanonymous_402653904);
+    L8: do {
+      var i_402653931 = 0;
+      var colontmp__402654041 = 0;
+      colontmp__402654041 = nimMin((matches_402653888).length, 29);
+      var i_402654042 = 0;
+      L9: do {
+          L10: while (true) {
+          if (!(i_402654042 < colontmp__402654041)) break L10;
+            i_402653931 = i_402654042;
+            matches_402653888[chckIndx(i_402653931, 0, (matches_402653888).length-1)]["Field0"].innerHTML = matches_402653888[chckIndx(i_402653931, 0, (matches_402653888).length-1)]["Field0"].getAttribute("data-doc-search-tag");
+            escapeCString_402653841(matches_402653888[chckIndx(i_402653931, 0, (matches_402653888).length-1)]["Field0"], "innerHTML");
+            add_402653232(ul_402653883, tree_402653189(makeNimstrLit("LI"), [matches_402653888[chckIndx(i_402653931, 0, (matches_402653888).length-1)]["Field0"]]));
+            i_402654042 = addInt(i_402654042, 1);
+          }
+      } while(false);
+    } while(false);
+    if ((ul_402653883.childNodes.length == 0)) {
+    add_402653232(result_402653847, tree_402653189(makeNimstrLit("B"), [text_402653239(makeNimstrLit("no search results"))]));
+    }
+    else {
+      add_402653232(result_402653847, tree_402653189(makeNimstrLit("B"), [text_402653239(makeNimstrLit("search results"))]));
+      add_402653232(result_402653847, ul_402653883);
+    }
+    
+
+  return result_402653847;
+
+}
+function search() {
+    function wrapper_402653998() {
+        var elem_402653999 = document.getElementById("searchInput");
+        var value_402654000 = elem_402653999.value;
+        if (!(((value_402654000).length == 0))) {
+        if ((oldtoc_402653986[0] == null)) {
+        oldtoc_402653986[0] = document.getElementById("tocRoot");
+        }
+        
+        var results_402654004 = dosearch_402653845(value_402654000);
+        replaceById_402653247("tocRoot", results_402654004);
+        }
+        else {
+        if (!((oldtoc_402653986[0] == null))) {
+        replaceById_402653247("tocRoot", oldtoc_402653986[0]);
+        }
+        }
+
+      
+    }
+
+    if (!((timer_402653987[0] == null))) {
+    clearTimeout(timer_402653987[0]);
+    }
+    
+    timer_402653987[0] = setTimeout(wrapper_402653998, 400);
+
+  
+}
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..5ba945b
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Refresh" content="0; url=regex.html" />
+  </head>
+  <body>
+    <p>Please follow <a href="regex.html">this link</a>.</p>
+  </body>
+</html>
\ No newline at end of file
diff --git a/docs/nimdoc.out.css b/docs/nimdoc.out.css
new file mode 100644
index 0000000..7d4a399
--- /dev/null
+++ b/docs/nimdoc.out.css
@@ -0,0 +1,938 @@
+/*
+Stylesheet for use with Docutils/rst2html.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+
+Modified from Chad Skeeters' rst2html-style
+https://bitbucket.org/cskeeters/rst2html-style/
+
+Modified by Boyd Greenfield and narimiran
+*/
+
+:root {
+  --primary-background: #fff;
+  --secondary-background: ghostwhite;
+  --third-background: #e8e8e8;
+  --info-background: #50c050;
+  --warning-background: #c0a000;
+  --error-background: #e04040;
+  --border: #dde;
+  --text: #222;
+  --anchor: #07b;
+  --anchor-focus: #607c9f;
+  --input-focus: #1fa0eb;
+  --strong: #3c3c3c;
+  --hint: #9A9A9A;
+  --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN4AAAA9CAYAAADCt9ebAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjAzOjQ4KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MDM6NDgrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4PsixkAAAJ5klEQVR4nO2dfbBUZR3HP3vvxVD0zo0ACXxBuQMoQjJ1DfMl0NIhNcuSZqQhfGt6UWtK06xJexkrmywVRTQlHCIdtclC0zBJvYIvvEUgZpc3XyC7RVbKlQu1/fHdbc+uu2fPOfs85+y55/nMnBl2z+5zfnc5v/M8z+8119XVRYroAG4HfgvMT1YUR4MMAa4HLkhakCRoSVqAELwLeBY4C7gF+D6QS1QiR1ROAJ4Dzk9akKQwoXhtwL4GxvHjU8AKoNPz3leAu4HBFq+bAyZZHD9rDAK+BywDDklYlkQxoXhfAtYAEw2MVckQYBHwU6or99nA08BBFq49GngUeBIYaWH8rNEJdAOXA60Jy5I4jSreSOBKYDzwBPCJhiUqcSjwe2BWnc9NLnxuvMFrnwqsAqYBBwBfNzh2FpmNfs9jkhakWcg1aFxZiH5UL3cDnwf+Xue7BwFjgFHAOwuv24tyob3cO0LIshP4EbCn8Pq/wKvA9sLxMvCvOmPsA1yDZnHv/nEv2mM+F0IeR4m8z7lM7tMbUbzj0CxX7YfbAXwaWFJ4PRrNIu9FS9KJyEIZN68CG4DnkRJtLBw7gHHAYuDdNb77EDAjBhkHIk7xKoiqeK3IwjilzuceQJvoZjdQ/AMZaeoZiWYgBXSEwyleBW0Rv3cR9ZUO4LSI48fN2wN+bi5wJNBvUZaBSCaVy48oxpVhwDdMC5ISxpJRh6/DLGEUrxXt29YBQ+2IkwquR76ofZIWxJFegireNLSnm48skFmmDfmiVgJHJyuKI620ADOpbWEcDPwYOZKD7OmyxCTkXL+wzueOiEEWR8poQb60V4A7kLm/yFjgKeALuM1xLfYDbkX+zEGe98cAX0Oui6viF8vR7OS6urragW2UZr21wK+Aiwlu7XPoN3sYOAd4H6WH1SnA0qSEcjQnRT/e1bgnsw16kGPez4/lyCBF48oNwL+TFGSAsgCndI4qFBVvJ0owdZhjL3CnxfHzBo8+YBMyol0CHBijrKbHS/LoA7Yio9sPgJNr/QHekLGR6MffL+KP4SjnHmQxtoXNmbQP+CHyV75hYDzTIWNpWkU8iR5mq71vVsZqXgtcFqNQ/wG2IOtfD8oi6AX+Ujj+isKz8sBrnu+1okyGdmD/wnEgcDClTIdRyJRvI1cvCMciq7At4rj5eoCPAusbHCfLigda/VyKgi+AtyreMGAzykGzQQ/wO+BxSlkCuy1dq8hw5OieUjimYT+x9bHCdWwS1823Ez1EXmhgjKwrXpHzkduuanbCtzGX+NkPPAj8GincNkPjNkIO5dadUjiOB95m+BonopQpm8R58/0JJbHWy2eshVM8sRvdbyurKV4Hmoka2WA/iwwLP6d+QmzSdKC92GzK/W9R+Q3woQbHCELcN991wJcjftcpXolngKm18vFmoVonYcgDv0Qz5pqGREuOTuA8lPYUZbndh0LJNpkUqgZx33xvomim7RG+6xSvnOm1gqQXoyiMoKxFs8VZpFfpQHvQK4HDUPnAsBa9bxGP0tUjF+IYCkxFew+/G3owdq20pgjzt3uPRscs/o43IaOhH2f4ZaAPRyZQP6vgbuCbyGext87F0sgIZFI/N8BnlwBnolovcWAjq/uzwM0+55cBJ0UYN84ZL+rfbnLMM4FfUDv7Z1XlCe8FetETbleNL7+CZrnvMjCVDuTOOA84Hf+96ga0PC8qXY50FQsuMg+41+d8p885R4n7gdt8zo+qvDkmUF4fZQXwEbS+99KDMhlWkw0eALqQglXyDDCdcovf+4lv5jPNXJ9zWc/FDMMdPudGVCreRlTWwVtWbynwYVQQCFSp61Q042WJLUjB1nneuw8tvXo97x1Lugvg+j1Mo9boySLVHtJFWqsthx5GlbSGeN5bigrHdqPl52Zj4qWLXvTQWY4KOX2ccgPMBLRcuy9+0YzhguXN4GuYq2Zc2R/NZg+hfYt3/9ZCepdQthmB4vIWIYOTbWyWzGt2Y0izG1fqjlltxnsdpbPMRMmd3lqTTumqMw7FZY5G5mSHw5dalreiRWYGWjbZ7gYUlFa0xOtIWA4vk1E6zWEoI+FvyYrjSAO1FG8DCmQGKd+DJFsGogWVVFiP/GWbga9Svg9NgtPQvnd04fUNCcriSBF+vqZ5nn9PQ+Xs4q401oI6EP0R+BkyXoAeAtcgBfwidnvkVaMVFTO6n1JoWTfqiONw1MVP8e6l3GVwOPJZXW5VItGGiuduAu5CZdOrMQJ1CHqpIFccS+LxaD/3Hcr7vF0Xw7UdAwQ/xduLGkJ6aUMhVAuwU006B3wM+ZLmozJ5QRhWkGs9yjKw1fhwDsq8eE/F+y+i1CeHIxD1wppupXrA5xyUOjQHMzU3cyjTeS2aaaN2Fzoc1bhch3xspuqBTkDulQVUz1q4mYEbNuewQD3FexGFS1VjOLoRHwOOinj9HAooXY2CSidHHKeSI5GFcRWNdSxqR7VH1iHHeTV24R+X53C8hSCBvPPqnD8B+AOygn6OYAm0ORSGthLl8B0d4DtRmIKsoMsJF1U/Hi1dt6DusIN8PrsIlUdwOAITpDFlC6q3MTbgmHm011qGepOvQSXPipyOCujW6rxqk0dRWYsVFe8PRSn5JxWOoEvdfOGzfnF5tnCRK+bGi33MoB1hL0U5d1H5J5oVD6A5mp8sQS6KSWh5e0jEcR4BPmhKqJA4xTM3XuxjBlW8DuRacDU3y0myNbNTPHPjxT5m0GTN15A/zVFiI+HKYzgc/ydMlrRfgmQWuYn0F91xJEQYxVuDnMcOrQAWJi2EI72ErQviwqLEQpQ+5XBEIqzi3YWLwF+BMiMcjshEqYR1Gdk1KmxBsaR9SQviSDdRFK8fxVU+YliWZmcbcq7vSFoQR/qJWvuxD0WgLDYoSzPzAqowtjVhORwDhEaKru4GPoliGgcyy4Hj0DLT4TBCo9WO88jQ8Bns97lLghvRTOfqqDiMYqrM+HyUYdBtaLykeRmlK12C9rQOh1FM1vd/HqUIzaT5e+LVoh/VxByHShs6HFaw0VjjHhTxP5d0LT+fRnu5q3HuAodlbHW02Q5cDByM+sw1642cRylCx6PeZiuTFScUFxK+f19QovaRS+t4tsasxhvABbZbSfUCV6CM7qtQl6Fm4E1U22UqcAYqvZ42fgJMxH6vdYc5nkBlSW6Pq4fbS6hb6jg0u9yGug7FyS5U1+UcVBbwbFSuMM1sQ1bXK4A9CcviqM0e9H80HdUxCpwIa4McygA/GfgAcCJqmGKKXUixupEv7nHsLc2agWNQ0d9OzC+PHNHIo1XeLCoe8kkqXiUtwKFoWXoEKqk3BpWLaC8cXsV8HT1J+tFTZKvn+DMqFZi1knvtyKg1O2lBHADcCVxEedNSAP4HJcsr0NNWHVUAAAAASUVORK5CYII=");
+
+  --keyword: #5e8f60;
+  --identifier: #222;
+  --comment: #484a86;
+  --operator: #155da4;
+  --punctuation: black;
+  --other: black;
+  --escapeSequence: #c4891b;
+  --number: #252dbe;
+  --literal: #a4255b;
+  --raw-data: #a4255b;
+}
+
+[data-theme="dark"] {
+  --primary-background: #171921;
+  --secondary-background: #1e202a;
+  --third-background: #2b2e3b;
+  --info-background: #008000;
+  --warning-background: #807000;
+  --error-background: #c03000;
+  --border: #0e1014;
+  --text: #fff;
+  --anchor: #8be9fd;
+  --anchor-focus: #8be9fd;
+  --input-focus: #8be9fd;
+  --strong: #bd93f9;
+  --hint: #7A7C85;
+  --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARMAAABMCAYAAABOBlMuAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjE4OjIyKzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQyNDQtYTExZi0yMjc5YmY4NDNhYTAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ZWRlYjM1NzAtYjZmYy1kMjQ0LWExMWYtMjI3OWJmODQzYWEwIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZWRlYjM1NzAtYjZmYy1kMjQ0LWExMWYtMjI3OWJmODQzYWEwIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQyNDQtYTExZi0yMjc5YmY4NDNhYTAiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MTg6MjIrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4JZNR8AAAfG0lEQVR4nO2deViTZ7r/7yxkJaxJ2MK+GCBAMCwS1kgUFQSKK4XWWqsz1jpjp3b0tDP1V+eqU391fqfT/mpPPd20drTFDS0KFEVWJSGAEgLIZpAICBJACIRs549Rj1WILAkBfD/XlevySp68z/0S3+/7vPdzLyidTgcLkU2bd+z39/f/q1gshsrKSoJELFCa2iaEuU9K6kb+8uXxv54/fzE8L/eswNT2zCfQpjbAGKS8lPFKSEjIXiaTCSEhIeDj4xNnapsQ5j6rktZGp6UlfxIdzQVzCplmanvmG1hTG2BIAtlc26CgoDfT0tL2e3l5AQCAjY0NkMnk/a9s2k6rrKw8UV8n1JjYTIQ5RlAw14KzmL3xze1vfJyUuMJaq9UCFovFm9qu+YbBxcSPFUYkk8l2Q0NDsvo6ocrQx5+I8Ih4bz6f/0l8fHyKlZXV4/dRKBQwmcwwMpn8A4FAoPgHhH9bV1sxa488wZxoaycnJ/a9e/duCa5fkc3WvAiTI4Ib77p+XdqHG9anbfLy8gAAgLGxMdBpF+bjvzExqJj4scKI0dHRnwQHB++orq7+AgDeMuTxJ2Jl4rqU9PT0EwEBAUQCgTDuGAaDAampqYepVKpHUHDk325Ulw0a266YuFW+Gzdu/MDPz29jfn7+XgA4aOw5ESZP6kvpCXv3vnM8NiaSamVl+fj9BepGNDoGFRN7e/slcXFxO1xcXMDJyWnH7j//H/fi4uJdgutXmgw5z5O8smn7X9euXbvf29sbMBjMhONQKBRYWVlBbGzsbjMzM3JoOG+/sKKwy1h2rd/4elpGRsYuLy+vaDweD2w2Oy1h5ZrCvEunEaeeiVnMiabyl/F2/+X9P+8JDPQHHA5napMWBAYTk6DgSNuEhIS9DAYDAP7tq1i6dOkqOp3OWbNu0wens44emeoxA9lcWwKBYEMkEm2JRKIdHo+3QKFQWJ1Op8ZgMER3d/dVq1evTnFycpr0MSkUCsTExGzH4/Gk1LTME/39/TI0Go1FoVCg1WrVY2NjipGRkcGRkRH5dPwrEZHLXMPCwjJSUlIy3dzcfB+97+rqGhYSEpIOAIiYmBguN3zL77dt3uPh4W5qUxYUBhMTb2/vjeHh4cvR6P/dILK0tITIyEg7BweHr363/Z3Ampqaf1Zcu/zMKiVsyVJvMplsRyKR7IhEor2FhYUbhUJhJCYm2pFIJB6JRAIymQx4PB7QaDRoNBowMzMDJycnwOOn7icjEokQGxu7icFgbLp///7jFY1WqwWlUgkjIyOgUCgO7Ni5Rz48PCwfHh7uGRkZeaBQKOSjo6ODCoVCXlNVKn/6uCsT13FXrVr1emho6BYKhfLMnP7+/omrU9LPX8g+UThloxEMxqJFXjxESAyPQcSEExrLWLNmzW57e/txP/fw8ABHR8cdDAaDt3xF2ru9vb03sVgs0cbGxs/FxWVZUlISj0aj+dna2oKtrS1M5PcwJCgUCry8vODRrs84vPfoH6OjoyCXy6Gvr+/R6+CWrX9s7evrk/b19bWr1Wqli4sLZ8OGDe95eXmxUSjUuAd0cHDwjoqK2sYKXFIhvnldYYTTQpgU4/8+jyASCYDGoCd+ZkYYF8OICYezl8PhuOkbQyAQIDo62s/NzS2np6cHbGxsgEajAYFAAAwGA1gsFia6CE0NgUAABwcHsLe3B61WC2q1eo9WqwWNRgNKpRLUajUQiUSgUCh6zwGHwwGTydzo5+eXBQBnZu8MEJ5keHhYPqyYWMtHR0ZBpVIhYj9FUDONgOUvT12+du3avMDAQJjssdRqNWCxCyrEZdLodDoQi8Ulx44de628NL/V1Pa8iERE8l2dHB2CJvpcq9Nqbt1qKURWj1Njxld0ZGTkAW9v70kLCQC8sEIC8O/HKx8fn2gmk8kHgCk7pRFmzrWyAikASE1tx0Jj2uH0EZHL/N7YtuvT4OBgzmz4OBYSeDweIiMjt2S++vtMP1YYEmmJsCCY8mNOIJtr6+zsHBcZGXmIw+G4mZubG8m0hU9HRwcUFxe/KxQKTyDRsQjznSmJCS9+dVRERMTfQ0NDo2xtbfUGiSFMjtHRUaitrc3Jzc09kHvxVLmp7UFAmC6oZQkvrZLL5RJhReHtiQb5scKIXC7371FRUX90dnYGIpE4JR8Jgn40Gg20t7fXFxYWfnr9+vWjz8sdYi+Osh4vzgUBwZSgtu94V+fs7Hx7YGCgra6u7khLS0u2RCwYeTQgKmYFh8fj/f/g4OAldnZ2prR1wdPd3Q1CofBQSUnJkdLi3N8E93FCY6k+Pj48FxcXjlar1ZSWlh65VvYr4kREmDNg79+/D3FxcW5OTk5uXl5evNbW1tL0jK3ZXV1d1ykUintycvInoaGhdkj+gvGxs7MDPp+/m0AgWMQvS/lyeHhYTqPRPJycnIJSU1NZ3t7eW2g0Gly/fv2oWq1Gij0hzClQ/gHhpLS0tEM8Hm/7I8Ho7++HlpYWsLa2Bg8PDxOb+OKhUCigqakJ7t+/D25ubuDu7g4oFAp0Oh08ePAAvv7666TTWUdzTG0nAsKTYMU3ryuSU18+4+bmFrZo0SIOAICVlRUsXrx4zkakLnRIJBI8CgJ8MtdJp9NBZ2enqL29XWRC8xAQxgUNAHD+3L8KGhoaCp78ABES04JCoX4jJAAAAwMDUFtbe96YpRMQEKbL41DU5ubmko6Ojj2PSgggzD36+/vrb9y4cX425zzw93/8EBjon2is44+NjSkePBjqGRwc7G5v7xBV19w8U5B/3qgrr9+/uWtXUuKKD/TZ9MXh/066/OuFmunO8dGBQ98HBbGSp/t9U6LRaDXK0dHBoeFhuVzeL22/0yFqamopufjLqRJ933ssJi0tLSXV1dWHGAzGbuObOzs8ubqa71vZKpUKOjo6blwpOF8zm/Mu5cVkLlkSaswprAHAaVihgK7O7oSGxltvfXLon3nXK4RHT2cdN4pfKDCAlZyUuMJan02nTmczAaBmunPw4qI3cbnh0/36XICq0+lgcPABp7OrK629vUP5z8++LLh2XXD05L++yxrvC4/F5EZ12WBS8saLS5Ys2U2lUufUY45SqQSlUgkqlQrUavXj19jYGGg0GtBoNKDT6UCn05VotVq1TqfToFAojFar1eh0Og0Wi8XhcDgeGo1+/PhgZmYGOBwOsFgsmJmZ/eY1F+nt7YXa2trs2Z73wdCQBgCMHp1IJpHA09MdPD3dLRIS+OtKisvWvbP7vf2lZdePVFwzbHTwyMiI3hidkZFRUKvUYzOZ48HQkBIA5nWqBAqFAktLC7C0tADmIh88Pz4uMSyUk7hn776DV4tKPn/6d/lNxp1MJqsRCASf8vn8XdMpOjRTVCoVjI2NgUqlAq1WCyMjI9DX1wf379+Hvr6+/Q8ePOgdGRmRKxSKx0WLFAqFXKlUKnQ6nUar1arHq47mxwrD4/F4Eg6HI2GxWDwej7cgkUjWFAqFam5uTjU3N6eRyeQPLSwswNraGqysrIBAIDwWFywW+zja11Qi29LSclIikeSZZPJZBovBAI8XA8HBQR9kZZ3lR8cmvFZSlGe00p8IkwONRkNERBj4+i7a4+XpHv307/IbMakWlciXJbx0nMPh7Jqo0JGh0el0MDo6Cl1dXSCVSkEmk7177969W319fe1DQ0M9KpVKoVarlWq1WjndNhUPG3ApAWDcOxLTLwSDwWAOotFoDBaLxRMIBAsrKysne3t7Xzqd7k2n0/c4OzsDlUoFHA4364IyMDAATU1NxdWikhcq6tXKyhJezljPJZKI2eERS5cZeoWCMD2srCwhPX0tVzk2djiCG//GtfLLUoBxShB0dHTU3Lx580sLC4vtJBLJKMZoNBqQSqUglUqPdnR01PT09DT19/fLHjx40DM0NNQ72933GiSVGgB4JFQK+LfoSAGgnL04yppEIh2xtLS0t7GxcaFSqR7Ozs4fMRgMcHR0nJX8pJs3b54Ui8UXjT7RHIRMIkFK8irfwcEHPwQELUmqvYHUGJkLmJubw8YNa/i9vfffY/px3myQiDTPiEl9nVDDX576jaenZ7SnpyfLUJNrNBqQyWRw+/bt4x0dHTdkMlltV1dXw/XygjkdEv4wB0YOAK0AUM70C8HQ6fSzdDrdm0qlejg6OrLc3Ny2MBiMadWjfR4PHjyAmzdvZs/1v5MxoVAokJK8iicWS95k+nH+s0EiQhqpzQGoVFtYk5a87ba0XQAA34xbpagg/5zoT7s/OGNnZ8eaaYkBuVwOnZ2d5VKpVNTS0lLS2NhYWFVZ3Dujg5qQh6uY+ocvCAiKIPn4+Jz19PSMdnV15VCpVL6Dg4NBViw6nQ5EItHRpqamqzM+2DzHzo4O69amftLQeKsAZrDLgmBY/PyYsCIhfs+SiKUFE5Y8EwqFx11cXDihoaFTjjFAoVAwPDwMHR0dourq6jNCofDHhZqUVnvjmgIAcgAgJyg40mLRokX8kJCQjT4+PussLS1n1JPl7t27UFxcfHguB6mNjY2B7G4naNRTWyygUCjAYDGAx+PB0sICSCSi3vFYLBbCwjjA8vddBQtATKb7d3saBwc7IJPJBpsHjUGDGRYLJBIJLK0sAfucmyIGg4FFi3y8AwNZtycUk5KiS02vvf7WWQaDkejg4DApQwAeh3xDaWnpPoFAcPxFqnP6sEvgGf+A8Bx3d/cvIyIiNi1evHjT8wpNj8fAwACUlZW9P9dD5+/ckcFbf9gd2dcnn9LNAovF4inmZHtXNxdOdBR3+/JlS33pdP29wolEInA4weuiYxOy5vvuTkeHDHb+8c8xvb33Z3R9/N+Df+uIjYk02DwkEsna2trS1d/fNyGeF7uTyw1/7g3R3t4O2OxA/TVghULhcQqFQk1JSfmYSNR/5wD4d6EfgUBwvLS09IhUKhW9qAV5H9YjKQwJi6uvrKw8ERoamhkSEpKp7w7yJEqlEiQSyZmysrJv53qjdaVSCZdyTk+3qFMrAJRHRPLPN95qeifj5fU7mYt8JhyMRqMhMJDFdnF25gDAvBYTpXIMWlpay2fq/8m5mDcIABYGnEcGAGI/VlhBZWX1yZdSkz55OX0dV5+7w9bGGvz8mPrFpK62QskJjf2GTqd7x8bGbpnID4BCoUAmk0lLSkqOiESik2UleS/MakQflYKrXQDQxY1a3tTe3i6KiIjY5OXlxX7e9+rr6wsuXbr0t4ffn9OgMWjghMZQRcLp+8GulRVI/QPC37Wxtnal0ajJtjY2E451ZjiBra31vE9lR2PQQKFQaAAwo98Yi8Xq9fpPd56HO6rlvKWJv/PwcK+JilyCmajWMw6HAzs7+rMFpQOCIn6zHywSFvXm5eUdFAqFZ9Rq9bgHa2trq79w4cK+zz49cAARkmcpL81v/a/Dhz49d+7c3qqqqjyVSjXuOJ1OBxKJpDw3N/fA5V+zax6978cKw/sHhM/raMrnUVdboSy4fPWQSFSjd5yFBQWIRNKEd2IEw1J4JUd88WL+R51d3XrHWVDMnxUTa2tr1zXrNiUGsrmPf7DS4tymCxcu7Kuurs55+kKQSqVN586d23vs+8NHDXUCC5Wzp3/Iy8rKeruysvLM2Nhvo7VVKhXU1tYWnj17du/T7UOdnZ2D7OzsfGGB09raVi4S1RzXl0eFw+EAj8chYjKLVFffyOrq1C8mJBLpWTFRKBRyDofzC4vFWvXk+1ev/CLOzs7eKxAIslQqFeh0Oujp6enKzs7em/XTd7OayTqfKb56sT4rK+sPAoHg5KO/o0KhAKFQmHXy5MkdF3/5+TeZmctXpIXZ29v7zqVcKWNRX1epuXu3U/y8pEw0GmndOZt0dnXVDw0P6/W5oNHoZ30mQ0NDPb29vfvj4+Pf3rR5B/7od188XnEUXr4gDgmL+0NfX5/U19d3d3l5+YGfTnyDtLmcIhXXLsu4UcvfR6PRGGtra9eysrIjYrE45+kt4Fheou/69es/unnz5vm7d+/Wmsre2WRkZGTQ1DYg/JYGiUiTm1ugBAC9IfHPiEmDpFITE7fqJI/H27lmzZpDq5LWtz55t6wUXO3ihMYerK+vz2tpaUFaM0yT8tL81ujYle+TSCTrvEunBU9/voTLd92wYcPHVCqV39XVdXCu7+oYCp1O90Kc50Jk3I5+xVcv1jc3N5d4enpSMzIyvkpK3sh78nORsKg3++yPBS/q1q+hKCm61DSekERGJ3ikp6d/ERsbm1xVVXWwtbX1hRFtFAqFPMLMUyZsDyoQCI7LZDKIiIjwzczM/GpV0vro2TTsRSUqZoX3+vXrP1u9enXi0NAQiESirIdRtggIc5oJ40zq6uryGhoa8ry8vBJCQ0O9USjU94mrN7yWc+EnvaXb5gJMvxCMp6cnl0Kh2Le1tZVXXLs8L1LXefGrWRkZGZ/x+XyeUqkEkUh0vqenZ14HZyG8OEwoJjdrygd37NxTEBkZmWBtbQ3BwcEeKBTq+/UbX3/355Pfzlmn66qk9dGbN29+k8PhbCSRSNDZ2Snb9ae/HCkpKTksEhbN2QTD5NSX+Vu3bj0cHBzsjcFg4O7du1BWVvbNwxB9BIQ5j94I2Fu3bhXW19cDl8sFLBYLHA7Hg0wmf/e77e84ffXlPz6fLSMnQ2paZkJ4eHjmtm3b+B4eHvZkMhlQKBTY29s72dvbfxgUFJT8x7ffP1NRUfHjXErnZ/qFYKKjo7dt3rz5g8DAQPtH/XHa2tpqGhsbC55/BASEuYFeMblz505NTU3NgfDw8PcwGAygUCjw9fW1IJPJn/1130Hv0tLSI4WXL4hny9inYS+Osvbz80tgMpn8jIwMPovFch2vpoiDgwM4ODhwfH19OYsWLeJv3/Hu+cbGxquzXZz5aZYlvMRJT0/fFhkZue3JZmfd3d0gEolOIr4ShPmEXjFpkFRqXlrzSnFnZ+d7Tk5OjzNfXVxcICMjY6ezszNnVdL6vU8HWhmbgKAIkrOzMyc1NTXz0YU4maAuOp0OK1as4EVFRfGEQqHg1dfePHzr1q2rs71S8WOF4f38/BLS09M/iIyM5DxdxLq5uVlcVVU1bgVwBIS5il4xAQCQyWRigUBwJikpKe3JVGQcDgdLly7l2tranti0ecf7IpEoy9hbxX6sMDydTvdevXr1ltjY2F3u7u6AxT73FJ7B3Nwc4uLiwthsdphQKCzZkL7l0/r6+oKbNeVG90+EhMXZL1++fFtycvKHrq6uz4igUqmE5ubmEiTHCWG+8dwrUXD9imz9xtd/jIuLS7N5KpsTjUZDUFCQE4PB+F4oFGYmJW888Mv5k4UTHGpGxC9LYaenp78VEhKyxdHRESgUyoyOh0KhwNraGuLi4qIDAgKi6+rqyjekb/mHMSN6N6RvSdu+ffseNpsdZm09ftuW+vp6EIvFSB9hhHnHpG7rUqm0orW1tdXS0tLj6TIEaDQaaDQaxMfH811dXTl/3Xfw+JUrVz411J01cfWG6IiIiC07d+5McHNzs7ewMGyOFw6HAwcHB6BSqVx3d/fwz7/4rkAgEBwXCoUnHpZonDGrU9J5MTEx27du3Zrm4uKC0beaqq6u/ry+vj7XEPMiIMwmkxKTimuXZe/u+fCkp6fnexPdUfF4PPj7+1szGIydLi4unF1/+kvenTt3RG1tbRXTqfma8lIG39/fP/HVV19NZrFYHpMpzjQTzMzMwNPTE+Pp6Zng6emZ4Ofnl5CesfV8bW1tznQe3/wDwvFeXl7Rvr6+Ca+88kpaUFCQh74GXzqdDrq7u6GpqankRQmdR1hYTNrhUFVVlcXj8d6ysrKy0OfstLS0hPj4eC6Xy+U2NzeDRCI5/sa2XeX37t1rGhwc7BoYGJBN1P+FFbiE5OzszGaxWImvvvrqpoCAAKfp+ERmCpPJBCaTmcnhcDJLS0u/TE59+YxUKhXoi/lg+oVgrKysGJaWlna2trYeaWlpXDabvTMgIGDSfp2KiorzbW1tL0zoPMLCYtJX6uVfs2u++PKowMPDgz+ZIslEIhECAgKAxWJlajSazJ6eHmhra4PW1tZvtmz9o6Czs7O+r6+vfWxsbFir1WosLCzsV6xYkcnj8d7z9vaelmPV0Hh5eYGnp+f2mJiY7UVFRZ/HL0v5tru7+5ZGo1FisVg8Docj4fF4CxsbG1c+nx/m7e39sYeHB7i4uIC5ufmU6r4ODQ1BZWXlifkSrYuA8DRTumIrKytPent78728vCb9HRQKBVgsFhwcHIBOpwObzd4yNja2RaVSwdDQEHR1dcHo6CjQaDRwdXWdsWPV0KBQKPDw8AA7O7udERERO2tra2FgYACoVCo4OTkBjUYDMpkMeDz+8WuqaLVaaGxsbL19+/YzSX8ICPOFqYrJidDQ0AwvLy/e80c/CwaDARKJBI86BdJoNHB3dwe1Wj0nViL6IJPJwGQywdnZGZRKJRAIBDBUx8OBgQEoLS39BtkORpjPTJg1PB61N64pmpqarvb39xvUiLkuJE9CJpPBxsbGYEICANDZ2SlHgtQQ5jtTEhMAgLq6ulyJRFJvDGNeREZGRkAikRSUFuci2cEI85opi0l+7hmBWCzOeV6dToTJcfv27cHr168jxbgR5j1TFhMAgObm5hKZDNl0MAQtLS3Xzpw6hkS8Isx7piUmUqlUIBAIJuyjgzA5Ojs7QSKRINGuCAuCaYmJsKKw68qVK59KJJIu5HFneiiVSigqKjouEolOmtoWBARDMC0xAQC4+MvPJadOnXq3ra1N8yL0dDEkOp0OSktLy/Pz8w8+3d4CAWG+Mm0xAQA4fuy/jl+8ePGju3fvGsqeBY9Wq4XKysrWU6dOvX31yi8mKyyFgGBoZiQmAAD/79D+fadPn96PCMrz0el0UFVV1frtt9+mj9fiAgFhPjNjMQEAyMvLO3Ds2LE/tLS0INmuerh27Vr9999//xoiJAgLEYOEntbVVigB4PNNm3cMpqSkfMRms50McdyFgkqlgqKiovJTp069nZ97BhEShAWJQePYj373xdF1GzbLFQrFx6Ghob766ne8KNy7dw+KiopO5ubmfmTK4tsICMbG4EkxWT99d35l4rre/v7+D0NCQvh0Ot3QU8wL1Go1SKVSTX5+/sH8/PyDSP8bhIWOUTLsLuVklQcFR65pbGzcvnLlyvfc3NwsCASCMaaac+h0OhgaGoLq6uqaCxcu/OV01tGcTw7uM7VZCAhGx2jpug/vxAd58atzoqKitq1cuXKnvb29saabE+h0Oqiurpbm5eUdrK6uPlspuDrvY0hmO4YIhUIBGq1/X2CmNqFQKL3/79HomZ/z82xEowyy9zFr80zGDqPn/hdeviBmL47ad+fOnRsRERGbQkNDo62srIw97azT2dkJxcXFx0tKSo7Mdh8hY4LD4TDPH2U4MFjMc6tLmZmZzaj+Aw6H0/t9PB4PGCxmRudNJBL0ngeZTAI0Gj3jv+1szfM88Hic8cUEAKCmqlQOAN/ELU2qkEgkySwWK3HRokVcBoMxG9MbDZ1OB83NzdDU1FRQW1t7XiAQHJ+ovu18pbr6Rg6L5ZtoM0EhcUPT0tJW8tWRb0vQqIkvgKqqmhnVfrl2TfANXo+gjKlUio4OWc1M5sjOzjnQUH8rbqLPu3t6moaGhmfc+3q25tGHUqmECoEIUKbIrVkcEkONiIh4jcvlvu7s7OxLo9GmVe7QVCgUCujq6oKGhoaCioqKo9XV1WeM3YDMVPDik1gpyas+XrVyeaKXl8czjyANjbcgI/MNmkg49Q4ECPOH3NyC4RUr+M8IcHt7B1y9WlKRl3/5kElKnD1sfXEoJCzueEBAQGJYWFgGk8nk2djYAIFAgLm4pTw6Ogqjo6Mgl8vhxo0b50tLS4/U19fnLvS2FIWXfxEDQNLmLW9ueW1TxtchHDaQyWRTm4VgYkZHR6G+vhF+/NfP+y5e+vVjiVgwZpKVydOwF0dZW1lZOTGZTD6bzU4LCAiIptPp8HTDL1MwOjoKLS0tUFdXd1IsFudIpdKKgYGB7tloJTrX4MUnsVJTEj9etzY10dHRAQAAGm81wcsZW5CVyQInL69gNCGBjwcAGBx8ANnncypOnTr3H9nn/reD55wovvrQpyIHAHFUzIocGo3mQaPRfBwdHVlubm7bXF1dgcFgABqNNvruglwuh7t374JMJoOOjo7P79y5I+ru7m7q7e1tXQi7MzOh8PIv4pCw2DdaWtte37Au7aPIyCWAxWABjUbPif9HCMbjURtKiaQBfvr5zH9evlJ0uLQ4r/nJMXNiZTIRrMAlJAcHB18HBweWo6Mjy8rKajeJRAJLS0uwtLQECwsLoFAogMfjAYvFgpmZ2XNXMyqVCoaHh2FoaAiGh4cfvwYGBqCvrw+6u7vfvnfvXlNvb29rT09Pq0QsUM7S6c4rNqS/lrZ5U+YPRBKR9M7u9xwqBUUvtNAudH766XSLE8PR49ixE78/8tVnX403Zk7fUR46NUUAIPIPCMdTKJTdNjY2QKPRgE6nA51OB1tbWyCRSIDD4YBAIAAejwcCgfDYUajVakGlUoFarQadTvfY79HX1wf9/f0gl8tBLpfDvXv3HvXw+dxQPYYXMj+d+P7Mmzv+5OHr6/OJWq1GBHeB09TcUiKuq/coKS3/eqIx/wPkiIXC3w6YjAAAAABJRU5ErkJggg==");
+
+  --keyword: #ff79c6;
+  --identifier: #f8f8f2;
+  --comment: #6272a4;
+  --operator: #ff79c6;
+  --punctuation: #f8f8f2;
+  --other: #f8f8f2;
+  --escapeSequence: #bd93f9;
+  --number: #bd93f9;
+  --literal: #f1fa8c;
+  --raw-data: #8be9fd;
+}
+
+.theme-switch-wrapper {
+  display: flex;
+  align-items: center;
+}
+
+.theme-switch-wrapper em {
+  margin-left: 10px;
+  font-size: 1rem;
+}
+
+.theme-switch {
+  display: inline-block;
+  height: 22px;
+  position: relative;
+  width: 50px;
+}
+
+.theme-switch input {
+  display: none;
+}
+
+.slider {
+  background-color: #ccc;
+  bottom: 0;
+  cursor: pointer;
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  transition: .4s;
+}
+
+.slider:before {
+  background-color: #fff;
+  bottom: 4px;
+  content: "";
+  height: 13px;
+  left: 4px;
+  position: absolute;
+  transition: .4s;
+  width: 13px;
+}
+
+input:checked + .slider {
+  background-color: #66bb6a;
+}
+
+input:checked + .slider:before {
+  transform: translateX(26px);
+}
+
+.slider.round {
+  border-radius: 17px;
+}
+
+.slider.round:before {
+  border-radius: 50%;
+}
+
+html {
+  font-size: 100%;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%; }
+
+body {
+  font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
+  font-weight: 400;
+  font-size: 1.125em;
+  line-height: 1.5;
+  color: var(--text);
+  background-color: var(--primary-background); }
+
+/* Skeleton grid */
+.container {
+  position: relative;
+  width: 100%;
+  max-width: 1050px;
+  margin: 0 auto;
+  padding: 0;
+  box-sizing: border-box; }
+
+.column,
+.columns {
+  width: 100%;
+  float: left;
+  box-sizing: border-box;
+  margin-left: 1%;
+}
+
+.column:first-child,
+.columns:first-child {
+  margin-left: 0; }
+
+.three.columns {
+  width: 22%;
+}
+
+.nine.columns {
+  width: 77.0%; }
+
+.twelve.columns {
+  width: 100%;
+  margin-left: 0; }
+
+@media screen and (max-width: 860px) {
+  .three.columns {
+    display: none;
+  }
+  .nine.columns {
+    width: 98.0%;
+  }
+  body {
+    font-size: 1em;
+    line-height: 1.35;
+  }
+}
+
+cite {
+  font-style: italic !important; }
+
+
+/* Nim search input */
+div#searchInputDiv {
+  margin-bottom: 1em;
+}
+input#searchInput {
+  width: 80%;
+}
+
+/*
+ * Some custom formatting for input forms.
+ * This also fixes input form colors on Firefox with a dark system theme on Linux.
+ */
+input {
+  -moz-appearance: none;
+  background-color: var(--secondary-background);
+  color: var(--text);
+  border: 1px solid var(--border);
+  font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
+  font-size: 0.9em;
+  padding: 6px;
+}
+
+input:focus {
+  border: 1px solid var(--input-focus);
+  box-shadow: 0 0 3px var(--input-focus);
+}
+
+select {
+  -moz-appearance: none;
+  background-color: var(--secondary-background);
+  color: var(--text);
+  border: 1px solid var(--border);
+  font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
+  font-size: 0.9em;
+  padding: 6px;
+}
+
+select:focus {
+  border: 1px solid var(--input-focus);
+  box-shadow: 0 0 3px var(--input-focus);
+}
+
+/* Docgen styles */
+/* Links */
+a {
+  color: var(--anchor);
+  text-decoration: none;
+}
+
+a span.Identifier {
+  text-decoration: underline;
+  text-decoration-color: #aab;
+}
+
+a.reference-toplevel {
+  font-weight: bold;
+}
+
+a.toc-backref {
+  text-decoration: none;
+  color: var(--text); }
+
+a.link-seesrc {
+  color: #607c9f;
+  font-size: 0.9em;
+  font-style: italic; }
+
+a:hover,
+a:focus {
+  color: var(--anchor-focus);
+  text-decoration: underline; }
+
+a:hover span.Identifier {
+  color: var(--anchor);
+}
+
+
+sub,
+sup {
+  position: relative;
+  font-size: 75%;
+  line-height: 0;
+  vertical-align: baseline; }
+
+sup {
+  top: -0.5em; }
+
+sub {
+  bottom: -0.25em; }
+
+img {
+  width: auto;
+  height: auto;
+  max-width: 100%;
+  vertical-align: middle;
+  border: 0;
+  -ms-interpolation-mode: bicubic; }
+
+@media print {
+  * {
+    color: black !important;
+    text-shadow: none !important;
+    background: transparent !important;
+    box-shadow: none !important; }
+
+  a,
+  a:visited {
+    text-decoration: underline; }
+
+  a[href]:after {
+    content: " (" attr(href) ")"; }
+
+  abbr[title]:after {
+    content: " (" attr(title) ")"; }
+
+  .ir a:after,
+  a[href^="javascript:"]:after,
+  a[href^="#"]:after {
+    content: ""; }
+
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid; }
+
+  thead {
+    display: table-header-group; }
+
+  tr,
+  img {
+    page-break-inside: avoid; }
+
+  img {
+    max-width: 100% !important; }
+
+  @page {
+    margin: 0.5cm; }
+
+  h1 {
+    page-break-before: always; }
+
+  h1.title {
+    page-break-before: avoid; }
+
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3; }
+
+  h2,
+  h3 {
+    page-break-after: avoid; }
+}
+
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+small {
+  font-size: 85%; }
+
+strong {
+  font-weight: 600;
+  font-size: 0.95em;
+  color: var(--strong);
+}
+
+em {
+  font-style: italic; }
+
+h1 {
+  font-size: 1.8em;
+  font-weight: 400;
+  padding-bottom: .25em;
+  border-bottom: 6px solid var(--third-background);
+  margin-top: 2.5em;
+  margin-bottom: 1em;
+  line-height: 1.2em; }
+
+h1.title {
+  padding-bottom: 1em;
+  border-bottom: 0px;
+  font-size: 2.5em;
+  text-align: center;
+  font-weight: 900;
+  margin-top: 0.75em;
+  margin-bottom: 0em;
+}
+
+h2 {
+  font-size: 1.3em;
+  margin-top: 2em; }
+
+h2.subtitle {
+  text-align: center; }
+
+h3 {
+  font-size: 1.125em;
+  font-style: italic;
+  margin-top: 1.5em; }
+
+h4 {
+  font-size: 1.125em;
+  margin-top: 1em; }
+
+h5 {
+  font-size: 1.125em;
+  margin-top: 0.75em; }
+
+h6 {
+  font-size: 1.1em; }
+
+
+ul,
+ol {
+  padding: 0;
+  margin-top: 0.5em;
+  margin-left: 0.75em; }
+
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+  margin-bottom: 0;
+  margin-left: 1.25em; }
+
+ul.simple > li {
+    list-style-type: circle;
+}
+
+ul.simple-boot li {
+    list-style-type: none;
+    margin-left: 0em;
+    margin-bottom: 0.5em;
+}
+
+ol.simple > li, ul.simple > li {
+  margin-bottom: 0.2em;
+  margin-left: 0.4em }
+
+ul.simple.simple-toc > li {
+    margin-top: 1em;
+}
+
+ul.simple-toc {
+  list-style: none;
+  font-size: 0.9em;
+  margin-left: -0.3em;
+  margin-top: 1em; }
+
+ul.simple-toc > li {
+    list-style-type: none;
+}
+
+ul.simple-toc-section {
+  list-style-type: circle;
+  margin-left: 0.8em;
+  color: #6c9aae; }
+
+ul.nested-toc-section {
+  list-style-type: circle;
+  margin-left: -0.75em;
+  color: var(--text);
+}
+
+ul.nested-toc-section > li {
+  margin-left: 1.25em;
+}
+
+
+ol.arabic {
+  list-style: decimal; }
+
+ol.loweralpha {
+  list-style: lower-alpha; }
+
+ol.upperalpha {
+  list-style: upper-alpha; }
+
+ol.lowerroman {
+  list-style: lower-roman; }
+
+ol.upperroman {
+  list-style: upper-roman; }
+
+ul.auto-toc {
+  list-style-type: none; }
+
+
+dl {
+  margin-bottom: 1.5em; }
+
+dt {
+  margin-bottom: -0.5em;
+  margin-left: 0.0em; }
+
+dd {
+  margin-left: 2.0em;
+  margin-bottom: 3.0em;
+  margin-top: 0.5em; }
+
+
+hr {
+  margin: 2em 0;
+  border: 0;
+  border-top: 1px solid #aaa; }
+
+blockquote {
+  font-size: 0.9em;
+  font-style: italic;
+  padding-left: 0.5em;
+  margin-left: 0;
+  border-left: 5px solid #bbc;
+}
+
+.pre {
+  font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;
+  font-weight: 500;
+  font-size: 0.85em;
+  color: var(--text);
+  background-color: var(--third-background);
+  padding-left: 3px;
+  padding-right: 3px;
+  border-radius: 4px;
+}
+
+pre {
+  font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;
+  color: var(--text);
+  font-weight: 500;
+  display: inline-block;
+  box-sizing: border-box;
+  min-width: 100%;
+  padding: 0.5em;
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+  font-size: 0.85em;
+  white-space: pre !important;
+  overflow-y: hidden;
+  overflow-x: visible;
+  background-color: var(--secondary-background);
+  border: 1px solid var(--border);
+  -webkit-border-radius: 6px;
+  -moz-border-radius: 6px;
+  border-radius: 6px; }
+
+.pre-scrollable {
+  max-height: 340px;
+  overflow-y: scroll; }
+
+
+/* Nim line-numbered tables */
+.line-nums-table {
+  width: 100%;
+  table-layout: fixed; }
+
+table.line-nums-table {
+  border-radius: 4px;
+  border: 1px solid #cccccc;
+  background-color: ghostwhite;
+  border-collapse: separate;
+  margin-top: 15px;
+  margin-bottom: 25px; }
+
+.line-nums-table tbody {
+  border: none; }
+
+.line-nums-table td pre {
+  border: none;
+  background-color: transparent; }
+
+.line-nums-table td.blob-line-nums {
+  width: 28px; }
+
+.line-nums-table td.blob-line-nums pre {
+  color: #b0b0b0;
+  -webkit-filter: opacity(75%);
+  text-align: right;
+  border-color: transparent;
+  background-color: transparent;
+  padding-left: 0px;
+  margin-left: 0px;
+  padding-right: 0px;
+  margin-right: 0px; }
+
+
+table {
+  max-width: 100%;
+  background-color: transparent;
+  margin-top: 0.5em;
+  margin-bottom: 1.5em;
+  border-collapse: collapse;
+  border-color: var(--third-background);
+  border-spacing: 0;
+  font-size: 0.9em;
+}
+
+table th, table td {
+  padding: 0px 0.5em 0px;
+  border-color: var(--third-background);
+}
+
+table th {
+  background-color: var(--third-background);
+  border-color: var(--third-background);
+  font-weight: bold; }
+
+table th.docinfo-name {
+    background-color: transparent;
+    text-align: right;
+}
+
+table tr:hover {
+  background-color: var(--third-background); }
+
+
+/* rst2html default used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+  border: 0; }
+
+table.borderless td, table.borderless th {
+  /* Override padding for "table.docutils td" with "! important".
+     The right padding separates the table cells. */
+  padding: 0 0.5em 0 0 !important; }
+
+.admonition {
+    padding: 0.3em;
+    background-color: var(--secondary-background);
+    border-left: 0.4em solid #7f7f84;
+    margin-bottom: 0.5em;
+    -webkit-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2);
+       -moz-box-shadow: 0 5px 8px -6px rgba(0,0,0,.2);
+            box-shadow: 0 5px 8px -6px rgba(0,0,0,.2);
+}
+.admonition-info {
+    border-color: var(--info-background);
+}
+.admonition-info-text {
+    color: var(--info-background);
+}
+.admonition-warning {
+    border-color: var(--warning-background);
+}
+.admonition-warning-text {
+    color: var(--warning-background);
+}
+.admonition-error {
+    border-color: var(--error-background);
+}
+.admonition-error-text {
+    color: var(--error-background);
+}
+
+.first {
+  /* Override more specific margin styles with "! important". */
+  margin-top: 0 !important; }
+
+.last, .with-subtitle {
+  margin-bottom: 0 !important; }
+
+.hidden {
+  display: none; }
+
+blockquote.epigraph {
+  margin: 2em 5em; }
+
+dl.docutils dd {
+  margin-bottom: 0.5em; }
+
+object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
+  overflow: hidden; }
+
+
+div.figure {
+  margin-left: 2em;
+  margin-right: 2em; }
+
+div.footer, div.header {
+  clear: both;
+  text-align: center;
+  color: #666;
+  font-size: smaller; }
+
+div.footer {
+    padding-top: 5em;
+}
+
+div.line-block {
+  display: block;
+  margin-top: 1em;
+  margin-bottom: 1em; }
+
+div.line-block div.line-block {
+  margin-top: 0;
+  margin-bottom: 0;
+  margin-left: 1.5em; }
+
+div.topic {
+  margin: 2em; }
+
+div.search_results {
+  background-color: var(--third-background);
+  margin: 3em;
+  padding: 1em;
+  border: 1px solid #4d4d4d;
+}
+
+div#global-links ul {
+  margin-left: 0;
+  list-style-type: none;
+}
+
+div#global-links > simple-boot {
+    margin-left: 3em;
+}
+
+hr.docutils {
+  width: 75%; }
+
+img.align-left, .figure.align-left, object.align-left {
+  clear: left;
+  float: left;
+  margin-right: 1em; }
+
+img.align-right, .figure.align-right, object.align-right {
+  clear: right;
+  float: right;
+  margin-left: 1em; }
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto; }
+
+.align-left {
+  text-align: left; }
+
+.align-center {
+  clear: both;
+  text-align: center; }
+
+.align-right {
+  text-align: right; }
+
+/* reset inner alignment in figures */
+div.align-right {
+  text-align: inherit; }
+
+p.attribution {
+  text-align: right;
+  margin-left: 50%; }
+
+p.caption {
+  font-style: italic; }
+
+p.credits {
+  font-style: italic;
+  font-size: smaller; }
+
+p.label {
+  white-space: nowrap; }
+
+p.rubric {
+  font-weight: bold;
+  font-size: larger;
+  color: maroon;
+  text-align: center; }
+
+p.topic-title {
+  font-weight: bold; }
+
+pre.address {
+  margin-bottom: 0;
+  margin-top: 0;
+  font: inherit; }
+
+pre.literal-block, pre.doctest-block, pre.math, pre.code {
+  margin-left: 2em;
+  margin-right: 2em; }
+
+pre.code .ln {
+  color: grey; }
+
+/* line numbers */
+pre.code, code {
+  background-color: #eeeeee; }
+
+pre.code .comment, code .comment {
+  color: #5c6576; }
+
+pre.code .keyword, code .keyword {
+  color: #3B0D06;
+  font-weight: bold; }
+
+pre.code .literal.string, code .literal.string {
+  color: #0c5404; }
+
+pre.code .name.builtin, code .name.builtin {
+  color: #352b84; }
+
+pre.code .deleted, code .deleted {
+  background-color: #DEB0A1; }
+
+pre.code .inserted, code .inserted {
+  background-color: #A3D289; }
+
+span.classifier {
+  font-style: oblique; }
+
+span.classifier-delimiter {
+  font-weight: bold; }
+
+span.option {
+  white-space: nowrap; }
+
+span.problematic {
+  color: #b30000; }
+
+span.section-subtitle {
+  /* font-size relative to parent (h1..h6 element) */
+  font-size: 80%; }
+
+span.DecNumber {
+  color: var(--number); }
+
+span.BinNumber {
+  color: var(--number); }
+
+span.HexNumber {
+  color: var(--number); }
+
+span.OctNumber {
+  color: var(--number); }
+
+span.FloatNumber {
+  color: var(--number); }
+
+span.Identifier {
+  color: var(--identifier); }
+
+span.Keyword {
+  font-weight: 600;
+  color: var(--keyword); }
+
+span.StringLit {
+  color: var(--literal); }
+
+span.LongStringLit {
+  color: var(--literal); }
+
+span.CharLit {
+  color: var(--literal); }
+
+span.EscapeSequence {
+  color: var(--escapeSequence); }
+
+span.Operator {
+  color: var(--operator); }
+
+span.Punctuation {
+  color: var(--punctuation); }
+
+span.Comment, span.LongComment {
+  font-style: italic;
+  font-weight: 400;
+  color: var(--comment); }
+
+span.RegularExpression {
+  color: darkviolet; }
+
+span.TagStart {
+  color: darkviolet; }
+
+span.TagEnd {
+  color: darkviolet; }
+
+span.Key {
+  color: #252dbe; }
+
+span.Value {
+  color: #252dbe; }
+
+span.RawData {
+  color: var(--raw-data); }
+
+span.Assembler {
+  color: #252dbe; }
+
+span.Preprocessor {
+  color: #252dbe; }
+
+span.Directive {
+  color: #252dbe; }
+
+span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference,
+span.Other {
+  color: var(--other); }
+
+/* Pop type, const, proc, and iterator defs in nim def blocks */
+dt pre > span.Identifier, dt pre > span.Operator {
+  color: var(--identifier);
+  font-weight: 700; }
+
+dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier,
+dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier {
+  color: var(--identifier);
+  font-weight: inherit; }
+
+/* Nim sprite for the footer (taken from main page favicon) */
+.nim-sprite {
+  display: inline-block;
+  width: 51px;
+  height: 14px;
+  background-position: 0 0;
+  background-size: 51px 14px;
+  -webkit-filter: opacity(50%);
+  background-repeat: no-repeat;
+  background-image: var(--nim-sprite-base64);
+  margin-bottom: 5px; }
+
+span.pragmadots {
+  /* Position: relative frees us up to make the dots
+  look really nice without fucking up the layout and
+  causing bulging in the parent container */
+  position: relative;
+  /* 1px down looks slightly nicer */
+  top: 1px;
+  padding: 2px;
+  background-color: var(--third-background);
+  border-radius: 4px;
+  margin: 0 2px;
+  cursor: pointer;
+  font-size: 0.8em;
+}
+
+span.pragmadots:hover {
+  background-color: var(--hint);
+}
+span.pragmawrap {
+  display: none;
+}
+
+span.attachedType {
+  display: none;
+  visibility: hidden;
+}
diff --git a/docs/regex.html b/docs/regex.html
new file mode 100644
index 0000000..82ea931
--- /dev/null
+++ b/docs/regex.html
@@ -0,0 +1,875 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex</title>
+<link rel="stylesheet" type="text/css" href="nimdoc.out.css">
+
+<script type="text/javascript" src="dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li><a class="reference" id="syntax_toc" href="#syntax">Syntax</a></li>
+<ul class="simple"><li><a class="reference" id="syntax-matching-one-character_toc" href="#syntax-matching-one-character">Matching one character</a></li>
+<li><a class="reference" id="syntax-character-classes_toc" href="#syntax-character-classes">Character classes</a></li>
+<li><a class="reference" id="syntax-composites_toc" href="#syntax-composites">Composites</a></li>
+<li><a class="reference" id="syntax-repetitions_toc" href="#syntax-repetitions">Repetitions</a></li>
+<li><a class="reference" id="syntax-empty-matches_toc" href="#syntax-empty-matches">Empty matches</a></li>
+<li><a class="reference" id="syntax-grouping-and-flags_toc" href="#syntax-grouping-and-flags">Grouping and flags</a></li>
+<li><a class="reference" id="syntax-escape-sequences_toc" href="#syntax-escape-sequences">Escape sequences</a></li>
+<li><a class="reference" id="syntax-perl-character-classes-unicode-friendly_toc" href="#syntax-perl-character-classes-unicode-friendly">Perl character classes (Unicode friendly)</a></li>
+<li><a class="reference" id="syntax-ascii-character-classes_toc" href="#syntax-ascii-character-classes">ASCII character classes</a></li>
+<li><a class="reference" id="syntax-lookaround-assertions_toc" href="#syntax-lookaround-assertions">Lookaround Assertions</a></li>
+</ul><li><a class="reference" id="examples_toc" href="#examples">Examples</a></li>
+<ul class="simple"><li><a class="reference" id="examples-multiple-captures_toc" href="#examples-multiple-captures">Multiple captures</a></li>
+<li><a class="reference" id="examples-verbose-mode_toc" href="#examples-verbose-mode">Verbose Mode</a></li>
+<li><a class="reference" id="examples-find-all_toc" href="#examples-find-all">Find All</a></li>
+<li><a class="reference" id="examples-match-macro_toc" href="#examples-match-macro">Match Macro</a></li>
+</ul><li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">contains
+      <li><a class="reference" href="#contains%2Cstring%2CRegex"
+    title="contains(s: string; pattern: Regex): bool">contains,<wbr>string,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">isInitialized
+      <li><a class="reference" href="#isInitialized%2CRegex"
+    title="isInitialized(re: Regex): bool">isInitialized,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">replace
+      <li><a class="reference" href="#replace%2Cstring%2CRegex%2Cstring%2Cint"
+    title="replace(s: string; pattern: Regex; by: string; limit = 0): string">replace,<wbr>string,<wbr>Regex,<wbr>string,<wbr>int</a></li>
+  <li><a class="reference" href="#replace%2Cstring%2CRegex%2Cproc%28RegexMatch%2Cstring%29%2Cint"
+    title="replace(s: string; pattern: Regex; by: proc (m: RegexMatch; s: string): string;
+        limit = 0): string">replace,<wbr>string,<wbr>Regex,<wbr>proc(RegexMatch,<wbr>string),<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">escapeRe
+      <li><a class="reference" href="#escapeRe%2Cstring"
+    title="escapeRe(s: string): string">escapeRe,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">split
+      <li><a class="reference" href="#split%2Cstring%2CRegex"
+    title="split(s: string; sep: Regex): seq[string]">split,<wbr>string,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">startsWith
+      <li><a class="reference" href="#startsWith%2Cstring%2CRegex%2Cint"
+    title="startsWith(s: string; pattern: Regex; start = 0): bool">startsWith,<wbr>string,<wbr>Regex,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">splitIncl
+      <li><a class="reference" href="#splitIncl%2Cstring%2CRegex"
+    title="splitIncl(s: string; sep: Regex): seq[string]">splitIncl,<wbr>string,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">match
+      <li><a class="reference" href="#match%2Cstring%2CRegex%2CRegexMatch%2Cint"
+    title="match(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool">match,<wbr>string,<wbr>Regex,<wbr>RegexMatch,<wbr>int</a></li>
+  <li><a class="reference" href="#match%2Cstring%2CRegex"
+    title="match(s: string; pattern: Regex): bool">match,<wbr>string,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">toPattern
+      <li><a class="reference" href="#toPattern%2Cstring"
+    title="toPattern(s: string): Regex">toPattern,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">findAll
+      <li><a class="reference" href="#findAll%2Cstring%2CRegex%2Cint"
+    title="findAll(s: string; pattern: Regex; start = 0): seq[RegexMatch]">findAll,<wbr>string,<wbr>Regex,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">findAllBounds
+      <li><a class="reference" href="#findAllBounds%2Cstring%2CRegex%2Cint"
+    title="findAllBounds(s: string; pattern: Regex; start = 0): seq[Slice[int]]">findAllBounds,<wbr>string,<wbr>Regex,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">groupLastCapture
+      <li><a class="reference" href="#groupLastCapture%2CRegexMatch%2Cint%2Cstring"
+    title="groupLastCapture(m: RegexMatch; i: int; text: string): string">groupLastCapture,<wbr>RegexMatch,<wbr>int,<wbr>string</a></li>
+  <li><a class="reference" href="#groupLastCapture%2CRegexMatch%2Cstring%2Cstring"
+    title="groupLastCapture(m: RegexMatch; groupName: string; text: string): string">groupLastCapture,<wbr>RegexMatch,<wbr>string,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">group
+      <li><a class="reference" href="#group%2CRegexMatch%2Cint"
+    title="group(m: RegexMatch; i: int): seq[Slice[int]]">group,<wbr>RegexMatch,<wbr>int</a></li>
+  <li><a class="reference" href="#group%2CRegexMatch%2Cint%2Cstring"
+    title="group(m: RegexMatch; i: int; text: string): seq[string]">group,<wbr>RegexMatch,<wbr>int,<wbr>string</a></li>
+  <li><a class="reference" href="#group%2CRegexMatch%2Cstring"
+    title="group(m: RegexMatch; s: string): seq[Slice[int]]">group,<wbr>RegexMatch,<wbr>string</a></li>
+  <li><a class="reference" href="#group%2CRegexMatch%2Cstring%2Cstring"
+    title="group(m: RegexMatch; groupName: string; text: string): seq[string]">group,<wbr>RegexMatch,<wbr>string,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">groupNames
+      <li><a class="reference" href="#groupNames%2CRegexMatch"
+    title="groupNames(m: RegexMatch): seq[string]">groupNames,<wbr>RegexMatch</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">findAndCaptureAll
+      <li><a class="reference" href="#findAndCaptureAll%2Cstring%2CRegex"
+    title="findAndCaptureAll(s: string; pattern: Regex): seq[string]">findAndCaptureAll,<wbr>string,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">endsWith
+      <li><a class="reference" href="#endsWith%2Cstring%2CRegex"
+    title="endsWith(s: string; pattern: Regex): bool">endsWith,<wbr>string,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">re
+      <li><a class="reference" href="#re%2Cstring"
+    title="re(s: string): Regex">re,<wbr>string</a></li>
+  <li><a class="reference" href="#re%2Cstaticstring"
+    title="re(s: static string): static[Regex]">re,<wbr>staticstring</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">groupFirstCapture
+      <li><a class="reference" href="#groupFirstCapture%2CRegexMatch%2Cint%2Cstring"
+    title="groupFirstCapture(m: RegexMatch; i: int; text: string): string">groupFirstCapture,<wbr>RegexMatch,<wbr>int,<wbr>string</a></li>
+  <li><a class="reference" href="#groupFirstCapture%2CRegexMatch%2Cstring%2Cstring"
+    title="groupFirstCapture(m: RegexMatch; groupName: string; text: string): string">groupFirstCapture,<wbr>RegexMatch,<wbr>string,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">find
+      <li><a class="reference" href="#find%2Cstring%2CRegex%2CRegexMatch%2Cint"
+    title="find(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool">find,<wbr>string,<wbr>Regex,<wbr>RegexMatch,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">groupsCount
+      <li><a class="reference" href="#groupsCount%2CRegexMatch"
+    title="groupsCount(m: RegexMatch): int">groupsCount,<wbr>RegexMatch</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">rex
+      <li><a class="reference" href="#rex%2Cstring"
+    title="rex(s: string): RegexLit">rex,<wbr>string</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#15" id="65">Iterators</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#group.i%2CRegexMatch%2Cint"
+    title="group(m: RegexMatch; i: int): Slice[int]">group</a></li>
+  <li><a class="reference" href="#group.i%2CRegexMatch%2Cstring"
+    title="group(m: RegexMatch; s: string): Slice[int]">group</a></li>
+  <li><a class="reference" href="#findAll.i%2Cstring%2CRegex%2Cint"
+    title="findAll(s: string; pattern: Regex; start = 0): RegexMatch">findAll</a></li>
+  <li><a class="reference" href="#findAllBounds.i%2Cstring%2CRegex%2Cint"
+    title="findAllBounds(s: string; pattern: Regex; start = 0): Slice[int]">findAllBounds</a></li>
+  <li><a class="reference" href="#split.i%2Cstring%2CRegex"
+    title="split(s: string; sep: Regex): string">split</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#17" id="67">Macros</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#match.m%2Cstring%2CRegexLit%2Cuntyped"
+    title="match(text: string; regex: RegexLit; body: untyped): untyped">match</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#19" id="69">Exports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc">A library for parsing, compiling, and executing regular expressions. The match time is linear in the length of the text and the regular expression. So, it can handle input from untrusted users. The syntax is similar to PCRE but lacks a few features that can not be implemented while keeping the space/time complexity guarantees, ex: backreferences.
+<h1><a class="toc-backref" id="syntax" href="#syntax">Syntax</a></h1>
+<h2><a class="toc-backref" id="syntax-matching-one-character" href="#syntax-matching-one-character">Matching one character</a></h2><pre class="listing"><span class="Operator">.</span>          <span class="Identifier">any</span> <span class="Identifier">character</span> <span class="Keyword">except</span> <span class="Identifier">new</span> <span class="Identifier">line</span> <span class="Punctuation">(</span><span class="Identifier">includes</span> <span class="Identifier">new</span> <span class="Identifier">line</span> <span class="Identifier">with</span> <span class="Identifier">s</span> <span class="Identifier">flag</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">d</span>         <span class="Identifier">digit</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">Nd</span><span class="Punctuation">}</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">D</span>         <span class="Keyword">not</span> <span class="Identifier">digit</span>
+<span class="Operator">\</span><span class="Identifier">pN</span>        <span class="Identifier">One</span><span class="Operator">-</span><span class="Identifier">letter</span> <span class="Identifier">name</span> <span class="Identifier">Unicode</span> <span class="Identifier">character</span> <span class="Identifier">class</span>
+<span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">Greek</span><span class="Punctuation">}</span>  <span class="Identifier">Unicode</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Punctuation">(</span><span class="Identifier">general</span> <span class="Identifier">category</span> <span class="Keyword">or</span> <span class="Identifier">script</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">PN</span>        <span class="Identifier">Negated</span> <span class="Identifier">one</span><span class="Operator">-</span><span class="Identifier">letter</span> <span class="Identifier">name</span> <span class="Identifier">Unicode</span> <span class="Identifier">character</span> <span class="Identifier">class</span>
+<span class="Operator">\</span><span class="Identifier">P</span><span class="Punctuation">{</span><span class="Identifier">Greek</span><span class="Punctuation">}</span>  <span class="Identifier">negated</span> <span class="Identifier">Unicode</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Punctuation">(</span><span class="Identifier">general</span> <span class="Identifier">category</span> <span class="Keyword">or</span> <span class="Identifier">script</span><span class="Punctuation">)</span></pre>
+<h2><a class="toc-backref" id="syntax-character-classes" href="#syntax-character-classes">Character classes</a></h2><pre class="listing"><span class="Punctuation">[</span><span class="Identifier">xyz</span><span class="Punctuation">]</span>         <span class="Identifier">A</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Identifier">matching</span> <span class="Identifier">either</span> <span class="Identifier">x</span><span class="Punctuation">,</span> <span class="Identifier">y</span> <span class="Keyword">or</span> <span class="Identifier">z</span> <span class="Punctuation">(</span><span class="Identifier">union</span><span class="Punctuation">)</span><span class="Operator">.</span>
+<span class="Punctuation">[</span><span class="Operator">^</span><span class="Identifier">xyz</span><span class="Punctuation">]</span>        <span class="Identifier">A</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Identifier">matching</span> <span class="Identifier">any</span> <span class="Identifier">character</span> <span class="Keyword">except</span> <span class="Identifier">x</span><span class="Punctuation">,</span> <span class="Identifier">y</span> <span class="Keyword">and</span> <span class="Identifier">z</span><span class="Operator">.</span>
+<span class="Punctuation">[</span><span class="Identifier">a</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Punctuation">]</span>         <span class="Identifier">A</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Identifier">matching</span> <span class="Identifier">any</span> <span class="Identifier">character</span> <span class="Keyword">in</span> <span class="Identifier">range</span> <span class="Identifier">a</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Operator">.</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">alpha</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">ASCII</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Za</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Operator">^</span><span class="Identifier">alpha</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>  <span class="Identifier">Negated</span> <span class="Identifier">ASCII</span> <span class="Identifier">character</span> <span class="Identifier">class</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">^</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Za</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Operator">\</span><span class="Punctuation">[</span><span class="Operator">\</span><span class="Punctuation">]</span><span class="Punctuation">]</span>        <span class="Identifier">Escaping</span> <span class="Keyword">in</span> <span class="Identifier">character</span> <span class="Identifier">classes</span> <span class="Punctuation">(</span><span class="Identifier">matching</span> <span class="Punctuation">[</span> <span class="Keyword">or</span> <span class="Punctuation">]</span><span class="Punctuation">)</span></pre>
+<h2><a class="toc-backref" id="syntax-composites" href="#syntax-composites">Composites</a></h2><pre class="listing"><span class="Identifier">xy</span>   <span class="Identifier">concatenation</span> <span class="Punctuation">(</span><span class="Identifier">x</span> <span class="Identifier">followed</span> <span class="Identifier">by</span> <span class="Identifier">y</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Operator">|</span><span class="Identifier">y</span>  <span class="Identifier">alternation</span> <span class="Punctuation">(</span><span class="Identifier">x</span> <span class="Keyword">or</span> <span class="Identifier">y</span><span class="Punctuation">,</span> <span class="Identifier">prefer</span> <span class="Identifier">x</span><span class="Punctuation">)</span></pre>
+<h2><a class="toc-backref" id="syntax-repetitions" href="#syntax-repetitions">Repetitions</a></h2><pre class="listing"><span class="Identifier">x</span><span class="Operator">*</span>       <span class="Identifier">zero</span> <span class="Keyword">or</span> <span class="Identifier">more</span> <span class="Keyword">of</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">greedy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Operator">+</span>       <span class="Identifier">one</span> <span class="Keyword">or</span> <span class="Identifier">more</span> <span class="Keyword">of</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">greedy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Operator">?</span>       <span class="Identifier">zero</span> <span class="Keyword">or</span> <span class="Identifier">one</span> <span class="Keyword">of</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">greedy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Operator">*?</span>      <span class="Identifier">zero</span> <span class="Keyword">or</span> <span class="Identifier">more</span> <span class="Keyword">of</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">ungreedy</span><span class="Operator">/</span><span class="Identifier">lazy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Operator">+?</span>      <span class="Identifier">one</span> <span class="Keyword">or</span> <span class="Identifier">more</span> <span class="Keyword">of</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">ungreedy</span><span class="Operator">/</span><span class="Identifier">lazy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Operator">??</span>      <span class="Identifier">zero</span> <span class="Keyword">or</span> <span class="Identifier">one</span> <span class="Keyword">of</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">ungreedy</span><span class="Operator">/</span><span class="Identifier">lazy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Punctuation">{</span><span class="Identifier">n</span><span class="Punctuation">,</span><span class="Identifier">m</span><span class="Punctuation">}</span>   <span class="Identifier">at</span> <span class="Identifier">least</span> <span class="Identifier">n</span> <span class="Identifier">x</span> <span class="Keyword">and</span> <span class="Identifier">at</span> <span class="Identifier">most</span> <span class="Identifier">m</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">greedy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Punctuation">{</span><span class="Identifier">n</span><span class="Punctuation">,</span><span class="Punctuation">}</span>    <span class="Identifier">at</span> <span class="Identifier">least</span> <span class="Identifier">n</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">greedy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Punctuation">{</span><span class="Identifier">n</span><span class="Punctuation">}</span>     <span class="Identifier">exactly</span> <span class="Identifier">n</span> <span class="Identifier">x</span>
+<span class="Identifier">x</span><span class="Punctuation">{</span><span class="Identifier">n</span><span class="Punctuation">,</span><span class="Identifier">m</span><span class="Punctuation">}</span><span class="Operator">?</span>  <span class="Identifier">at</span> <span class="Identifier">least</span> <span class="Identifier">n</span> <span class="Identifier">x</span> <span class="Keyword">and</span> <span class="Identifier">at</span> <span class="Identifier">most</span> <span class="Identifier">m</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">ungreedy</span><span class="Operator">/</span><span class="Identifier">lazy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Punctuation">{</span><span class="Identifier">n</span><span class="Punctuation">,</span><span class="Punctuation">}</span><span class="Operator">?</span>   <span class="Identifier">at</span> <span class="Identifier">least</span> <span class="Identifier">n</span> <span class="Identifier">x</span> <span class="Punctuation">(</span><span class="Identifier">ungreedy</span><span class="Operator">/</span><span class="Identifier">lazy</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span><span class="Punctuation">{</span><span class="Identifier">n</span><span class="Punctuation">}</span><span class="Operator">?</span>    <span class="Identifier">exactly</span> <span class="Identifier">n</span> <span class="Identifier">x</span></pre>
+<h2><a class="toc-backref" id="syntax-empty-matches" href="#syntax-empty-matches">Empty matches</a></h2><pre class="listing"><span class="Operator">^</span>   <span class="Identifier">the</span> <span class="Identifier">beginning</span> <span class="Keyword">of</span> <span class="Identifier">text</span> <span class="Punctuation">(</span><span class="Keyword">or</span> <span class="Identifier">start</span><span class="Operator">-</span><span class="Keyword">of</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">with</span> <span class="Identifier">multi</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">mode</span><span class="Punctuation">)</span>
+<span class="Operator">$</span>   <span class="Identifier">the</span> <span class="Keyword">end</span> <span class="Keyword">of</span> <span class="Identifier">text</span> <span class="Punctuation">(</span><span class="Keyword">or</span> <span class="Keyword">end</span><span class="Operator">-</span><span class="Keyword">of</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">with</span> <span class="Identifier">multi</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">mode</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">A</span>  <span class="Identifier">only</span> <span class="Identifier">the</span> <span class="Identifier">beginning</span> <span class="Keyword">of</span> <span class="Identifier">text</span> <span class="Punctuation">(</span><span class="Identifier">even</span> <span class="Identifier">with</span> <span class="Identifier">multi</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">mode</span> <span class="Identifier">enabled</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">z</span>  <span class="Identifier">only</span> <span class="Identifier">the</span> <span class="Keyword">end</span> <span class="Keyword">of</span> <span class="Identifier">text</span> <span class="Punctuation">(</span><span class="Identifier">even</span> <span class="Identifier">with</span> <span class="Identifier">multi</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">mode</span> <span class="Identifier">enabled</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">b</span>  <span class="Identifier">a</span> <span class="Identifier">Unicode</span> <span class="Identifier">word</span> <span class="Identifier">boundary</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">w</span> <span class="Identifier">on</span> <span class="Identifier">one</span> <span class="Identifier">side</span> <span class="Keyword">and</span> <span class="Operator">\</span><span class="Identifier">W</span><span class="Punctuation">,</span> <span class="Operator">\</span><span class="Identifier">A</span><span class="Punctuation">,</span> <span class="Keyword">or</span> <span class="Operator">\</span><span class="Identifier">z</span> <span class="Identifier">on</span> <span class="Identifier">other</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">B</span>  <span class="Keyword">not</span> <span class="Identifier">a</span> <span class="Identifier">Unicode</span> <span class="Identifier">word</span> <span class="Identifier">boundary</span></pre>
+<h2><a class="toc-backref" id="syntax-grouping-and-flags" href="#syntax-grouping-and-flags">Grouping and flags</a></h2><pre class="listing"><span class="Punctuation">(</span><span class="Identifier">exp</span><span class="Punctuation">)</span>          <span class="Identifier">numbered</span> <span class="Identifier">capture</span> <span class="Identifier">group</span> <span class="Punctuation">(</span><span class="Identifier">indexed</span> <span class="Identifier">by</span> <span class="Identifier">opening</span> <span class="Identifier">parenthesis</span><span class="Punctuation">)</span>
+<span class="Punctuation">(</span><span class="Operator">?</span><span class="Identifier">P</span><span class="Operator">&lt;</span><span class="Identifier">name</span><span class="Operator">&gt;</span><span class="Identifier">exp</span><span class="Punctuation">)</span>  <span class="Identifier">named</span> <span class="Punctuation">(</span><span class="Identifier">also</span> <span class="Identifier">numbered</span><span class="Punctuation">)</span> <span class="Identifier">capture</span> <span class="Identifier">group</span> <span class="Punctuation">(</span><span class="Identifier">allowed</span> <span class="Identifier">chars</span><span class="Punctuation">:</span> <span class="Punctuation">[</span><span class="Identifier">_0</span><span class="Operator">-</span><span class="DecNumber">9</span><span class="Identifier">a</span><span class="Operator">-</span><span class="Identifier">zA</span><span class="Operator">-</span><span class="Identifier">Z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">(</span><span class="Operator">?:</span><span class="Identifier">exp</span><span class="Punctuation">)</span>        <span class="Identifier">non</span><span class="Operator">-</span><span class="Identifier">capturing</span> <span class="Identifier">group</span>
+<span class="Punctuation">(</span><span class="Operator">?</span><span class="Identifier">flags</span><span class="Punctuation">)</span>       <span class="Identifier">set</span> <span class="Identifier">flags</span> <span class="Identifier">within</span> <span class="Identifier">current</span> <span class="Identifier">group</span>
+<span class="Punctuation">(</span><span class="Operator">?</span><span class="Identifier">flags</span><span class="Punctuation">:</span><span class="Identifier">exp</span><span class="Punctuation">)</span>   <span class="Identifier">set</span> <span class="Identifier">flags</span> <span class="Keyword">for</span> <span class="Identifier">exp</span> <span class="Punctuation">(</span><span class="Identifier">non</span><span class="Operator">-</span><span class="Identifier">capturing</span><span class="Punctuation">)</span></pre><p>Flags are each a single character. For example, (?x) sets the flag x and (?-x) clears the flag x. Multiple flags can be set or cleared at the same time: (?xy) sets both the x and y flags, (?x-y) sets the x flag and clears the y flag, and (?-xy) clears both the x and y flags.</p>
+<pre class="listing"><span class="Identifier">i</span>  <span class="Keyword">case</span><span class="Operator">-</span><span class="Identifier">insensitive</span><span class="Punctuation">:</span> <span class="Identifier">letters</span> <span class="Identifier">match</span> <span class="Identifier">both</span> <span class="Identifier">upper</span> <span class="Keyword">and</span> <span class="Identifier">lower</span> <span class="Keyword">case</span>
+<span class="Identifier">m</span>  <span class="Identifier">multi</span><span class="Operator">-</span><span class="Identifier">line</span> <span class="Identifier">mode</span><span class="Punctuation">:</span> <span class="Operator">^</span> <span class="Keyword">and</span> <span class="Operator">$</span> <span class="Identifier">match</span> <span class="Identifier">begin</span><span class="Operator">/</span><span class="Keyword">end</span> <span class="Keyword">of</span> <span class="Identifier">line</span>
+<span class="Identifier">s</span>  <span class="Identifier">allow</span> <span class="Operator">.</span> <span class="Identifier">to</span> <span class="Identifier">match</span> <span class="Operator">\</span><span class="Identifier">L</span> <span class="Punctuation">(</span><span class="Identifier">new</span> <span class="Identifier">line</span><span class="Punctuation">)</span>
+<span class="Identifier">U</span>  <span class="Identifier">swap</span> <span class="Identifier">the</span> <span class="Identifier">meaning</span> <span class="Keyword">of</span> <span class="Identifier">x</span><span class="Operator">*</span> <span class="Keyword">and</span> <span class="Identifier">x</span><span class="Operator">*?</span> <span class="Punctuation">(</span><span class="Identifier">un</span><span class="Operator">-</span><span class="Identifier">greedy</span> <span class="Identifier">mode</span><span class="Punctuation">)</span>
+<span class="Identifier">u</span>  <span class="Identifier">Unicode</span> <span class="Identifier">support</span> <span class="Punctuation">(</span><span class="Identifier">enabled</span> <span class="Identifier">by</span> <span class="Identifier">default</span><span class="Punctuation">)</span>
+<span class="Identifier">x</span>  <span class="Identifier">ignore</span> <span class="Identifier">whitespace</span> <span class="Keyword">and</span> <span class="Identifier">allow</span> <span class="Identifier">line</span> <span class="Identifier">comments</span> <span class="Punctuation">(</span><span class="Identifier">starting</span> <span class="Identifier">with</span> <span class="Punctuation">`</span><span class="Comment">#`)</span></pre><p><tt class="docutils literal"><span class="pre">All flags are disabled by default unless stated otherwise</span></tt></p>
+
+<h2><a class="toc-backref" id="syntax-escape-sequences" href="#syntax-escape-sequences">Escape sequences</a></h2><pre class="listing"><span class="Operator">\*</span>         <span class="Identifier">literal</span> <span class="Operator">*</span><span class="Punctuation">,</span> <span class="Identifier">works</span> <span class="Keyword">for</span> <span class="Identifier">any</span> <span class="Identifier">punctuation</span> <span class="Identifier">character</span><span class="Punctuation">:</span> <span class="Operator">\.+*?</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Operator">|</span><span class="Punctuation">[</span><span class="Punctuation">]</span><span class="Punctuation">{</span><span class="Punctuation">}</span><span class="Operator">^$</span>
+<span class="Operator">\</span><span class="Identifier">a</span>         <span class="Identifier">bell</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">x07</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">f</span>         <span class="Identifier">form</span> <span class="Identifier">feed</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">x0C</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">t</span>         <span class="Identifier">horizontal</span> <span class="Identifier">tab</span>
+<span class="Operator">\</span><span class="Identifier">n</span>         <span class="Identifier">new</span> <span class="Identifier">line</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">L</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">r</span>         <span class="Identifier">carriage</span> <span class="Keyword">return</span>
+<span class="Operator">\</span><span class="Identifier">v</span>         <span class="Identifier">vertical</span> <span class="Identifier">tab</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">x0B</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="DecNumber">123</span>       <span class="Identifier">octal</span> <span class="Identifier">character</span> <span class="Identifier">code</span> <span class="Punctuation">(</span><span class="Identifier">up</span> <span class="Identifier">to</span> <span class="Identifier">three</span> <span class="Identifier">digits</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">x7F</span>       <span class="Identifier">hex</span> <span class="Identifier">character</span> <span class="Identifier">code</span> <span class="Punctuation">(</span><span class="Identifier">exactly</span> <span class="Identifier">two</span> <span class="Identifier">digits</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">x</span><span class="Punctuation">{</span><span class="DecNumber">10</span><span class="Identifier">FFFF</span><span class="Punctuation">}</span> <span class="Identifier">any</span> <span class="Identifier">hex</span> <span class="Identifier">character</span> <span class="Identifier">code</span> <span class="Identifier">corresponding</span> <span class="Identifier">to</span> <span class="Identifier">a</span> <span class="Identifier">Unicode</span> <span class="Identifier">code</span> <span class="Identifier">point</span>
+<span class="Operator">\</span><span class="Identifier">u007F</span>     <span class="Identifier">hex</span> <span class="Identifier">character</span> <span class="Identifier">code</span> <span class="Punctuation">(</span><span class="Identifier">exactly</span> <span class="Identifier">four</span> <span class="Identifier">digits</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">U0010FFFF</span> <span class="Identifier">hex</span> <span class="Identifier">character</span> <span class="Identifier">code</span> <span class="Punctuation">(</span><span class="Identifier">exactly</span> <span class="Identifier">eight</span> <span class="Identifier">digits</span><span class="Punctuation">)</span></pre>
+<h2><a class="toc-backref" id="syntax-perl-character-classes-unicode-friendly" href="#syntax-perl-character-classes-unicode-friendly">Perl character classes (Unicode friendly)</a></h2><p>These classes are based on the definitions provided in <a class="reference external" href="http://www.unicode.org/reports/tr18/#Compatibility_Properties">UTS#18</a></p>
+<pre class="listing"><span class="Operator">\</span><span class="Identifier">d</span>  <span class="Identifier">digit</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">Nd</span><span class="Punctuation">}</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">D</span>  <span class="Keyword">not</span> <span class="Identifier">digit</span>
+<span class="Operator">\</span><span class="Identifier">s</span>  <span class="Identifier">whitespace</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">White_Space</span><span class="Punctuation">}</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">S</span>  <span class="Keyword">not</span> <span class="Identifier">whitespace</span>
+<span class="Operator">\</span><span class="Identifier">w</span>  <span class="Identifier">word</span> <span class="Identifier">character</span> <span class="Punctuation">(</span><span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">Alphabetic</span><span class="Punctuation">}</span> <span class="Operator">+</span> <span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">M</span><span class="Punctuation">}</span> <span class="Operator">+</span> <span class="Operator">\</span><span class="Identifier">d</span> <span class="Operator">+</span> <span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">Pc</span><span class="Punctuation">}</span> <span class="Operator">+</span> <span class="Operator">\</span><span class="Identifier">p</span><span class="Punctuation">{</span><span class="Identifier">Join_Control</span><span class="Punctuation">}</span><span class="Punctuation">)</span>
+<span class="Operator">\</span><span class="Identifier">W</span>  <span class="Keyword">not</span> <span class="Identifier">word</span> <span class="Identifier">character</span></pre>
+<h2><a class="toc-backref" id="syntax-ascii-character-classes" href="#syntax-ascii-character-classes">ASCII character classes</a></h2><pre class="listing"><span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">alnum</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">alphanumeric</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="DecNumber">0</span><span class="Operator">-</span><span class="DecNumber">9</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Za</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">alpha</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">alphabetic</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Za</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">ascii</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">ASCII</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">\</span><span class="Identifier">x00</span><span class="Operator">-\</span><span class="Identifier">x7F</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">blank</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">blank</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">\</span><span class="Identifier">t</span> <span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">cntrl</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">control</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">\</span><span class="Identifier">x00</span><span class="Operator">-\</span><span class="Identifier">x1F</span><span class="Operator">\</span><span class="Identifier">x7F</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">digit</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">digits</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="DecNumber">0</span><span class="Operator">-</span><span class="DecNumber">9</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">graph</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">graphical</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">!-~</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">lower</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">lower</span> <span class="Keyword">case</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Identifier">a</span><span class="Operator">-</span><span class="Identifier">z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">print</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">printable</span> <span class="Punctuation">(</span><span class="Punctuation">[</span> <span class="Operator">-~</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">punct</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">punctuation</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">!-/:-@\</span><span class="Punctuation">[</span><span class="Operator">-</span><span class="Punctuation">`</span><span class="Punctuation">{</span><span class="Operator">-~</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">space</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">whitespace</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Operator">\</span><span class="Identifier">t</span><span class="Operator">\</span><span class="Identifier">n</span><span class="Operator">\</span><span class="Identifier">v</span><span class="Operator">\</span><span class="Identifier">f</span><span class="Operator">\</span><span class="Identifier">r</span> <span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">upper</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>   <span class="Identifier">upper</span> <span class="Keyword">case</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Z</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">word</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>    <span class="Identifier">word</span> <span class="Identifier">characters</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="DecNumber">0</span><span class="Operator">-</span><span class="DecNumber">9</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Za</span><span class="Operator">-</span><span class="Identifier">z_</span><span class="Punctuation">]</span><span class="Punctuation">)</span>
+<span class="Punctuation">[</span><span class="Punctuation">[</span><span class="Punctuation">:</span><span class="Identifier">xdigit</span><span class="Punctuation">:</span><span class="Punctuation">]</span><span class="Punctuation">]</span>  <span class="Identifier">hex</span> <span class="Identifier">digit</span> <span class="Punctuation">(</span><span class="Punctuation">[</span><span class="DecNumber">0</span><span class="Operator">-</span><span class="DecNumber">9</span><span class="Identifier">A</span><span class="Operator">-</span><span class="Identifier">Fa</span><span class="Operator">-</span><span class="Identifier">f</span><span class="Punctuation">]</span><span class="Punctuation">)</span></pre>
+<h2><a class="toc-backref" id="syntax-lookaround-assertions" href="#syntax-lookaround-assertions">Lookaround Assertions</a></h2><pre class="listing"><span class="Punctuation">(</span><span class="Operator">?=</span><span class="Identifier">regex</span><span class="Punctuation">)</span>   <span class="Identifier">A</span> <span class="Identifier">positive</span> <span class="Identifier">lookahead</span> <span class="Identifier">assertion</span>
+<span class="Punctuation">(</span><span class="Operator">?!</span><span class="Identifier">regex</span><span class="Punctuation">)</span>   <span class="Identifier">A</span> <span class="Identifier">negative</span> <span class="Identifier">lookahead</span> <span class="Identifier">assertion</span>
+<span class="Punctuation">(</span><span class="Operator">?&lt;=</span><span class="Identifier">regex</span><span class="Punctuation">)</span>  <span class="Identifier">A</span> <span class="Identifier">positive</span> <span class="Identifier">lookbehind</span> <span class="Identifier">assertion</span>
+<span class="Punctuation">(</span><span class="Operator">?&lt;!</span><span class="Identifier">regex</span><span class="Punctuation">)</span>  <span class="Identifier">A</span> <span class="Identifier">negative</span> <span class="Identifier">lookbehind</span> <span class="Identifier">assertion</span></pre><p>Any regex expression is a valid lookaround; groups are captured as well. Beware, lookarounds containing repetitions (<tt class="docutils literal"><span class="pre">*</span></tt>, <tt class="docutils literal"><span class="pre">+</span></tt>, and <tt class="docutils literal"><span class="pre">{n,}</span></tt>) may run in polynomial time.</p>
+
+<h1><a class="toc-backref" id="examples" href="#examples">Examples</a></h1>
+<h2><a class="toc-backref" id="examples-multiple-captures" href="#examples-multiple-captures">Multiple captures</a></h2><p>Unlike most regex engines, this library supports capturing all repetitions. Most other libraries return only the last capture. The caveat is even non-repeated groups or characters are returned as a list of captures instead of a single capture.</p>
+<pre class="listing"><span class="Keyword">let</span> <span class="Identifier">text</span> <span class="Operator">=</span> <span class="StringLit">&quot;nim c --styleCheck:hint --colors:off regex.nim&quot;</span>
+<span class="Keyword">var</span> <span class="Identifier">m</span><span class="Punctuation">:</span> <span class="Identifier">RegexMatch</span>
+<span class="Keyword">if</span> <span class="Identifier">match</span><span class="Punctuation">(</span><span class="Identifier">text</span><span class="Punctuation">,</span> <span class="RawData">re&quot;nim c (?:--(\w+:\w+) *)+ (\w+).nim&quot;</span><span class="Punctuation">,</span> <span class="Identifier">m</span><span class="Punctuation">)</span><span class="Punctuation">:</span>
+  <span class="Identifier">doAssert</span> <span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">,</span> <span class="Identifier">text</span><span class="Punctuation">)</span> <span class="Operator">==</span> <span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;styleCheck:hint&quot;</span><span class="Punctuation">,</span> <span class="StringLit">&quot;colors:off&quot;</span><span class="Punctuation">]</span>
+  <span class="Identifier">doAssert</span> <span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">1</span><span class="Punctuation">,</span> <span class="Identifier">text</span><span class="Punctuation">)</span> <span class="Operator">==</span> <span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;regex&quot;</span><span class="Punctuation">]</span>
+<span class="Keyword">else</span><span class="Punctuation">:</span>
+  <span class="Identifier">doAssert</span> <span class="Identifier">false</span><span class="Punctuation">,</span> <span class="StringLit">&quot;no match&quot;</span></pre>
+<h2><a class="toc-backref" id="examples-verbose-mode" href="#examples-verbose-mode">Verbose Mode</a></h2><p>Verbose mode <tt class="docutils literal"><span class="pre">(?x)</span></tt> makes regexes more readable by allowing comments and multi-lines within the regular expression itself. The caveat is spaces and pound signs must be scaped to be matched.</p>
+<pre class="listing"><span class="Keyword">const</span> <span class="Identifier">exp</span> <span class="Operator">=</span> <span class="LongStringLit">re&quot;&quot;&quot;(?x)
+\#   # the hashtag
+\w+  # hashtag words
+&quot;&quot;&quot;</span>
+<span class="Keyword">let</span> <span class="Identifier">text</span> <span class="Operator">=</span> <span class="StringLit">&quot;#NimLang&quot;</span>
+<span class="Identifier">doAssert</span> <span class="Identifier">match</span><span class="Punctuation">(</span><span class="Identifier">text</span><span class="Punctuation">,</span> <span class="Identifier">exp</span><span class="Punctuation">)</span></pre>
+<h2><a class="toc-backref" id="examples-find-all" href="#examples-find-all">Find All</a></h2><p>The <tt class="docutils literal"><span class="pre">findAll</span></tt> function will find all boundaries and captures that match the regular expression.</p>
+<pre class="listing"><span class="Keyword">let</span> <span class="Identifier">text</span> <span class="Operator">=</span> <span class="LongStringLit">&quot;&quot;&quot;
+The Continental's email list:
+john_wick@continental.com
+winston@continental.com
+ms_perkins@continental.com
+&quot;&quot;&quot;</span>
+<span class="Keyword">var</span> <span class="Identifier">matches</span> <span class="Operator">=</span> <span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span>
+<span class="Keyword">var</span> <span class="Identifier">captures</span> <span class="Operator">=</span> <span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span>
+<span class="Keyword">for</span> <span class="Identifier">m</span> <span class="Keyword">in</span> <span class="Identifier">findAll</span><span class="Punctuation">(</span><span class="Identifier">text</span><span class="Punctuation">,</span> <span class="RawData">re&quot;(\w+)@\w+\.\w+&quot;</span><span class="Punctuation">)</span><span class="Punctuation">:</span>
+  <span class="Identifier">matches</span><span class="Operator">.</span><span class="Identifier">add</span> <span class="Identifier">text</span><span class="Punctuation">[</span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">boundaries</span><span class="Punctuation">]</span>
+  <span class="Identifier">captures</span><span class="Operator">.</span><span class="Identifier">add</span> <span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">,</span> <span class="Identifier">text</span><span class="Punctuation">)</span>
+<span class="Identifier">doAssert</span> <span class="Identifier">matches</span> <span class="Operator">==</span> <span class="Operator">@</span><span class="Punctuation">[</span>
+  <span class="StringLit">&quot;john_wick@continental.com&quot;</span><span class="Punctuation">,</span>
+  <span class="StringLit">&quot;winston@continental.com&quot;</span><span class="Punctuation">,</span>
+  <span class="StringLit">&quot;ms_perkins@continental.com&quot;</span>
+<span class="Punctuation">]</span>
+<span class="Identifier">doAssert</span> <span class="Identifier">captures</span> <span class="Operator">==</span> <span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;john_wick&quot;</span><span class="Punctuation">,</span> <span class="StringLit">&quot;winston&quot;</span><span class="Punctuation">,</span> <span class="StringLit">&quot;ms_perkins&quot;</span><span class="Punctuation">]</span></pre>
+<h2><a class="toc-backref" id="examples-match-macro" href="#examples-match-macro">Match Macro</a></h2><p>The <tt class="docutils literal"><span class="pre">match</span></tt> macro is sometimes more convenient, and faster than the function version. It will run a full match on the whole string, similar to <tt class="docutils literal"><span class="pre">^regex$</span></tt>.</p>
+<p>A <tt class="docutils literal"><span class="pre">matches: seq[string]</span></tt> variable is injected into the scope, and it contains the submatches for every capture group.</p>
+<pre class="listing"><span class="Keyword">var</span> <span class="Identifier">matched</span> <span class="Operator">=</span> <span class="Identifier">false</span>
+<span class="Keyword">let</span> <span class="Identifier">text</span> <span class="Operator">=</span> <span class="StringLit">&quot;[my link](https://example.com)&quot;</span>
+<span class="Identifier">match</span> <span class="Identifier">text</span><span class="Punctuation">,</span> <span class="RawData">rex&quot;\[([^\]]+)\]\((https?://[^)]+)\)&quot;</span><span class="Punctuation">:</span>
+  <span class="Identifier">doAssert</span> <span class="Identifier">matches</span> <span class="Operator">==</span> <span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;my link&quot;</span><span class="Punctuation">,</span> <span class="StringLit">&quot;https://example.com&quot;</span><span class="Punctuation">]</span>
+  <span class="Identifier">matched</span> <span class="Operator">=</span> <span class="Identifier">true</span>
+<span class="Identifier">doAssert</span> <span class="Identifier">matched</span></pre></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="regex/types.html">regex/types</a>, <a class="reference external" href="regex/common.html">regex/common</a>, <a class="reference external" href="regex/compiler.html">regex/compiler</a>, <a class="reference external" href="regex/nfatype.html">regex/nfatype</a>, <a class="reference external" href="regex/nfafindall.html">regex/nfafindall</a>, <a class="reference external" href="regex/nfamatch.html">regex/nfamatch</a>, <a class="reference external" href="regex/litopt.html">regex/litopt</a>, <a class="reference external" href="regex/nfamacro.html">regex/nfamacro</a>, <a class="reference external" href="regex/parser.html">regex/parser</a>, <a class="reference external" href="regex/exptransformation.html">regex/exptransformation</a>, <a class="reference external" href="regex/dotgraph.html">regex/dotgraph</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="re,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#re%2Cstring"><span class="Identifier">re</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><a href="regex/common.html#RegexError"><span class="Identifier">RegexError</span></a><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Parse and compile a regular expression at run-time
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">abcx</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="RawData">re&quot;abc\w&quot;</span><span class="Whitespace">
+</span><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">abcx2</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">re</span><span class="Punctuation">(</span><span class="RawData">r&quot;abc\w&quot;</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">pat</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="RawData">r&quot;abc\w&quot;</span><span class="Whitespace">
+</span><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">abcx3</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">re</span><span class="Punctuation">(</span><span class="Identifier">pat</span><span class="Punctuation">)</span></pre>
+
+</dd>
+<a id="re,staticstring"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#re%2Cstaticstring"><span class="Identifier">re</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">static</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">static</span><span class="Other">[</span><a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Parse and compile a regular expression at compile-time
+
+</dd>
+<a id="toPattern,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toPattern%2Cstring"><span class="Identifier">toPattern</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><a href="regex/common.html#RegexError"><span class="Identifier">RegexError</span></a><span class="Other">]</span><span class="Other">,</span>
+                                   <span class="Identifier">deprecated</span><span class="Other">:</span> <span class="StringLit">&quot;Use `re` instead&quot;</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+  <div class="deprecation-message">
+    <b>Deprecated:</b> Use `re` instead
+  </div>
+
+
+
+</dd>
+<a id="rex,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#rex%2Cstring"><span class="Identifier">rex</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexLit"><span class="Identifier">RegexLit</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Raw regex literal string
+
+</dd>
+<a id="group,RegexMatch,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#group%2CRegexMatch%2Cint"><span class="Identifier">group</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return slices for a given group. Use the iterator version if you care about performance
+
+</dd>
+<a id="group,RegexMatch,int,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#group%2CRegexMatch%2Cint%2Cstring"><span class="Identifier">group</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return seq of captured text by group number <tt class="docutils literal"><span class="pre">i</span></tt>
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello beautiful world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(hello) (?:([^\s]+)\s?)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;hello&quot;</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">1</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;beautiful&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;world&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="groupFirstCapture,RegexMatch,int,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#groupFirstCapture%2CRegexMatch%2Cint%2Cstring"><span class="Identifier">groupFirstCapture</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return first capture for a given capturing group
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello beautiful world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(hello) (?:([^\s]+)\s?)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupFirstCapture</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupFirstCapture</span><span class="Punctuation">(</span><span class="DecNumber">1</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;beautiful&quot;</span></pre>
+
+</dd>
+<a id="groupLastCapture,RegexMatch,int,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#groupLastCapture%2CRegexMatch%2Cint%2Cstring"><span class="Identifier">groupLastCapture</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return last capture for a given capturing group
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello beautiful world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(hello) (?:([^\s]+)\s?)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupLastCapture</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupLastCapture</span><span class="Punctuation">(</span><span class="DecNumber">1</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;world&quot;</span></pre>
+
+</dd>
+<a id="group,RegexMatch,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#group%2CRegexMatch%2Cstring"><span class="Identifier">group</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">KeyError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return slices for a given named group. Use the iterator version if you care about performance
+
+</dd>
+<a id="group,RegexMatch,string,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#group%2CRegexMatch%2Cstring%2Cstring"><span class="Identifier">group</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">groupName</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">KeyError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return seq of captured text by group <tt class="docutils literal"><span class="pre">groupName</span></tt>
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello beautiful world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(?P&lt;greet&gt;hello) (?:(?P&lt;who&gt;[^\s]+)\s?)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="StringLit">&quot;greet&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;hello&quot;</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="StringLit">&quot;who&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;beautiful&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;world&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="groupFirstCapture,RegexMatch,string,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#groupFirstCapture%2CRegexMatch%2Cstring%2Cstring"><span class="Identifier">groupFirstCapture</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">groupName</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">KeyError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return first capture for a given capturing group
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello beautiful world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(?P&lt;greet&gt;hello) (?:(?P&lt;who&gt;[^\s]+)\s?)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupFirstCapture</span><span class="Punctuation">(</span><span class="StringLit">&quot;greet&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupFirstCapture</span><span class="Punctuation">(</span><span class="StringLit">&quot;who&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;beautiful&quot;</span></pre>
+
+</dd>
+<a id="groupLastCapture,RegexMatch,string,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#groupLastCapture%2CRegexMatch%2Cstring%2Cstring"><span class="Identifier">groupLastCapture</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">groupName</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">KeyError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return last capture for a given capturing group
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello beautiful world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(?P&lt;greet&gt;hello) (?:(?P&lt;who&gt;[^\s]+)\s?)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupLastCapture</span><span class="Punctuation">(</span><span class="StringLit">&quot;greet&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupLastCapture</span><span class="Punctuation">(</span><span class="StringLit">&quot;who&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;world&quot;</span></pre>
+
+</dd>
+<a id="groupsCount,RegexMatch"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#groupsCount%2CRegexMatch"><span class="Identifier">groupsCount</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return the number of capturing groups
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;ab&quot;</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(a)(b)&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupsCount</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="DecNumber">2</span></pre>
+
+</dd>
+<a id="groupNames,RegexMatch"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#groupNames%2CRegexMatch"><span class="Identifier">groupNames</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return the names of capturing groups.
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;hello world&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(?P&lt;greet&gt;hello) (?P&lt;who&gt;world)&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">groupNames</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;greet&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;who&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="match,string,Regex,RegexMatch,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#match%2Cstring%2CRegex%2CRegexMatch%2Cint"><span class="Identifier">match</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">m</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a match if the whole string matches the regular expression. This is similar to <tt class="docutils literal"><span class="pre">find(text, re&quot;^regex$&quot;, m)</span></tt> but has better performance
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcd&quot;</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;abcd&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Keyword">not</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcd&quot;</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;abc&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span></pre>
+
+</dd>
+<a id="match,string,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#match%2Cstring%2CRegex"><span class="Identifier">match</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="findAll,string,Regex,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#findAll%2Cstring%2CRegex%2Cint"><span class="Identifier">findAll</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="findAllBounds,string,Regex,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#findAllBounds%2Cstring%2CRegex%2Cint"><span class="Identifier">findAllBounds</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="findAndCaptureAll,string,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#findAndCaptureAll%2Cstring%2CRegex"><span class="Identifier">findAndCaptureAll</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+search through the string and return a seq with captures.
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">findAndCaptureAll</span><span class="Punctuation">(</span><span class="StringLit">&quot;a1b2c3d4e5&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">re&quot;\d&quot;</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace">
+  </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;1&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;2&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;3&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;4&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;5&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="contains,string,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#contains%2Cstring%2CRegex"><span class="Identifier">contains</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+search for the pattern anywhere in the string
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="RawData">re&quot;bc&quot;</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcd&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="RawData">re&quot;(23)+&quot;</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="StringLit">&quot;23232&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="RawData">re&quot;^(23)+$&quot;</span><span class="Whitespace"> </span><span class="Keyword">notin</span><span class="Whitespace"> </span><span class="StringLit">&quot;23232&quot;</span></pre>
+
+</dd>
+<a id="find,string,Regex,RegexMatch,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#find%2Cstring%2CRegex%2CRegexMatch%2Cint"><span class="Identifier">find</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">m</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+search through the string looking for the first location where there is a match
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcd&quot;</span><span class="Operator">.</span><span class="Identifier">find</span><span class="Punctuation">(</span><span class="RawData">re&quot;bc&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Keyword">and</span><span class="Whitespace">
+  </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">boundaries</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="DecNumber">1</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">2</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Keyword">not</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcd&quot;</span><span class="Operator">.</span><span class="Identifier">find</span><span class="Punctuation">(</span><span class="RawData">re&quot;de&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;2222&quot;</span><span class="Operator">.</span><span class="Identifier">find</span><span class="Punctuation">(</span><span class="RawData">re&quot;(22)*&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Keyword">and</span><span class="Whitespace">
+  </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="DecNumber">0</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">1</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="DecNumber">2</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">3</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="split,string,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#split%2Cstring%2CRegex"><span class="Identifier">split</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">sep</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return not matched substrings
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">split</span><span class="Punctuation">(</span><span class="StringLit">&quot;11a22Ϊ33Ⓐ44弢55&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">re&quot;\d+&quot;</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace">
+  </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;a&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;Ϊ&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;Ⓐ&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;弢&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="splitIncl,string,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#splitIncl%2Cstring%2CRegex"><span class="Identifier">splitIncl</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">sep</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return not matched substrings, including captured groups
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace">
+  </span><span class="Identifier">parts</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">splitIncl</span><span class="Punctuation">(</span><span class="StringLit">&quot;a,b&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">re&quot;(,)&quot;</span><span class="Punctuation">)</span><span class="Whitespace">
+  </span><span class="Identifier">expected</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;a&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;,&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;b&quot;</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">parts</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Identifier">expected</span></pre>
+
+</dd>
+<a id="startsWith,string,Regex,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#startsWith%2Cstring%2CRegex%2Cint"><span class="Identifier">startsWith</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return whether the string starts with the pattern or not
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Operator">.</span><span class="Identifier">startsWith</span><span class="Punctuation">(</span><span class="RawData">re&quot;\w&quot;</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Keyword">not</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Operator">.</span><span class="Identifier">startsWith</span><span class="Punctuation">(</span><span class="RawData">re&quot;\d&quot;</span><span class="Punctuation">)</span></pre>
+
+</dd>
+<a id="endsWith,string,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#endsWith%2Cstring%2CRegex"><span class="Identifier">endsWith</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return whether the string ends with the pattern or not
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Operator">.</span><span class="Identifier">endsWith</span><span class="Punctuation">(</span><span class="RawData">re&quot;\w&quot;</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Keyword">not</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Operator">.</span><span class="Identifier">endsWith</span><span class="Punctuation">(</span><span class="RawData">re&quot;\d&quot;</span><span class="Punctuation">)</span></pre>
+
+</dd>
+<a id="replace,string,Regex,string,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#replace%2Cstring%2CRegex%2Cstring%2Cint"><span class="Identifier">replace</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">by</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">limit</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">ValueError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+<p>Replace matched substrings.</p>
+<p>Matched groups can be accessed with <tt class="docutils literal"><span class="pre">$N</span></tt> notation, where <tt class="docutils literal"><span class="pre">N</span></tt> is the group's index, starting at 1 (1-indexed). <tt class="docutils literal"><span class="pre">$$</span></tt> means literal <tt class="docutils literal"><span class="pre">$</span></tt>.</p>
+<p>If <tt class="docutils literal"><span class="pre">limit</span></tt> is given, at most <tt class="docutils literal"><span class="pre">limit</span></tt> replacements are done. <tt class="docutils literal"><span class="pre">limit</span></tt> of 0 means there is no limit</p>
+
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;aaa&quot;</span><span class="Operator">.</span><span class="Identifier">replace</span><span class="Punctuation">(</span><span class="RawData">re&quot;a&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;b&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="DecNumber">1</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="StringLit">&quot;baa&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Operator">.</span><span class="Identifier">replace</span><span class="Punctuation">(</span><span class="RawData">re&quot;(a(b)c)&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;m($1) m($2)&quot;</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace">
+  </span><span class="StringLit">&quot;m(abc) m(b)&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="StringLit">&quot;Nim is awesome!&quot;</span><span class="Operator">.</span><span class="Identifier">replace</span><span class="Punctuation">(</span><span class="RawData">re&quot;(\w\B)&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;$1_&quot;</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace">
+  </span><span class="StringLit">&quot;N_i_m i_s a_w_e_s_o_m_e!&quot;</span></pre>
+
+</dd>
+<a id="replace,string,Regex,proc(RegexMatch,string),int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#replace%2Cstring%2CRegex%2Cproc%28RegexMatch%2Cstring%29%2Cint"><span class="Identifier">replace</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span>
+             <span class="Identifier">by</span><span class="Other">:</span> <span class="Keyword">proc</span> <span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">limit</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+<p>Replace matched substrings.</p>
+<p>If <tt class="docutils literal"><span class="pre">limit</span></tt> is given, at most <tt class="docutils literal"><span class="pre">limit</span></tt> replacements are done. <tt class="docutils literal"><span class="pre">limit</span></tt> of 0 means there is no limit</p>
+
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">proc</span><span class="Whitespace"> </span><span class="Identifier">removeEvenWords</span><span class="Punctuation">(</span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">s</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">string</span><span class="Punctuation">)</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">string</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace">
+  </span><span class="Identifier">result</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;&quot;</span><span class="Whitespace">
+  </span><span class="Keyword">if</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">1</span><span class="Punctuation">)</span><span class="Operator">.</span><span class="Identifier">len</span><span class="Whitespace"> </span><span class="Keyword">mod</span><span class="Whitespace"> </span><span class="DecNumber">2</span><span class="Whitespace"> </span><span class="Operator">!=</span><span class="Whitespace"> </span><span class="DecNumber">0</span><span class="Punctuation">:</span><span class="Whitespace">
+    </span><span class="Identifier">result</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">s</span><span class="Punctuation">[</span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">)</span><span class="Punctuation">[</span><span class="DecNumber">0</span><span class="Punctuation">]</span><span class="Punctuation">]</span><span class="Whitespace">
+
+</span><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;Es macht Spaß, alle geraden Wörter zu entfernen!&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">replace</span><span class="Punctuation">(</span><span class="RawData">re&quot;((\w)+\s*)&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">removeEvenWords</span><span class="Punctuation">)</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace">
+  </span><span class="StringLit">&quot;macht , geraden entfernen!&quot;</span></pre>
+
+</dd>
+<a id="isInitialized,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#isInitialized%2CRegex"><span class="Identifier">isInitialized</span></a><span class="Other">(</span><span class="Identifier">re</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Check whether the regex has been initialized
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">re</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">Regex</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Keyword">not</span><span class="Whitespace"> </span><span class="Identifier">re</span><span class="Operator">.</span><span class="Identifier">isInitialized</span><span class="Whitespace">
+</span><span class="Identifier">re</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="RawData">re&quot;foo&quot;</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">re</span><span class="Operator">.</span><span class="Identifier">isInitialized</span></pre>
+
+</dd>
+<a id="escapeRe,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#escapeRe%2Cstring"><span class="Identifier">escapeRe</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Escape special regex characters in <tt class="docutils literal"><span class="pre">s</span></tt> so that it can be matched verbatim
+
+</dd>
+
+</dl></div>
+<div class="section" id="15">
+<h1><a class="toc-backref" href="#15">Iterators</a></h1>
+<dl class="item">
+<a id="group.i,RegexMatch,int"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#group.i%2CRegexMatch%2Cint"><span class="Identifier">group</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return slices for a given group. Slices of start &gt; end are empty matches (i.e.: <tt class="docutils literal"><span class="pre">re&quot;(\d?)&quot;</span></tt>) and they are included same as in PCRE.
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(\w)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">captures</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">for</span><span class="Whitespace"> </span><span class="Identifier">bounds</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="DecNumber">0</span><span class="Punctuation">)</span><span class="Punctuation">:</span><span class="Whitespace">
+  </span><span class="Identifier">captures</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">[</span><span class="Identifier">bounds</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">captures</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;a&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;b&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;c&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="group.i,RegexMatch,string"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#group.i%2CRegexMatch%2Cstring"><span class="Identifier">group</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">KeyError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return slices for a given named group
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">:</span><span class="Whitespace"> </span><span class="Identifier">RegexMatch</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Operator">.</span><span class="Identifier">match</span><span class="Punctuation">(</span><span class="RawData">re&quot;(?P&lt;foo&gt;\w)+&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">captures</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">for</span><span class="Whitespace"> </span><span class="Identifier">bounds</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">group</span><span class="Punctuation">(</span><span class="StringLit">&quot;foo&quot;</span><span class="Punctuation">)</span><span class="Punctuation">:</span><span class="Whitespace">
+  </span><span class="Identifier">captures</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">[</span><span class="Identifier">bounds</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">captures</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;a&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;b&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;c&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="findAll.i,string,Regex,int"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#findAll.i%2Cstring%2CRegex%2Cint"><span class="Identifier">findAll</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+search through the string and return each match. Empty matches (start &gt; end) are included
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcabc&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">bounds</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">Slice</span><span class="Punctuation">[</span><span class="Identifier">int</span><span class="Punctuation">]</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">found</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">for</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="Identifier">findAll</span><span class="Punctuation">(</span><span class="Identifier">text</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">re&quot;bc&quot;</span><span class="Punctuation">)</span><span class="Punctuation">:</span><span class="Whitespace">
+  </span><span class="Identifier">bounds</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Whitespace"> </span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">boundaries</span><span class="Whitespace">
+  </span><span class="Identifier">found</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Punctuation">[</span><span class="Identifier">m</span><span class="Operator">.</span><span class="Identifier">boundaries</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">bounds</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="DecNumber">1</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">2</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="DecNumber">4</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">5</span><span class="Punctuation">]</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">found</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;bc&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;bc&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="findAllBounds.i,string,Regex,int"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#findAllBounds.i%2Cstring%2CRegex%2Cint"><span class="Identifier">findAllBounds</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">pattern</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+search through the string and return each match. Empty matches (start &gt; end) are included
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">let</span><span class="Whitespace"> </span><span class="Identifier">text</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="StringLit">&quot;abcabc&quot;</span><span class="Whitespace">
+</span><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">bounds</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">Slice</span><span class="Punctuation">[</span><span class="Identifier">int</span><span class="Punctuation">]</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">for</span><span class="Whitespace"> </span><span class="Identifier">bd</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="Identifier">findAllBounds</span><span class="Punctuation">(</span><span class="Identifier">text</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">re&quot;bc&quot;</span><span class="Punctuation">)</span><span class="Punctuation">:</span><span class="Whitespace">
+  </span><span class="Identifier">bounds</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Whitespace"> </span><span class="Identifier">bd</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">bounds</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="DecNumber">1</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">2</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="DecNumber">4</span><span class="Whitespace"> </span><span class="Operator">..</span><span class="Whitespace"> </span><span class="DecNumber">5</span><span class="Punctuation">]</span></pre>
+
+</dd>
+<a id="split.i,string,Regex"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#split.i%2Cstring%2CRegex"><span class="Identifier">split</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">sep</span><span class="Other">:</span> <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return not matched substrings
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Keyword">var</span><span class="Whitespace"> </span><span class="Identifier">found</span><span class="Whitespace"> </span><span class="Operator">=</span><span class="Whitespace"> </span><span class="Identifier">newSeq</span><span class="Punctuation">[</span><span class="Identifier">string</span><span class="Punctuation">]</span><span class="Punctuation">(</span><span class="Punctuation">)</span><span class="Whitespace">
+</span><span class="Keyword">for</span><span class="Whitespace"> </span><span class="Identifier">s</span><span class="Whitespace"> </span><span class="Keyword">in</span><span class="Whitespace"> </span><span class="Identifier">split</span><span class="Punctuation">(</span><span class="StringLit">&quot;11a22Ϊ33Ⓐ44弢55&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">re&quot;\d+&quot;</span><span class="Punctuation">)</span><span class="Punctuation">:</span><span class="Whitespace">
+  </span><span class="Identifier">found</span><span class="Operator">.</span><span class="Identifier">add</span><span class="Whitespace"> </span><span class="Identifier">s</span><span class="Whitespace">
+</span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">found</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;a&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;Ϊ&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;Ⓐ&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;弢&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+
+</dl></div>
+<div class="section" id="17">
+<h1><a class="toc-backref" href="#17">Macros</a></h1>
+<dl class="item">
+<a id="match.m,string,RegexLit,untyped"></a>
+<dt><pre><span class="Keyword">macro</span> <a href="#match.m%2Cstring%2CRegexLit%2Cuntyped"><span class="Identifier">match</span></a><span class="Other">(</span><span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">regex</span><span class="Other">:</span> <a href="regex/nfatype.html#RegexLit"><span class="Identifier">RegexLit</span></a><span class="Other">;</span> <span class="Identifier">body</span><span class="Other">:</span> <span class="Identifier">untyped</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
+<dd>
+
+<p>return a match if the whole string matches the regular expression. This is similar to the <tt class="docutils literal"><span class="pre">match</span></tt> function, but faster. Notice it requires a raw regex <em>literal</em> string as second parameter; the regex must be known at compile time, and cannot be a var/let/const</p>
+<p>A <tt class="docutils literal"><span class="pre">matches: seq[string]</span></tt> variable is injected into the scope, and it contains the submatches for every capture group. If a group is repeated (ex: <tt class="docutils literal"><span class="pre">(\w)+</span></tt>), it will contain the last capture for that group.</p>
+<p>Note: Only available in Nim +1.1</p>
+
+<p><strong class="examples_text">Example:</strong></p>
+<pre class="listing"><span class="Identifier">match</span><span class="Whitespace"> </span><span class="StringLit">&quot;abc&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="RawData">rex&quot;(a(b)c)&quot;</span><span class="Punctuation">:</span><span class="Whitespace">
+  </span><span class="Identifier">doAssert</span><span class="Whitespace"> </span><span class="Identifier">matches</span><span class="Whitespace"> </span><span class="Operator">==</span><span class="Whitespace"> </span><span class="Operator">@</span><span class="Punctuation">[</span><span class="StringLit">&quot;abc&quot;</span><span class="Punctuation">,</span><span class="Whitespace"> </span><span class="StringLit">&quot;b&quot;</span><span class="Punctuation">]</span></pre>
+
+</dd>
+
+</dl></div>
+<div class="section" id="19">
+<h1><a class="toc-backref" href="#19">Exports</a></h1>
+<dl class="item">
+<a href="regex/nfatype.html#RegexLit"><span class="Identifier">RegexLit</span></a>, <a href="regex/nfatype.html#Regex"><span class="Identifier">Regex</span></a>, <a href="regex/nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a>, <a href="regex/common.html#RegexError"><span class="Identifier">RegexError</span></a>
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:33 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex.idx b/docs/regex.idx
new file mode 100644
index 0000000..13f658c
--- /dev/null
+++ b/docs/regex.idx
@@ -0,0 +1,51 @@
+Syntax	regex.html#syntax	 Syntax	
+Matching one character	regex.html#syntax-matching-one-character	  Matching one character	
+Character classes	regex.html#syntax-character-classes	  Character classes	
+Composites	regex.html#syntax-composites	  Composites	
+Repetitions	regex.html#syntax-repetitions	  Repetitions	
+Empty matches	regex.html#syntax-empty-matches	  Empty matches	
+Grouping and flags	regex.html#syntax-grouping-and-flags	  Grouping and flags	
+Escape sequences	regex.html#syntax-escape-sequences	  Escape sequences	
+Perl character classes (Unicode friendly)	regex.html#syntax-perl-character-classes-unicode-friendly	  Perl character classes (Unicode friendly)	
+ASCII character classes	regex.html#syntax-ascii-character-classes	  ASCII character classes	
+Lookaround Assertions	regex.html#syntax-lookaround-assertions	  Lookaround Assertions	
+Examples	regex.html#examples	 Examples	
+Multiple captures	regex.html#examples-multiple-captures	  Multiple captures	
+Verbose Mode	regex.html#examples-verbose-mode	  Verbose Mode	
+Find All	regex.html#examples-find-all	  Find All	
+Match Macro	regex.html#examples-match-macro	  Match Macro	
+re	regex.html#re,string	regex: re(s: string): Regex	
+re	regex.html#re,staticstring	regex: re(s: static string): static[Regex]	
+toPattern	regex.html#toPattern,string	regex: toPattern(s: string): Regex	
+rex	regex.html#rex,string	regex: rex(s: string): RegexLit	
+group	regex.html#group.i,RegexMatch,int	regex: group(m: RegexMatch; i: int): Slice[int]	
+group	regex.html#group,RegexMatch,int	regex: group(m: RegexMatch; i: int): seq[Slice[int]]	
+group	regex.html#group,RegexMatch,int,string	regex: group(m: RegexMatch; i: int; text: string): seq[string]	
+groupFirstCapture	regex.html#groupFirstCapture,RegexMatch,int,string	regex: groupFirstCapture(m: RegexMatch; i: int; text: string): string	
+groupLastCapture	regex.html#groupLastCapture,RegexMatch,int,string	regex: groupLastCapture(m: RegexMatch; i: int; text: string): string	
+group	regex.html#group.i,RegexMatch,string	regex: group(m: RegexMatch; s: string): Slice[int]	
+group	regex.html#group,RegexMatch,string	regex: group(m: RegexMatch; s: string): seq[Slice[int]]	
+group	regex.html#group,RegexMatch,string,string	regex: group(m: RegexMatch; groupName: string; text: string): seq[string]	
+groupFirstCapture	regex.html#groupFirstCapture,RegexMatch,string,string	regex: groupFirstCapture(m: RegexMatch; groupName: string; text: string): string	
+groupLastCapture	regex.html#groupLastCapture,RegexMatch,string,string	regex: groupLastCapture(m: RegexMatch; groupName: string; text: string): string	
+groupsCount	regex.html#groupsCount,RegexMatch	regex: groupsCount(m: RegexMatch): int	
+groupNames	regex.html#groupNames,RegexMatch	regex: groupNames(m: RegexMatch): seq[string]	
+match	regex.html#match.m,string,RegexLit,untyped	regex: match(text: string; regex: RegexLit; body: untyped): untyped	
+match	regex.html#match,string,Regex,RegexMatch,int	regex: match(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool	
+match	regex.html#match,string,Regex	regex: match(s: string; pattern: Regex): bool	
+findAll	regex.html#findAll.i,string,Regex,int	regex: findAll(s: string; pattern: Regex; start = 0): RegexMatch	
+findAll	regex.html#findAll,string,Regex,int	regex: findAll(s: string; pattern: Regex; start = 0): seq[RegexMatch]	
+findAllBounds	regex.html#findAllBounds.i,string,Regex,int	regex: findAllBounds(s: string; pattern: Regex; start = 0): Slice[int]	
+findAllBounds	regex.html#findAllBounds,string,Regex,int	regex: findAllBounds(s: string; pattern: Regex; start = 0): seq[Slice[int]]	
+findAndCaptureAll	regex.html#findAndCaptureAll,string,Regex	regex: findAndCaptureAll(s: string; pattern: Regex): seq[string]	
+contains	regex.html#contains,string,Regex	regex: contains(s: string; pattern: Regex): bool	
+find	regex.html#find,string,Regex,RegexMatch,int	regex: find(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool	
+split	regex.html#split.i,string,Regex	regex: split(s: string; sep: Regex): string	
+split	regex.html#split,string,Regex	regex: split(s: string; sep: Regex): seq[string]	
+splitIncl	regex.html#splitIncl,string,Regex	regex: splitIncl(s: string; sep: Regex): seq[string]	
+startsWith	regex.html#startsWith,string,Regex,int	regex: startsWith(s: string; pattern: Regex; start = 0): bool	
+endsWith	regex.html#endsWith,string,Regex	regex: endsWith(s: string; pattern: Regex): bool	
+replace	regex.html#replace,string,Regex,string,int	regex: replace(s: string; pattern: Regex; by: string; limit = 0): string	
+replace	regex.html#replace,string,Regex,proc(RegexMatch,string),int	regex: replace(s: string; pattern: Regex; by: proc (m: RegexMatch; s: string): string;\n        limit = 0): string	
+isInitialized	regex.html#isInitialized,Regex	regex: isInitialized(re: Regex): bool	
+escapeRe	regex.html#escapeRe,string	regex: escapeRe(s: string): string	
diff --git a/docs/regex/common.html b/docs/regex/common.html
new file mode 100644
index 0000000..21c9711
--- /dev/null
+++ b/docs/regex/common.html
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/common</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/common</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#RegexError"
+    title="RegexError = object of ValueError">RegexError</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#10" id="60">Consts</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#invalidRune"
+    title="invalidRune = -1&apos;i32">invalidRune</a></li>
+  <li><a class="reference" href="#lineBreakRune"
+    title="lineBreakRune = 10&apos;i32">lineBreakRune</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section"><=
+      <li><a class="reference" href="#%3C%3D%2CRune%2CRune"
+    title="`&lt;=`(x, y: Rune): bool"><=,<wbr>Rune,<wbr>Rune</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">toRune
+      <li><a class="reference" href="#toRune%2Cstring"
+    title="toRune(s: string): Rune">toRune,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">cmp
+      <li><a class="reference" href="#cmp%2CRune%2CRune"
+    title="cmp(x, y: Rune): int">cmp,<wbr>Rune,<wbr>Rune</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">bwRuneAt
+      <li><a class="reference" href="#bwRuneAt%2Cstring%2Cint"
+    title="bwRuneAt(s: string; n: int): Rune">bwRuneAt,<wbr>string,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">%%
+      <li><a class="reference" href="#%25%25%2Cstring%2CopenArray%5Bstring%5D"
+    title="`%%`(formatstr: string; a: openArray[string]): string">%%,<wbr>string,<wbr>openArray[string]</a></li>
+  <li><a class="reference" href="#%25%25%2Cstring%2Cstring"
+    title="`%%`(formatstr: string; a: string): string">%%,<wbr>string,<wbr>string</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#18" id="68">Templates</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#bwFastRuneAt.t%2Cstring%2Cint%2CRune"
+    title="bwFastRuneAt(s: string; n: var int; result: var Rune): untyped">bwFastRuneAt</a></li>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="RegexError"></a>
+<dt><pre><a href="common.html#RegexError"><span class="Identifier">RegexError</span></a> <span class="Other">=</span> <span class="Keyword">object</span> <span class="Keyword">of</span> <span class="Identifier">ValueError</span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="10">
+<h1><a class="toc-backref" href="#10">Consts</a></h1>
+<dl class="item">
+<a id="invalidRune"></a>
+<dt><pre><a href="common.html#invalidRune"><span class="Identifier">invalidRune</span></a> <span class="Other">=</span> <span class="DecNumber">-1'i32</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="lineBreakRune"></a>
+<dt><pre><a href="common.html#lineBreakRune"><span class="Identifier">lineBreakRune</span></a> <span class="Other">=</span> <span class="DecNumber">10'i32</span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="toRune,string"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#toRune%2Cstring"><span class="Identifier">toRune</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Rune</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="<=,Rune,Rune"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#%3C%3D%2CRune%2CRune"><span class="Identifier">`&lt;=`</span></a><span class="Other">(</span><span class="Identifier">x</span><span class="Other">,</span> <span class="Identifier">y</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="cmp,Rune,Rune"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#cmp%2CRune%2CRune"><span class="Identifier">cmp</span></a><span class="Other">(</span><span class="Identifier">x</span><span class="Other">,</span> <span class="Identifier">y</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="bwRuneAt,string,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#bwRuneAt%2Cstring%2Cint"><span class="Identifier">bwRuneAt</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">n</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Rune</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Take rune ending at <tt class="docutils literal"><span class="pre">n</span></tt>
+
+</dd>
+<a id="%%,string,openArray[string]"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#%25%25%2Cstring%2CopenArray%5Bstring%5D"><span class="Identifier">`%%`</span></a><span class="Other">(</span><span class="Identifier">formatstr</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">a</span><span class="Other">:</span> <span class="Identifier">openArray</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">noSideEffect</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+same as <tt class="docutils literal"><span class="pre">&quot;$#&quot; % [&quot;foo&quot;]</span></tt> but returns empty string on error
+
+</dd>
+<a id="%%,string,string"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#%25%25%2Cstring%2Cstring"><span class="Identifier">`%%`</span></a><span class="Other">(</span><span class="Identifier">formatstr</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">a</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="18">
+<h1><a class="toc-backref" href="#18">Templates</a></h1>
+<dl class="item">
+<a id="bwFastRuneAt.t,string,int,Rune"></a>
+<dt><pre><span class="Keyword">template</span> <a href="#bwFastRuneAt.t%2Cstring%2Cint%2CRune"><span class="Identifier">bwFastRuneAt</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">n</span><span class="Other">:</span> <span class="Keyword">var</span> <span class="Identifier">int</span><span class="Other">;</span> <span class="Identifier">result</span><span class="Other">:</span> <span class="Keyword">var</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
+<dd>
+
+Take rune ending at <tt class="docutils literal"><span class="pre">n</span></tt>
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:28 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/common.idx b/docs/regex/common.idx
new file mode 100644
index 0000000..576d474
--- /dev/null
+++ b/docs/regex/common.idx
@@ -0,0 +1,10 @@
+RegexError	regex/common.html#RegexError	common: RegexError	
+invalidRune	regex/common.html#invalidRune	common: invalidRune	
+lineBreakRune	regex/common.html#lineBreakRune	common: lineBreakRune	
+toRune	regex/common.html#toRune,string	common: toRune(s: string): Rune	
+`&lt;=`	regex/common.html#<=,Rune,Rune	common: `&lt;=`(x, y: Rune): bool	
+cmp	regex/common.html#cmp,Rune,Rune	common: cmp(x, y: Rune): int	
+bwRuneAt	regex/common.html#bwRuneAt,string,int	common: bwRuneAt(s: string; n: int): Rune	
+bwFastRuneAt	regex/common.html#bwFastRuneAt.t,string,int,Rune	common: bwFastRuneAt(s: string; n: var int; result: var Rune): untyped	
+`%%`	regex/common.html#%%,string,openArray[string]	common: `%%`(formatstr: string; a: openArray[string]): string	
+`%%`	regex/common.html#%%,string,string	common: `%%`(formatstr: string; a: string): string	
diff --git a/docs/regex/compiler.html b/docs/regex/compiler.html
new file mode 100644
index 0000000..8c7310f
--- /dev/null
+++ b/docs/regex/compiler.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/compiler</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/compiler</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">reCt
+      <li><a class="reference" href="#reCt%2Cstring"
+    title="reCt(s: string): Regex">reCt,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">reImpl
+      <li><a class="reference" href="#reImpl%2Cstring"
+    title="reImpl(s: string): Regex">reImpl,<wbr>string</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="parser.html">parser</a>, <a class="reference external" href="exptransformation.html">exptransformation</a>, <a class="reference external" href="types.html">types</a>, <a class="reference external" href="nfatype.html">nfatype</a>, <a class="reference external" href="nfa.html">nfa</a>, <a class="reference external" href="litopt.html">litopt</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="reImpl,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#reImpl%2Cstring"><span class="Identifier">reImpl</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="reCt,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#reCt%2Cstring"><span class="Identifier">reCt</span></a><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">compileTime</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/compiler.idx b/docs/regex/compiler.idx
new file mode 100644
index 0000000..9c79cb6
--- /dev/null
+++ b/docs/regex/compiler.idx
@@ -0,0 +1,2 @@
+reImpl	regex/compiler.html#reImpl,string	compiler: reImpl(s: string): Regex	
+reCt	regex/compiler.html#reCt,string	compiler: reCt(s: string): Regex	
diff --git a/docs/regex/dotgraph.html b/docs/regex/dotgraph.html
new file mode 100644
index 0000000..4929425
--- /dev/null
+++ b/docs/regex/dotgraph.html
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/dotgraph</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/dotgraph</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">graphToFile
+      <li><a class="reference" href="#graphToFile%2CRegex%2Cstring"
+    title="graphToFile(regex: Regex; dir: string)">graphToFile,<wbr>Regex,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">graph
+      <li><a class="reference" href="#graph%2CNfa"
+    title="graph(nfa: Nfa): string">graph,<wbr>Nfa</a></li>
+  <li><a class="reference" href="#graph%2CRegex"
+    title="graph(regex: Regex): string">graph,<wbr>Regex</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="nfatype.html">nfatype</a>, <a class="reference external" href="types.html">types</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="graph,Nfa"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#graph%2CNfa"><span class="Identifier">graph</span></a><span class="Other">(</span><span class="Identifier">nfa</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="graph,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#graph%2CRegex"><span class="Identifier">graph</span></a><span class="Other">(</span><span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="graphToFile,Regex,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#graphToFile%2CRegex%2Cstring"><span class="Identifier">graphToFile</span></a><span class="Other">(</span><span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">dir</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">WriteIOEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/dotgraph.idx b/docs/regex/dotgraph.idx
new file mode 100644
index 0000000..72f49b1
--- /dev/null
+++ b/docs/regex/dotgraph.idx
@@ -0,0 +1,3 @@
+graph	regex/dotgraph.html#graph,Nfa	dotgraph: graph(nfa: Nfa): string	
+graph	regex/dotgraph.html#graph,Regex	dotgraph: graph(regex: Regex): string	
+graphToFile	regex/dotgraph.html#graphToFile,Regex,string	dotgraph: graphToFile(regex: Regex; dir: string)	
diff --git a/docs/regex/exptransformation.html b/docs/regex/exptransformation.html
new file mode 100644
index 0000000..beb0a1b
--- /dev/null
+++ b/docs/regex/exptransformation.html
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/exptransformation</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/exptransformation</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#GroupsCapture"
+    title="GroupsCapture = object
+  count*: int16
+  names*: OrderedTable[string, int16]">GroupsCapture</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">toAtoms
+      <li><a class="reference" href="#toAtoms%2CExp%2CGroupsCapture"
+    title="toAtoms(exp: Exp; groups: var GroupsCapture): AtomsExp">toAtoms,<wbr>Exp,<wbr>GroupsCapture</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">transformExp
+      <li><a class="reference" href="#transformExp%2CExp%2CGroupsCapture"
+    title="transformExp(exp: Exp; groups: var GroupsCapture): RpnExp">transformExp,<wbr>Exp,<wbr>GroupsCapture</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="exptype.html">exptype</a>, <a class="reference external" href="types.html">types</a>, <a class="reference external" href="common.html">common</a>, <a class="reference external" href="scanner.html">scanner</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="GroupsCapture"></a>
+<dt><pre><a href="exptransformation.html#GroupsCapture"><span class="Identifier">GroupsCapture</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">count</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+  <span class="Identifier">names</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">OrderedTable</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">,</span> <span class="Identifier">int16</span><span class="Other">]</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="toAtoms,Exp,GroupsCapture"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toAtoms%2CExp%2CGroupsCapture"><span class="Identifier">toAtoms</span></a><span class="Other">(</span><span class="Identifier">exp</span><span class="Other">:</span> <a href="exptype.html#Exp"><span class="Identifier">Exp</span></a><span class="Other">;</span> <span class="Identifier">groups</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="exptransformation.html#GroupsCapture"><span class="Identifier">GroupsCapture</span></a><span class="Other">)</span><span class="Other">:</span> <a href="exptype.html#AtomsExp"><span class="Identifier">AtomsExp</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="transformExp,Exp,GroupsCapture"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#transformExp%2CExp%2CGroupsCapture"><span class="Identifier">transformExp</span></a><span class="Other">(</span><span class="Identifier">exp</span><span class="Other">:</span> <a href="exptype.html#Exp"><span class="Identifier">Exp</span></a><span class="Other">;</span> <span class="Identifier">groups</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="exptransformation.html#GroupsCapture"><span class="Identifier">GroupsCapture</span></a><span class="Other">)</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span>
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/exptransformation.idx b/docs/regex/exptransformation.idx
new file mode 100644
index 0000000..2348f8a
--- /dev/null
+++ b/docs/regex/exptransformation.idx
@@ -0,0 +1,3 @@
+GroupsCapture	regex/exptransformation.html#GroupsCapture	exptransformation: GroupsCapture	
+toAtoms	regex/exptransformation.html#toAtoms,Exp,GroupsCapture	exptransformation: toAtoms(exp: Exp; groups: var GroupsCapture): AtomsExp	
+transformExp	regex/exptransformation.html#transformExp,Exp,GroupsCapture	exptransformation: transformExp(exp: Exp; groups: var GroupsCapture): RpnExp	
diff --git a/docs/regex/exptype.html b/docs/regex/exptype.html
new file mode 100644
index 0000000..faa8ea4
--- /dev/null
+++ b/docs/regex/exptype.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/exptype</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/exptype</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#Exp"
+    title="Exp = object
+  s*: seq[Node]">Exp</a></li>
+  <li><a class="reference" href="#AtomsExp"
+    title="AtomsExp = object
+  s*: seq[Node]">AtomsExp</a></li>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="types.html">types</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="Exp"></a>
+<dt><pre><a href="exptype.html#Exp"><span class="Identifier">Exp</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">s</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="AtomsExp"></a>
+<dt><pre><a href="exptype.html#AtomsExp"><span class="Identifier">AtomsExp</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">s</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:28 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/exptype.idx b/docs/regex/exptype.idx
new file mode 100644
index 0000000..da31e1d
--- /dev/null
+++ b/docs/regex/exptype.idx
@@ -0,0 +1,2 @@
+Exp	regex/exptype.html#Exp	exptype: Exp	
+AtomsExp	regex/exptype.html#AtomsExp	exptype: AtomsExp	
diff --git a/docs/regex/litopt.html b/docs/regex/litopt.html
new file mode 100644
index 0000000..2fad1c0
--- /dev/null
+++ b/docs/regex/litopt.html
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/litopt</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/litopt</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#LitOpt"
+    title="LitOpt = object
+  lit*: Rune
+  nfa*: Nfa">LitOpt</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">litopt2
+      <li><a class="reference" href="#litopt2%2CRpnExp"
+    title="litopt2(exp: RpnExp): LitOpt">litopt2,<wbr>RpnExp</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">canOpt
+      <li><a class="reference" href="#canOpt%2CLitOpt"
+    title="canOpt(litOpt: LitOpt): bool">canOpt,<wbr>LitOpt</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc">Literals optimization. This is about optimizing the find operation by quickly searching Regular Expression literals within the input string. See issue #59.</p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="types.html">types</a>, <a class="reference external" href="nodematch.html">nodematch</a>, <a class="reference external" href="nfa.html">nfa</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="LitOpt"></a>
+<dt><pre><a href="litopt.html#LitOpt"><span class="Identifier">LitOpt</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">lit</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">Rune</span>
+  <span class="Identifier">nfa</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="canOpt,LitOpt"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#canOpt%2CLitOpt"><span class="Identifier">canOpt</span></a><span class="Other">(</span><span class="Identifier">litOpt</span><span class="Other">:</span> <a href="litopt.html#LitOpt"><span class="Identifier">LitOpt</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="litopt2,RpnExp"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#litopt2%2CRpnExp"><span class="Identifier">litopt2</span></a><span class="Other">(</span><span class="Identifier">exp</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a><span class="Other">)</span><span class="Other">:</span> <a href="litopt.html#LitOpt"><span class="Identifier">LitOpt</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/litopt.idx b/docs/regex/litopt.idx
new file mode 100644
index 0000000..17ad921
--- /dev/null
+++ b/docs/regex/litopt.idx
@@ -0,0 +1,3 @@
+LitOpt	regex/litopt.html#LitOpt	litopt: LitOpt	
+canOpt	regex/litopt.html#canOpt,LitOpt	litopt: canOpt(litOpt: LitOpt): bool	
+litopt2	regex/litopt.html#litopt2,RpnExp	litopt: litopt2(exp: RpnExp): LitOpt	
diff --git a/docs/regex/nfa.html b/docs/regex/nfa.html
new file mode 100644
index 0000000..5d48767
--- /dev/null
+++ b/docs/regex/nfa.html
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nfa</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nfa</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">subExps
+      <li><a class="reference" href="#subExps%2CRpnExp"
+    title="subExps(exp: RpnExp): RpnExp">subExps,<wbr>RpnExp</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">eNfa
+      <li><a class="reference" href="#eNfa%2CRpnExp"
+    title="eNfa(exp: RpnExp): Enfa">eNfa,<wbr>RpnExp</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">eRemoval
+      <li><a class="reference" href="#eRemoval%2CEnfa"
+    title="eRemoval(eNfa: Enfa): Nfa">eRemoval,<wbr>Enfa</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">nfa2
+      <li><a class="reference" href="#nfa2%2CRpnExp"
+    title="nfa2(exp: RpnExp): Nfa">nfa2,<wbr>RpnExp</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="types.html">types</a>, <a class="reference external" href="common.html">common</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="eNfa,RpnExp"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#eNfa%2CRpnExp"><span class="Identifier">eNfa</span></a><span class="Other">(</span><span class="Identifier">exp</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Enfa"><span class="Identifier">Enfa</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><a href="common.html#RegexError"><span class="Identifier">RegexError</span></a><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Thompson's construction
+
+</dd>
+<a id="eRemoval,Enfa"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#eRemoval%2CEnfa"><span class="Identifier">eRemoval</span></a><span class="Other">(</span><span class="Identifier">eNfa</span><span class="Other">:</span> <a href="types.html#Enfa"><span class="Identifier">Enfa</span></a><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Remove e-transitions and return remaining state transtions and submatches, and zero matches. Transitions are added in matching order (BFS), which may help matching performance
+
+</dd>
+<a id="subExps,RpnExp"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#subExps%2CRpnExp"><span class="Identifier">subExps</span></a><span class="Other">(</span><span class="Identifier">exp</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a><span class="Other">)</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="nfa2,RpnExp"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#nfa2%2CRpnExp"><span class="Identifier">nfa2</span></a><span class="Other">(</span><span class="Identifier">exp</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><a href="common.html#RegexError"><span class="Identifier">RegexError</span></a><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nfa.idx b/docs/regex/nfa.idx
new file mode 100644
index 0000000..e9f2c56
--- /dev/null
+++ b/docs/regex/nfa.idx
@@ -0,0 +1,4 @@
+eNfa	regex/nfa.html#eNfa,RpnExp	nfa: eNfa(exp: RpnExp): Enfa	
+eRemoval	regex/nfa.html#eRemoval,Enfa	nfa: eRemoval(eNfa: Enfa): Nfa	
+subExps	regex/nfa.html#subExps,RpnExp	nfa: subExps(exp: RpnExp): RpnExp	
+nfa2	regex/nfa.html#nfa2,RpnExp	nfa: nfa2(exp: RpnExp): Nfa	
diff --git a/docs/regex/nfafindall.html b/docs/regex/nfafindall.html
new file mode 100644
index 0000000..d8b15bd
--- /dev/null
+++ b/docs/regex/nfafindall.html
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nfafindall</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nfafindall</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#RegexMatches"
+    title="RegexMatches = object
+  a, b: Submatches
+  m: Matches
+  c: Capts
+  look: Lookaround">RegexMatches</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">dummyMatch
+      <li><a class="reference" href="#dummyMatch%2CRegexMatches%2Cint"
+    title="dummyMatch(ms: var RegexMatches; i: int)">dummyMatch,<wbr>RegexMatches,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">findSomeImpl
+      <li><a class="reference" href="#findSomeImpl%2Cstring%2CRegex%2CRegexMatches%2CNatural%2Cset%5BMatchFlag%5D"
+    title="findSomeImpl(text: string; regex: Regex; ms: var RegexMatches;
+             start: Natural = 0; flags: set[MatchFlag] = {}): int">findSomeImpl,<wbr>string,<wbr>Regex,<wbr>RegexMatches,<wbr>Natural,<wbr>set[MatchFlag]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">fillMatchImpl
+      <li><a class="reference" href="#fillMatchImpl%2CRegexMatch%2CMatchItemIdx%2CRegexMatches%2CRegex"
+    title="fillMatchImpl(m: var RegexMatch; mi: MatchItemIdx; ms: RegexMatches;
+              regex: Regex)">fillMatchImpl,<wbr>RegexMatch,<wbr>MatchItemIdx,<wbr>RegexMatches,<wbr>Regex</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">findSomeOptImpl
+      <li><a class="reference" href="#findSomeOptImpl%2Cstring%2CRegex%2CRegexMatches%2CNatural"
+    title="findSomeOptImpl(text: string; regex: Regex; ms: var RegexMatches; start: Natural): int">findSomeOptImpl,<wbr>string,<wbr>Regex,<wbr>RegexMatches,<wbr>Natural</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#15" id="65">Iterators</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#bounds.i%2CRegexMatches"
+    title="bounds(ms: RegexMatches): Slice[int]">bounds</a></li>
+  <li><a class="reference" href="#items.i%2CRegexMatches"
+    title="items(ms: RegexMatches): MatchItemIdx">items</a></li>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc">Linear time NFA findAll</p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="common.html">common</a>, <a class="reference external" href="nodematch.html">nodematch</a>, <a class="reference external" href="types.html">types</a>, <a class="reference external" href="nfatype.html">nfatype</a>, <a class="reference external" href="nfamatch.html">nfamatch</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="RegexMatches"></a>
+<dt><pre><a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a>
+  <span class="Identifier">m</span><span class="Other">:</span> <span class="Identifier">Matches</span>
+  <span class="Identifier">c</span><span class="Other">:</span> <a href="nfatype.html#Capts"><span class="Identifier">Capts</span></a>
+  <span class="Identifier">look</span><span class="Other">:</span> <a href="nfamatch.html#Lookaround"><span class="Identifier">Lookaround</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="fillMatchImpl,RegexMatch,MatchItemIdx,RegexMatches,Regex"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#fillMatchImpl%2CRegexMatch%2CMatchItemIdx%2CRegexMatches%2CRegex"><span class="Identifier">fillMatchImpl</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">mi</span><span class="Other">:</span> <span class="Identifier">MatchItemIdx</span><span class="Other">;</span> <span class="Identifier">ms</span><span class="Other">:</span> <a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a><span class="Other">;</span>
+                   <span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="dummyMatch,RegexMatches,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#dummyMatch%2CRegexMatches%2Cint"><span class="Identifier">dummyMatch</span></a><span class="Other">(</span><span class="Identifier">ms</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+hack to support <tt class="docutils literal"><span class="pre">split</span></tt> last value. we need to add the end boundary if it has not matched the end (no match implies this too)
+
+</dd>
+<a id="findSomeImpl,string,Regex,RegexMatches,Natural,set[MatchFlag]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#findSomeImpl%2Cstring%2CRegex%2CRegexMatches%2CNatural%2Cset%5BMatchFlag%5D"><span class="Identifier">findSomeImpl</span></a><span class="Other">(</span><span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">ms</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a><span class="Other">;</span>
+                  <span class="Identifier">start</span><span class="Other">:</span> <span class="Identifier">Natural</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">;</span> <span class="Identifier">flags</span><span class="Other">:</span> <span class="Identifier">set</span><span class="Other">[</span><a href="nfatype.html#MatchFlag"><span class="Identifier">MatchFlag</span></a><span class="Other">]</span> <span class="Other">=</span> <span class="Other">{</span><span class="Other">}</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="findSomeOptImpl,string,Regex,RegexMatches,Natural"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#findSomeOptImpl%2Cstring%2CRegex%2CRegexMatches%2CNatural"><span class="Identifier">findSomeOptImpl</span></a><span class="Other">(</span><span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">ms</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a><span class="Other">;</span>
+                     <span class="Identifier">start</span><span class="Other">:</span> <span class="Identifier">Natural</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="15">
+<h1><a class="toc-backref" href="#15">Iterators</a></h1>
+<dl class="item">
+<a id="bounds.i,RegexMatches"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#bounds.i%2CRegexMatches"><span class="Identifier">bounds</span></a><span class="Other">(</span><span class="Identifier">ms</span><span class="Other">:</span> <a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="items.i,RegexMatches"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#items.i%2CRegexMatches"><span class="Identifier">items</span></a><span class="Other">(</span><span class="Identifier">ms</span><span class="Other">:</span> <a href="nfafindall.html#RegexMatches"><span class="Identifier">RegexMatches</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">MatchItemIdx</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nfafindall.idx b/docs/regex/nfafindall.idx
new file mode 100644
index 0000000..3400374
--- /dev/null
+++ b/docs/regex/nfafindall.idx
@@ -0,0 +1,7 @@
+RegexMatches	regex/nfafindall.html#RegexMatches	nfafindall: RegexMatches	
+bounds	regex/nfafindall.html#bounds.i,RegexMatches	nfafindall: bounds(ms: RegexMatches): Slice[int]	
+items	regex/nfafindall.html#items.i,RegexMatches	nfafindall: items(ms: RegexMatches): MatchItemIdx	
+fillMatchImpl	regex/nfafindall.html#fillMatchImpl,RegexMatch,MatchItemIdx,RegexMatches,Regex	nfafindall: fillMatchImpl(m: var RegexMatch; mi: MatchItemIdx; ms: RegexMatches;\n              regex: Regex)	
+dummyMatch	regex/nfafindall.html#dummyMatch,RegexMatches,int	nfafindall: dummyMatch(ms: var RegexMatches; i: int)	
+findSomeImpl	regex/nfafindall.html#findSomeImpl,string,Regex,RegexMatches,Natural,set[MatchFlag]	nfafindall: findSomeImpl(text: string; regex: Regex; ms: var RegexMatches;\n             start: Natural = 0; flags: set[MatchFlag] = {}): int	
+findSomeOptImpl	regex/nfafindall.html#findSomeOptImpl,string,Regex,RegexMatches,Natural	nfafindall: findSomeOptImpl(text: string; regex: Regex; ms: var RegexMatches; start: Natural): int	
diff --git a/docs/regex/nfamacro.html b/docs/regex/nfamacro.html
new file mode 100644
index 0000000..58ea4a1
--- /dev/null
+++ b/docs/regex/nfamacro.html
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nfamacro</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nfamacro</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">matchImpl
+      <li><a class="reference" href="#matchImpl%2CNimNode%2CNimNode%2CNimNode"
+    title="matchImpl(text, expLit, body: NimNode): NimNode">matchImpl,<wbr>NimNode,<wbr>NimNode,<wbr>NimNode</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc">NFA matcher for static regexes</p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="common.html">common</a>, <a class="reference external" href="types.html">types</a>, <a class="reference external" href="nfatype.html">nfatype</a>, <a class="reference external" href="compiler.html">compiler</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="matchImpl,NimNode,NimNode,NimNode"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#matchImpl%2CNimNode%2CNimNode%2CNimNode"><span class="Identifier">matchImpl</span></a><span class="Other">(</span><span class="Identifier">text</span><span class="Other">,</span> <span class="Identifier">expLit</span><span class="Other">,</span> <span class="Identifier">body</span><span class="Other">:</span> <span class="Identifier">NimNode</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">NimNode</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">Exception</span><span class="Other">,</span> <span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nfamacro.idx b/docs/regex/nfamacro.idx
new file mode 100644
index 0000000..228212e
--- /dev/null
+++ b/docs/regex/nfamacro.idx
@@ -0,0 +1 @@
+matchImpl	regex/nfamacro.html#matchImpl,NimNode,NimNode,NimNode	nfamacro: matchImpl(text, expLit, body: NimNode): NimNode	
diff --git a/docs/regex/nfamatch.html b/docs/regex/nfamatch.html
new file mode 100644
index 0000000..6985df7
--- /dev/null
+++ b/docs/regex/nfamatch.html
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nfamatch</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nfamatch</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#Lookaround"
+    title="Lookaround = object
+  ahead*: AheadSig
+  behind*: BehindSig
+  smL*: SmLookaround">Lookaround</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">startsWithImpl
+      <li><a class="reference" href="#startsWithImpl%2Cstring%2CRegex%2Cint"
+    title="startsWithImpl(text: string; regex: Regex; start: int): bool">startsWithImpl,<wbr>string,<wbr>Regex,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">matchImpl
+      <li><a class="reference" href="#matchImpl%2Cstring%2CRegex%2CRegexMatch%2Cint"
+    title="matchImpl(text: string; regex: Regex; m: var RegexMatch; start = 0): bool">matchImpl,<wbr>string,<wbr>Regex,<wbr>RegexMatch,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">reversedMatchImpl
+      <li><a class="reference" href="#reversedMatchImpl%2CSubmatches%2CSubmatches%2Cstring%2CNfa%2CLookaround%2Cint%2Cint"
+    title="reversedMatchImpl(smA, smB: var Submatches; text: string; nfa: Nfa;
+                  look: var Lookaround; start, limit: int): int">reversedMatchImpl,<wbr>Submatches,<wbr>Submatches,<wbr>string,<wbr>Nfa,<wbr>Lookaround,<wbr>int,<wbr>int</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#18" id="68">Templates</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#lookAroundTpl.t"
+    title="lookAroundTpl(): untyped">lookAroundTpl</a></li>
+  <li><a class="reference" href="#initLook.t"
+    title="initLook(): Lookaround">initLook</a></li>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc">NFA matcher for non-static regexes</p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="common.html">common</a>, <a class="reference external" href="nodematch.html">nodematch</a>, <a class="reference external" href="types.html">types</a>, <a class="reference external" href="nfatype.html">nfatype</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="Lookaround"></a>
+<dt><pre><a href="nfamatch.html#Lookaround"><span class="Identifier">Lookaround</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">ahead</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">AheadSig</span>
+  <span class="Identifier">behind</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">BehindSig</span>
+  <span class="Identifier">smL</span><span class="Operator">*</span><span class="Other">:</span> <a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="reversedMatchImpl,Submatches,Submatches,string,Nfa,Lookaround,int,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#reversedMatchImpl%2CSubmatches%2CSubmatches%2Cstring%2CNfa%2CLookaround%2Cint%2Cint"><span class="Identifier">reversedMatchImpl</span></a><span class="Other">(</span><span class="Identifier">smA</span><span class="Other">,</span> <span class="Identifier">smB</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">;</span> <span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">nfa</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a><span class="Other">;</span>
+                       <span class="Identifier">look</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfamatch.html#Lookaround"><span class="Identifier">Lookaround</span></a><span class="Other">;</span> <span class="Identifier">start</span><span class="Other">,</span> <span class="Identifier">limit</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="matchImpl,string,Regex,RegexMatch,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#matchImpl%2Cstring%2CRegex%2CRegexMatch%2Cint"><span class="Identifier">matchImpl</span></a><span class="Other">(</span><span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">m</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">;</span> <span class="Identifier">start</span> <span class="Other">=</span> <span class="DecNumber">0</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="startsWithImpl,string,Regex,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#startsWithImpl%2Cstring%2CRegex%2Cint"><span class="Identifier">startsWithImpl</span></a><span class="Other">(</span><span class="Identifier">text</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">;</span> <span class="Identifier">regex</span><span class="Other">:</span> <a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a><span class="Other">;</span> <span class="Identifier">start</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RootEffect</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="18">
+<h1><a class="toc-backref" href="#18">Templates</a></h1>
+<dl class="item">
+<a id="lookAroundTpl.t"></a>
+<dt><pre><span class="Keyword">template</span> <a href="#lookAroundTpl.t"><span class="Identifier">lookAroundTpl</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">dirty</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="initLook.t"></a>
+<dt><pre><span class="Keyword">template</span> <a href="#initLook.t"><span class="Identifier">initLook</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="nfamatch.html#Lookaround"><span class="Identifier">Lookaround</span></a></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nfamatch.idx b/docs/regex/nfamatch.idx
new file mode 100644
index 0000000..0b87631
--- /dev/null
+++ b/docs/regex/nfamatch.idx
@@ -0,0 +1,6 @@
+Lookaround	regex/nfamatch.html#Lookaround	nfamatch: Lookaround	
+lookAroundTpl	regex/nfamatch.html#lookAroundTpl.t	nfamatch: lookAroundTpl(): untyped	
+reversedMatchImpl	regex/nfamatch.html#reversedMatchImpl,Submatches,Submatches,string,Nfa,Lookaround,int,int	nfamatch: reversedMatchImpl(smA, smB: var Submatches; text: string; nfa: Nfa;\n                  look: var Lookaround; start, limit: int): int	
+initLook	regex/nfamatch.html#initLook.t	nfamatch: initLook(): Lookaround	
+matchImpl	regex/nfamatch.html#matchImpl,string,Regex,RegexMatch,int	nfamatch: matchImpl(text: string; regex: Regex; m: var RegexMatch; start = 0): bool	
+startsWithImpl	regex/nfamatch.html#startsWithImpl,string,Regex,int	nfamatch: startsWithImpl(text: string; regex: Regex; start: int): bool	
diff --git a/docs/regex/nfatype.html b/docs/regex/nfatype.html
new file mode 100644
index 0000000..832ea7b
--- /dev/null
+++ b/docs/regex/nfatype.html
@@ -0,0 +1,552 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nfatype</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nfatype</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#CaptIdx"
+    title="CaptIdx = int32">CaptIdx</a></li>
+  <li><a class="reference" href="#CaptNode"
+    title="CaptNode = object
+  parent*: CaptIdx
+  bound*: int
+  idx*: int16">CaptNode</a></li>
+  <li><a class="reference" href="#Capts"
+    title="Capts = seq[CaptNode]">Capts</a></li>
+  <li><a class="reference" href="#Captures"
+    title="Captures = seq[seq[Slice[int]]]">Captures</a></li>
+  <li><a class="reference" href="#RegexLit"
+    title="RegexLit = distinct string">RegexLit</a></li>
+  <li><a class="reference" href="#Regex"
+    title="Regex = object
+  nfa*: Nfa
+  groupsCount*: int16
+  namedGroups*: OrderedTable[string, int16]
+  litOpt*: LitOpt">Regex</a></li>
+  <li><a class="reference" href="#MatchFlag"
+    title="MatchFlag = enum
+  mfShortestMatch, mfNoCaptures, mfFindMatch, mfFindMatchOpt, mfAnchored,
+  mfBwMatch, mfReverseCapts">MatchFlag</a></li>
+  <li><a class="reference" href="#MatchFlags"
+    title="MatchFlags = set[MatchFlag]">MatchFlags</a></li>
+  <li><a class="reference" href="#RegexMatch"
+    title="RegexMatch = object
+  captures*: Captures
+  namedGroups*: OrderedTable[string, int16]
+  boundaries*: Slice[int]">RegexMatch</a></li>
+  <li><a class="reference" href="#NodeIdx"
+    title="NodeIdx = int16">NodeIdx</a></li>
+  <li><a class="reference" href="#Bounds"
+    title="Bounds = Slice[int]">Bounds</a></li>
+  <li><a class="reference" href="#PState"
+    title="PState = tuple[ni: NodeIdx, ci: CaptIdx, bounds: Bounds]">PState</a></li>
+  <li><a class="reference" href="#Submatches"
+    title="Submatches = ref object
+  sx: seq[PState]
+  ss: seq[int16]
+  si: int16">Submatches</a></li>
+  <li><a class="reference" href="#SmLookaroundItem"
+    title="SmLookaroundItem = object
+  a, b: Submatches">SmLookaroundItem</a></li>
+  <li><a class="reference" href="#SmLookaround"
+    title="SmLookaround = object
+  s: seq[SmLookaroundItem]
+  i: int">SmLookaround</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">setLen
+      <li><a class="reference" href="#setLen%2CSubmatches%2Cint"
+    title="setLen(sm: var Submatches; size: int)">setLen,<wbr>Submatches,<wbr>int</a></li>
+  <li><a class="reference" href="#setLen%2CSmLookaroundItem%2Cint"
+    title="setLen(item: var SmLookaroundItem; size: int)">setLen,<wbr>SmLookaroundItem,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">constructSubmatches
+      <li><a class="reference" href="#constructSubmatches%2CCaptures%2CCapts%2Cint%2Cint"
+    title="constructSubmatches(captures: var Captures; capts: Capts; capt, size: int)">constructSubmatches,<wbr>Captures,<wbr>Capts,<wbr>int,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">len
+      <li><a class="reference" href="#len%2CSubmatches"
+    title="len(sm: Submatches): int">len,<wbr>Submatches</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">add
+      <li><a class="reference" href="#add%2CSubmatches%2CPState"
+    title="add(sm: var Submatches; item: PState)">add,<wbr>Submatches,<wbr>PState</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">hasState
+      <li><a class="reference" href="#hasState%2CSubmatches%2Cint16"
+    title="hasState(sm: Submatches; n: int16): bool">hasState,<wbr>Submatches,<wbr>int16</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">removeLast
+      <li><a class="reference" href="#removeLast%2CSmLookaround"
+    title="removeLast(sm: var SmLookaround)">removeLast,<wbr>SmLookaround</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">clear
+      <li><a class="reference" href="#clear%2CRegexMatch"
+    title="clear(m: var RegexMatch)">clear,<wbr>RegexMatch</a></li>
+  <li><a class="reference" href="#clear%2CSubmatches"
+    title="clear(sm: var Submatches)">clear,<wbr>Submatches</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">grow
+      <li><a class="reference" href="#grow%2CSmLookaround"
+    title="grow(sm: var SmLookaround)">grow,<wbr>SmLookaround</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">reverse
+      <li><a class="reference" href="#reverse%2CCapts%2Cint32%2Cint32"
+    title="reverse(capts: var Capts; a, b: int32): int32">reverse,<wbr>Capts,<wbr>int32,<wbr>int32</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">cap
+      <li><a class="reference" href="#cap%2CSubmatches"
+    title="cap(sm: Submatches): int">cap,<wbr>Submatches</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">[]
+      <li><a class="reference" href="#%5B%5D%2CSubmatches%2Cint"
+    title="`[]`(sm: Submatches; i: int): PState">[],<wbr>Submatches,<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">newSubmatches
+      <li><a class="reference" href="#newSubmatches%2Cint"
+    title="newSubmatches(size: int): Submatches">newSubmatches,<wbr>int</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#15" id="65">Iterators</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#items.i%2CSubmatches"
+    title="items(sm: Submatches): PState">items</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#18" id="68">Templates</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#last.t%2CSmLookaround"
+    title="last(sm: var SmLookaround): untyped">last</a></li>
+  <li><a class="reference" href="#lastA.t%2CSmLookaround"
+    title="lastA(sm: var SmLookaround): untyped">lastA</a></li>
+  <li><a class="reference" href="#lastB.t%2CSmLookaround"
+    title="lastB(sm: var SmLookaround): untyped">lastB</a></li>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc">Types used by the NFA</p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="types.html">types</a>, <a class="reference external" href="litopt.html">litopt</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="CaptIdx"></a>
+<dt><pre><a href="nfatype.html#CaptIdx"><span class="Identifier">CaptIdx</span></a> <span class="Other">=</span> <span class="Identifier">int32</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="CaptNode"></a>
+<dt><pre><a href="nfatype.html#CaptNode"><span class="Identifier">CaptNode</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">parent</span><span class="Operator">*</span><span class="Other">:</span> <a href="nfatype.html#CaptIdx"><span class="Identifier">CaptIdx</span></a>
+  <span class="Identifier">bound</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int</span>
+  <span class="Identifier">idx</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Capts"></a>
+<dt><pre><a href="nfatype.html#Capts"><span class="Identifier">Capts</span></a> <span class="Other">=</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nfatype.html#CaptNode"><span class="Identifier">CaptNode</span></a><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Captures"></a>
+<dt><pre><a href="nfatype.html#Captures"><span class="Identifier">Captures</span></a> <span class="Other">=</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span><span class="Other">]</span><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="RegexLit"></a>
+<dt><pre><a href="nfatype.html#RegexLit"><span class="Identifier">RegexLit</span></a> <span class="Other">=</span> <span class="Keyword">distinct</span> <span class="Identifier">string</span></pre></dt>
+<dd>
+
+raw regex literal string
+
+</dd>
+<a id="Regex"></a>
+<dt><pre><a href="nfatype.html#Regex"><span class="Identifier">Regex</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">nfa</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a>
+  <span class="Identifier">groupsCount</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+  <span class="Identifier">namedGroups</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">OrderedTable</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">,</span> <span class="Identifier">int16</span><span class="Other">]</span>
+  <span class="Identifier">litOpt</span><span class="Operator">*</span><span class="Other">:</span> <a href="litopt.html#LitOpt"><span class="Identifier">LitOpt</span></a>
+</pre></dt>
+<dd>
+
+a compiled regular expression
+
+</dd>
+<a id="MatchFlag"></a>
+<dt><pre><a href="nfatype.html#MatchFlag"><span class="Identifier">MatchFlag</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
+  <span class="Identifier">mfShortestMatch</span><span class="Other">,</span> <span class="Identifier">mfNoCaptures</span><span class="Other">,</span> <span class="Identifier">mfFindMatch</span><span class="Other">,</span> <span class="Identifier">mfFindMatchOpt</span><span class="Other">,</span> <span class="Identifier">mfAnchored</span><span class="Other">,</span>
+  <span class="Identifier">mfBwMatch</span><span class="Other">,</span> <span class="Identifier">mfReverseCapts</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="MatchFlags"></a>
+<dt><pre><a href="nfatype.html#MatchFlags"><span class="Identifier">MatchFlags</span></a> <span class="Other">=</span> <span class="Identifier">set</span><span class="Other">[</span><a href="nfatype.html#MatchFlag"><span class="Identifier">MatchFlag</span></a><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="RegexMatch"></a>
+<dt><pre><a href="nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">captures</span><span class="Operator">*</span><span class="Other">:</span> <a href="nfatype.html#Captures"><span class="Identifier">Captures</span></a>
+  <span class="Identifier">namedGroups</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">OrderedTable</span><span class="Other">[</span><span class="Identifier">string</span><span class="Other">,</span> <span class="Identifier">int16</span><span class="Other">]</span>
+  <span class="Identifier">boundaries</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span>
+</pre></dt>
+<dd>
+
+result from matching operations
+
+</dd>
+<a id="NodeIdx"></a>
+<dt><pre><a href="nfatype.html#NodeIdx"><span class="Identifier">NodeIdx</span></a> <span class="Other">=</span> <span class="Identifier">int16</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Bounds"></a>
+<dt><pre><a href="nfatype.html#Bounds"><span class="Identifier">Bounds</span></a> <span class="Other">=</span> <span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">int</span><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="PState"></a>
+<dt><pre><a href="nfatype.html#PState"><span class="Identifier">PState</span></a> <span class="Other">=</span> <span class="Keyword">tuple</span><span class="Other">[</span><span class="Identifier">ni</span><span class="Other">:</span> <a href="nfatype.html#NodeIdx"><span class="Identifier">NodeIdx</span></a><span class="Other">,</span> <span class="Identifier">ci</span><span class="Other">:</span> <a href="nfatype.html#CaptIdx"><span class="Identifier">CaptIdx</span></a><span class="Other">,</span> <span class="Identifier">bounds</span><span class="Other">:</span> <a href="nfatype.html#Bounds"><span class="Identifier">Bounds</span></a><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Submatches"></a>
+<dt><pre><a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a> <span class="Other">=</span> <span class="Keyword">ref</span> <span class="Keyword">object</span>
+  <span class="Identifier">sx</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nfatype.html#PState"><span class="Identifier">PState</span></a><span class="Other">]</span>
+  <span class="Identifier">ss</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">int16</span><span class="Other">]</span>
+  <span class="Identifier">si</span><span class="Other">:</span> <span class="Identifier">int16</span>
+</pre></dt>
+<dd>
+
+Parallel states would be a better name. This is a sparse set
+
+</dd>
+<a id="SmLookaroundItem"></a>
+<dt><pre><a href="nfatype.html#SmLookaroundItem"><span class="Identifier">SmLookaroundItem</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="SmLookaround"></a>
+<dt><pre><a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nfatype.html#SmLookaroundItem"><span class="Identifier">SmLookaroundItem</span></a><span class="Other">]</span>
+  <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="constructSubmatches,Captures,Capts,int,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#constructSubmatches%2CCaptures%2CCapts%2Cint%2Cint"><span class="Identifier">constructSubmatches</span></a><span class="Other">(</span><span class="Identifier">captures</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#Captures"><span class="Identifier">Captures</span></a><span class="Other">;</span> <span class="Identifier">capts</span><span class="Other">:</span> <a href="nfatype.html#Capts"><span class="Identifier">Capts</span></a><span class="Other">;</span> <span class="Identifier">capt</span><span class="Other">,</span> <span class="Identifier">size</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
+    <span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="reverse,Capts,int32,int32"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#reverse%2CCapts%2Cint32%2Cint32"><span class="Identifier">reverse</span></a><span class="Other">(</span><span class="Identifier">capts</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#Capts"><span class="Identifier">Capts</span></a><span class="Other">;</span> <span class="Identifier">a</span><span class="Other">,</span> <span class="Identifier">b</span><span class="Other">:</span> <span class="Identifier">int32</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int32</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+reverse capture indices from a to b; return head
+
+</dd>
+<a id="clear,RegexMatch"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#clear%2CRegexMatch"><span class="Identifier">clear</span></a><span class="Other">(</span><span class="Identifier">m</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#RegexMatch"><span class="Identifier">RegexMatch</span></a><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="newSubmatches,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#newSubmatches%2Cint"><span class="Identifier">newSubmatches</span></a><span class="Other">(</span><span class="Identifier">size</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="[],Submatches,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#%5B%5D%2CSubmatches%2Cint"><span class="Identifier">`[]`</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">;</span> <span class="Identifier">i</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <a href="nfatype.html#PState"><span class="Identifier">PState</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="hasState,Submatches,int16"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#hasState%2CSubmatches%2Cint16"><span class="Identifier">hasState</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">;</span> <span class="Identifier">n</span><span class="Other">:</span> <span class="Identifier">int16</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="add,Submatches,PState"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#add%2CSubmatches%2CPState"><span class="Identifier">add</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">;</span> <span class="Identifier">item</span><span class="Other">:</span> <a href="nfatype.html#PState"><span class="Identifier">PState</span></a><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="len,Submatches"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#len%2CSubmatches"><span class="Identifier">len</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="clear,Submatches"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#clear%2CSubmatches"><span class="Identifier">clear</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="cap,Submatches"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#cap%2CSubmatches"><span class="Identifier">cap</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="setLen,Submatches,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#setLen%2CSubmatches%2Cint"><span class="Identifier">setLen</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">;</span> <span class="Identifier">size</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="setLen,SmLookaroundItem,int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#setLen%2CSmLookaroundItem%2Cint"><span class="Identifier">setLen</span></a><span class="Other">(</span><span class="Identifier">item</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#SmLookaroundItem"><span class="Identifier">SmLookaroundItem</span></a><span class="Other">;</span> <span class="Identifier">size</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span>
+    <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="grow,SmLookaround"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#grow%2CSmLookaround"><span class="Identifier">grow</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="removeLast,SmLookaround"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#removeLast%2CSmLookaround"><span class="Identifier">removeLast</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="15">
+<h1><a class="toc-backref" href="#15">Iterators</a></h1>
+<dl class="item">
+<a id="items.i,Submatches"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#items.i%2CSubmatches"><span class="Identifier">items</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <a href="nfatype.html#Submatches"><span class="Identifier">Submatches</span></a><span class="Other">)</span><span class="Other">:</span> <a href="nfatype.html#PState"><span class="Identifier">PState</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="18">
+<h1><a class="toc-backref" href="#18">Templates</a></h1>
+<dl class="item">
+<a id="last.t,SmLookaround"></a>
+<dt><pre><span class="Keyword">template</span> <a href="#last.t%2CSmLookaround"><span class="Identifier">last</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="lastA.t,SmLookaround"></a>
+<dt><pre><span class="Keyword">template</span> <a href="#lastA.t%2CSmLookaround"><span class="Identifier">lastA</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="lastB.t,SmLookaround"></a>
+<dt><pre><span class="Keyword">template</span> <a href="#lastB.t%2CSmLookaround"><span class="Identifier">lastB</span></a><span class="Other">(</span><span class="Identifier">sm</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="nfatype.html#SmLookaround"><span class="Identifier">SmLookaround</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">untyped</span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nfatype.idx b/docs/regex/nfatype.idx
new file mode 100644
index 0000000..b7fd88c
--- /dev/null
+++ b/docs/regex/nfatype.idx
@@ -0,0 +1,40 @@
+CaptIdx	regex/nfatype.html#CaptIdx	nfatype: CaptIdx	
+CaptNode	regex/nfatype.html#CaptNode	nfatype: CaptNode	
+Capts	regex/nfatype.html#Capts	nfatype: Capts	
+Captures	regex/nfatype.html#Captures	nfatype: Captures	
+constructSubmatches	regex/nfatype.html#constructSubmatches,Captures,Capts,int,int	nfatype: constructSubmatches(captures: var Captures; capts: Capts; capt, size: int)	
+reverse	regex/nfatype.html#reverse,Capts,int32,int32	nfatype: reverse(capts: var Capts; a, b: int32): int32	
+RegexLit	regex/nfatype.html#RegexLit	nfatype: RegexLit	
+Regex	regex/nfatype.html#Regex	nfatype: Regex	
+mfShortestMatch	regex/nfatype.html#mfShortestMatch	MatchFlag.mfShortestMatch	
+mfNoCaptures	regex/nfatype.html#mfNoCaptures	MatchFlag.mfNoCaptures	
+mfFindMatch	regex/nfatype.html#mfFindMatch	MatchFlag.mfFindMatch	
+mfFindMatchOpt	regex/nfatype.html#mfFindMatchOpt	MatchFlag.mfFindMatchOpt	
+mfAnchored	regex/nfatype.html#mfAnchored	MatchFlag.mfAnchored	
+mfBwMatch	regex/nfatype.html#mfBwMatch	MatchFlag.mfBwMatch	
+mfReverseCapts	regex/nfatype.html#mfReverseCapts	MatchFlag.mfReverseCapts	
+MatchFlag	regex/nfatype.html#MatchFlag	nfatype: MatchFlag	
+MatchFlags	regex/nfatype.html#MatchFlags	nfatype: MatchFlags	
+RegexMatch	regex/nfatype.html#RegexMatch	nfatype: RegexMatch	
+clear	regex/nfatype.html#clear,RegexMatch	nfatype: clear(m: var RegexMatch)	
+NodeIdx	regex/nfatype.html#NodeIdx	nfatype: NodeIdx	
+Bounds	regex/nfatype.html#Bounds	nfatype: Bounds	
+PState	regex/nfatype.html#PState	nfatype: PState	
+Submatches	regex/nfatype.html#Submatches	nfatype: Submatches	
+newSubmatches	regex/nfatype.html#newSubmatches,int	nfatype: newSubmatches(size: int): Submatches	
+`[]`	regex/nfatype.html#[],Submatches,int	nfatype: `[]`(sm: Submatches; i: int): PState	
+hasState	regex/nfatype.html#hasState,Submatches,int16	nfatype: hasState(sm: Submatches; n: int16): bool	
+add	regex/nfatype.html#add,Submatches,PState	nfatype: add(sm: var Submatches; item: PState)	
+len	regex/nfatype.html#len,Submatches	nfatype: len(sm: Submatches): int	
+clear	regex/nfatype.html#clear,Submatches	nfatype: clear(sm: var Submatches)	
+items	regex/nfatype.html#items.i,Submatches	nfatype: items(sm: Submatches): PState	
+cap	regex/nfatype.html#cap,Submatches	nfatype: cap(sm: Submatches): int	
+setLen	regex/nfatype.html#setLen,Submatches,int	nfatype: setLen(sm: var Submatches; size: int)	
+SmLookaroundItem	regex/nfatype.html#SmLookaroundItem	nfatype: SmLookaroundItem	
+SmLookaround	regex/nfatype.html#SmLookaround	nfatype: SmLookaround	
+setLen	regex/nfatype.html#setLen,SmLookaroundItem,int	nfatype: setLen(item: var SmLookaroundItem; size: int)	
+last	regex/nfatype.html#last.t,SmLookaround	nfatype: last(sm: var SmLookaround): untyped	
+lastA	regex/nfatype.html#lastA.t,SmLookaround	nfatype: lastA(sm: var SmLookaround): untyped	
+lastB	regex/nfatype.html#lastB.t,SmLookaround	nfatype: lastB(sm: var SmLookaround): untyped	
+grow	regex/nfatype.html#grow,SmLookaround	nfatype: grow(sm: var SmLookaround)	
+removeLast	regex/nfatype.html#removeLast,SmLookaround	nfatype: removeLast(sm: var SmLookaround)	
diff --git a/docs/regex/nimdoc.out.css b/docs/regex/nimdoc.out.css
new file mode 100644
index 0000000..4ee73ea
--- /dev/null
+++ b/docs/regex/nimdoc.out.css
@@ -0,0 +1,891 @@
+/*
+Stylesheet for use with Docutils/rst2html.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+
+Modified from Chad Skeeters' rst2html-style
+https://bitbucket.org/cskeeters/rst2html-style/
+
+Modified by Boyd Greenfield and narimiran
+*/
+
+:root {
+  --primary-background: #fff;
+  --secondary-background: ghostwhite;
+  --third-background: #e8e8e8;
+  --border: #dde;
+  --text: #222;
+  --anchor: #07b;
+  --anchor-focus: #607c9f;
+  --input-focus: #1fa0eb;
+  --strong: #3c3c3c;
+  --hint: #9A9A9A;
+  --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAN4AAAA9CAYAAADCt9ebAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjAzOjQ4KzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMjoyODo0MSswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MzMzNGYwMWEtMjAxMS1hNTRkLTk1YzctYjk4MTAxZTAxYTJhIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozMzM0ZjAxYS0yMDExLWE1NGQtOTVjNy1iOTgxMDFlMDFhMmEiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MDM6NDgrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4PsixkAAAJ5klEQVR4nO2dfbBUZR3HP3vvxVD0zo0ACXxBuQMoQjJ1DfMl0NIhNcuSZqQhfGt6UWtK06xJexkrmywVRTQlHCIdtclC0zBJvYIvvEUgZpc3XyC7RVbKlQu1/fHdbc+uu2fPOfs85+y55/nMnBl2z+5zfnc5v/M8z+8119XVRYroAG4HfgvMT1YUR4MMAa4HLkhakCRoSVqAELwLeBY4C7gF+D6QS1QiR1ROAJ4Dzk9akKQwoXhtwL4GxvHjU8AKoNPz3leAu4HBFq+bAyZZHD9rDAK+BywDDklYlkQxoXhfAtYAEw2MVckQYBHwU6or99nA08BBFq49GngUeBIYaWH8rNEJdAOXA60Jy5I4jSreSOBKYDzwBPCJhiUqcSjwe2BWnc9NLnxuvMFrnwqsAqYBBwBfNzh2FpmNfs9jkhakWcg1aFxZiH5UL3cDnwf+Xue7BwFjgFHAOwuv24tyob3cO0LIshP4EbCn8Pq/wKvA9sLxMvCvOmPsA1yDZnHv/nEv2mM+F0IeR4m8z7lM7tMbUbzj0CxX7YfbAXwaWFJ4PRrNIu9FS9KJyEIZN68CG4DnkRJtLBw7gHHAYuDdNb77EDAjBhkHIk7xKoiqeK3IwjilzuceQJvoZjdQ/AMZaeoZiWYgBXSEwyleBW0Rv3cR9ZUO4LSI48fN2wN+bi5wJNBvUZaBSCaVy48oxpVhwDdMC5ISxpJRh6/DLGEUrxXt29YBQ+2IkwquR76ofZIWxJFegireNLSnm48skFmmDfmiVgJHJyuKI620ADOpbWEcDPwYOZKD7OmyxCTkXL+wzueOiEEWR8poQb60V4A7kLm/yFjgKeALuM1xLfYDbkX+zEGe98cAX0Oui6viF8vR7OS6urragW2UZr21wK+Aiwlu7XPoN3sYOAd4H6WH1SnA0qSEcjQnRT/e1bgnsw16kGPez4/lyCBF48oNwL+TFGSAsgCndI4qFBVvJ0owdZhjL3CnxfHzBo8+YBMyol0CHBijrKbHS/LoA7Yio9sPgJNr/QHekLGR6MffL+KP4SjnHmQxtoXNmbQP+CHyV75hYDzTIWNpWkU8iR5mq71vVsZqXgtcFqNQ/wG2IOtfD8oi6AX+Ujj+isKz8sBrnu+1okyGdmD/wnEgcDClTIdRyJRvI1cvCMciq7At4rj5eoCPAusbHCfLigda/VyKgi+AtyreMGAzykGzQQ/wO+BxSlkCuy1dq8hw5OieUjimYT+x9bHCdWwS1823Ez1EXmhgjKwrXpHzkduuanbCtzGX+NkPPAj8GincNkPjNkIO5dadUjiOB95m+BonopQpm8R58/0JJbHWy2eshVM8sRvdbyurKV4Hmoka2WA/iwwLP6d+QmzSdKC92GzK/W9R+Q3woQbHCELcN991wJcjftcpXolngKm18vFmoVonYcgDv0Qz5pqGREuOTuA8lPYUZbndh0LJNpkUqgZx33xvomim7RG+6xSvnOm1gqQXoyiMoKxFs8VZpFfpQHvQK4HDUPnAsBa9bxGP0tUjF+IYCkxFew+/G3owdq20pgjzt3uPRscs/o43IaOhH2f4ZaAPRyZQP6vgbuCbyGext87F0sgIZFI/N8BnlwBnolovcWAjq/uzwM0+55cBJ0UYN84ZL+rfbnLMM4FfUDv7Z1XlCe8FetETbleNL7+CZrnvMjCVDuTOOA84Hf+96ga0PC8qXY50FQsuMg+41+d8p885R4n7gdt8zo+qvDkmUF4fZQXwEbS+99KDMhlWkw0eALqQglXyDDCdcovf+4lv5jPNXJ9zWc/FDMMdPudGVCreRlTWwVtWbynwYVQQCFSp61Q042WJLUjB1nneuw8tvXo97x1Lugvg+j1Mo9boySLVHtJFWqsthx5GlbSGeN5bigrHdqPl52Zj4qWLXvTQWY4KOX2ccgPMBLRcuy9+0YzhguXN4GuYq2Zc2R/NZg+hfYt3/9ZCepdQthmB4vIWIYOTbWyWzGt2Y0izG1fqjlltxnsdpbPMRMmd3lqTTumqMw7FZY5G5mSHw5dalreiRWYGWjbZ7gYUlFa0xOtIWA4vk1E6zWEoI+FvyYrjSAO1FG8DCmQGKd+DJFsGogWVVFiP/GWbga9Svg9NgtPQvnd04fUNCcriSBF+vqZ5nn9PQ+Xs4q401oI6EP0R+BkyXoAeAtcgBfwidnvkVaMVFTO6n1JoWTfqiONw1MVP8e6l3GVwOPJZXW5VItGGiuduAu5CZdOrMQJ1CHqpIFccS+LxaD/3Hcr7vF0Xw7UdAwQ/xduLGkJ6aUMhVAuwU006B3wM+ZLmozJ5QRhWkGs9yjKw1fhwDsq8eE/F+y+i1CeHIxD1wppupXrA5xyUOjQHMzU3cyjTeS2aaaN2Fzoc1bhch3xspuqBTkDulQVUz1q4mYEbNuewQD3FexGFS1VjOLoRHwOOinj9HAooXY2CSidHHKeSI5GFcRWNdSxqR7VH1iHHeTV24R+X53C8hSCBvPPqnD8B+AOygn6OYAm0ORSGthLl8B0d4DtRmIKsoMsJF1U/Hi1dt6DusIN8PrsIlUdwOAITpDFlC6q3MTbgmHm011qGepOvQSXPipyOCujW6rxqk0dRWYsVFe8PRSn5JxWOoEvdfOGzfnF5tnCRK+bGi33MoB1hL0U5d1H5J5oVD6A5mp8sQS6KSWh5e0jEcR4BPmhKqJA4xTM3XuxjBlW8DuRacDU3y0myNbNTPHPjxT5m0GTN15A/zVFiI+HKYzgc/ydMlrRfgmQWuYn0F91xJEQYxVuDnMcOrQAWJi2EI72ErQviwqLEQpQ+5XBEIqzi3YWLwF+BMiMcjshEqYR1Gdk1KmxBsaR9SQviSDdRFK8fxVU+YliWZmcbcq7vSFoQR/qJWvuxD0WgLDYoSzPzAqowtjVhORwDhEaKru4GPoliGgcyy4Hj0DLT4TBCo9WO88jQ8Bns97lLghvRTOfqqDiMYqrM+HyUYdBtaLykeRmlK12C9rQOh1FM1vd/HqUIzaT5e+LVoh/VxByHShs6HFaw0VjjHhTxP5d0LT+fRnu5q3HuAodlbHW02Q5cDByM+sw1642cRylCx6PeZiuTFScUFxK+f19QovaRS+t4tsasxhvABbZbSfUCV6CM7qtQl6Fm4E1U22UqcAYqvZ42fgJMxH6vdYc5nkBlSW6Pq4fbS6hb6jg0u9yGug7FyS5U1+UcVBbwbFSuMM1sQ1bXK4A9CcviqM0e9H80HdUxCpwIa4McygA/GfgAcCJqmGKKXUixupEv7nHsLc2agWNQ0d9OzC+PHNHIo1XeLCoe8kkqXiUtwKFoWXoEKqk3BpWLaC8cXsV8HT1J+tFTZKvn+DMqFZi1knvtyKg1O2lBHADcCVxEedNSAP4HJcsr0NNWHVUAAAAASUVORK5CYII=");
+
+  --keyword: #5e8f60;
+  --identifier: #222;
+  --comment: #484a86;
+  --operator: #155da4;
+  --punctuation: black;
+  --other: black;
+  --escapeSequence: #c4891b;
+  --number: #252dbe;
+  --literal: #a4255b;
+  --raw-data: #a4255b;
+}
+
+[data-theme="dark"] {
+  --primary-background: #171921;
+  --secondary-background: #1e202a;
+  --third-background: #2b2e3b;
+  --border: #0e1014;
+  --text: #fff;
+  --anchor: #8be9fd;
+  --anchor-focus: #8be9fd;
+  --input-focus: #8be9fd;
+  --strong: #bd93f9;
+  --hint: #7A7C85;
+  --nim-sprite-base64: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARMAAABMCAYAAABOBlMuAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFFmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTEyLTAzVDAxOjE4OjIyKzAxOjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0xMi0wM1QwMToyMDoxMCswMTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQyNDQtYTExZi0yMjc5YmY4NDNhYTAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ZWRlYjM1NzAtYjZmYy1kMjQ0LWExMWYtMjI3OWJmODQzYWEwIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZWRlYjM1NzAtYjZmYy1kMjQ0LWExMWYtMjI3OWJmODQzYWEwIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDplZGViMzU3MC1iNmZjLWQyNDQtYTExZi0yMjc5YmY4NDNhYTAiIHN0RXZ0OndoZW49IjIwMTktMTItMDNUMDE6MTg6MjIrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4JZNR8AAAfG0lEQVR4nO2deViTZ7r/7yxkJaxJ2MK+GCBAMCwS1kgUFQSKK4XWWqsz1jpjp3b0tDP1V+eqU391fqfT/mpPPd20drTFDS0KFEVWJSGAEgLIZpAICBJACIRs549Rj1WILAkBfD/XlevySp68z/0S3+/7vPdzLyidTgcLkU2bd+z39/f/q1gshsrKSoJELFCa2iaEuU9K6kb+8uXxv54/fzE8L/eswNT2zCfQpjbAGKS8lPFKSEjIXiaTCSEhIeDj4xNnapsQ5j6rktZGp6UlfxIdzQVzCplmanvmG1hTG2BIAtlc26CgoDfT0tL2e3l5AQCAjY0NkMnk/a9s2k6rrKw8UV8n1JjYTIQ5RlAw14KzmL3xze1vfJyUuMJaq9UCFovFm9qu+YbBxcSPFUYkk8l2Q0NDsvo6ocrQx5+I8Ih4bz6f/0l8fHyKlZXV4/dRKBQwmcwwMpn8A4FAoPgHhH9bV1sxa488wZxoaycnJ/a9e/duCa5fkc3WvAiTI4Ib77p+XdqHG9anbfLy8gAAgLGxMdBpF+bjvzExqJj4scKI0dHRnwQHB++orq7+AgDeMuTxJ2Jl4rqU9PT0EwEBAUQCgTDuGAaDAampqYepVKpHUHDk325Ulw0a266YuFW+Gzdu/MDPz29jfn7+XgA4aOw5ESZP6kvpCXv3vnM8NiaSamVl+fj9BepGNDoGFRN7e/slcXFxO1xcXMDJyWnH7j//H/fi4uJdgutXmgw5z5O8smn7X9euXbvf29sbMBjMhONQKBRYWVlBbGzsbjMzM3JoOG+/sKKwy1h2rd/4elpGRsYuLy+vaDweD2w2Oy1h5ZrCvEunEaeeiVnMiabyl/F2/+X9P+8JDPQHHA5napMWBAYTk6DgSNuEhIS9DAYDAP7tq1i6dOkqOp3OWbNu0wens44emeoxA9lcWwKBYEMkEm2JRKIdHo+3QKFQWJ1Op8ZgMER3d/dVq1evTnFycpr0MSkUCsTExGzH4/Gk1LTME/39/TI0Go1FoVCg1WrVY2NjipGRkcGRkRH5dPwrEZHLXMPCwjJSUlIy3dzcfB+97+rqGhYSEpIOAIiYmBguN3zL77dt3uPh4W5qUxYUBhMTb2/vjeHh4cvR6P/dILK0tITIyEg7BweHr363/Z3Ampqaf1Zcu/zMKiVsyVJvMplsRyKR7IhEor2FhYUbhUJhJCYm2pFIJB6JRAIymQx4PB7QaDRoNBowMzMDJycnwOOn7icjEokQGxu7icFgbLp///7jFY1WqwWlUgkjIyOgUCgO7Ni5Rz48PCwfHh7uGRkZeaBQKOSjo6ODCoVCXlNVKn/6uCsT13FXrVr1emho6BYKhfLMnP7+/omrU9LPX8g+UThloxEMxqJFXjxESAyPQcSEExrLWLNmzW57e/txP/fw8ABHR8cdDAaDt3xF2ru9vb03sVgs0cbGxs/FxWVZUlISj0aj+dna2oKtrS1M5PcwJCgUCry8vODRrs84vPfoH6OjoyCXy6Gvr+/R6+CWrX9s7evrk/b19bWr1Wqli4sLZ8OGDe95eXmxUSjUuAd0cHDwjoqK2sYKXFIhvnldYYTTQpgU4/8+jyASCYDGoCd+ZkYYF8OICYezl8PhuOkbQyAQIDo62s/NzS2np6cHbGxsgEajAYFAAAwGA1gsFia6CE0NgUAABwcHsLe3B61WC2q1eo9WqwWNRgNKpRLUajUQiUSgUCh6zwGHwwGTydzo5+eXBQBnZu8MEJ5keHhYPqyYWMtHR0ZBpVIhYj9FUDONgOUvT12+du3avMDAQJjssdRqNWCxCyrEZdLodDoQi8Ulx44de628NL/V1Pa8iERE8l2dHB2CJvpcq9Nqbt1qKURWj1Njxld0ZGTkAW9v70kLCQC8sEIC8O/HKx8fn2gmk8kHgCk7pRFmzrWyAikASE1tx0Jj2uH0EZHL/N7YtuvT4OBgzmz4OBYSeDweIiMjt2S++vtMP1YYEmmJsCCY8mNOIJtr6+zsHBcZGXmIw+G4mZubG8m0hU9HRwcUFxe/KxQKTyDRsQjznSmJCS9+dVRERMTfQ0NDo2xtbfUGiSFMjtHRUaitrc3Jzc09kHvxVLmp7UFAmC6oZQkvrZLL5RJhReHtiQb5scKIXC7371FRUX90dnYGIpE4JR8Jgn40Gg20t7fXFxYWfnr9+vWjz8sdYi+Osh4vzgUBwZSgtu94V+fs7Hx7YGCgra6u7khLS0u2RCwYeTQgKmYFh8fj/f/g4OAldnZ2prR1wdPd3Q1CofBQSUnJkdLi3N8E93FCY6k+Pj48FxcXjlar1ZSWlh65VvYr4kREmDNg79+/D3FxcW5OTk5uXl5evNbW1tL0jK3ZXV1d1ykUintycvInoaGhdkj+gvGxs7MDPp+/m0AgWMQvS/lyeHhYTqPRPJycnIJSU1NZ3t7eW2g0Gly/fv2oWq1Gij0hzClQ/gHhpLS0tEM8Hm/7I8Ho7++HlpYWsLa2Bg8PDxOb+OKhUCigqakJ7t+/D25ubuDu7g4oFAp0Oh08ePAAvv7666TTWUdzTG0nAsKTYMU3ryuSU18+4+bmFrZo0SIOAICVlRUsXrx4zkakLnRIJBI8CgJ8MtdJp9NBZ2enqL29XWRC8xAQxgUNAHD+3L8KGhoaCp78ABES04JCoX4jJAAAAwMDUFtbe96YpRMQEKbL41DU5ubmko6Ojj2PSgggzD36+/vrb9y4cX425zzw93/8EBjon2is44+NjSkePBjqGRwc7G5v7xBV19w8U5B/3qgrr9+/uWtXUuKKD/TZ9MXh/066/OuFmunO8dGBQ98HBbGSp/t9U6LRaDXK0dHBoeFhuVzeL22/0yFqamopufjLqRJ933ssJi0tLSXV1dWHGAzGbuObOzs8ubqa71vZKpUKOjo6blwpOF8zm/Mu5cVkLlkSaswprAHAaVihgK7O7oSGxltvfXLon3nXK4RHT2cdN4pfKDCAlZyUuMJan02nTmczAaBmunPw4qI3cbnh0/36XICq0+lgcPABp7OrK629vUP5z8++LLh2XXD05L++yxrvC4/F5EZ12WBS8saLS5Ys2U2lUufUY45SqQSlUgkqlQrUavXj19jYGGg0GtBoNKDT6UCn05VotVq1TqfToFAojFar1eh0Og0Wi8XhcDgeGo1+/PhgZmYGOBwOsFgsmJmZ/eY1F+nt7YXa2trs2Z73wdCQBgCMHp1IJpHA09MdPD3dLRIS+OtKisvWvbP7vf2lZdePVFwzbHTwyMiI3hidkZFRUKvUYzOZ48HQkBIA5nWqBAqFAktLC7C0tADmIh88Pz4uMSyUk7hn776DV4tKPn/6d/lNxp1MJqsRCASf8vn8XdMpOjRTVCoVjI2NgUqlAq1WCyMjI9DX1wf379+Hvr6+/Q8ePOgdGRmRKxSKx0WLFAqFXKlUKnQ6nUar1arHq47mxwrD4/F4Eg6HI2GxWDwej7cgkUjWFAqFam5uTjU3N6eRyeQPLSwswNraGqysrIBAIDwWFywW+zja11Qi29LSclIikeSZZPJZBovBAI8XA8HBQR9kZZ3lR8cmvFZSlGe00p8IkwONRkNERBj4+i7a4+XpHv307/IbMakWlciXJbx0nMPh7Jqo0JGh0el0MDo6Cl1dXSCVSkEmk7177969W319fe1DQ0M9KpVKoVarlWq1WjndNhUPG3ApAWDcOxLTLwSDwWAOotFoDBaLxRMIBAsrKysne3t7Xzqd7k2n0/c4OzsDlUoFHA4364IyMDAATU1NxdWikhcq6tXKyhJezljPJZKI2eERS5cZeoWCMD2srCwhPX0tVzk2djiCG//GtfLLUoBxShB0dHTU3Lx580sLC4vtJBLJKMZoNBqQSqUglUqPdnR01PT09DT19/fLHjx40DM0NNQ72933GiSVGgB4JFQK+LfoSAGgnL04yppEIh2xtLS0t7GxcaFSqR7Ozs4fMRgMcHR0nJX8pJs3b54Ui8UXjT7RHIRMIkFK8irfwcEHPwQELUmqvYHUGJkLmJubw8YNa/i9vfffY/px3myQiDTPiEl9nVDDX576jaenZ7SnpyfLUJNrNBqQyWRw+/bt4x0dHTdkMlltV1dXw/XygjkdEv4wB0YOAK0AUM70C8HQ6fSzdDrdm0qlejg6OrLc3Ny2MBiMadWjfR4PHjyAmzdvZs/1v5MxoVAokJK8iicWS95k+nH+s0EiQhqpzQGoVFtYk5a87ba0XQAA34xbpagg/5zoT7s/OGNnZ8eaaYkBuVwOnZ2d5VKpVNTS0lLS2NhYWFVZ3Dujg5qQh6uY+ocvCAiKIPn4+Jz19PSMdnV15VCpVL6Dg4NBViw6nQ5EItHRpqamqzM+2DzHzo4O69amftLQeKsAZrDLgmBY/PyYsCIhfs+SiKUFE5Y8EwqFx11cXDihoaFTjjFAoVAwPDwMHR0dourq6jNCofDHhZqUVnvjmgIAcgAgJyg40mLRokX8kJCQjT4+PussLS1n1JPl7t27UFxcfHguB6mNjY2B7G4naNRTWyygUCjAYDGAx+PB0sICSCSi3vFYLBbCwjjA8vddBQtATKb7d3saBwc7IJPJBpsHjUGDGRYLJBIJLK0sAfucmyIGg4FFi3y8AwNZtycUk5KiS02vvf7WWQaDkejg4DApQwAeh3xDaWnpPoFAcPxFqnP6sEvgGf+A8Bx3d/cvIyIiNi1evHjT8wpNj8fAwACUlZW9P9dD5+/ckcFbf9gd2dcnn9LNAovF4inmZHtXNxdOdBR3+/JlS33pdP29wolEInA4weuiYxOy5vvuTkeHDHb+8c8xvb33Z3R9/N+Df+uIjYk02DwkEsna2trS1d/fNyGeF7uTyw1/7g3R3t4O2OxA/TVghULhcQqFQk1JSfmYSNR/5wD4d6EfgUBwvLS09IhUKhW9qAV5H9YjKQwJi6uvrKw8ERoamhkSEpKp7w7yJEqlEiQSyZmysrJv53qjdaVSCZdyTk+3qFMrAJRHRPLPN95qeifj5fU7mYt8JhyMRqMhMJDFdnF25gDAvBYTpXIMWlpay2fq/8m5mDcIABYGnEcGAGI/VlhBZWX1yZdSkz55OX0dV5+7w9bGGvz8mPrFpK62QskJjf2GTqd7x8bGbpnID4BCoUAmk0lLSkqOiESik2UleS/MakQflYKrXQDQxY1a3tTe3i6KiIjY5OXlxX7e9+rr6wsuXbr0t4ffn9OgMWjghMZQRcLp+8GulRVI/QPC37Wxtnal0ajJtjY2E451ZjiBra31vE9lR2PQQKFQaAAwo98Yi8Xq9fpPd56HO6rlvKWJv/PwcK+JilyCmajWMw6HAzs7+rMFpQOCIn6zHywSFvXm5eUdFAqFZ9Rq9bgHa2trq79w4cK+zz49cAARkmcpL81v/a/Dhz49d+7c3qqqqjyVSjXuOJ1OBxKJpDw3N/fA5V+zax6978cKw/sHhM/raMrnUVdboSy4fPWQSFSjd5yFBQWIRNKEd2IEw1J4JUd88WL+R51d3XrHWVDMnxUTa2tr1zXrNiUGsrmPf7DS4tymCxcu7Kuurs55+kKQSqVN586d23vs+8NHDXUCC5Wzp3/Iy8rKeruysvLM2Nhvo7VVKhXU1tYWnj17du/T7UOdnZ2D7OzsfGGB09raVi4S1RzXl0eFw+EAj8chYjKLVFffyOrq1C8mJBLpWTFRKBRyDofzC4vFWvXk+1ev/CLOzs7eKxAIslQqFeh0Oujp6enKzs7em/XTd7OayTqfKb56sT4rK+sPAoHg5KO/o0KhAKFQmHXy5MkdF3/5+TeZmctXpIXZ29v7zqVcKWNRX1epuXu3U/y8pEw0GmndOZt0dnXVDw0P6/W5oNHoZ30mQ0NDPb29vfvj4+Pf3rR5B/7od188XnEUXr4gDgmL+0NfX5/U19d3d3l5+YGfTnyDtLmcIhXXLsu4UcvfR6PRGGtra9eysrIjYrE45+kt4Fheou/69es/unnz5vm7d+/Wmsre2WRkZGTQ1DYg/JYGiUiTm1ugBAC9IfHPiEmDpFITE7fqJI/H27lmzZpDq5LWtz55t6wUXO3ihMYerK+vz2tpaUFaM0yT8tL81ujYle+TSCTrvEunBU9/voTLd92wYcPHVCqV39XVdXCu7+oYCp1O90Kc50Jk3I5+xVcv1jc3N5d4enpSMzIyvkpK3sh78nORsKg3++yPBS/q1q+hKCm61DSekERGJ3ikp6d/ERsbm1xVVXWwtbX1hRFtFAqFPMLMUyZsDyoQCI7LZDKIiIjwzczM/GpV0vro2TTsRSUqZoX3+vXrP1u9enXi0NAQiESirIdRtggIc5oJ40zq6uryGhoa8ry8vBJCQ0O9USjU94mrN7yWc+EnvaXb5gJMvxCMp6cnl0Kh2Le1tZVXXLs8L1LXefGrWRkZGZ/x+XyeUqkEkUh0vqenZ14HZyG8OEwoJjdrygd37NxTEBkZmWBtbQ3BwcEeKBTq+/UbX3/355Pfzlmn66qk9dGbN29+k8PhbCSRSNDZ2Snb9ae/HCkpKTksEhbN2QTD5NSX+Vu3bj0cHBzsjcFg4O7du1BWVvbNwxB9BIQ5j94I2Fu3bhXW19cDl8sFLBYLHA7Hg0wmf/e77e84ffXlPz6fLSMnQ2paZkJ4eHjmtm3b+B4eHvZkMhlQKBTY29s72dvbfxgUFJT8x7ffP1NRUfHjXErnZ/qFYKKjo7dt3rz5g8DAQPtH/XHa2tpqGhsbC55/BASEuYFeMblz505NTU3NgfDw8PcwGAygUCjw9fW1IJPJn/1130Hv0tLSI4WXL4hny9inYS+Osvbz80tgMpn8jIwMPovFch2vpoiDgwM4ODhwfH19OYsWLeJv3/Hu+cbGxquzXZz5aZYlvMRJT0/fFhkZue3JZmfd3d0gEolOIr4ShPmEXjFpkFRqXlrzSnFnZ+d7Tk5OjzNfXVxcICMjY6ezszNnVdL6vU8HWhmbgKAIkrOzMyc1NTXz0YU4maAuOp0OK1as4EVFRfGEQqHg1dfePHzr1q2rs71S8WOF4f38/BLS09M/iIyM5DxdxLq5uVlcVVU1bgVwBIS5il4xAQCQyWRigUBwJikpKe3JVGQcDgdLly7l2tranti0ecf7IpEoy9hbxX6sMDydTvdevXr1ltjY2F3u7u6AxT73FJ7B3Nwc4uLiwthsdphQKCzZkL7l0/r6+oKbNeVG90+EhMXZL1++fFtycvKHrq6uz4igUqmE5ubmEiTHCWG+8dwrUXD9imz9xtd/jIuLS7N5KpsTjUZDUFCQE4PB+F4oFGYmJW888Mv5k4UTHGpGxC9LYaenp78VEhKyxdHRESgUyoyOh0KhwNraGuLi4qIDAgKi6+rqyjekb/mHMSN6N6RvSdu+ffseNpsdZm09ftuW+vp6EIvFSB9hhHnHpG7rUqm0orW1tdXS0tLj6TIEaDQaaDQaxMfH811dXTl/3Xfw+JUrVz411J01cfWG6IiIiC07d+5McHNzs7ewMGyOFw6HAwcHB6BSqVx3d/fwz7/4rkAgEBwXCoUnHpZonDGrU9J5MTEx27du3Zrm4uKC0beaqq6u/ry+vj7XEPMiIMwmkxKTimuXZe/u+fCkp6fnexPdUfF4PPj7+1szGIydLi4unF1/+kvenTt3RG1tbRXTqfma8lIG39/fP/HVV19NZrFYHpMpzjQTzMzMwNPTE+Pp6Zng6emZ4Ofnl5CesfV8bW1tznQe3/wDwvFeXl7Rvr6+Ca+88kpaUFCQh74GXzqdDrq7u6GpqankRQmdR1hYTNrhUFVVlcXj8d6ysrKy0OfstLS0hPj4eC6Xy+U2NzeDRCI5/sa2XeX37t1rGhwc7BoYGJBN1P+FFbiE5OzszGaxWImvvvrqpoCAAKfp+ERmCpPJBCaTmcnhcDJLS0u/TE59+YxUKhXoi/lg+oVgrKysGJaWlna2trYeaWlpXDabvTMgIGDSfp2KiorzbW1tL0zoPMLCYtJX6uVfs2u++PKowMPDgz+ZIslEIhECAgKAxWJlajSazJ6eHmhra4PW1tZvtmz9o6Czs7O+r6+vfWxsbFir1WosLCzsV6xYkcnj8d7z9vaelmPV0Hh5eYGnp+f2mJiY7UVFRZ/HL0v5tru7+5ZGo1FisVg8Docj4fF4CxsbG1c+nx/m7e39sYeHB7i4uIC5ufmU6r4ODQ1BZWXlifkSrYuA8DRTumIrKytPent78728vCb9HRQKBVgsFhwcHIBOpwObzd4yNja2RaVSwdDQEHR1dcHo6CjQaDRwdXWdsWPV0KBQKPDw8AA7O7udERERO2tra2FgYACoVCo4OTkBjUYDMpkMeDz+8WuqaLVaaGxsbL19+/YzSX8ICPOFqYrJidDQ0AwvLy/e80c/CwaDARKJBI86BdJoNHB3dwe1Wj0nViL6IJPJwGQywdnZGZRKJRAIBDBUx8OBgQEoLS39BtkORpjPTJg1PB61N64pmpqarvb39xvUiLkuJE9CJpPBxsbGYEICANDZ2SlHgtQQ5jtTEhMAgLq6ulyJRFJvDGNeREZGRkAikRSUFuci2cEI85opi0l+7hmBWCzOeV6dToTJcfv27cHr168jxbgR5j1TFhMAgObm5hKZDNl0MAQtLS3Xzpw6hkS8Isx7piUmUqlUIBAIJuyjgzA5Ojs7QSKRINGuCAuCaYmJsKKw68qVK59KJJIu5HFneiiVSigqKjouEolOmtoWBARDMC0xAQC4+MvPJadOnXq3ra1N8yL0dDEkOp0OSktLy/Pz8w8+3d4CAWG+Mm0xAQA4fuy/jl+8ePGju3fvGsqeBY9Wq4XKysrWU6dOvX31yi8mKyyFgGBoZiQmAAD/79D+fadPn96PCMrz0el0UFVV1frtt9+mj9fiAgFhPjNjMQEAyMvLO3Ds2LE/tLS0INmuerh27Vr9999//xoiJAgLEYOEntbVVigB4PNNm3cMpqSkfMRms50McdyFgkqlgqKiovJTp069nZ97BhEShAWJQePYj373xdF1GzbLFQrFx6Ghob766ne8KNy7dw+KiopO5ubmfmTK4tsICMbG4EkxWT99d35l4rre/v7+D0NCQvh0Ot3QU8wL1Go1SKVSTX5+/sH8/PyDSP8bhIWOUTLsLuVklQcFR65pbGzcvnLlyvfc3NwsCASCMaaac+h0OhgaGoLq6uqaCxcu/OV01tGcTw7uM7VZCAhGx2jpug/vxAd58atzoqKitq1cuXKnvb29saabE+h0Oqiurpbm5eUdrK6uPlspuDrvY0hmO4YIhUIBGq1/X2CmNqFQKL3/79HomZ/z82xEowyy9zFr80zGDqPn/hdeviBmL47ad+fOnRsRERGbQkNDo62srIw97azT2dkJxcXFx0tKSo7Mdh8hY4LD4TDPH2U4MFjMc6tLmZmZzaj+Aw6H0/t9PB4PGCxmRudNJBL0ngeZTAI0Gj3jv+1szfM88Hic8cUEAKCmqlQOAN/ELU2qkEgkySwWK3HRokVcBoMxG9MbDZ1OB83NzdDU1FRQW1t7XiAQHJ+ovu18pbr6Rg6L5ZtoM0EhcUPT0tJW8tWRb0vQqIkvgKqqmhnVfrl2TfANXo+gjKlUio4OWc1M5sjOzjnQUH8rbqLPu3t6moaGhmfc+3q25tGHUqmECoEIUKbIrVkcEkONiIh4jcvlvu7s7OxLo9GmVe7QVCgUCujq6oKGhoaCioqKo9XV1WeM3YDMVPDik1gpyas+XrVyeaKXl8czjyANjbcgI/MNmkg49Q4ECPOH3NyC4RUr+M8IcHt7B1y9WlKRl3/5kElKnD1sfXEoJCzueEBAQGJYWFgGk8nk2djYAIFAgLm4pTw6Ogqjo6Mgl8vhxo0b50tLS4/U19fnLvS2FIWXfxEDQNLmLW9ueW1TxtchHDaQyWRTm4VgYkZHR6G+vhF+/NfP+y5e+vVjiVgwZpKVydOwF0dZW1lZOTGZTD6bzU4LCAiIptPp8HTDL1MwOjoKLS0tUFdXd1IsFudIpdKKgYGB7tloJTrX4MUnsVJTEj9etzY10dHRAQAAGm81wcsZW5CVyQInL69gNCGBjwcAGBx8ANnncypOnTr3H9nn/reD55wovvrQpyIHAHFUzIocGo3mQaPRfBwdHVlubm7bXF1dgcFgABqNNvruglwuh7t374JMJoOOjo7P79y5I+ru7m7q7e1tXQi7MzOh8PIv4pCw2DdaWtte37Au7aPIyCWAxWABjUbPif9HCMbjURtKiaQBfvr5zH9evlJ0uLQ4r/nJMXNiZTIRrMAlJAcHB18HBweWo6Mjy8rKajeJRAJLS0uwtLQECwsLoFAogMfjAYvFgpmZ2XNXMyqVCoaHh2FoaAiGh4cfvwYGBqCvrw+6u7vfvnfvXlNvb29rT09Pq0QsUM7S6c4rNqS/lrZ5U+YPRBKR9M7u9xwqBUUvtNAudH766XSLE8PR49ixE78/8tVnX403Zk7fUR46NUUAIPIPCMdTKJTdNjY2QKPRgE6nA51OB1tbWyCRSIDD4YBAIAAejwcCgfDYUajVakGlUoFarQadTvfY79HX1wf9/f0gl8tBLpfDvXv3HvXw+dxQPYYXMj+d+P7Mmzv+5OHr6/OJWq1GBHeB09TcUiKuq/coKS3/eqIx/wPkiIXC3w6YjAAAAABJRU5ErkJggg==");
+
+  --keyword: #ff79c6;
+  --identifier: #f8f8f2;
+  --comment: #6272a4;
+  --operator: #ff79c6;
+  --punctuation: #f8f8f2;
+  --other: #f8f8f2;
+  --escapeSequence: #bd93f9;
+  --number: #bd93f9;
+  --literal: #f1fa8c;
+  --raw-data: #8be9fd;
+}
+
+.theme-switch-wrapper {
+  display: flex;
+  align-items: center;
+
+  em {
+    margin-left: 10px;
+    font-size: 1rem;
+  }
+}
+.theme-switch {
+  display: inline-block;
+  height: 22px;
+  position: relative;
+  width: 50px;
+}
+
+.theme-switch input {
+  display: none;
+}
+
+.slider {
+  background-color: #ccc;
+  bottom: 0;
+  cursor: pointer;
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  transition: .4s;
+}
+
+.slider:before {
+  background-color: #fff;
+  bottom: 4px;
+  content: "";
+  height: 13px;
+  left: 4px;
+  position: absolute;
+  transition: .4s;
+  width: 13px;
+}
+
+input:checked + .slider {
+  background-color: #66bb6a;
+}
+
+input:checked + .slider:before {
+  transform: translateX(26px);
+}
+
+.slider.round {
+  border-radius: 17px;
+}
+
+.slider.round:before {
+  border-radius: 50%;
+}
+
+html {
+  font-size: 100%;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%; }
+
+body {
+  font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
+  font-weight: 400;
+  font-size: 1.125em;
+  line-height: 1.5;
+  color: var(--text);
+  background-color: var(--primary-background); }
+
+/* Skeleton grid */
+.container {
+  position: relative;
+  width: 100%;
+  max-width: 1050px;
+  margin: 0 auto;
+  padding: 0;
+  box-sizing: border-box; }
+
+.column,
+.columns {
+  width: 100%;
+  float: left;
+  box-sizing: border-box;
+  margin-left: 1%;
+}
+
+.column:first-child,
+.columns:first-child {
+  margin-left: 0; }
+
+.three.columns {
+  width: 19%; }
+
+.nine.columns {
+  width: 80.0%; }
+
+.twelve.columns {
+  width: 100%;
+  margin-left: 0; }
+
+@media screen and (max-width: 860px) {
+  .three.columns {
+    display: none;
+  }
+  .nine.columns {
+    width: 98.0%;
+  }
+  body {
+    font-size: 1em;
+    line-height: 1.35;
+  }
+}
+
+cite {
+  font-style: italic !important; }
+
+
+/* Nim search input */
+div#searchInputDiv {
+  margin-bottom: 1em;
+}
+input#searchInput {
+  width: 80%;
+}
+
+/*
+ * Some custom formatting for input forms.
+ * This also fixes input form colors on Firefox with a dark system theme on Linux.
+ */
+input {
+  -moz-appearance: none;
+  background-color: var(--secondary-background);
+  color: var(--text);
+  border: 1px solid var(--border);
+  font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
+  font-size: 0.9em;
+  padding: 6px;
+}
+
+input:focus {
+  border: 1px solid var(--input-focus);
+  box-shadow: 0 0 3px var(--input-focus);
+}
+
+select {
+  -moz-appearance: none;
+  background-color: var(--secondary-background);
+  color: var(--text);
+  border: 1px solid var(--border);
+  font-family: "Lato", "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
+  font-size: 0.9em;
+  padding: 6px;
+}
+
+select:focus {
+  border: 1px solid var(--input-focus);
+  box-shadow: 0 0 3px var(--input-focus);
+}
+
+/* Docgen styles */
+/* Links */
+a {
+  color: var(--anchor);
+  text-decoration: none;
+}
+
+a span.Identifier {
+  text-decoration: underline;
+  text-decoration-color: #aab;
+}
+
+a.reference-toplevel {
+  font-weight: bold;
+}
+
+a.toc-backref {
+  text-decoration: none;
+  color: var(--text); }
+
+a.link-seesrc {
+  color: #607c9f;
+  font-size: 0.9em;
+  font-style: italic; }
+
+a:hover,
+a:focus {
+  color: var(--anchor-focus);
+  text-decoration: underline; }
+
+a:hover span.Identifier {
+  color: var(--anchor);
+}
+
+
+sub,
+sup {
+  position: relative;
+  font-size: 75%;
+  line-height: 0;
+  vertical-align: baseline; }
+
+sup {
+  top: -0.5em; }
+
+sub {
+  bottom: -0.25em; }
+
+img {
+  width: auto;
+  height: auto;
+  max-width: 100%;
+  vertical-align: middle;
+  border: 0;
+  -ms-interpolation-mode: bicubic; }
+
+@media print {
+  * {
+    color: black !important;
+    text-shadow: none !important;
+    background: transparent !important;
+    box-shadow: none !important; }
+
+  a,
+  a:visited {
+    text-decoration: underline; }
+
+  a[href]:after {
+    content: " (" attr(href) ")"; }
+
+  abbr[title]:after {
+    content: " (" attr(title) ")"; }
+
+  .ir a:after,
+  a[href^="javascript:"]:after,
+  a[href^="#"]:after {
+    content: ""; }
+
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid; }
+
+  thead {
+    display: table-header-group; }
+
+  tr,
+  img {
+    page-break-inside: avoid; }
+
+  img {
+    max-width: 100% !important; }
+
+  @page {
+    margin: 0.5cm; }
+
+  h1 {
+    page-break-before: always; }
+
+  h1.title {
+    page-break-before: avoid; }
+
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3; }
+
+  h2,
+  h3 {
+    page-break-after: avoid; }
+}
+
+
+p {
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+}
+
+small {
+  font-size: 85%; }
+
+strong {
+  font-weight: 600;
+  font-size: 0.95em;
+  color: var(--strong);
+}
+
+em {
+  font-style: italic; }
+
+h1 {
+  font-size: 1.8em;
+  font-weight: 400;
+  padding-bottom: .25em;
+  border-bottom: 6px solid var(--third-background);
+  margin-top: 2.5em;
+  margin-bottom: 1em;
+  line-height: 1.2em; }
+
+h1.title {
+  padding-bottom: 1em;
+  border-bottom: 0px;
+  font-size: 2.5em;
+  text-align: center;
+  font-weight: 900;
+  margin-top: 0.75em;
+  margin-bottom: 0em;
+}
+
+h2 {
+  font-size: 1.3em;
+  margin-top: 2em; }
+
+h2.subtitle {
+  text-align: center; }
+
+h3 {
+  font-size: 1.125em;
+  font-style: italic;
+  margin-top: 1.5em; }
+
+h4 {
+  font-size: 1.125em;
+  margin-top: 1em; }
+
+h5 {
+  font-size: 1.125em;
+  margin-top: 0.75em; }
+
+h6 {
+  font-size: 1.1em; }
+
+
+ul,
+ol {
+  padding: 0;
+  margin-top: 0.5em;
+  margin-left: 0.75em; }
+
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+  margin-bottom: 0;
+  margin-left: 1.25em; }
+
+li {
+    list-style-type: circle;
+}
+
+ul.simple-boot li {
+    list-style-type: none;
+    margin-left: 0em;
+    margin-bottom: 0.5em;
+}
+
+ol.simple > li, ul.simple > li {
+  margin-bottom: 0.25em;
+  margin-left: 0.4em }
+
+ul.simple.simple-toc > li {
+    margin-top: 1em;
+}
+
+ul.simple-toc {
+  list-style: none;
+  font-size: 0.9em;
+  margin-left: -0.3em;
+  margin-top: 1em; }
+
+ul.simple-toc > li {
+    list-style-type: none;
+}
+
+ul.simple-toc-section {
+  list-style-type: circle;
+  margin-left: 1em;
+  color: #6c9aae; }
+
+
+ol.arabic {
+  list-style: decimal; }
+
+ol.loweralpha {
+  list-style: lower-alpha; }
+
+ol.upperalpha {
+  list-style: upper-alpha; }
+
+ol.lowerroman {
+  list-style: lower-roman; }
+
+ol.upperroman {
+  list-style: upper-roman; }
+
+ul.auto-toc {
+  list-style-type: none; }
+
+
+dl {
+  margin-bottom: 1.5em; }
+
+dt {
+  margin-bottom: -0.5em;
+  margin-left: 0.0em; }
+
+dd {
+  margin-left: 2.0em;
+  margin-bottom: 3.0em;
+  margin-top: 0.5em; }
+
+
+hr {
+  margin: 2em 0;
+  border: 0;
+  border-top: 1px solid #aaa; }
+
+blockquote {
+  font-size: 0.9em;
+  font-style: italic;
+  padding-left: 0.5em;
+  margin-left: 0;
+  border-left: 5px solid #bbc;
+}
+
+.pre {
+  font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;
+  font-weight: 500;
+  font-size: 0.85em;
+  color: var(--text);
+  background-color: var(--third-background);
+  padding-left: 3px;
+  padding-right: 3px;
+  border-radius: 4px;
+}
+
+pre {
+  font-family: "Source Code Pro", Monaco, Menlo, Consolas, "Courier New", monospace;
+  color: var(--text);
+  font-weight: 500;
+  display: inline-block;
+  box-sizing: border-box;
+  min-width: 100%;
+  padding: 0.5em;
+  margin-top: 0.5em;
+  margin-bottom: 0.5em;
+  font-size: 0.85em;
+  white-space: pre !important;
+  overflow-y: hidden;
+  overflow-x: visible;
+  background-color: var(--secondary-background);
+  border: 1px solid var(--border);
+  -webkit-border-radius: 6px;
+  -moz-border-radius: 6px;
+  border-radius: 6px; }
+
+.pre-scrollable {
+  max-height: 340px;
+  overflow-y: scroll; }
+
+
+/* Nim line-numbered tables */
+.line-nums-table {
+  width: 100%;
+  table-layout: fixed; }
+
+table.line-nums-table {
+  border-radius: 4px;
+  border: 1px solid #cccccc;
+  background-color: ghostwhite;
+  border-collapse: separate;
+  margin-top: 15px;
+  margin-bottom: 25px; }
+
+.line-nums-table tbody {
+  border: none; }
+
+.line-nums-table td pre {
+  border: none;
+  background-color: transparent; }
+
+.line-nums-table td.blob-line-nums {
+  width: 28px; }
+
+.line-nums-table td.blob-line-nums pre {
+  color: #b0b0b0;
+  -webkit-filter: opacity(75%);
+  text-align: right;
+  border-color: transparent;
+  background-color: transparent;
+  padding-left: 0px;
+  margin-left: 0px;
+  padding-right: 0px;
+  margin-right: 0px; }
+
+
+table {
+  max-width: 100%;
+  background-color: transparent;
+  margin-top: 0.5em;
+  margin-bottom: 1.5em;
+  border-collapse: collapse;
+  border-color: var(--third-background);
+  border-spacing: 0;
+  font-size: 0.9em;
+}
+
+table th, table td {
+  padding: 0px 0.5em 0px;
+  border-color: var(--third-background);
+}
+
+table th {
+  background-color: var(--third-background);
+  border-color: var(--third-background);
+  font-weight: bold; }
+
+table th.docinfo-name {
+    background-color: transparent;
+}
+
+table tr:hover {
+  background-color: var(--third-background); }
+
+
+/* rst2html default used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+  border: 0; }
+
+table.borderless td, table.borderless th {
+  /* Override padding for "table.docutils td" with "! important".
+     The right padding separates the table cells. */
+  padding: 0 0.5em 0 0 !important; }
+
+.first {
+  /* Override more specific margin styles with "! important". */
+  margin-top: 0 !important; }
+
+.last, .with-subtitle {
+  margin-bottom: 0 !important; }
+
+.hidden {
+  display: none; }
+
+blockquote.epigraph {
+  margin: 2em 5em; }
+
+dl.docutils dd {
+  margin-bottom: 0.5em; }
+
+object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
+  overflow: hidden; }
+
+
+div.figure {
+  margin-left: 2em;
+  margin-right: 2em; }
+
+div.footer, div.header {
+  clear: both;
+  text-align: center;
+  color: #666;
+  font-size: smaller; }
+
+div.footer {
+    padding-top: 5em;
+}
+
+div.line-block {
+  display: block;
+  margin-top: 1em;
+  margin-bottom: 1em; }
+
+div.line-block div.line-block {
+  margin-top: 0;
+  margin-bottom: 0;
+  margin-left: 1.5em; }
+
+div.topic {
+  margin: 2em; }
+
+div.search_results {
+  background-color: antiquewhite;
+  margin: 3em;
+  padding: 1em;
+  border: 1px solid #4d4d4d;
+}
+
+div#global-links ul {
+  margin-left: 0;
+  list-style-type: none;
+}
+
+div#global-links > simple-boot {
+    margin-left: 3em;
+}
+
+hr.docutils {
+  width: 75%; }
+
+img.align-left, .figure.align-left, object.align-left {
+  clear: left;
+  float: left;
+  margin-right: 1em; }
+
+img.align-right, .figure.align-right, object.align-right {
+  clear: right;
+  float: right;
+  margin-left: 1em; }
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto; }
+
+.align-left {
+  text-align: left; }
+
+.align-center {
+  clear: both;
+  text-align: center; }
+
+.align-right {
+  text-align: right; }
+
+/* reset inner alignment in figures */
+div.align-right {
+  text-align: inherit; }
+
+p.attribution {
+  text-align: right;
+  margin-left: 50%; }
+
+p.caption {
+  font-style: italic; }
+
+p.credits {
+  font-style: italic;
+  font-size: smaller; }
+
+p.label {
+  white-space: nowrap; }
+
+p.rubric {
+  font-weight: bold;
+  font-size: larger;
+  color: maroon;
+  text-align: center; }
+
+p.topic-title {
+  font-weight: bold; }
+
+pre.address {
+  margin-bottom: 0;
+  margin-top: 0;
+  font: inherit; }
+
+pre.literal-block, pre.doctest-block, pre.math, pre.code {
+  margin-left: 2em;
+  margin-right: 2em; }
+
+pre.code .ln {
+  color: grey; }
+
+/* line numbers */
+pre.code, code {
+  background-color: #eeeeee; }
+
+pre.code .comment, code .comment {
+  color: #5c6576; }
+
+pre.code .keyword, code .keyword {
+  color: #3B0D06;
+  font-weight: bold; }
+
+pre.code .literal.string, code .literal.string {
+  color: #0c5404; }
+
+pre.code .name.builtin, code .name.builtin {
+  color: #352b84; }
+
+pre.code .deleted, code .deleted {
+  background-color: #DEB0A1; }
+
+pre.code .inserted, code .inserted {
+  background-color: #A3D289; }
+
+span.classifier {
+  font-style: oblique; }
+
+span.classifier-delimiter {
+  font-weight: bold; }
+
+span.option {
+  white-space: nowrap; }
+
+span.problematic {
+  color: #b30000; }
+
+span.section-subtitle {
+  /* font-size relative to parent (h1..h6 element) */
+  font-size: 80%; }
+
+span.DecNumber {
+  color: var(--number); }
+
+span.BinNumber {
+  color: var(--number); }
+
+span.HexNumber {
+  color: var(--number); }
+
+span.OctNumber {
+  color: var(--number); }
+
+span.FloatNumber {
+  color: var(--number); }
+
+span.Identifier {
+  color: var(--identifier); }
+
+span.Keyword {
+  font-weight: 600;
+  color: var(--keyword); }
+
+span.StringLit {
+  color: var(--literal); }
+
+span.LongStringLit {
+  color: var(--literal); }
+
+span.CharLit {
+  color: var(--literal); }
+
+span.EscapeSequence {
+  color: var(--escapeSequence); }
+
+span.Operator {
+  color: var(--operator); }
+
+span.Punctuation {
+  color: var(--punctuation); }
+
+span.Comment, span.LongComment {
+  font-style: italic;
+  font-weight: 400;
+  color: var(--comment); }
+
+span.RegularExpression {
+  color: darkviolet; }
+
+span.TagStart {
+  color: darkviolet; }
+
+span.TagEnd {
+  color: darkviolet; }
+
+span.Key {
+  color: #252dbe; }
+
+span.Value {
+  color: #252dbe; }
+
+span.RawData {
+  color: var(--raw-data); }
+
+span.Assembler {
+  color: #252dbe; }
+
+span.Preprocessor {
+  color: #252dbe; }
+
+span.Directive {
+  color: #252dbe; }
+
+span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference,
+span.Other {
+  color: var(--other); }
+
+/* Pop type, const, proc, and iterator defs in nim def blocks */
+dt pre > span.Identifier, dt pre > span.Operator {
+  color: var(--identifier);
+  font-weight: 700; }
+
+dt pre > span.Keyword ~ span.Identifier, dt pre > span.Identifier ~ span.Identifier,
+dt pre > span.Operator ~ span.Identifier, dt pre > span.Other ~ span.Identifier {
+  color: var(--identifier);
+  font-weight: inherit; }
+
+/* Nim sprite for the footer (taken from main page favicon) */
+.nim-sprite {
+  display: inline-block;
+  width: 51px;
+  height: 14px;
+  background-position: 0 0;
+  background-size: 51px 14px;
+  -webkit-filter: opacity(50%);
+  background-repeat: no-repeat;
+  background-image: var(--nim-sprite-base64);
+  margin-bottom: 5px; }
+
+span.pragmadots {
+  /* Position: relative frees us up to make the dots
+  look really nice without fucking up the layout and
+  causing bulging in the parent container */
+  position: relative;
+  /* 1px down looks slightly nicer */
+  top: 1px;
+  padding: 2px;
+  background-color: var(--third-background);
+  border-radius: 4px;
+  margin: 0 2px;
+  cursor: pointer;
+  font-size: 0.8em;
+}
+
+span.pragmadots:hover {
+  background-color: var(--hint);
+}
+span.pragmawrap {
+  display: none;
+}
+
+span.attachedType {
+  display: none;
+  visibility: hidden;
+}
\ No newline at end of file
diff --git a/docs/regex/nodematch.html b/docs/regex/nodematch.html
new file mode 100644
index 0000000..822535c
--- /dev/null
+++ b/docs/regex/nodematch.html
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nodematch</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nodematch</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">swapCase
+      <li><a class="reference" href="#swapCase%2CRune"
+    title="swapCase(r: Rune): Rune">swapCase,<wbr>Rune</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">match
+      <li><a class="reference" href="#match%2CNode%2CRune%2CRune"
+    title="match(n: Node; r: Rune; nxt: Rune): bool">match,<wbr>Node,<wbr>Rune,<wbr>Rune</a></li>
+  <li><a class="reference" href="#match%2CNode%2CRune"
+    title="match(n: Node; r: Rune): bool">match,<wbr>Node,<wbr>Rune</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="types.html">types</a>, <a class="reference external" href="common.html">common</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="match,Node,Rune,Rune"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#match%2CNode%2CRune%2CRune"><span class="Identifier">match</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">;</span> <span class="Identifier">r</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">;</span> <span class="Identifier">nxt</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+match for <tt class="docutils literal"><span class="pre">Node</span></tt> of assertion kind. Return whether the node matches the current characters or not
+
+</dd>
+<a id="swapCase,Rune"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#swapCase%2CRune"><span class="Identifier">swapCase</span></a><span class="Other">(</span><span class="Identifier">r</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Rune</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="match,Node,Rune"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#match%2CNode%2CRune"><span class="Identifier">match</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">;</span> <span class="Identifier">r</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">inline</span><span class="Other">,</span> <span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+match for <tt class="docutils literal"><span class="pre">Node</span></tt> of matchable kind. Return whether the node matches the current character or not
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nodematch.idx b/docs/regex/nodematch.idx
new file mode 100644
index 0000000..4304fe4
--- /dev/null
+++ b/docs/regex/nodematch.idx
@@ -0,0 +1,3 @@
+match	regex/nodematch.html#match,Node,Rune,Rune	nodematch: match(n: Node; r: Rune; nxt: Rune): bool	
+swapCase	regex/nodematch.html#swapCase,Rune	nodematch: swapCase(r: Rune): Rune	
+match	regex/nodematch.html#match,Node,Rune	nodematch: match(n: Node; r: Rune): bool	
diff --git a/docs/regex/nodetype.html b/docs/regex/nodetype.html
new file mode 100644
index 0000000..fe4307c
--- /dev/null
+++ b/docs/regex/nodetype.html
@@ -0,0 +1,443 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/nodetype</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+</script>
+
+</head>
+<body onload="main()">
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/nodetype</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#Flag"
+    title="Flag = enum
+  flagCaseInsensitive, flagNotCaseInsensitive, flagMultiLine, flagNotMultiLine,
+  flagAnyMatchNewLine, flagNotAnyMatchNewLine, flagUnGreedy, flagNotUnGreedy,
+  flagUnicode, flagNotUnicode, flagVerbose, flagNotVerbose">Flag</a></li>
+  <li><a class="reference" href="#NodeKind"
+    title="NodeKind = enum
+  reChar, reCharCi, reJoiner, reGroupStart, reGroupEnd, reOr, reZeroOrMore,
+  reOneOrMore, reZeroOrOne, reRepRange, reStartSym, reEndSym, reStartSymML,
+  reEndSymML, reStart, reEnd, reWordBoundary, reNotWordBoundary, reWord,
+  reDigit, reWhiteSpace, reUCC, reNotAlphaNum, reNotDigit, reNotWhiteSpace,
+  reNotUCC, reAny, reAnyNl, reWordBoundaryAscii, reNotWordBoundaryAscii,
+  reWordAscii, reDigitAscii, reWhiteSpaceAscii, reNotAlphaNumAscii,
+  reNotDigitAscii, reNotWhiteSpaceAscii, reAnyAscii, reAnyNlAscii, reInSet,
+  reNotSet, reLookahead, reLookbehind, reNotLookahead, reNotLookbehind, reSkip,
+  reEoe">NodeKind</a></li>
+  <li><a class="reference" href="#NodeUid"
+    title="NodeUid = int16">NodeUid</a></li>
+  <li><a class="reference" href="#Node"
+    title="Node = object
+  kind*: NodeKind
+  cp*: Rune
+  next*: seq[int16]
+  isGreedy*: bool
+  uid*: NodeUid
+  idx*: int16
+  isCapturing*: bool
+  name*: string
+  flags*: seq[Flag]
+  min*, max*: int16
+  cps*: HashSet[Rune]
+  ranges*: seq[Slice[Rune]]
+  shorthands*: seq[Node]
+  cc*: UnicodeCategorySet">Node</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#10" id="60">Consts</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#opKind"
+    title="opKind = {reJoiner, reOr, reZeroOrMore, reOneOrMore, reZeroOrOne, reRepRange}">opKind</a></li>
+  <li><a class="reference" href="#assertionKind"
+    title="assertionKind = {reStartSym, reEndSym, reStartSymML, reEndSymML, reStart, reEnd,
+                 reWordBoundary, reNotWordBoundary, reWordBoundaryAscii,
+                 reNotWordBoundaryAscii, reLookahead, reLookbehind,
+                 reNotLookahead, reNotLookbehind}">assertionKind</a></li>
+  <li><a class="reference" href="#shorthandKind"
+    title="shorthandKind = {reWord, reDigit, reWhiteSpace, reUCC, reNotAlphaNum,
+                 reNotDigit, reNotWhiteSpace, reNotUCC, reWordAscii,
+                 reDigitAscii, reWhiteSpaceAscii, reNotAlphaNumAscii,
+                 reNotDigitAscii, reNotWhiteSpaceAscii}">shorthandKind</a></li>
+  <li><a class="reference" href="#matchableKind"
+    title="matchableKind = {reChar, reCharCi, reWord, reDigit, reWhiteSpace, reUCC,
+                 reNotAlphaNum, reNotDigit, reNotWhiteSpace, reNotUCC, reAny,
+                 reAnyNl, reInSet, reNotSet, reWordAscii, reDigitAscii,
+                 reWhiteSpaceAscii, reNotAlphaNumAscii, reNotDigitAscii,
+                 reNotWhiteSpaceAscii, reAnyAscii, reAnyNlAscii}">matchableKind</a></li>
+  <li><a class="reference" href="#repetitionKind"
+    title="repetitionKind = {reZeroOrMore, reOneOrMore, reRepRange}">repetitionKind</a></li>
+  <li><a class="reference" href="#groupKind"
+    title="groupKind = {reGroupStart, reGroupEnd}">groupKind</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#13" id="63">Funcs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">initNotSetNode
+      <li><a class="reference" href="#initNotSetNode"
+    title="initNotSetNode(): Node">initNotSetNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initEoeNode
+      <li><a class="reference" href="#initEoeNode"
+    title="initEoeNode(): Node">initEoeNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initSkipNode
+      <li><a class="reference" href="#initSkipNode%2CopenArray%5Bint16%5D"
+    title="initSkipNode(next: openArray[int16]): Node">initSkipNode,<wbr>openArray[int16]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initGroupStart
+      <li><a class="reference" href="#initGroupStart%2Cstring%2Cseq%5BFlag%5D"
+    title="initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node">initGroupStart,<wbr>string,<wbr>seq[Flag]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initJoinerNode
+      <li><a class="reference" href="#initJoinerNode"
+    title="initJoinerNode(): Node">initJoinerNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initSetNode
+      <li><a class="reference" href="#initSetNode"
+    title="initSetNode(): Node">initSetNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">toString
+      <li><a class="reference" href="#toString%2CNode"
+    title="toString(n: Node): string">toString,<wbr>Node</a></li>
+  <li><a class="reference" href="#toString%2Cseq%5BNode%5D"
+    title="toString(n: seq[Node]): string">toString,<wbr>seq[Node]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">isEmpty
+      <li><a class="reference" href="#isEmpty%2CNode"
+    title="isEmpty(n: Node): bool">isEmpty,<wbr>Node</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">toCharNode
+      <li><a class="reference" href="#toCharNode%2CRune"
+    title="toCharNode(r: Rune): Node">toCharNode,<wbr>Rune</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="common.html">common</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="Flag"></a>
+<dt><pre><a href="nodetype.html#Flag"><span class="Identifier">Flag</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
+  <span class="Identifier">flagCaseInsensitive</span><span class="Other">,</span> <span class="Identifier">flagNotCaseInsensitive</span><span class="Other">,</span> <span class="Identifier">flagMultiLine</span><span class="Other">,</span> <span class="Identifier">flagNotMultiLine</span><span class="Other">,</span>
+  <span class="Identifier">flagAnyMatchNewLine</span><span class="Other">,</span> <span class="Identifier">flagNotAnyMatchNewLine</span><span class="Other">,</span> <span class="Identifier">flagUnGreedy</span><span class="Other">,</span> <span class="Identifier">flagNotUnGreedy</span><span class="Other">,</span>
+  <span class="Identifier">flagUnicode</span><span class="Other">,</span> <span class="Identifier">flagNotUnicode</span><span class="Other">,</span> <span class="Identifier">flagVerbose</span><span class="Other">,</span> <span class="Identifier">flagNotVerbose</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="NodeKind"></a>
+<dt><pre><a href="nodetype.html#NodeKind"><span class="Identifier">NodeKind</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
+  <span class="Identifier">reChar</span><span class="Other">,</span> <span class="Identifier">reCharCi</span><span class="Other">,</span> <span class="Identifier">reJoiner</span><span class="Other">,</span> <span class="Identifier">reGroupStart</span><span class="Other">,</span> <span class="Identifier">reGroupEnd</span><span class="Other">,</span> <span class="Identifier">reOr</span><span class="Other">,</span> <span class="Identifier">reZeroOrMore</span><span class="Other">,</span>
+  <span class="Identifier">reOneOrMore</span><span class="Other">,</span> <span class="Identifier">reZeroOrOne</span><span class="Other">,</span> <span class="Identifier">reRepRange</span><span class="Other">,</span> <span class="Identifier">reStartSym</span><span class="Other">,</span> <span class="Identifier">reEndSym</span><span class="Other">,</span> <span class="Identifier">reStartSymML</span><span class="Other">,</span>
+  <span class="Identifier">reEndSymML</span><span class="Other">,</span> <span class="Identifier">reStart</span><span class="Other">,</span> <span class="Identifier">reEnd</span><span class="Other">,</span> <span class="Identifier">reWordBoundary</span><span class="Other">,</span> <span class="Identifier">reNotWordBoundary</span><span class="Other">,</span> <span class="Identifier">reWord</span><span class="Other">,</span>
+  <span class="Identifier">reDigit</span><span class="Other">,</span> <span class="Identifier">reWhiteSpace</span><span class="Other">,</span> <span class="Identifier">reUCC</span><span class="Other">,</span> <span class="Identifier">reNotAlphaNum</span><span class="Other">,</span> <span class="Identifier">reNotDigit</span><span class="Other">,</span> <span class="Identifier">reNotWhiteSpace</span><span class="Other">,</span>
+  <span class="Identifier">reNotUCC</span><span class="Other">,</span> <span class="Identifier">reAny</span><span class="Other">,</span> <span class="Identifier">reAnyNl</span><span class="Other">,</span> <span class="Identifier">reWordBoundaryAscii</span><span class="Other">,</span> <span class="Identifier">reNotWordBoundaryAscii</span><span class="Other">,</span>
+  <span class="Identifier">reWordAscii</span><span class="Other">,</span> <span class="Identifier">reDigitAscii</span><span class="Other">,</span> <span class="Identifier">reWhiteSpaceAscii</span><span class="Other">,</span> <span class="Identifier">reNotAlphaNumAscii</span><span class="Other">,</span>
+  <span class="Identifier">reNotDigitAscii</span><span class="Other">,</span> <span class="Identifier">reNotWhiteSpaceAscii</span><span class="Other">,</span> <span class="Identifier">reAnyAscii</span><span class="Other">,</span> <span class="Identifier">reAnyNlAscii</span><span class="Other">,</span> <span class="Identifier">reInSet</span><span class="Other">,</span>
+  <span class="Identifier">reNotSet</span><span class="Other">,</span> <span class="Identifier">reLookahead</span><span class="Other">,</span> <span class="Identifier">reLookbehind</span><span class="Other">,</span> <span class="Identifier">reNotLookahead</span><span class="Other">,</span> <span class="Identifier">reNotLookbehind</span><span class="Other">,</span> <span class="Identifier">reSkip</span><span class="Other">,</span>
+  <span class="Identifier">reEoe</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="NodeUid"></a>
+<dt><pre><a href="nodetype.html#NodeUid"><span class="Identifier">NodeUid</span></a> <span class="Other">=</span> <span class="Identifier">int16</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Node"></a>
+<dt><pre><a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">kind</span><span class="Operator">*</span><span class="Other">:</span> <a href="nodetype.html#NodeKind"><span class="Identifier">NodeKind</span></a>
+  <span class="Identifier">cp</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">Rune</span>
+  <span class="Identifier">next</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">int16</span><span class="Other">]</span>
+  <span class="Identifier">isGreedy</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
+  <span class="Identifier">uid</span><span class="Operator">*</span><span class="Other">:</span> <a href="nodetype.html#NodeUid"><span class="Identifier">NodeUid</span></a>
+  <span class="Identifier">idx</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+  <span class="Identifier">isCapturing</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
+  <span class="Identifier">name</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">string</span>
+  <span class="Identifier">flags</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nodetype.html#Flag"><span class="Identifier">Flag</span></a><span class="Other">]</span>
+  <span class="Identifier">min</span><span class="Operator">*</span><span class="Other">,</span> <span class="Identifier">max</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+  <span class="Identifier">cps</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">HashSet</span><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span>
+  <span class="Identifier">ranges</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span><span class="Other">]</span>
+  <span class="Identifier">shorthands</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nodetype.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+  <span class="Identifier">cc</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">UnicodeCategorySet</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="10">
+<h1><a class="toc-backref" href="#10">Consts</a></h1>
+<dl class="item">
+<a id="opKind"></a>
+<dt><pre><a href="nodetype.html#opKind"><span class="Identifier">opKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reJoiner</span><span class="Other">,</span> <span class="DecNumber">reOr</span><span class="Other">,</span> <span class="DecNumber">reZeroOrMore</span><span class="Other">,</span> <span class="DecNumber">reOneOrMore</span><span class="Other">,</span> <span class="DecNumber">reZeroOrOne</span><span class="Other">,</span> <span class="DecNumber">reRepRange</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="assertionKind"></a>
+<dt><pre><a href="nodetype.html#assertionKind"><span class="Identifier">assertionKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reStartSym</span><span class="Other">,</span> <span class="DecNumber">reEndSym</span><span class="Other">,</span> <span class="DecNumber">reStartSymML</span><span class="Other">,</span> <span class="DecNumber">reEndSymML</span><span class="Other">,</span> <span class="DecNumber">reStart</span><span class="Other">,</span> <span class="DecNumber">reEnd</span><span class="Other">,</span>
+                 <span class="DecNumber">reWordBoundary</span><span class="Other">,</span> <span class="DecNumber">reNotWordBoundary</span><span class="Other">,</span> <span class="DecNumber">reWordBoundaryAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotWordBoundaryAscii</span><span class="Other">,</span> <span class="DecNumber">reLookahead</span><span class="Other">,</span> <span class="DecNumber">reLookbehind</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotLookahead</span><span class="Other">,</span> <span class="DecNumber">reNotLookbehind</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="shorthandKind"></a>
+<dt><pre><a href="nodetype.html#shorthandKind"><span class="Identifier">shorthandKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reWord</span><span class="Other">,</span> <span class="DecNumber">reDigit</span><span class="Other">,</span> <span class="DecNumber">reWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reUCC</span><span class="Other">,</span> <span class="DecNumber">reNotAlphaNum</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotDigit</span><span class="Other">,</span> <span class="DecNumber">reNotWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reNotUCC</span><span class="Other">,</span> <span class="DecNumber">reWordAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reDigitAscii</span><span class="Other">,</span> <span class="DecNumber">reWhiteSpaceAscii</span><span class="Other">,</span> <span class="DecNumber">reNotAlphaNumAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotDigitAscii</span><span class="Other">,</span> <span class="DecNumber">reNotWhiteSpaceAscii</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="matchableKind"></a>
+<dt><pre><a href="nodetype.html#matchableKind"><span class="Identifier">matchableKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reChar</span><span class="Other">,</span> <span class="DecNumber">reCharCi</span><span class="Other">,</span> <span class="DecNumber">reWord</span><span class="Other">,</span> <span class="DecNumber">reDigit</span><span class="Other">,</span> <span class="DecNumber">reWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reUCC</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotAlphaNum</span><span class="Other">,</span> <span class="DecNumber">reNotDigit</span><span class="Other">,</span> <span class="DecNumber">reNotWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reNotUCC</span><span class="Other">,</span> <span class="DecNumber">reAny</span><span class="Other">,</span>
+                 <span class="DecNumber">reAnyNl</span><span class="Other">,</span> <span class="DecNumber">reInSet</span><span class="Other">,</span> <span class="DecNumber">reNotSet</span><span class="Other">,</span> <span class="DecNumber">reWordAscii</span><span class="Other">,</span> <span class="DecNumber">reDigitAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reWhiteSpaceAscii</span><span class="Other">,</span> <span class="DecNumber">reNotAlphaNumAscii</span><span class="Other">,</span> <span class="DecNumber">reNotDigitAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotWhiteSpaceAscii</span><span class="Other">,</span> <span class="DecNumber">reAnyAscii</span><span class="Other">,</span> <span class="DecNumber">reAnyNlAscii</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="repetitionKind"></a>
+<dt><pre><a href="nodetype.html#repetitionKind"><span class="Identifier">repetitionKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reZeroOrMore</span><span class="Other">,</span> <span class="DecNumber">reOneOrMore</span><span class="Other">,</span> <span class="DecNumber">reRepRange</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="groupKind"></a>
+<dt><pre><a href="nodetype.html#groupKind"><span class="Identifier">groupKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reGroupStart</span><span class="Other">,</span> <span class="DecNumber">reGroupEnd</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="13">
+<h1><a class="toc-backref" href="#13">Funcs</a></h1>
+<dl class="item">
+<a id="toCharNode,Rune"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toCharNode%2CRune"><span class="Identifier">toCharNode</span></a><span class="Other">(</span><span class="Identifier">r</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a <tt class="docutils literal"><span class="pre">Node</span></tt> that is meant to be matched against text characters
+
+</dd>
+<a id="initJoinerNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initJoinerNode"><span class="Identifier">initJoinerNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a <tt class="docutils literal"><span class="pre">Node</span></tt> of <tt class="docutils literal"><span class="pre">reJoiner</span></tt> kind. Joiners are temporary nodes, they serve to generate the NFA but they are never part of it
+
+</dd>
+<a id="initEoeNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initEoeNode"><span class="Identifier">initEoeNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return the end-of-expression <tt class="docutils literal"><span class="pre">Node</span></tt>. This is a dummy node that marks a match as successful
+
+</dd>
+<a id="initSetNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initSetNode"><span class="Identifier">initSetNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a set <tt class="docutils literal"><span class="pre">Node</span></tt>, parsed from an expression such as <tt class="docutils literal"><span class="pre">[a-z]</span></tt>
+
+</dd>
+<a id="initNotSetNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initNotSetNode"><span class="Identifier">initNotSetNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a negated set <tt class="docutils literal"><span class="pre">Node</span></tt>, parsed from an expression such as <tt class="docutils literal"><span class="pre">[^a-z]</span></tt>
+
+</dd>
+<a id="initGroupStart,string,seq[Flag]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initGroupStart%2Cstring%2Cseq%5BFlag%5D"><span class="Identifier">initGroupStart</span></a><span class="Other">(</span><span class="Identifier">name</span><span class="Other">:</span> <span class="Identifier">string</span> <span class="Other">=</span> <span class="StringLit">&quot;&quot;</span><span class="Other">;</span> <span class="Identifier">flags</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nodetype.html#Flag"><span class="Identifier">Flag</span></a><span class="Other">]</span> <span class="Other">=</span> <span class="Operator">@</span><span class="Other">[</span><span class="Other">]</span><span class="Other">;</span>
+                    <span class="Identifier">isCapturing</span> <span class="Other">=</span> <span class="Identifier">true</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a <tt class="docutils literal"><span class="pre">reGroupStart</span></tt> node
+
+</dd>
+<a id="initSkipNode,openArray[int16]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initSkipNode%2CopenArray%5Bint16%5D"><span class="Identifier">initSkipNode</span></a><span class="Other">(</span><span class="Identifier">next</span><span class="Other">:</span> <span class="Identifier">openArray</span><span class="Other">[</span><span class="Identifier">int16</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Return a dummy node that should be skipped while traversing the NFA
+
+</dd>
+<a id="isEmpty,Node"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#isEmpty%2CNode"><span class="Identifier">isEmpty</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+check if a set <tt class="docutils literal"><span class="pre">Node</span></tt> is empty
+
+</dd>
+<a id="toString,Node"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toString%2CNode"><span class="Identifier">toString</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <a href="nodetype.html#Node"><span class="Identifier">Node</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return the string representation of a <tt class="docutils literal"><span class="pre">Node</span></tt>. The string is always equivalent to the original expression but not necessarily equal
+
+</dd>
+<a id="toString,seq[Node]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toString%2Cseq%5BNode%5D"><span class="Identifier">toString</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="nodetype.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2020-11-22 06:24:09 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/nodetype.idx b/docs/regex/nodetype.idx
new file mode 100644
index 0000000..0e94f5e
--- /dev/null
+++ b/docs/regex/nodetype.idx
@@ -0,0 +1,78 @@
+flagCaseInsensitive	regex/nodetype.html#flagCaseInsensitive	Flag.flagCaseInsensitive	
+flagNotCaseInsensitive	regex/nodetype.html#flagNotCaseInsensitive	Flag.flagNotCaseInsensitive	
+flagMultiLine	regex/nodetype.html#flagMultiLine	Flag.flagMultiLine	
+flagNotMultiLine	regex/nodetype.html#flagNotMultiLine	Flag.flagNotMultiLine	
+flagAnyMatchNewLine	regex/nodetype.html#flagAnyMatchNewLine	Flag.flagAnyMatchNewLine	
+flagNotAnyMatchNewLine	regex/nodetype.html#flagNotAnyMatchNewLine	Flag.flagNotAnyMatchNewLine	
+flagUnGreedy	regex/nodetype.html#flagUnGreedy	Flag.flagUnGreedy	
+flagNotUnGreedy	regex/nodetype.html#flagNotUnGreedy	Flag.flagNotUnGreedy	
+flagUnicode	regex/nodetype.html#flagUnicode	Flag.flagUnicode	
+flagNotUnicode	regex/nodetype.html#flagNotUnicode	Flag.flagNotUnicode	
+flagVerbose	regex/nodetype.html#flagVerbose	Flag.flagVerbose	
+flagNotVerbose	regex/nodetype.html#flagNotVerbose	Flag.flagNotVerbose	
+Flag	regex/nodetype.html#Flag	nodetype: Flag	
+reChar	regex/nodetype.html#reChar	NodeKind.reChar	
+reCharCi	regex/nodetype.html#reCharCi	NodeKind.reCharCi	
+reJoiner	regex/nodetype.html#reJoiner	NodeKind.reJoiner	
+reGroupStart	regex/nodetype.html#reGroupStart	NodeKind.reGroupStart	
+reGroupEnd	regex/nodetype.html#reGroupEnd	NodeKind.reGroupEnd	
+reOr	regex/nodetype.html#reOr	NodeKind.reOr	
+reZeroOrMore	regex/nodetype.html#reZeroOrMore	NodeKind.reZeroOrMore	
+reOneOrMore	regex/nodetype.html#reOneOrMore	NodeKind.reOneOrMore	
+reZeroOrOne	regex/nodetype.html#reZeroOrOne	NodeKind.reZeroOrOne	
+reRepRange	regex/nodetype.html#reRepRange	NodeKind.reRepRange	
+reStartSym	regex/nodetype.html#reStartSym	NodeKind.reStartSym	
+reEndSym	regex/nodetype.html#reEndSym	NodeKind.reEndSym	
+reStartSymML	regex/nodetype.html#reStartSymML	NodeKind.reStartSymML	
+reEndSymML	regex/nodetype.html#reEndSymML	NodeKind.reEndSymML	
+reStart	regex/nodetype.html#reStart	NodeKind.reStart	
+reEnd	regex/nodetype.html#reEnd	NodeKind.reEnd	
+reWordBoundary	regex/nodetype.html#reWordBoundary	NodeKind.reWordBoundary	
+reNotWordBoundary	regex/nodetype.html#reNotWordBoundary	NodeKind.reNotWordBoundary	
+reWord	regex/nodetype.html#reWord	NodeKind.reWord	
+reDigit	regex/nodetype.html#reDigit	NodeKind.reDigit	
+reWhiteSpace	regex/nodetype.html#reWhiteSpace	NodeKind.reWhiteSpace	
+reUCC	regex/nodetype.html#reUCC	NodeKind.reUCC	
+reNotAlphaNum	regex/nodetype.html#reNotAlphaNum	NodeKind.reNotAlphaNum	
+reNotDigit	regex/nodetype.html#reNotDigit	NodeKind.reNotDigit	
+reNotWhiteSpace	regex/nodetype.html#reNotWhiteSpace	NodeKind.reNotWhiteSpace	
+reNotUCC	regex/nodetype.html#reNotUCC	NodeKind.reNotUCC	
+reAny	regex/nodetype.html#reAny	NodeKind.reAny	
+reAnyNl	regex/nodetype.html#reAnyNl	NodeKind.reAnyNl	
+reWordBoundaryAscii	regex/nodetype.html#reWordBoundaryAscii	NodeKind.reWordBoundaryAscii	
+reNotWordBoundaryAscii	regex/nodetype.html#reNotWordBoundaryAscii	NodeKind.reNotWordBoundaryAscii	
+reWordAscii	regex/nodetype.html#reWordAscii	NodeKind.reWordAscii	
+reDigitAscii	regex/nodetype.html#reDigitAscii	NodeKind.reDigitAscii	
+reWhiteSpaceAscii	regex/nodetype.html#reWhiteSpaceAscii	NodeKind.reWhiteSpaceAscii	
+reNotAlphaNumAscii	regex/nodetype.html#reNotAlphaNumAscii	NodeKind.reNotAlphaNumAscii	
+reNotDigitAscii	regex/nodetype.html#reNotDigitAscii	NodeKind.reNotDigitAscii	
+reNotWhiteSpaceAscii	regex/nodetype.html#reNotWhiteSpaceAscii	NodeKind.reNotWhiteSpaceAscii	
+reAnyAscii	regex/nodetype.html#reAnyAscii	NodeKind.reAnyAscii	
+reAnyNlAscii	regex/nodetype.html#reAnyNlAscii	NodeKind.reAnyNlAscii	
+reInSet	regex/nodetype.html#reInSet	NodeKind.reInSet	
+reNotSet	regex/nodetype.html#reNotSet	NodeKind.reNotSet	
+reLookahead	regex/nodetype.html#reLookahead	NodeKind.reLookahead	
+reLookbehind	regex/nodetype.html#reLookbehind	NodeKind.reLookbehind	
+reNotLookahead	regex/nodetype.html#reNotLookahead	NodeKind.reNotLookahead	
+reNotLookbehind	regex/nodetype.html#reNotLookbehind	NodeKind.reNotLookbehind	
+reSkip	regex/nodetype.html#reSkip	NodeKind.reSkip	
+reEoe	regex/nodetype.html#reEoe	NodeKind.reEoe	
+NodeKind	regex/nodetype.html#NodeKind	nodetype: NodeKind	
+NodeUid	regex/nodetype.html#NodeUid	nodetype: NodeUid	
+Node	regex/nodetype.html#Node	nodetype: Node	
+toCharNode	regex/nodetype.html#toCharNode,Rune	nodetype: toCharNode(r: Rune): Node	
+initJoinerNode	regex/nodetype.html#initJoinerNode	nodetype: initJoinerNode(): Node	
+initEoeNode	regex/nodetype.html#initEoeNode	nodetype: initEoeNode(): Node	
+initSetNode	regex/nodetype.html#initSetNode	nodetype: initSetNode(): Node	
+initNotSetNode	regex/nodetype.html#initNotSetNode	nodetype: initNotSetNode(): Node	
+initGroupStart	regex/nodetype.html#initGroupStart,string,seq[Flag]	nodetype: initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node	
+initSkipNode	regex/nodetype.html#initSkipNode,openArray[int16]	nodetype: initSkipNode(next: openArray[int16]): Node	
+isEmpty	regex/nodetype.html#isEmpty,Node	nodetype: isEmpty(n: Node): bool	
+opKind	regex/nodetype.html#opKind	nodetype: opKind	
+assertionKind	regex/nodetype.html#assertionKind	nodetype: assertionKind	
+shorthandKind	regex/nodetype.html#shorthandKind	nodetype: shorthandKind	
+matchableKind	regex/nodetype.html#matchableKind	nodetype: matchableKind	
+repetitionKind	regex/nodetype.html#repetitionKind	nodetype: repetitionKind	
+groupKind	regex/nodetype.html#groupKind	nodetype: groupKind	
+toString	regex/nodetype.html#toString,Node	nodetype: toString(n: Node): string	
+toString	regex/nodetype.html#toString,seq[Node]	nodetype: toString(n: seq[Node]): string	
diff --git a/docs/regex/parser.html b/docs/regex/parser.html
new file mode 100644
index 0000000..89a3a8b
--- /dev/null
+++ b/docs/regex/parser.html
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/parser</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/parser</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">parse
+      <li><a class="reference" href="#parse%2Cstring"
+    title="parse(expression: string): Exp">parse,<wbr>string</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="exptype.html">exptype</a>, <a class="reference external" href="types.html">types</a>, <a class="reference external" href="common.html">common</a>, <a class="reference external" href="scanner.html">scanner</a>
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="parse,string"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#parse%2Cstring"><span class="Identifier">parse</span></a><span class="Other">(</span><span class="Identifier">expression</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="exptype.html#Exp"><span class="Identifier">Exp</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">RegexError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+convert a <tt class="docutils literal"><span class="pre">string</span></tt> regex expression into a <tt class="docutils literal"><span class="pre">Node</span></tt> expression
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:29 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/parser.idx b/docs/regex/parser.idx
new file mode 100644
index 0000000..d2e67a7
--- /dev/null
+++ b/docs/regex/parser.idx
@@ -0,0 +1 @@
+parse	regex/parser.html#parse,string	parser: parse(expression: string): Exp	
diff --git a/docs/regex/scanner.html b/docs/regex/scanner.html
new file mode 100644
index 0000000..898a070
--- /dev/null
+++ b/docs/regex/scanner.html
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/scanner</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/scanner</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#Scanner"
+    title="Scanner[T] = ref object
+  raw*: string
+  s*: seq[T]
+  pos*: int">Scanner</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">scan
+      <li><a class="reference" href="#scan%2Cseq%5BT%5D"
+    title="scan[T](s: seq[T]): Scanner[T]">scan,<wbr>seq[T]</a></li>
+  <li><a class="reference" href="#scan%2Cstring"
+    title="scan(raw: string): Scanner[Rune]">scan,<wbr>string</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">newScanner
+      <li><a class="reference" href="#newScanner%2Cseq%5BT%5D"
+    title="newScanner[T](s: seq[T]): Scanner[T]">newScanner,<wbr>seq[T]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">peek
+      <li><a class="reference" href="#peek%2CScanner%5BRune%5D"
+    title="peek(sc: Scanner[Rune]): Rune">peek,<wbr>Scanner[Rune]</a></li>
+  <li><a class="reference" href="#peek%2CScanner%5BNode%5D"
+    title="peek(sc: Scanner[Node]): Node">peek,<wbr>Scanner[Node]</a></li>
+  <li><a class="reference" href="#peek%2CScanner%5BRune%5D%2Cint"
+    title="peek(sc: Scanner[Rune]; n: int): Rune">peek,<wbr>Scanner[Rune],<wbr>int</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">next
+      <li><a class="reference" href="#next%2CScanner%5BT%5D"
+    title="next[T](sc: Scanner[T]): T">next,<wbr>Scanner[T]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">curr
+      <li><a class="reference" href="#curr%2CScanner%5BT%5D"
+    title="curr[T](sc: Scanner[T]): T">curr,<wbr>Scanner[T]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">find
+      <li><a class="reference" href="#find%2CScanner%5BRune%5D%2CRune"
+    title="find(sc: Scanner[Rune]; r: Rune): int">find,<wbr>Scanner[Rune],<wbr>Rune</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">finished
+      <li><a class="reference" href="#finished%2CScanner%5BT%5D"
+    title="finished[T](sc: Scanner[T]): bool">finished,<wbr>Scanner[T]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">prev
+      <li><a class="reference" href="#prev%2CScanner%5BT%5D"
+    title="prev[T](sc: Scanner[T]): T">prev,<wbr>Scanner[T]</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#15" id="65">Iterators</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#items.i%2CScanner%5BT%5D"
+    title="items[T](sc: Scanner[T]): T">items</a></li>
+  <li><a class="reference" href="#mitems.i%2CScanner%5BT%5D"
+    title="mitems[T](sc: var Scanner[T]): var T">mitems</a></li>
+  <li><a class="reference" href="#peek.i%2CScanner%5BT%5D"
+    title="peek[T](sc: Scanner[T]): (T, T)">peek</a></li>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="types.html">types</a>, <a class="reference external" href="common.html">common</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="Scanner"></a>
+<dt><pre><a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span> <span class="Other">=</span> <span class="Keyword">ref</span> <span class="Keyword">object</span>
+  <span class="Identifier">raw</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">string</span>
+  <span class="Identifier">s</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span>
+  <span class="Identifier">pos</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int</span>
+</pre></dt>
+<dd>
+
+A scanner is a common construct for reading data
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="newScanner,seq[T]"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#newScanner%2Cseq%5BT%5D"><span class="Identifier">newScanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="scan,seq[T]"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#scan%2Cseq%5BT%5D"><span class="Identifier">scan</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">s</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="scan,string"></a>
+<dt><pre><span class="Keyword">proc</span> <a href="#scan%2Cstring"><span class="Identifier">scan</span></a><span class="Other">(</span><span class="Identifier">raw</span><span class="Other">:</span> <span class="Identifier">string</span><span class="Other">)</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="finished,Scanner[T]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#finished%2CScanner%5BT%5D"><span class="Identifier">finished</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="prev,Scanner[T]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#prev%2CScanner%5BT%5D"><span class="Identifier">prev</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="curr,Scanner[T]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#curr%2CScanner%5BT%5D"><span class="Identifier">curr</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="next,Scanner[T]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#next%2CScanner%5BT%5D"><span class="Identifier">next</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
+<dd>
+
+return current item and consume it
+
+</dd>
+<a id="peek,Scanner[Rune]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#peek%2CScanner%5BRune%5D"><span class="Identifier">peek</span></a><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Rune</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="peek,Scanner[Node]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#peek%2CScanner%5BNode%5D"><span class="Identifier">peek</span></a><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="peek,Scanner[Rune],int"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#peek%2CScanner%5BRune%5D%2Cint"><span class="Identifier">peek</span></a><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span><span class="Other">;</span> <span class="Identifier">n</span><span class="Other">:</span> <span class="Identifier">int</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">Rune</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="find,Scanner[Rune],Rune"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#find%2CScanner%5BRune%5D%2CRune"><span class="Identifier">find</span></a><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span><span class="Other">;</span> <span class="Identifier">r</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">int</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return number of consumed chars. The scanner's position is not moved. <tt class="docutils literal"><span class="pre">-1</span></tt> is returned when char is not found
+
+</dd>
+
+</dl></div>
+<div class="section" id="15">
+<h1><a class="toc-backref" href="#15">Iterators</a></h1>
+<dl class="item">
+<a id="items.i,Scanner[T]"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#items.i%2CScanner%5BT%5D"><span class="Identifier">items</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">T</span></pre></dt>
+<dd>
+
+the yielded item gets consumed
+
+</dd>
+<a id="mitems.i,Scanner[T]"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#mitems.i%2CScanner%5BT%5D"><span class="Identifier">mitems</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <span class="Keyword">var</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Keyword">var</span> <span class="Identifier">T</span></pre></dt>
+<dd>
+
+the yielded item gets consumed
+
+</dd>
+<a id="peek.i,Scanner[T]"></a>
+<dt><pre><span class="Keyword">iterator</span> <a href="#peek.i%2CScanner%5BT%5D"><span class="Identifier">peek</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">(</span><span class="Identifier">sc</span><span class="Other">:</span> <a href="scanner.html#Scanner"><span class="Identifier">Scanner</span></a><span class="Other">[</span><span class="Identifier">T</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Other">(</span><span class="Identifier">T</span><span class="Other">,</span> <span class="Identifier">T</span><span class="Other">)</span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:28 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/scanner.idx b/docs/regex/scanner.idx
new file mode 100644
index 0000000..abf7669
--- /dev/null
+++ b/docs/regex/scanner.idx
@@ -0,0 +1,15 @@
+Scanner	regex/scanner.html#Scanner	scanner: Scanner	
+newScanner	regex/scanner.html#newScanner,seq[T]	scanner: newScanner[T](s: seq[T]): Scanner[T]	
+scan	regex/scanner.html#scan,seq[T]	scanner: scan[T](s: seq[T]): Scanner[T]	
+scan	regex/scanner.html#scan,string	scanner: scan(raw: string): Scanner[Rune]	
+items	regex/scanner.html#items.i,Scanner[T]	scanner: items[T](sc: Scanner[T]): T	
+mitems	regex/scanner.html#mitems.i,Scanner[T]	scanner: mitems[T](sc: var Scanner[T]): var T	
+finished	regex/scanner.html#finished,Scanner[T]	scanner: finished[T](sc: Scanner[T]): bool	
+prev	regex/scanner.html#prev,Scanner[T]	scanner: prev[T](sc: Scanner[T]): T	
+curr	regex/scanner.html#curr,Scanner[T]	scanner: curr[T](sc: Scanner[T]): T	
+next	regex/scanner.html#next,Scanner[T]	scanner: next[T](sc: Scanner[T]): T	
+peek	regex/scanner.html#peek,Scanner[Rune]	scanner: peek(sc: Scanner[Rune]): Rune	
+peek	regex/scanner.html#peek,Scanner[Node]	scanner: peek(sc: Scanner[Node]): Node	
+peek	regex/scanner.html#peek.i,Scanner[T]	scanner: peek[T](sc: Scanner[T]): (T, T)	
+peek	regex/scanner.html#peek,Scanner[Rune],int	scanner: peek(sc: Scanner[Rune]; n: int): Rune	
+find	regex/scanner.html#find,Scanner[Rune],Rune	scanner: find(sc: Scanner[Rune]; r: Rune): int	
diff --git a/docs/regex/types.html b/docs/regex/types.html
new file mode 100644
index 0000000..705acbd
--- /dev/null
+++ b/docs/regex/types.html
@@ -0,0 +1,572 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>regex/types</title>
+<link rel="stylesheet" type="text/css" href="../nimdoc.out.css">
+
+<script type="text/javascript" src="../dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">regex/types</h1>
+    <div class="row">
+  <div class="three columns">
+  <div class="theme-switch-wrapper">
+    <label class="theme-switch" for="checkbox">
+      <input type="checkbox" id="checkbox" />
+      <div class="slider round"></div>
+    </label>
+    &nbsp;&nbsp;&nbsp; <em>Dark Mode</em>
+  </div>
+  <div id="global-links">
+    <ul class="simple">
+    <li>
+      <a href="../theindex.html">Index</a>
+    </li>
+    </ul>
+  </div>
+  <div id="searchInputDiv">
+    Search: <input type="text" id="searchInput"
+      onkeyup="search()" />
+  </div>
+  <div>
+    Group by:
+    <select onchange="groupBy(this.value)">
+      <option value="section">Section</option>
+      <option value="type">Type</option>
+    </select>
+  </div>
+  <ul class="simple simple-toc" id="toc-list">
+<li>
+  <a class="reference reference-toplevel" href="#6" id="56">Imports</a>
+  <ul class="simple simple-toc-section">
+    
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#7" id="57">Types</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#RpnExp"
+    title="RpnExp = object
+  s*: seq[Node]">RpnExp</a></li>
+  <li><a class="reference" href="#Enfa"
+    title="Enfa = object
+  s*: seq[Node]">Enfa</a></li>
+  <li><a class="reference" href="#TransitionsAll"
+    title="TransitionsAll = seq[seq[int16]]">TransitionsAll</a></li>
+  <li><a class="reference" href="#ZclosureStates"
+    title="ZclosureStates = seq[seq[Node]]">ZclosureStates</a></li>
+  <li><a class="reference" href="#Transitions"
+    title="Transitions = object
+  allZ*: TransitionsAll
+  z*: ZclosureStates">Transitions</a></li>
+  <li><a class="reference" href="#Nfa"
+    title="Nfa = object
+  s*: seq[Node]
+  t*: Transitions">Nfa</a></li>
+  <li><a class="reference" href="#Flag"
+    title="Flag = enum
+  flagCaseInsensitive, flagNotCaseInsensitive, flagMultiLine, flagNotMultiLine,
+  flagAnyMatchNewLine, flagNotAnyMatchNewLine, flagUnGreedy, flagNotUnGreedy,
+  flagUnicode, flagNotUnicode, flagVerbose, flagNotVerbose">Flag</a></li>
+  <li><a class="reference" href="#NodeKind"
+    title="NodeKind = enum
+  reChar, reCharCi, reJoiner, reGroupStart, reGroupEnd, reOr, reZeroOrMore,
+  reOneOrMore, reZeroOrOne, reRepRange, reStartSym, reEndSym, reStartSymML,
+  reEndSymML, reStart, reEnd, reWordBoundary, reNotWordBoundary, reWord,
+  reDigit, reWhiteSpace, reUCC, reNotAlphaNum, reNotDigit, reNotWhiteSpace,
+  reNotUCC, reAny, reAnyNl, reWordBoundaryAscii, reNotWordBoundaryAscii,
+  reWordAscii, reDigitAscii, reWhiteSpaceAscii, reNotAlphaNumAscii,
+  reNotDigitAscii, reNotWhiteSpaceAscii, reAnyAscii, reAnyNlAscii, reInSet,
+  reNotSet, reLookahead, reLookbehind, reNotLookahead, reNotLookbehind, reSkip,
+  reEoe">NodeKind</a></li>
+  <li><a class="reference" href="#NodeUid"
+    title="NodeUid = int16">NodeUid</a></li>
+  <li><a class="reference" href="#Node"
+    title="Node = object
+  kind*: NodeKind
+  cp*: Rune
+  next*: seq[int16]
+  isGreedy*: bool
+  uid*: NodeUid
+  idx*: int16
+  isCapturing*: bool
+  name*: string
+  flags*: seq[Flag]
+  min*, max*: int16
+  cps*: HashSet[Rune]
+  ranges*: seq[Slice[Rune]]
+  shorthands*: seq[Node]
+  cc*: UnicodeCategorySet
+  subExp*: SubExp">Node</a></li>
+  <li><a class="reference" href="#SubExp"
+    title="SubExp = object
+  nfa*: Nfa
+  rpn*: RpnExp
+  reverseCapts*: bool">SubExp</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#10" id="60">Consts</a>
+  <ul class="simple simple-toc-section">
+      <li><a class="reference" href="#opKind"
+    title="opKind = {reJoiner, reOr, reZeroOrMore, reOneOrMore, reZeroOrOne, reRepRange}">opKind</a></li>
+  <li><a class="reference" href="#assertionKind"
+    title="assertionKind = {reStartSym, reEndSym, reStartSymML, reEndSymML, reStart, reEnd,
+                 reWordBoundary, reNotWordBoundary, reWordBoundaryAscii,
+                 reNotWordBoundaryAscii, reLookahead, reLookbehind,
+                 reNotLookahead, reNotLookbehind}">assertionKind</a></li>
+  <li><a class="reference" href="#lookaroundKind"
+    title="lookaroundKind = {reLookahead, reLookbehind, reNotLookahead, reNotLookbehind}">lookaroundKind</a></li>
+  <li><a class="reference" href="#lookaheadKind"
+    title="lookaheadKind = {reLookahead, reNotLookahead}">lookaheadKind</a></li>
+  <li><a class="reference" href="#lookbehindKind"
+    title="lookbehindKind = {reLookbehind, reNotLookbehind}">lookbehindKind</a></li>
+  <li><a class="reference" href="#shorthandKind"
+    title="shorthandKind = {reWord, reDigit, reWhiteSpace, reUCC, reNotAlphaNum,
+                 reNotDigit, reNotWhiteSpace, reNotUCC, reWordAscii,
+                 reDigitAscii, reWhiteSpaceAscii, reNotAlphaNumAscii,
+                 reNotDigitAscii, reNotWhiteSpaceAscii}">shorthandKind</a></li>
+  <li><a class="reference" href="#matchableKind"
+    title="matchableKind = {reChar, reCharCi, reWord, reDigit, reWhiteSpace, reUCC,
+                 reNotAlphaNum, reNotDigit, reNotWhiteSpace, reNotUCC, reAny,
+                 reAnyNl, reInSet, reNotSet, reWordAscii, reDigitAscii,
+                 reWhiteSpaceAscii, reNotAlphaNumAscii, reNotDigitAscii,
+                 reNotWhiteSpaceAscii, reAnyAscii, reAnyNlAscii}">matchableKind</a></li>
+  <li><a class="reference" href="#repetitionKind"
+    title="repetitionKind = {reZeroOrMore, reOneOrMore, reRepRange}">repetitionKind</a></li>
+  <li><a class="reference" href="#groupKind"
+    title="groupKind = {reGroupStart, reGroupEnd}">groupKind</a></li>
+  <li><a class="reference" href="#groupStartKind"
+    title="groupStartKind = {reGroupStart, reLookahead..reNotLookbehind}">groupStartKind</a></li>
+
+  </ul>
+</li>
+<li>
+  <a class="reference reference-toplevel" href="#12" id="62">Procs</a>
+  <ul class="simple simple-toc-section">
+      <ul class="simple nested-toc-section">initNotSetNode
+      <li><a class="reference" href="#initNotSetNode"
+    title="initNotSetNode(): Node">initNotSetNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">$
+      <li><a class="reference" href="#%24%2CNode"
+    title="`$`(n: Node): string">$,<wbr>Node</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initEoeNode
+      <li><a class="reference" href="#initEoeNode"
+    title="initEoeNode(): Node">initEoeNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initSkipNode
+      <li><a class="reference" href="#initSkipNode%2CopenArray%5Bint16%5D"
+    title="initSkipNode(next: openArray[int16]): Node">initSkipNode,<wbr>openArray[int16]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initGroupStart
+      <li><a class="reference" href="#initGroupStart%2Cstring%2Cseq%5BFlag%5D"
+    title="initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node">initGroupStart,<wbr>string,<wbr>seq[Flag]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initJoinerNode
+      <li><a class="reference" href="#initJoinerNode"
+    title="initJoinerNode(): Node">initJoinerNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">initSetNode
+      <li><a class="reference" href="#initSetNode"
+    title="initSetNode(): Node">initSetNode</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">toString
+      <li><a class="reference" href="#toString%2Cseq%5BNode%5D"
+    title="toString(n: seq[Node]): string">toString,<wbr>seq[Node]</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">isEmpty
+      <li><a class="reference" href="#isEmpty%2CNode"
+    title="isEmpty(n: Node): bool">isEmpty,<wbr>Node</a></li>
+
+  </ul>
+  <ul class="simple nested-toc-section">toCharNode
+      <li><a class="reference" href="#toCharNode%2CRune"
+    title="toCharNode(r: Rune): Node">toCharNode,<wbr>Rune</a></li>
+
+  </ul>
+
+  </ul>
+</li>
+
+</ul>
+
+  </div>
+  
+  <div class="nine columns" id="content">
+  <div id="tocRoot"></div>
+  
+  <p class="module-desc"></p>
+  <div class="section" id="6">
+<h1><a class="toc-backref" href="#6">Imports</a></h1>
+<dl class="item">
+<a class="reference external" href="common.html">common</a>
+</dl></div>
+<div class="section" id="7">
+<h1><a class="toc-backref" href="#7">Types</a></h1>
+<dl class="item">
+<a id="RpnExp"></a>
+<dt><pre><a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">s</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Enfa"></a>
+<dt><pre><a href="types.html#Enfa"><span class="Identifier">Enfa</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">s</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="TransitionsAll"></a>
+<dt><pre><a href="types.html#TransitionsAll"><span class="Identifier">TransitionsAll</span></a> <span class="Other">=</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">int16</span><span class="Other">]</span><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="ZclosureStates"></a>
+<dt><pre><a href="types.html#ZclosureStates"><span class="Identifier">ZclosureStates</span></a> <span class="Other">=</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span><span class="Other">]</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Transitions"></a>
+<dt><pre><a href="types.html#Transitions"><span class="Identifier">Transitions</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">allZ</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#TransitionsAll"><span class="Identifier">TransitionsAll</span></a>
+  <span class="Identifier">z</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#ZclosureStates"><span class="Identifier">ZclosureStates</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Nfa"></a>
+<dt><pre><a href="types.html#Nfa"><span class="Identifier">Nfa</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">s</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+  <span class="Identifier">t</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#Transitions"><span class="Identifier">Transitions</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Flag"></a>
+<dt><pre><a href="types.html#Flag"><span class="Identifier">Flag</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
+  <span class="Identifier">flagCaseInsensitive</span><span class="Other">,</span> <span class="Identifier">flagNotCaseInsensitive</span><span class="Other">,</span> <span class="Identifier">flagMultiLine</span><span class="Other">,</span> <span class="Identifier">flagNotMultiLine</span><span class="Other">,</span>
+  <span class="Identifier">flagAnyMatchNewLine</span><span class="Other">,</span> <span class="Identifier">flagNotAnyMatchNewLine</span><span class="Other">,</span> <span class="Identifier">flagUnGreedy</span><span class="Other">,</span> <span class="Identifier">flagNotUnGreedy</span><span class="Other">,</span>
+  <span class="Identifier">flagUnicode</span><span class="Other">,</span> <span class="Identifier">flagNotUnicode</span><span class="Other">,</span> <span class="Identifier">flagVerbose</span><span class="Other">,</span> <span class="Identifier">flagNotVerbose</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="NodeKind"></a>
+<dt><pre><a href="types.html#NodeKind"><span class="Identifier">NodeKind</span></a> <span class="Other">=</span> <span class="Keyword">enum</span>
+  <span class="Identifier">reChar</span><span class="Other">,</span> <span class="Identifier">reCharCi</span><span class="Other">,</span> <span class="Identifier">reJoiner</span><span class="Other">,</span> <span class="Identifier">reGroupStart</span><span class="Other">,</span> <span class="Identifier">reGroupEnd</span><span class="Other">,</span> <span class="Identifier">reOr</span><span class="Other">,</span> <span class="Identifier">reZeroOrMore</span><span class="Other">,</span>
+  <span class="Identifier">reOneOrMore</span><span class="Other">,</span> <span class="Identifier">reZeroOrOne</span><span class="Other">,</span> <span class="Identifier">reRepRange</span><span class="Other">,</span> <span class="Identifier">reStartSym</span><span class="Other">,</span> <span class="Identifier">reEndSym</span><span class="Other">,</span> <span class="Identifier">reStartSymML</span><span class="Other">,</span>
+  <span class="Identifier">reEndSymML</span><span class="Other">,</span> <span class="Identifier">reStart</span><span class="Other">,</span> <span class="Identifier">reEnd</span><span class="Other">,</span> <span class="Identifier">reWordBoundary</span><span class="Other">,</span> <span class="Identifier">reNotWordBoundary</span><span class="Other">,</span> <span class="Identifier">reWord</span><span class="Other">,</span>
+  <span class="Identifier">reDigit</span><span class="Other">,</span> <span class="Identifier">reWhiteSpace</span><span class="Other">,</span> <span class="Identifier">reUCC</span><span class="Other">,</span> <span class="Identifier">reNotAlphaNum</span><span class="Other">,</span> <span class="Identifier">reNotDigit</span><span class="Other">,</span> <span class="Identifier">reNotWhiteSpace</span><span class="Other">,</span>
+  <span class="Identifier">reNotUCC</span><span class="Other">,</span> <span class="Identifier">reAny</span><span class="Other">,</span> <span class="Identifier">reAnyNl</span><span class="Other">,</span> <span class="Identifier">reWordBoundaryAscii</span><span class="Other">,</span> <span class="Identifier">reNotWordBoundaryAscii</span><span class="Other">,</span>
+  <span class="Identifier">reWordAscii</span><span class="Other">,</span> <span class="Identifier">reDigitAscii</span><span class="Other">,</span> <span class="Identifier">reWhiteSpaceAscii</span><span class="Other">,</span> <span class="Identifier">reNotAlphaNumAscii</span><span class="Other">,</span>
+  <span class="Identifier">reNotDigitAscii</span><span class="Other">,</span> <span class="Identifier">reNotWhiteSpaceAscii</span><span class="Other">,</span> <span class="Identifier">reAnyAscii</span><span class="Other">,</span> <span class="Identifier">reAnyNlAscii</span><span class="Other">,</span> <span class="Identifier">reInSet</span><span class="Other">,</span>
+  <span class="Identifier">reNotSet</span><span class="Other">,</span> <span class="Identifier">reLookahead</span><span class="Other">,</span> <span class="Identifier">reLookbehind</span><span class="Other">,</span> <span class="Identifier">reNotLookahead</span><span class="Other">,</span> <span class="Identifier">reNotLookbehind</span><span class="Other">,</span> <span class="Identifier">reSkip</span><span class="Other">,</span>
+  <span class="Identifier">reEoe</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="NodeUid"></a>
+<dt><pre><a href="types.html#NodeUid"><span class="Identifier">NodeUid</span></a> <span class="Other">=</span> <span class="Identifier">int16</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="Node"></a>
+<dt><pre><a href="types.html#Node"><span class="Identifier">Node</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">kind</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#NodeKind"><span class="Identifier">NodeKind</span></a>
+  <span class="Identifier">cp</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">Rune</span>
+  <span class="Identifier">next</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">int16</span><span class="Other">]</span>
+  <span class="Identifier">isGreedy</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
+  <span class="Identifier">uid</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#NodeUid"><span class="Identifier">NodeUid</span></a>
+  <span class="Identifier">idx</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+  <span class="Identifier">isCapturing</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
+  <span class="Identifier">name</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">string</span>
+  <span class="Identifier">flags</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Flag"><span class="Identifier">Flag</span></a><span class="Other">]</span>
+  <span class="Identifier">min</span><span class="Operator">*</span><span class="Other">,</span> <span class="Identifier">max</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">int16</span>
+  <span class="Identifier">cps</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">HashSet</span><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span>
+  <span class="Identifier">ranges</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><span class="Identifier">Slice</span><span class="Other">[</span><span class="Identifier">Rune</span><span class="Other">]</span><span class="Other">]</span>
+  <span class="Identifier">shorthands</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span>
+  <span class="Identifier">cc</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">UnicodeCategorySet</span>
+  <span class="Identifier">subExp</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#SubExp"><span class="Identifier">SubExp</span></a>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="SubExp"></a>
+<dt><pre><a href="types.html#SubExp"><span class="Identifier">SubExp</span></a> <span class="Other">=</span> <span class="Keyword">object</span>
+  <span class="Identifier">nfa</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#Nfa"><span class="Identifier">Nfa</span></a>
+  <span class="Identifier">rpn</span><span class="Operator">*</span><span class="Other">:</span> <a href="types.html#RpnExp"><span class="Identifier">RpnExp</span></a>
+  <span class="Identifier">reverseCapts</span><span class="Operator">*</span><span class="Other">:</span> <span class="Identifier">bool</span>
+</pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="10">
+<h1><a class="toc-backref" href="#10">Consts</a></h1>
+<dl class="item">
+<a id="opKind"></a>
+<dt><pre><a href="types.html#opKind"><span class="Identifier">opKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reJoiner</span><span class="Other">,</span> <span class="DecNumber">reOr</span><span class="Other">,</span> <span class="DecNumber">reZeroOrMore</span><span class="Other">,</span> <span class="DecNumber">reOneOrMore</span><span class="Other">,</span> <span class="DecNumber">reZeroOrOne</span><span class="Other">,</span> <span class="DecNumber">reRepRange</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="assertionKind"></a>
+<dt><pre><a href="types.html#assertionKind"><span class="Identifier">assertionKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reStartSym</span><span class="Other">,</span> <span class="DecNumber">reEndSym</span><span class="Other">,</span> <span class="DecNumber">reStartSymML</span><span class="Other">,</span> <span class="DecNumber">reEndSymML</span><span class="Other">,</span> <span class="DecNumber">reStart</span><span class="Other">,</span> <span class="DecNumber">reEnd</span><span class="Other">,</span>
+                 <span class="DecNumber">reWordBoundary</span><span class="Other">,</span> <span class="DecNumber">reNotWordBoundary</span><span class="Other">,</span> <span class="DecNumber">reWordBoundaryAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotWordBoundaryAscii</span><span class="Other">,</span> <span class="DecNumber">reLookahead</span><span class="Other">,</span> <span class="DecNumber">reLookbehind</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotLookahead</span><span class="Other">,</span> <span class="DecNumber">reNotLookbehind</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="lookaroundKind"></a>
+<dt><pre><a href="types.html#lookaroundKind"><span class="Identifier">lookaroundKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reLookahead</span><span class="Other">,</span> <span class="DecNumber">reLookbehind</span><span class="Other">,</span> <span class="DecNumber">reNotLookahead</span><span class="Other">,</span> <span class="DecNumber">reNotLookbehind</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="lookaheadKind"></a>
+<dt><pre><a href="types.html#lookaheadKind"><span class="Identifier">lookaheadKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reLookahead</span><span class="Other">,</span> <span class="DecNumber">reNotLookahead</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="lookbehindKind"></a>
+<dt><pre><a href="types.html#lookbehindKind"><span class="Identifier">lookbehindKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reLookbehind</span><span class="Other">,</span> <span class="DecNumber">reNotLookbehind</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="shorthandKind"></a>
+<dt><pre><a href="types.html#shorthandKind"><span class="Identifier">shorthandKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reWord</span><span class="Other">,</span> <span class="DecNumber">reDigit</span><span class="Other">,</span> <span class="DecNumber">reWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reUCC</span><span class="Other">,</span> <span class="DecNumber">reNotAlphaNum</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotDigit</span><span class="Other">,</span> <span class="DecNumber">reNotWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reNotUCC</span><span class="Other">,</span> <span class="DecNumber">reWordAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reDigitAscii</span><span class="Other">,</span> <span class="DecNumber">reWhiteSpaceAscii</span><span class="Other">,</span> <span class="DecNumber">reNotAlphaNumAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotDigitAscii</span><span class="Other">,</span> <span class="DecNumber">reNotWhiteSpaceAscii</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="matchableKind"></a>
+<dt><pre><a href="types.html#matchableKind"><span class="Identifier">matchableKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reChar</span><span class="Other">,</span> <span class="DecNumber">reCharCi</span><span class="Other">,</span> <span class="DecNumber">reWord</span><span class="Other">,</span> <span class="DecNumber">reDigit</span><span class="Other">,</span> <span class="DecNumber">reWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reUCC</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotAlphaNum</span><span class="Other">,</span> <span class="DecNumber">reNotDigit</span><span class="Other">,</span> <span class="DecNumber">reNotWhiteSpace</span><span class="Other">,</span> <span class="DecNumber">reNotUCC</span><span class="Other">,</span> <span class="DecNumber">reAny</span><span class="Other">,</span>
+                 <span class="DecNumber">reAnyNl</span><span class="Other">,</span> <span class="DecNumber">reInSet</span><span class="Other">,</span> <span class="DecNumber">reNotSet</span><span class="Other">,</span> <span class="DecNumber">reWordAscii</span><span class="Other">,</span> <span class="DecNumber">reDigitAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reWhiteSpaceAscii</span><span class="Other">,</span> <span class="DecNumber">reNotAlphaNumAscii</span><span class="Other">,</span> <span class="DecNumber">reNotDigitAscii</span><span class="Other">,</span>
+                 <span class="DecNumber">reNotWhiteSpaceAscii</span><span class="Other">,</span> <span class="DecNumber">reAnyAscii</span><span class="Other">,</span> <span class="DecNumber">reAnyNlAscii</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="repetitionKind"></a>
+<dt><pre><a href="types.html#repetitionKind"><span class="Identifier">repetitionKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reZeroOrMore</span><span class="Other">,</span> <span class="DecNumber">reOneOrMore</span><span class="Other">,</span> <span class="DecNumber">reRepRange</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="groupKind"></a>
+<dt><pre><a href="types.html#groupKind"><span class="Identifier">groupKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reGroupStart</span><span class="Other">,</span> <span class="DecNumber">reGroupEnd</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+<a id="groupStartKind"></a>
+<dt><pre><a href="types.html#groupStartKind"><span class="Identifier">groupStartKind</span></a> <span class="Other">=</span> <span class="Other">{</span><span class="DecNumber">reGroupStart</span><span class="Other">,</span> <span class="DecNumber">reLookahead</span><span class="Other">..</span><span class="DecNumber">reNotLookbehind</span><span class="Other">}</span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+<div class="section" id="12">
+<h1><a class="toc-backref" href="#12">Procs</a></h1>
+<dl class="item">
+<a id="toCharNode,Rune"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toCharNode%2CRune"><span class="Identifier">toCharNode</span></a><span class="Other">(</span><span class="Identifier">r</span><span class="Other">:</span> <span class="Identifier">Rune</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a <tt class="docutils literal"><span class="pre">Node</span></tt> that is meant to be matched against text characters
+
+</dd>
+<a id="initJoinerNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initJoinerNode"><span class="Identifier">initJoinerNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a <tt class="docutils literal"><span class="pre">Node</span></tt> of <tt class="docutils literal"><span class="pre">reJoiner</span></tt> kind. Joiners are temporary nodes, they serve to generate the NFA but they are never part of it
+
+</dd>
+<a id="initEoeNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initEoeNode"><span class="Identifier">initEoeNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return the end-of-expression <tt class="docutils literal"><span class="pre">Node</span></tt>. This is a dummy node that marks a match as successful
+
+</dd>
+<a id="initSetNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initSetNode"><span class="Identifier">initSetNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a set <tt class="docutils literal"><span class="pre">Node</span></tt>, parsed from an expression such as <tt class="docutils literal"><span class="pre">[a-z]</span></tt>
+
+</dd>
+<a id="initNotSetNode"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initNotSetNode"><span class="Identifier">initNotSetNode</span></a><span class="Other">(</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a negated set <tt class="docutils literal"><span class="pre">Node</span></tt>, parsed from an expression such as <tt class="docutils literal"><span class="pre">[^a-z]</span></tt>
+
+</dd>
+<a id="initGroupStart,string,seq[Flag]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initGroupStart%2Cstring%2Cseq%5BFlag%5D"><span class="Identifier">initGroupStart</span></a><span class="Other">(</span><span class="Identifier">name</span><span class="Other">:</span> <span class="Identifier">string</span> <span class="Other">=</span> <span class="StringLit">&quot;&quot;</span><span class="Other">;</span> <span class="Identifier">flags</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Flag"><span class="Identifier">Flag</span></a><span class="Other">]</span> <span class="Other">=</span> <span class="Operator">@</span><span class="Other">[</span><span class="Other">]</span><span class="Other">;</span>
+                    <span class="Identifier">isCapturing</span> <span class="Other">=</span> <span class="Identifier">true</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return a <tt class="docutils literal"><span class="pre">reGroupStart</span></tt> node
+
+</dd>
+<a id="initSkipNode,openArray[int16]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#initSkipNode%2CopenArray%5Bint16%5D"><span class="Identifier">initSkipNode</span></a><span class="Other">(</span><span class="Identifier">next</span><span class="Other">:</span> <span class="Identifier">openArray</span><span class="Other">[</span><span class="Identifier">int16</span><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+Return a dummy node that should be skipped while traversing the NFA
+
+</dd>
+<a id="isEmpty,Node"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#isEmpty%2CNode"><span class="Identifier">isEmpty</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">bool</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+check if a set <tt class="docutils literal"><span class="pre">Node</span></tt> is empty
+
+</dd>
+<a id="$,Node"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#%24%2CNode"><span class="Identifier">`$`</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+return the string representation of a <tt class="docutils literal"><span class="pre">Node</span></tt>. The string is always equivalent to the original expression but not necessarily equal
+
+</dd>
+<a id="toString,seq[Node]"></a>
+<dt><pre><span class="Keyword">func</span> <a href="#toString%2Cseq%5BNode%5D"><span class="Identifier">toString</span></a><span class="Other">(</span><span class="Identifier">n</span><span class="Other">:</span> <span class="Identifier">seq</span><span class="Other">[</span><a href="types.html#Node"><span class="Identifier">Node</span></a><span class="Other">]</span><span class="Other">)</span><span class="Other">:</span> <span class="Identifier">string</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
+<dd>
+
+
+
+</dd>
+
+</dl></div>
+
+  </div>
+</div>
+
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:28 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/docs/regex/types.idx b/docs/regex/types.idx
new file mode 100644
index 0000000..c45fae8
--- /dev/null
+++ b/docs/regex/types.idx
@@ -0,0 +1,89 @@
+RpnExp	regex/types.html#RpnExp	types: RpnExp	
+Enfa	regex/types.html#Enfa	types: Enfa	
+TransitionsAll	regex/types.html#TransitionsAll	types: TransitionsAll	
+ZclosureStates	regex/types.html#ZclosureStates	types: ZclosureStates	
+Transitions	regex/types.html#Transitions	types: Transitions	
+Nfa	regex/types.html#Nfa	types: Nfa	
+flagCaseInsensitive	regex/types.html#flagCaseInsensitive	Flag.flagCaseInsensitive	
+flagNotCaseInsensitive	regex/types.html#flagNotCaseInsensitive	Flag.flagNotCaseInsensitive	
+flagMultiLine	regex/types.html#flagMultiLine	Flag.flagMultiLine	
+flagNotMultiLine	regex/types.html#flagNotMultiLine	Flag.flagNotMultiLine	
+flagAnyMatchNewLine	regex/types.html#flagAnyMatchNewLine	Flag.flagAnyMatchNewLine	
+flagNotAnyMatchNewLine	regex/types.html#flagNotAnyMatchNewLine	Flag.flagNotAnyMatchNewLine	
+flagUnGreedy	regex/types.html#flagUnGreedy	Flag.flagUnGreedy	
+flagNotUnGreedy	regex/types.html#flagNotUnGreedy	Flag.flagNotUnGreedy	
+flagUnicode	regex/types.html#flagUnicode	Flag.flagUnicode	
+flagNotUnicode	regex/types.html#flagNotUnicode	Flag.flagNotUnicode	
+flagVerbose	regex/types.html#flagVerbose	Flag.flagVerbose	
+flagNotVerbose	regex/types.html#flagNotVerbose	Flag.flagNotVerbose	
+Flag	regex/types.html#Flag	types: Flag	
+reChar	regex/types.html#reChar	NodeKind.reChar	
+reCharCi	regex/types.html#reCharCi	NodeKind.reCharCi	
+reJoiner	regex/types.html#reJoiner	NodeKind.reJoiner	
+reGroupStart	regex/types.html#reGroupStart	NodeKind.reGroupStart	
+reGroupEnd	regex/types.html#reGroupEnd	NodeKind.reGroupEnd	
+reOr	regex/types.html#reOr	NodeKind.reOr	
+reZeroOrMore	regex/types.html#reZeroOrMore	NodeKind.reZeroOrMore	
+reOneOrMore	regex/types.html#reOneOrMore	NodeKind.reOneOrMore	
+reZeroOrOne	regex/types.html#reZeroOrOne	NodeKind.reZeroOrOne	
+reRepRange	regex/types.html#reRepRange	NodeKind.reRepRange	
+reStartSym	regex/types.html#reStartSym	NodeKind.reStartSym	
+reEndSym	regex/types.html#reEndSym	NodeKind.reEndSym	
+reStartSymML	regex/types.html#reStartSymML	NodeKind.reStartSymML	
+reEndSymML	regex/types.html#reEndSymML	NodeKind.reEndSymML	
+reStart	regex/types.html#reStart	NodeKind.reStart	
+reEnd	regex/types.html#reEnd	NodeKind.reEnd	
+reWordBoundary	regex/types.html#reWordBoundary	NodeKind.reWordBoundary	
+reNotWordBoundary	regex/types.html#reNotWordBoundary	NodeKind.reNotWordBoundary	
+reWord	regex/types.html#reWord	NodeKind.reWord	
+reDigit	regex/types.html#reDigit	NodeKind.reDigit	
+reWhiteSpace	regex/types.html#reWhiteSpace	NodeKind.reWhiteSpace	
+reUCC	regex/types.html#reUCC	NodeKind.reUCC	
+reNotAlphaNum	regex/types.html#reNotAlphaNum	NodeKind.reNotAlphaNum	
+reNotDigit	regex/types.html#reNotDigit	NodeKind.reNotDigit	
+reNotWhiteSpace	regex/types.html#reNotWhiteSpace	NodeKind.reNotWhiteSpace	
+reNotUCC	regex/types.html#reNotUCC	NodeKind.reNotUCC	
+reAny	regex/types.html#reAny	NodeKind.reAny	
+reAnyNl	regex/types.html#reAnyNl	NodeKind.reAnyNl	
+reWordBoundaryAscii	regex/types.html#reWordBoundaryAscii	NodeKind.reWordBoundaryAscii	
+reNotWordBoundaryAscii	regex/types.html#reNotWordBoundaryAscii	NodeKind.reNotWordBoundaryAscii	
+reWordAscii	regex/types.html#reWordAscii	NodeKind.reWordAscii	
+reDigitAscii	regex/types.html#reDigitAscii	NodeKind.reDigitAscii	
+reWhiteSpaceAscii	regex/types.html#reWhiteSpaceAscii	NodeKind.reWhiteSpaceAscii	
+reNotAlphaNumAscii	regex/types.html#reNotAlphaNumAscii	NodeKind.reNotAlphaNumAscii	
+reNotDigitAscii	regex/types.html#reNotDigitAscii	NodeKind.reNotDigitAscii	
+reNotWhiteSpaceAscii	regex/types.html#reNotWhiteSpaceAscii	NodeKind.reNotWhiteSpaceAscii	
+reAnyAscii	regex/types.html#reAnyAscii	NodeKind.reAnyAscii	
+reAnyNlAscii	regex/types.html#reAnyNlAscii	NodeKind.reAnyNlAscii	
+reInSet	regex/types.html#reInSet	NodeKind.reInSet	
+reNotSet	regex/types.html#reNotSet	NodeKind.reNotSet	
+reLookahead	regex/types.html#reLookahead	NodeKind.reLookahead	
+reLookbehind	regex/types.html#reLookbehind	NodeKind.reLookbehind	
+reNotLookahead	regex/types.html#reNotLookahead	NodeKind.reNotLookahead	
+reNotLookbehind	regex/types.html#reNotLookbehind	NodeKind.reNotLookbehind	
+reSkip	regex/types.html#reSkip	NodeKind.reSkip	
+reEoe	regex/types.html#reEoe	NodeKind.reEoe	
+NodeKind	regex/types.html#NodeKind	types: NodeKind	
+NodeUid	regex/types.html#NodeUid	types: NodeUid	
+Node	regex/types.html#Node	types: Node	
+SubExp	regex/types.html#SubExp	types: SubExp	
+toCharNode	regex/types.html#toCharNode,Rune	types: toCharNode(r: Rune): Node	
+initJoinerNode	regex/types.html#initJoinerNode	types: initJoinerNode(): Node	
+initEoeNode	regex/types.html#initEoeNode	types: initEoeNode(): Node	
+initSetNode	regex/types.html#initSetNode	types: initSetNode(): Node	
+initNotSetNode	regex/types.html#initNotSetNode	types: initNotSetNode(): Node	
+initGroupStart	regex/types.html#initGroupStart,string,seq[Flag]	types: initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node	
+initSkipNode	regex/types.html#initSkipNode,openArray[int16]	types: initSkipNode(next: openArray[int16]): Node	
+isEmpty	regex/types.html#isEmpty,Node	types: isEmpty(n: Node): bool	
+opKind	regex/types.html#opKind	types: opKind	
+assertionKind	regex/types.html#assertionKind	types: assertionKind	
+lookaroundKind	regex/types.html#lookaroundKind	types: lookaroundKind	
+lookaheadKind	regex/types.html#lookaheadKind	types: lookaheadKind	
+lookbehindKind	regex/types.html#lookbehindKind	types: lookbehindKind	
+shorthandKind	regex/types.html#shorthandKind	types: shorthandKind	
+matchableKind	regex/types.html#matchableKind	types: matchableKind	
+repetitionKind	regex/types.html#repetitionKind	types: repetitionKind	
+groupKind	regex/types.html#groupKind	types: groupKind	
+groupStartKind	regex/types.html#groupStartKind	types: groupStartKind	
+`$`	regex/types.html#$,Node	types: `$`(n: Node): string	
+toString	regex/types.html#toString,seq[Node]	types: toString(n: seq[Node]): string	
diff --git a/docs/theindex.html b/docs/theindex.html
new file mode 100644
index 0000000..dc60f43
--- /dev/null
+++ b/docs/theindex.html
@@ -0,0 +1,1085 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--  This file is generated by Nim. -->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+<!-- Favicon -->
+<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAUAAAAF////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAIAAABbAAAAlQAAAKIAAACbAAAAmwAAAKIAAACVAAAAWwAAAAL///8A////AP///wD///8A////AAAAABQAAADAAAAAYwAAAA3///8A////AP///wD///8AAAAADQAAAGMAAADAAAAAFP///wD///8A////AP///wAAAACdAAAAOv///wD///8A////AP///wD///8A////AP///wD///8AAAAAOgAAAJ3///8A////AP///wAAAAAnAAAAcP///wAAAAAoAAAASv///wD///8A////AP///wAAAABKAAAAKP///wAAAABwAAAAJ////wD///8AAAAAgQAAABwAAACIAAAAkAAAAJMAAACtAAAAFQAAABUAAACtAAAAkwAAAJAAAACIAAAAHAAAAIH///8A////AAAAAKQAAACrAAAAaP///wD///8AAAAARQAAANIAAADSAAAARf///wD///8AAAAAaAAAAKsAAACk////AAAAADMAAACcAAAAnQAAABj///8A////AP///wAAAAAYAAAAGP///wD///8A////AAAAABgAAACdAAAAnAAAADMAAAB1AAAAwwAAAP8AAADpAAAAsQAAAE4AAAAb////AP///wAAAAAbAAAATgAAALEAAADpAAAA/wAAAMMAAAB1AAAAtwAAAOkAAAD/AAAA/wAAAP8AAADvAAAA3gAAAN4AAADeAAAA3gAAAO8AAAD/AAAA/wAAAP8AAADpAAAAtwAAAGUAAAA/AAAA3wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADfAAAAPwAAAGX///8A////AAAAAEgAAADtAAAAvwAAAL0AAADGAAAA7wAAAO8AAADGAAAAvQAAAL8AAADtAAAASP///wD///8A////AP///wD///8AAAAAO////wD///8A////AAAAAIcAAACH////AP///wD///8AAAAAO////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD4HwAA7/cAAN/7AAD//wAAoYUAAJ55AACf+QAAh+EAAAAAAADAAwAA4AcAAP5/AAD//wAA//8AAA=="/>
+<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4QQQEwksSS9ZWwAAAk1JREFUWMPtll2ITVEUx39nn/O7Y5qR8f05wtCUUr6ZIS++8pEnkZInPImneaCQ5METNdOkeFBKUhMPRIkHKfEuUZSUlGlKPN2TrgfncpvmnntnmlEyq1Z7t89/rf9a6+y99oZxGZf/XeIq61EdtgKXgdXA0xrYAvBjOIF1AI9zvjcC74BSpndrJPkBWDScTF8Aa4E3wDlgHbASaANmVqlcCnwHvgDvgVfAJ+AikAAvgfVZwLnSVZHZaOuKoQi3ZOMi4NkYkpe1p4J7A8BpYAD49hfIy/oqG0+hLomiKP2L5L+1ubn5115S+3OAn4EnwBlgMzCjyt6ZAnQCJ4A7wOs88iRJHvw50HoujuPBoCKwHWiosy8MdfZnAdcHk8dxXFJ3VQbQlCTJvRBCGdRbD4M6uc5glpY3eAihpN5S5w12diSEcCCEcKUO4ljdr15T76ur1FDDLIQQ3qv71EdDOe3Kxj3leRXyk+pxdWnFWod6Wt2bY3de3aSuUHcPBVimHs7mK9WrmeOF6lR1o9qnzskh2ar2qm1qizpfXaPeVGdlmGN5pb09qMxz1Xb1kLqgzn1RyH7JUXW52lr5e/Kqi9qpto7V1atuUzfnARrV7jEib1T76gG2qxdGmXyiekkt1GswPTtek0aBfJp6YySGBfWg2tPQ0FAYgf1stUfdmdcjarbYJEniKIq6gY/Aw+zWHAC+p2labGpqiorFYgGYCEzN7oQdQClN07O1/EfDyGgC0ALMBdYAi4FyK+4H3gLPsxfR1zRNi+NP7nH5J+QntnXe5B5mpfQAAAAASUVORK5CYII=">
+
+<!-- Google fonts -->
+<link href='https://fonts.googleapis.com/css?family=Lato:400,600,900' rel='stylesheet' type='text/css'/>
+<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro:400,500,600' rel='stylesheet' type='text/css'/>
+
+<!-- CSS -->
+<title>Index</title>
+<link rel="stylesheet" type="text/css" href="nimdoc.out.css">
+
+<script type="text/javascript" src="dochack.js"></script>
+
+<script type="text/javascript">
+function main() {
+  var pragmaDots = document.getElementsByClassName("pragmadots");
+  for (var i = 0; i < pragmaDots.length; i++) {
+    pragmaDots[i].onclick = function(event) {
+      // Hide tease
+      event.target.parentNode.style.display = "none";
+      // Show actual
+      event.target.parentNode.nextElementSibling.style.display = "inline";
+    }
+  }
+
+  const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
+  function switchTheme(e) {
+      if (e.target.checked) {
+          document.documentElement.setAttribute('data-theme', 'dark');
+          localStorage.setItem('theme', 'dark');
+      } else {
+          document.documentElement.setAttribute('data-theme', 'light');
+          localStorage.setItem('theme', 'light');
+      }
+  }
+
+  toggleSwitch.addEventListener('change', switchTheme, false);
+
+  const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
+  if (currentTheme) {
+    document.documentElement.setAttribute('data-theme', currentTheme);
+
+    if (currentTheme === 'dark') {
+      toggleSwitch.checked = true;
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', main);
+</script>
+
+</head>
+<body>
+<div class="document" id="documentId">
+  <div class="container">
+    <h1 class="title">Index</h1>
+    Modules: <a href="regex.html">regex</a>, <a href="regex/common.html">regex/common</a>, <a href="regex/compiler.html">regex/compiler</a>, <a href="regex/dotgraph.html">regex/dotgraph</a>, <a href="regex/exptransformation.html">regex/exptransformation</a>, <a href="regex/exptype.html">regex/exptype</a>, <a href="regex/litopt.html">regex/litopt</a>, <a href="regex/nfa.html">regex/nfa</a>, <a href="regex/nfafindall.html">regex/nfafindall</a>, <a href="regex/nfamacro.html">regex/nfamacro</a>, <a href="regex/nfamatch.html">regex/nfamatch</a>, <a href="regex/nfatype.html">regex/nfatype</a>, <a href="regex/nodematch.html">regex/nodematch</a>, <a href="regex/nodetype.html">regex/nodetype</a>, <a href="regex/parser.html">regex/parser</a>, <a href="regex/scanner.html">regex/scanner</a>, <a href="regex/types.html">regex/types</a>.<br/><p /><h2>API symbols</h2>
+<dl><dt><a name="%60%24%60" href="#%60%24%60"><span>`$`:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: `$`(n: Node): string" href="regex/types.html#%24%2CNode">types: `$`(n: Node): string</a></li>
+          </ul></dd>
+<dt><a name="%60%25%25%60" href="#%60%25%25%60"><span>`%%`:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: `%%`(formatstr: string; a: openArray[string]): string" href="regex/common.html#%25%25%2Cstring%2CopenArray%5Bstring%5D">common: `%%`(formatstr: string; a: openArray[string]): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="common: `%%`(formatstr: string; a: string): string" href="regex/common.html#%25%25%2Cstring%2Cstring">common: `%%`(formatstr: string; a: string): string</a></li>
+          </ul></dd>
+<dt><a name="%60%26lt%3B%3D%60" href="#%60%26lt%3B%3D%60"><span>`&lt;=`:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: `&lt;=`(x, y: Rune): bool" href="regex/common.html#%3C%3D%2CRune%2CRune">common: `&lt;=`(x, y: Rune): bool</a></li>
+          </ul></dd>
+<dt><a name="%60%5B%5D%60" href="#%60%5B%5D%60"><span>`[]`:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: `[]`(sm: Submatches; i: int): PState" href="regex/nfatype.html#%5B%5D%2CSubmatches%2Cint">nfatype: `[]`(sm: Submatches; i: int): PState</a></li>
+          </ul></dd>
+<dt><a name="add" href="#add"><span>add:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: add(sm: var Submatches; item: PState)" href="regex/nfatype.html#add%2CSubmatches%2CPState">nfatype: add(sm: var Submatches; item: PState)</a></li>
+          </ul></dd>
+<dt><a name="assertionKind" href="#assertionKind"><span>assertionKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: assertionKind" href="regex/nodetype.html#assertionKind">nodetype: assertionKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: assertionKind" href="regex/types.html#assertionKind">types: assertionKind</a></li>
+          </ul></dd>
+<dt><a name="AtomsExp" href="#AtomsExp"><span>AtomsExp:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="exptype: AtomsExp" href="regex/exptype.html#AtomsExp">exptype: AtomsExp</a></li>
+          </ul></dd>
+<dt><a name="bounds" href="#bounds"><span>bounds:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: bounds(ms: RegexMatches): Slice[int]" href="regex/nfafindall.html#bounds.i%2CRegexMatches">nfafindall: bounds(ms: RegexMatches): Slice[int]</a></li>
+          </ul></dd>
+<dt><a name="Bounds" href="#Bounds"><span>Bounds:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: Bounds" href="regex/nfatype.html#Bounds">nfatype: Bounds</a></li>
+          </ul></dd>
+<dt><a name="bwFastRuneAt" href="#bwFastRuneAt"><span>bwFastRuneAt:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: bwFastRuneAt(s: string; n: var int; result: var Rune): untyped" href="regex/common.html#bwFastRuneAt.t%2Cstring%2Cint%2CRune">common: bwFastRuneAt(s: string; n: var int; result: var Rune): untyped</a></li>
+          </ul></dd>
+<dt><a name="bwRuneAt" href="#bwRuneAt"><span>bwRuneAt:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: bwRuneAt(s: string; n: int): Rune" href="regex/common.html#bwRuneAt%2Cstring%2Cint">common: bwRuneAt(s: string; n: int): Rune</a></li>
+          </ul></dd>
+<dt><a name="canOpt" href="#canOpt"><span>canOpt:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="litopt: canOpt(litOpt: LitOpt): bool" href="regex/litopt.html#canOpt%2CLitOpt">litopt: canOpt(litOpt: LitOpt): bool</a></li>
+          </ul></dd>
+<dt><a name="cap" href="#cap"><span>cap:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: cap(sm: Submatches): int" href="regex/nfatype.html#cap%2CSubmatches">nfatype: cap(sm: Submatches): int</a></li>
+          </ul></dd>
+<dt><a name="CaptIdx" href="#CaptIdx"><span>CaptIdx:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: CaptIdx" href="regex/nfatype.html#CaptIdx">nfatype: CaptIdx</a></li>
+          </ul></dd>
+<dt><a name="CaptNode" href="#CaptNode"><span>CaptNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: CaptNode" href="regex/nfatype.html#CaptNode">nfatype: CaptNode</a></li>
+          </ul></dd>
+<dt><a name="Capts" href="#Capts"><span>Capts:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: Capts" href="regex/nfatype.html#Capts">nfatype: Capts</a></li>
+          </ul></dd>
+<dt><a name="Captures" href="#Captures"><span>Captures:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: Captures" href="regex/nfatype.html#Captures">nfatype: Captures</a></li>
+          </ul></dd>
+<dt><a name="clear" href="#clear"><span>clear:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: clear(m: var RegexMatch)" href="regex/nfatype.html#clear%2CRegexMatch">nfatype: clear(m: var RegexMatch)</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nfatype: clear(sm: var Submatches)" href="regex/nfatype.html#clear%2CSubmatches">nfatype: clear(sm: var Submatches)</a></li>
+          </ul></dd>
+<dt><a name="cmp" href="#cmp"><span>cmp:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: cmp(x, y: Rune): int" href="regex/common.html#cmp%2CRune%2CRune">common: cmp(x, y: Rune): int</a></li>
+          </ul></dd>
+<dt><a name="constructSubmatches" href="#constructSubmatches"><span>constructSubmatches:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: constructSubmatches(captures: var Captures; capts: Capts; capt, size: int)" href="regex/nfatype.html#constructSubmatches%2CCaptures%2CCapts%2Cint%2Cint">nfatype: constructSubmatches(captures: var Captures; capts: Capts; capt, size: int)</a></li>
+          </ul></dd>
+<dt><a name="contains" href="#contains"><span>contains:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: contains(s: string; pattern: Regex): bool" href="regex.html#contains%2Cstring%2CRegex">regex: contains(s: string; pattern: Regex): bool</a></li>
+          </ul></dd>
+<dt><a name="curr" href="#curr"><span>curr:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: curr[T](sc: Scanner[T]): T" href="regex/scanner.html#curr%2CScanner%5BT%5D">scanner: curr[T](sc: Scanner[T]): T</a></li>
+          </ul></dd>
+<dt><a name="dummyMatch" href="#dummyMatch"><span>dummyMatch:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: dummyMatch(ms: var RegexMatches; i: int)" href="regex/nfafindall.html#dummyMatch%2CRegexMatches%2Cint">nfafindall: dummyMatch(ms: var RegexMatches; i: int)</a></li>
+          </ul></dd>
+<dt><a name="endsWith" href="#endsWith"><span>endsWith:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: endsWith(s: string; pattern: Regex): bool" href="regex.html#endsWith%2Cstring%2CRegex">regex: endsWith(s: string; pattern: Regex): bool</a></li>
+          </ul></dd>
+<dt><a name="eNfa" href="#eNfa"><span>eNfa:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfa: eNfa(exp: RpnExp): Enfa" href="regex/nfa.html#eNfa%2CRpnExp">nfa: eNfa(exp: RpnExp): Enfa</a></li>
+          </ul></dd>
+<dt><a name="Enfa" href="#Enfa"><span>Enfa:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: Enfa" href="regex/types.html#Enfa">types: Enfa</a></li>
+          </ul></dd>
+<dt><a name="eRemoval" href="#eRemoval"><span>eRemoval:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfa: eRemoval(eNfa: Enfa): Nfa" href="regex/nfa.html#eRemoval%2CEnfa">nfa: eRemoval(eNfa: Enfa): Nfa</a></li>
+          </ul></dd>
+<dt><a name="escapeRe" href="#escapeRe"><span>escapeRe:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: escapeRe(s: string): string" href="regex.html#escapeRe%2Cstring">regex: escapeRe(s: string): string</a></li>
+          </ul></dd>
+<dt><a name="Exp" href="#Exp"><span>Exp:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="exptype: Exp" href="regex/exptype.html#Exp">exptype: Exp</a></li>
+          </ul></dd>
+<dt><a name="fillMatchImpl" href="#fillMatchImpl"><span>fillMatchImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: fillMatchImpl(m: var RegexMatch; mi: MatchItemIdx; ms: RegexMatches;
+              regex: Regex)" href="regex/nfafindall.html#fillMatchImpl%2CRegexMatch%2CMatchItemIdx%2CRegexMatches%2CRegex">nfafindall: fillMatchImpl(m: var RegexMatch; mi: MatchItemIdx; ms: RegexMatches;
+              regex: Regex)</a></li>
+          </ul></dd>
+<dt><a name="find" href="#find"><span>find:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: find(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool" href="regex.html#find%2Cstring%2CRegex%2CRegexMatch%2Cint">regex: find(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="scanner: find(sc: Scanner[Rune]; r: Rune): int" href="regex/scanner.html#find%2CScanner%5BRune%5D%2CRune">scanner: find(sc: Scanner[Rune]; r: Rune): int</a></li>
+          </ul></dd>
+<dt><a name="findAll" href="#findAll"><span>findAll:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: findAll(s: string; pattern: Regex; start = 0): seq[RegexMatch]" href="regex.html#findAll%2Cstring%2CRegex%2Cint">regex: findAll(s: string; pattern: Regex; start = 0): seq[RegexMatch]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: findAll(s: string; pattern: Regex; start = 0): RegexMatch" href="regex.html#findAll.i%2Cstring%2CRegex%2Cint">regex: findAll(s: string; pattern: Regex; start = 0): RegexMatch</a></li>
+          </ul></dd>
+<dt><a name="findAllBounds" href="#findAllBounds"><span>findAllBounds:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: findAllBounds(s: string; pattern: Regex; start = 0): seq[Slice[int]]" href="regex.html#findAllBounds%2Cstring%2CRegex%2Cint">regex: findAllBounds(s: string; pattern: Regex; start = 0): seq[Slice[int]]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: findAllBounds(s: string; pattern: Regex; start = 0): Slice[int]" href="regex.html#findAllBounds.i%2Cstring%2CRegex%2Cint">regex: findAllBounds(s: string; pattern: Regex; start = 0): Slice[int]</a></li>
+          </ul></dd>
+<dt><a name="findAndCaptureAll" href="#findAndCaptureAll"><span>findAndCaptureAll:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: findAndCaptureAll(s: string; pattern: Regex): seq[string]" href="regex.html#findAndCaptureAll%2Cstring%2CRegex">regex: findAndCaptureAll(s: string; pattern: Regex): seq[string]</a></li>
+          </ul></dd>
+<dt><a name="findSomeImpl" href="#findSomeImpl"><span>findSomeImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: findSomeImpl(text: string; regex: Regex; ms: var RegexMatches;
+             start: Natural = 0; flags: set[MatchFlag] = {}): int" href="regex/nfafindall.html#findSomeImpl%2Cstring%2CRegex%2CRegexMatches%2CNatural%2Cset%5BMatchFlag%5D">nfafindall: findSomeImpl(text: string; regex: Regex; ms: var RegexMatches;
+             start: Natural = 0; flags: set[MatchFlag] = {}): int</a></li>
+          </ul></dd>
+<dt><a name="findSomeOptImpl" href="#findSomeOptImpl"><span>findSomeOptImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: findSomeOptImpl(text: string; regex: Regex; ms: var RegexMatches; start: Natural): int" href="regex/nfafindall.html#findSomeOptImpl%2Cstring%2CRegex%2CRegexMatches%2CNatural">nfafindall: findSomeOptImpl(text: string; regex: Regex; ms: var RegexMatches; start: Natural): int</a></li>
+          </ul></dd>
+<dt><a name="finished" href="#finished"><span>finished:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: finished[T](sc: Scanner[T]): bool" href="regex/scanner.html#finished%2CScanner%5BT%5D">scanner: finished[T](sc: Scanner[T]): bool</a></li>
+          </ul></dd>
+<dt><a name="Flag" href="#Flag"><span>Flag:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: Flag" href="regex/nodetype.html#Flag">nodetype: Flag</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: Flag" href="regex/types.html#Flag">types: Flag</a></li>
+          </ul></dd>
+<dt><a name="flagAnyMatchNewLine" href="#flagAnyMatchNewLine"><span>flagAnyMatchNewLine:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagAnyMatchNewLine" href="regex/nodetype.html#flagAnyMatchNewLine">Flag.flagAnyMatchNewLine</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagAnyMatchNewLine" href="regex/types.html#flagAnyMatchNewLine">Flag.flagAnyMatchNewLine</a></li>
+          </ul></dd>
+<dt><a name="flagCaseInsensitive" href="#flagCaseInsensitive"><span>flagCaseInsensitive:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagCaseInsensitive" href="regex/nodetype.html#flagCaseInsensitive">Flag.flagCaseInsensitive</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagCaseInsensitive" href="regex/types.html#flagCaseInsensitive">Flag.flagCaseInsensitive</a></li>
+          </ul></dd>
+<dt><a name="flagMultiLine" href="#flagMultiLine"><span>flagMultiLine:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagMultiLine" href="regex/nodetype.html#flagMultiLine">Flag.flagMultiLine</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagMultiLine" href="regex/types.html#flagMultiLine">Flag.flagMultiLine</a></li>
+          </ul></dd>
+<dt><a name="flagNotAnyMatchNewLine" href="#flagNotAnyMatchNewLine"><span>flagNotAnyMatchNewLine:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotAnyMatchNewLine" href="regex/nodetype.html#flagNotAnyMatchNewLine">Flag.flagNotAnyMatchNewLine</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotAnyMatchNewLine" href="regex/types.html#flagNotAnyMatchNewLine">Flag.flagNotAnyMatchNewLine</a></li>
+          </ul></dd>
+<dt><a name="flagNotCaseInsensitive" href="#flagNotCaseInsensitive"><span>flagNotCaseInsensitive:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotCaseInsensitive" href="regex/nodetype.html#flagNotCaseInsensitive">Flag.flagNotCaseInsensitive</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotCaseInsensitive" href="regex/types.html#flagNotCaseInsensitive">Flag.flagNotCaseInsensitive</a></li>
+          </ul></dd>
+<dt><a name="flagNotMultiLine" href="#flagNotMultiLine"><span>flagNotMultiLine:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotMultiLine" href="regex/nodetype.html#flagNotMultiLine">Flag.flagNotMultiLine</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotMultiLine" href="regex/types.html#flagNotMultiLine">Flag.flagNotMultiLine</a></li>
+          </ul></dd>
+<dt><a name="flagNotUnGreedy" href="#flagNotUnGreedy"><span>flagNotUnGreedy:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotUnGreedy" href="regex/nodetype.html#flagNotUnGreedy">Flag.flagNotUnGreedy</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotUnGreedy" href="regex/types.html#flagNotUnGreedy">Flag.flagNotUnGreedy</a></li>
+          </ul></dd>
+<dt><a name="flagNotUnicode" href="#flagNotUnicode"><span>flagNotUnicode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotUnicode" href="regex/nodetype.html#flagNotUnicode">Flag.flagNotUnicode</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotUnicode" href="regex/types.html#flagNotUnicode">Flag.flagNotUnicode</a></li>
+          </ul></dd>
+<dt><a name="flagNotVerbose" href="#flagNotVerbose"><span>flagNotVerbose:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotVerbose" href="regex/nodetype.html#flagNotVerbose">Flag.flagNotVerbose</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagNotVerbose" href="regex/types.html#flagNotVerbose">Flag.flagNotVerbose</a></li>
+          </ul></dd>
+<dt><a name="flagUnGreedy" href="#flagUnGreedy"><span>flagUnGreedy:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagUnGreedy" href="regex/nodetype.html#flagUnGreedy">Flag.flagUnGreedy</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagUnGreedy" href="regex/types.html#flagUnGreedy">Flag.flagUnGreedy</a></li>
+          </ul></dd>
+<dt><a name="flagUnicode" href="#flagUnicode"><span>flagUnicode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagUnicode" href="regex/nodetype.html#flagUnicode">Flag.flagUnicode</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagUnicode" href="regex/types.html#flagUnicode">Flag.flagUnicode</a></li>
+          </ul></dd>
+<dt><a name="flagVerbose" href="#flagVerbose"><span>flagVerbose:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="Flag.flagVerbose" href="regex/nodetype.html#flagVerbose">Flag.flagVerbose</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="Flag.flagVerbose" href="regex/types.html#flagVerbose">Flag.flagVerbose</a></li>
+          </ul></dd>
+<dt><a name="graph" href="#graph"><span>graph:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="dotgraph: graph(nfa: Nfa): string" href="regex/dotgraph.html#graph%2CNfa">dotgraph: graph(nfa: Nfa): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="dotgraph: graph(regex: Regex): string" href="regex/dotgraph.html#graph%2CRegex">dotgraph: graph(regex: Regex): string</a></li>
+          </ul></dd>
+<dt><a name="graphToFile" href="#graphToFile"><span>graphToFile:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="dotgraph: graphToFile(regex: Regex; dir: string)" href="regex/dotgraph.html#graphToFile%2CRegex%2Cstring">dotgraph: graphToFile(regex: Regex; dir: string)</a></li>
+          </ul></dd>
+<dt><a name="group" href="#group"><span>group:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: group(m: RegexMatch; i: int): seq[Slice[int]]" href="regex.html#group%2CRegexMatch%2Cint">regex: group(m: RegexMatch; i: int): seq[Slice[int]]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: group(m: RegexMatch; i: int; text: string): seq[string]" href="regex.html#group%2CRegexMatch%2Cint%2Cstring">regex: group(m: RegexMatch; i: int; text: string): seq[string]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: group(m: RegexMatch; s: string): seq[Slice[int]]" href="regex.html#group%2CRegexMatch%2Cstring">regex: group(m: RegexMatch; s: string): seq[Slice[int]]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: group(m: RegexMatch; groupName: string; text: string): seq[string]" href="regex.html#group%2CRegexMatch%2Cstring%2Cstring">regex: group(m: RegexMatch; groupName: string; text: string): seq[string]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: group(m: RegexMatch; i: int): Slice[int]" href="regex.html#group.i%2CRegexMatch%2Cint">regex: group(m: RegexMatch; i: int): Slice[int]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: group(m: RegexMatch; s: string): Slice[int]" href="regex.html#group.i%2CRegexMatch%2Cstring">regex: group(m: RegexMatch; s: string): Slice[int]</a></li>
+          </ul></dd>
+<dt><a name="groupFirstCapture" href="#groupFirstCapture"><span>groupFirstCapture:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: groupFirstCapture(m: RegexMatch; i: int; text: string): string" href="regex.html#groupFirstCapture%2CRegexMatch%2Cint%2Cstring">regex: groupFirstCapture(m: RegexMatch; i: int; text: string): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: groupFirstCapture(m: RegexMatch; groupName: string; text: string): string" href="regex.html#groupFirstCapture%2CRegexMatch%2Cstring%2Cstring">regex: groupFirstCapture(m: RegexMatch; groupName: string; text: string): string</a></li>
+          </ul></dd>
+<dt><a name="groupKind" href="#groupKind"><span>groupKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: groupKind" href="regex/nodetype.html#groupKind">nodetype: groupKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: groupKind" href="regex/types.html#groupKind">types: groupKind</a></li>
+          </ul></dd>
+<dt><a name="groupLastCapture" href="#groupLastCapture"><span>groupLastCapture:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: groupLastCapture(m: RegexMatch; i: int; text: string): string" href="regex.html#groupLastCapture%2CRegexMatch%2Cint%2Cstring">regex: groupLastCapture(m: RegexMatch; i: int; text: string): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: groupLastCapture(m: RegexMatch; groupName: string; text: string): string" href="regex.html#groupLastCapture%2CRegexMatch%2Cstring%2Cstring">regex: groupLastCapture(m: RegexMatch; groupName: string; text: string): string</a></li>
+          </ul></dd>
+<dt><a name="groupNames" href="#groupNames"><span>groupNames:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: groupNames(m: RegexMatch): seq[string]" href="regex.html#groupNames%2CRegexMatch">regex: groupNames(m: RegexMatch): seq[string]</a></li>
+          </ul></dd>
+<dt><a name="GroupsCapture" href="#GroupsCapture"><span>GroupsCapture:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="exptransformation: GroupsCapture" href="regex/exptransformation.html#GroupsCapture">exptransformation: GroupsCapture</a></li>
+          </ul></dd>
+<dt><a name="groupsCount" href="#groupsCount"><span>groupsCount:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: groupsCount(m: RegexMatch): int" href="regex.html#groupsCount%2CRegexMatch">regex: groupsCount(m: RegexMatch): int</a></li>
+          </ul></dd>
+<dt><a name="groupStartKind" href="#groupStartKind"><span>groupStartKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: groupStartKind" href="regex/types.html#groupStartKind">types: groupStartKind</a></li>
+          </ul></dd>
+<dt><a name="grow" href="#grow"><span>grow:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: grow(sm: var SmLookaround)" href="regex/nfatype.html#grow%2CSmLookaround">nfatype: grow(sm: var SmLookaround)</a></li>
+          </ul></dd>
+<dt><a name="hasState" href="#hasState"><span>hasState:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: hasState(sm: Submatches; n: int16): bool" href="regex/nfatype.html#hasState%2CSubmatches%2Cint16">nfatype: hasState(sm: Submatches; n: int16): bool</a></li>
+          </ul></dd>
+<dt><a name="initEoeNode" href="#initEoeNode"><span>initEoeNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: initEoeNode(): Node" href="regex/nodetype.html#initEoeNode">nodetype: initEoeNode(): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: initEoeNode(): Node" href="regex/types.html#initEoeNode">types: initEoeNode(): Node</a></li>
+          </ul></dd>
+<dt><a name="initGroupStart" href="#initGroupStart"><span>initGroupStart:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node" href="regex/nodetype.html#initGroupStart%2Cstring%2Cseq%5BFlag%5D">nodetype: initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node" href="regex/types.html#initGroupStart%2Cstring%2Cseq%5BFlag%5D">types: initGroupStart(name: string = &quot;&quot;; flags: seq[Flag] = @[]; isCapturing = true): Node</a></li>
+          </ul></dd>
+<dt><a name="initJoinerNode" href="#initJoinerNode"><span>initJoinerNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: initJoinerNode(): Node" href="regex/nodetype.html#initJoinerNode">nodetype: initJoinerNode(): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: initJoinerNode(): Node" href="regex/types.html#initJoinerNode">types: initJoinerNode(): Node</a></li>
+          </ul></dd>
+<dt><a name="initLook" href="#initLook"><span>initLook:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfamatch: initLook(): Lookaround" href="regex/nfamatch.html#initLook.t">nfamatch: initLook(): Lookaround</a></li>
+          </ul></dd>
+<dt><a name="initNotSetNode" href="#initNotSetNode"><span>initNotSetNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: initNotSetNode(): Node" href="regex/nodetype.html#initNotSetNode">nodetype: initNotSetNode(): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: initNotSetNode(): Node" href="regex/types.html#initNotSetNode">types: initNotSetNode(): Node</a></li>
+          </ul></dd>
+<dt><a name="initSetNode" href="#initSetNode"><span>initSetNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: initSetNode(): Node" href="regex/nodetype.html#initSetNode">nodetype: initSetNode(): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: initSetNode(): Node" href="regex/types.html#initSetNode">types: initSetNode(): Node</a></li>
+          </ul></dd>
+<dt><a name="initSkipNode" href="#initSkipNode"><span>initSkipNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: initSkipNode(next: openArray[int16]): Node" href="regex/nodetype.html#initSkipNode%2CopenArray%5Bint16%5D">nodetype: initSkipNode(next: openArray[int16]): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: initSkipNode(next: openArray[int16]): Node" href="regex/types.html#initSkipNode%2CopenArray%5Bint16%5D">types: initSkipNode(next: openArray[int16]): Node</a></li>
+          </ul></dd>
+<dt><a name="invalidRune" href="#invalidRune"><span>invalidRune:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: invalidRune" href="regex/common.html#invalidRune">common: invalidRune</a></li>
+          </ul></dd>
+<dt><a name="isEmpty" href="#isEmpty"><span>isEmpty:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: isEmpty(n: Node): bool" href="regex/nodetype.html#isEmpty%2CNode">nodetype: isEmpty(n: Node): bool</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: isEmpty(n: Node): bool" href="regex/types.html#isEmpty%2CNode">types: isEmpty(n: Node): bool</a></li>
+          </ul></dd>
+<dt><a name="isInitialized" href="#isInitialized"><span>isInitialized:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: isInitialized(re: Regex): bool" href="regex.html#isInitialized%2CRegex">regex: isInitialized(re: Regex): bool</a></li>
+          </ul></dd>
+<dt><a name="items" href="#items"><span>items:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: items(ms: RegexMatches): MatchItemIdx" href="regex/nfafindall.html#items.i%2CRegexMatches">nfafindall: items(ms: RegexMatches): MatchItemIdx</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nfatype: items(sm: Submatches): PState" href="regex/nfatype.html#items.i%2CSubmatches">nfatype: items(sm: Submatches): PState</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="scanner: items[T](sc: Scanner[T]): T" href="regex/scanner.html#items.i%2CScanner%5BT%5D">scanner: items[T](sc: Scanner[T]): T</a></li>
+          </ul></dd>
+<dt><a name="last" href="#last"><span>last:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: last(sm: var SmLookaround): untyped" href="regex/nfatype.html#last.t%2CSmLookaround">nfatype: last(sm: var SmLookaround): untyped</a></li>
+          </ul></dd>
+<dt><a name="lastA" href="#lastA"><span>lastA:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: lastA(sm: var SmLookaround): untyped" href="regex/nfatype.html#lastA.t%2CSmLookaround">nfatype: lastA(sm: var SmLookaround): untyped</a></li>
+          </ul></dd>
+<dt><a name="lastB" href="#lastB"><span>lastB:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: lastB(sm: var SmLookaround): untyped" href="regex/nfatype.html#lastB.t%2CSmLookaround">nfatype: lastB(sm: var SmLookaround): untyped</a></li>
+          </ul></dd>
+<dt><a name="len" href="#len"><span>len:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: len(sm: Submatches): int" href="regex/nfatype.html#len%2CSubmatches">nfatype: len(sm: Submatches): int</a></li>
+          </ul></dd>
+<dt><a name="lineBreakRune" href="#lineBreakRune"><span>lineBreakRune:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: lineBreakRune" href="regex/common.html#lineBreakRune">common: lineBreakRune</a></li>
+          </ul></dd>
+<dt><a name="LitOpt" href="#LitOpt"><span>LitOpt:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="litopt: LitOpt" href="regex/litopt.html#LitOpt">litopt: LitOpt</a></li>
+          </ul></dd>
+<dt><a name="litopt2" href="#litopt2"><span>litopt2:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="litopt: litopt2(exp: RpnExp): LitOpt" href="regex/litopt.html#litopt2%2CRpnExp">litopt: litopt2(exp: RpnExp): LitOpt</a></li>
+          </ul></dd>
+<dt><a name="lookaheadKind" href="#lookaheadKind"><span>lookaheadKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: lookaheadKind" href="regex/types.html#lookaheadKind">types: lookaheadKind</a></li>
+          </ul></dd>
+<dt><a name="Lookaround" href="#Lookaround"><span>Lookaround:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfamatch: Lookaround" href="regex/nfamatch.html#Lookaround">nfamatch: Lookaround</a></li>
+          </ul></dd>
+<dt><a name="lookaroundKind" href="#lookaroundKind"><span>lookaroundKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: lookaroundKind" href="regex/types.html#lookaroundKind">types: lookaroundKind</a></li>
+          </ul></dd>
+<dt><a name="lookAroundTpl" href="#lookAroundTpl"><span>lookAroundTpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfamatch: lookAroundTpl(): untyped" href="regex/nfamatch.html#lookAroundTpl.t">nfamatch: lookAroundTpl(): untyped</a></li>
+          </ul></dd>
+<dt><a name="lookbehindKind" href="#lookbehindKind"><span>lookbehindKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: lookbehindKind" href="regex/types.html#lookbehindKind">types: lookbehindKind</a></li>
+          </ul></dd>
+<dt><a name="match" href="#match"><span>match:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: match(s: string; pattern: Regex): bool" href="regex.html#match%2Cstring%2CRegex">regex: match(s: string; pattern: Regex): bool</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: match(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool" href="regex.html#match%2Cstring%2CRegex%2CRegexMatch%2Cint">regex: match(s: string; pattern: Regex; m: var RegexMatch; start = 0): bool</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: match(text: string; regex: RegexLit; body: untyped): untyped" href="regex.html#match.m%2Cstring%2CRegexLit%2Cuntyped">regex: match(text: string; regex: RegexLit; body: untyped): untyped</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nodematch: match(n: Node; r: Rune): bool" href="regex/nodematch.html#match%2CNode%2CRune">nodematch: match(n: Node; r: Rune): bool</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nodematch: match(n: Node; r: Rune; nxt: Rune): bool" href="regex/nodematch.html#match%2CNode%2CRune%2CRune">nodematch: match(n: Node; r: Rune; nxt: Rune): bool</a></li>
+          </ul></dd>
+<dt><a name="matchableKind" href="#matchableKind"><span>matchableKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: matchableKind" href="regex/nodetype.html#matchableKind">nodetype: matchableKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: matchableKind" href="regex/types.html#matchableKind">types: matchableKind</a></li>
+          </ul></dd>
+<dt><a name="MatchFlag" href="#MatchFlag"><span>MatchFlag:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: MatchFlag" href="regex/nfatype.html#MatchFlag">nfatype: MatchFlag</a></li>
+          </ul></dd>
+<dt><a name="MatchFlags" href="#MatchFlags"><span>MatchFlags:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: MatchFlags" href="regex/nfatype.html#MatchFlags">nfatype: MatchFlags</a></li>
+          </ul></dd>
+<dt><a name="matchImpl" href="#matchImpl"><span>matchImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfamacro: matchImpl(text, expLit, body: NimNode): NimNode" href="regex/nfamacro.html#matchImpl%2CNimNode%2CNimNode%2CNimNode">nfamacro: matchImpl(text, expLit, body: NimNode): NimNode</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nfamatch: matchImpl(text: string; regex: Regex; m: var RegexMatch; start = 0): bool" href="regex/nfamatch.html#matchImpl%2Cstring%2CRegex%2CRegexMatch%2Cint">nfamatch: matchImpl(text: string; regex: Regex; m: var RegexMatch; start = 0): bool</a></li>
+          </ul></dd>
+<dt><a name="mfAnchored" href="#mfAnchored"><span>mfAnchored:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfAnchored" href="regex/nfatype.html#mfAnchored">MatchFlag.mfAnchored</a></li>
+          </ul></dd>
+<dt><a name="mfBwMatch" href="#mfBwMatch"><span>mfBwMatch:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfBwMatch" href="regex/nfatype.html#mfBwMatch">MatchFlag.mfBwMatch</a></li>
+          </ul></dd>
+<dt><a name="mfFindMatch" href="#mfFindMatch"><span>mfFindMatch:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfFindMatch" href="regex/nfatype.html#mfFindMatch">MatchFlag.mfFindMatch</a></li>
+          </ul></dd>
+<dt><a name="mfFindMatchOpt" href="#mfFindMatchOpt"><span>mfFindMatchOpt:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfFindMatchOpt" href="regex/nfatype.html#mfFindMatchOpt">MatchFlag.mfFindMatchOpt</a></li>
+          </ul></dd>
+<dt><a name="mfNoCaptures" href="#mfNoCaptures"><span>mfNoCaptures:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfNoCaptures" href="regex/nfatype.html#mfNoCaptures">MatchFlag.mfNoCaptures</a></li>
+          </ul></dd>
+<dt><a name="mfReverseCapts" href="#mfReverseCapts"><span>mfReverseCapts:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfReverseCapts" href="regex/nfatype.html#mfReverseCapts">MatchFlag.mfReverseCapts</a></li>
+          </ul></dd>
+<dt><a name="mfShortestMatch" href="#mfShortestMatch"><span>mfShortestMatch:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="MatchFlag.mfShortestMatch" href="regex/nfatype.html#mfShortestMatch">MatchFlag.mfShortestMatch</a></li>
+          </ul></dd>
+<dt><a name="mitems" href="#mitems"><span>mitems:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: mitems[T](sc: var Scanner[T]): var T" href="regex/scanner.html#mitems.i%2CScanner%5BT%5D">scanner: mitems[T](sc: var Scanner[T]): var T</a></li>
+          </ul></dd>
+<dt><a name="newScanner" href="#newScanner"><span>newScanner:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: newScanner[T](s: seq[T]): Scanner[T]" href="regex/scanner.html#newScanner%2Cseq%5BT%5D">scanner: newScanner[T](s: seq[T]): Scanner[T]</a></li>
+          </ul></dd>
+<dt><a name="newSubmatches" href="#newSubmatches"><span>newSubmatches:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: newSubmatches(size: int): Submatches" href="regex/nfatype.html#newSubmatches%2Cint">nfatype: newSubmatches(size: int): Submatches</a></li>
+          </ul></dd>
+<dt><a name="next" href="#next"><span>next:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: next[T](sc: Scanner[T]): T" href="regex/scanner.html#next%2CScanner%5BT%5D">scanner: next[T](sc: Scanner[T]): T</a></li>
+          </ul></dd>
+<dt><a name="Nfa" href="#Nfa"><span>Nfa:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: Nfa" href="regex/types.html#Nfa">types: Nfa</a></li>
+          </ul></dd>
+<dt><a name="nfa2" href="#nfa2"><span>nfa2:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfa: nfa2(exp: RpnExp): Nfa" href="regex/nfa.html#nfa2%2CRpnExp">nfa: nfa2(exp: RpnExp): Nfa</a></li>
+          </ul></dd>
+<dt><a name="Node" href="#Node"><span>Node:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: Node" href="regex/nodetype.html#Node">nodetype: Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: Node" href="regex/types.html#Node">types: Node</a></li>
+          </ul></dd>
+<dt><a name="NodeIdx" href="#NodeIdx"><span>NodeIdx:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: NodeIdx" href="regex/nfatype.html#NodeIdx">nfatype: NodeIdx</a></li>
+          </ul></dd>
+<dt><a name="NodeKind" href="#NodeKind"><span>NodeKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: NodeKind" href="regex/nodetype.html#NodeKind">nodetype: NodeKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: NodeKind" href="regex/types.html#NodeKind">types: NodeKind</a></li>
+          </ul></dd>
+<dt><a name="NodeUid" href="#NodeUid"><span>NodeUid:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: NodeUid" href="regex/nodetype.html#NodeUid">nodetype: NodeUid</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: NodeUid" href="regex/types.html#NodeUid">types: NodeUid</a></li>
+          </ul></dd>
+<dt><a name="opKind" href="#opKind"><span>opKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: opKind" href="regex/nodetype.html#opKind">nodetype: opKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: opKind" href="regex/types.html#opKind">types: opKind</a></li>
+          </ul></dd>
+<dt><a name="parse" href="#parse"><span>parse:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="parser: parse(expression: string): Exp" href="regex/parser.html#parse%2Cstring">parser: parse(expression: string): Exp</a></li>
+          </ul></dd>
+<dt><a name="peek" href="#peek"><span>peek:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: peek(sc: Scanner[Node]): Node" href="regex/scanner.html#peek%2CScanner%5BNode%5D">scanner: peek(sc: Scanner[Node]): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="scanner: peek(sc: Scanner[Rune]): Rune" href="regex/scanner.html#peek%2CScanner%5BRune%5D">scanner: peek(sc: Scanner[Rune]): Rune</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="scanner: peek(sc: Scanner[Rune]; n: int): Rune" href="regex/scanner.html#peek%2CScanner%5BRune%5D%2Cint">scanner: peek(sc: Scanner[Rune]; n: int): Rune</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="scanner: peek[T](sc: Scanner[T]): (T, T)" href="regex/scanner.html#peek.i%2CScanner%5BT%5D">scanner: peek[T](sc: Scanner[T]): (T, T)</a></li>
+          </ul></dd>
+<dt><a name="prev" href="#prev"><span>prev:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: prev[T](sc: Scanner[T]): T" href="regex/scanner.html#prev%2CScanner%5BT%5D">scanner: prev[T](sc: Scanner[T]): T</a></li>
+          </ul></dd>
+<dt><a name="PState" href="#PState"><span>PState:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: PState" href="regex/nfatype.html#PState">nfatype: PState</a></li>
+          </ul></dd>
+<dt><a name="re" href="#re"><span>re:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: re(s: static string): static[Regex]" href="regex.html#re%2Cstaticstring">regex: re(s: static string): static[Regex]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: re(s: string): Regex" href="regex.html#re%2Cstring">regex: re(s: string): Regex</a></li>
+          </ul></dd>
+<dt><a name="reAny" href="#reAny"><span>reAny:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAny" href="regex/nodetype.html#reAny">NodeKind.reAny</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAny" href="regex/types.html#reAny">NodeKind.reAny</a></li>
+          </ul></dd>
+<dt><a name="reAnyAscii" href="#reAnyAscii"><span>reAnyAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAnyAscii" href="regex/nodetype.html#reAnyAscii">NodeKind.reAnyAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAnyAscii" href="regex/types.html#reAnyAscii">NodeKind.reAnyAscii</a></li>
+          </ul></dd>
+<dt><a name="reAnyNl" href="#reAnyNl"><span>reAnyNl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAnyNl" href="regex/nodetype.html#reAnyNl">NodeKind.reAnyNl</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAnyNl" href="regex/types.html#reAnyNl">NodeKind.reAnyNl</a></li>
+          </ul></dd>
+<dt><a name="reAnyNlAscii" href="#reAnyNlAscii"><span>reAnyNlAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAnyNlAscii" href="regex/nodetype.html#reAnyNlAscii">NodeKind.reAnyNlAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reAnyNlAscii" href="regex/types.html#reAnyNlAscii">NodeKind.reAnyNlAscii</a></li>
+          </ul></dd>
+<dt><a name="reChar" href="#reChar"><span>reChar:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reChar" href="regex/nodetype.html#reChar">NodeKind.reChar</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reChar" href="regex/types.html#reChar">NodeKind.reChar</a></li>
+          </ul></dd>
+<dt><a name="reCharCi" href="#reCharCi"><span>reCharCi:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reCharCi" href="regex/nodetype.html#reCharCi">NodeKind.reCharCi</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reCharCi" href="regex/types.html#reCharCi">NodeKind.reCharCi</a></li>
+          </ul></dd>
+<dt><a name="reCt" href="#reCt"><span>reCt:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="compiler: reCt(s: string): Regex" href="regex/compiler.html#reCt%2Cstring">compiler: reCt(s: string): Regex</a></li>
+          </ul></dd>
+<dt><a name="reDigit" href="#reDigit"><span>reDigit:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reDigit" href="regex/nodetype.html#reDigit">NodeKind.reDigit</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reDigit" href="regex/types.html#reDigit">NodeKind.reDigit</a></li>
+          </ul></dd>
+<dt><a name="reDigitAscii" href="#reDigitAscii"><span>reDigitAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reDigitAscii" href="regex/nodetype.html#reDigitAscii">NodeKind.reDigitAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reDigitAscii" href="regex/types.html#reDigitAscii">NodeKind.reDigitAscii</a></li>
+          </ul></dd>
+<dt><a name="reEnd" href="#reEnd"><span>reEnd:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEnd" href="regex/nodetype.html#reEnd">NodeKind.reEnd</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEnd" href="regex/types.html#reEnd">NodeKind.reEnd</a></li>
+          </ul></dd>
+<dt><a name="reEndSym" href="#reEndSym"><span>reEndSym:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEndSym" href="regex/nodetype.html#reEndSym">NodeKind.reEndSym</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEndSym" href="regex/types.html#reEndSym">NodeKind.reEndSym</a></li>
+          </ul></dd>
+<dt><a name="reEndSymML" href="#reEndSymML"><span>reEndSymML:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEndSymML" href="regex/nodetype.html#reEndSymML">NodeKind.reEndSymML</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEndSymML" href="regex/types.html#reEndSymML">NodeKind.reEndSymML</a></li>
+          </ul></dd>
+<dt><a name="reEoe" href="#reEoe"><span>reEoe:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEoe" href="regex/nodetype.html#reEoe">NodeKind.reEoe</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reEoe" href="regex/types.html#reEoe">NodeKind.reEoe</a></li>
+          </ul></dd>
+<dt><a name="Regex" href="#Regex"><span>Regex:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: Regex" href="regex/nfatype.html#Regex">nfatype: Regex</a></li>
+          </ul></dd>
+<dt><a name="RegexError" href="#RegexError"><span>RegexError:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: RegexError" href="regex/common.html#RegexError">common: RegexError</a></li>
+          </ul></dd>
+<dt><a name="RegexLit" href="#RegexLit"><span>RegexLit:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: RegexLit" href="regex/nfatype.html#RegexLit">nfatype: RegexLit</a></li>
+          </ul></dd>
+<dt><a name="RegexMatch" href="#RegexMatch"><span>RegexMatch:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: RegexMatch" href="regex/nfatype.html#RegexMatch">nfatype: RegexMatch</a></li>
+          </ul></dd>
+<dt><a name="RegexMatches" href="#RegexMatches"><span>RegexMatches:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfafindall: RegexMatches" href="regex/nfafindall.html#RegexMatches">nfafindall: RegexMatches</a></li>
+          </ul></dd>
+<dt><a name="reGroupEnd" href="#reGroupEnd"><span>reGroupEnd:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reGroupEnd" href="regex/nodetype.html#reGroupEnd">NodeKind.reGroupEnd</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reGroupEnd" href="regex/types.html#reGroupEnd">NodeKind.reGroupEnd</a></li>
+          </ul></dd>
+<dt><a name="reGroupStart" href="#reGroupStart"><span>reGroupStart:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reGroupStart" href="regex/nodetype.html#reGroupStart">NodeKind.reGroupStart</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reGroupStart" href="regex/types.html#reGroupStart">NodeKind.reGroupStart</a></li>
+          </ul></dd>
+<dt><a name="reImpl" href="#reImpl"><span>reImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="compiler: reImpl(s: string): Regex" href="regex/compiler.html#reImpl%2Cstring">compiler: reImpl(s: string): Regex</a></li>
+          </ul></dd>
+<dt><a name="reInSet" href="#reInSet"><span>reInSet:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reInSet" href="regex/nodetype.html#reInSet">NodeKind.reInSet</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reInSet" href="regex/types.html#reInSet">NodeKind.reInSet</a></li>
+          </ul></dd>
+<dt><a name="reJoiner" href="#reJoiner"><span>reJoiner:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reJoiner" href="regex/nodetype.html#reJoiner">NodeKind.reJoiner</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reJoiner" href="regex/types.html#reJoiner">NodeKind.reJoiner</a></li>
+          </ul></dd>
+<dt><a name="reLookahead" href="#reLookahead"><span>reLookahead:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reLookahead" href="regex/nodetype.html#reLookahead">NodeKind.reLookahead</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reLookahead" href="regex/types.html#reLookahead">NodeKind.reLookahead</a></li>
+          </ul></dd>
+<dt><a name="reLookbehind" href="#reLookbehind"><span>reLookbehind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reLookbehind" href="regex/nodetype.html#reLookbehind">NodeKind.reLookbehind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reLookbehind" href="regex/types.html#reLookbehind">NodeKind.reLookbehind</a></li>
+          </ul></dd>
+<dt><a name="removeLast" href="#removeLast"><span>removeLast:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: removeLast(sm: var SmLookaround)" href="regex/nfatype.html#removeLast%2CSmLookaround">nfatype: removeLast(sm: var SmLookaround)</a></li>
+          </ul></dd>
+<dt><a name="reNotAlphaNum" href="#reNotAlphaNum"><span>reNotAlphaNum:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotAlphaNum" href="regex/nodetype.html#reNotAlphaNum">NodeKind.reNotAlphaNum</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotAlphaNum" href="regex/types.html#reNotAlphaNum">NodeKind.reNotAlphaNum</a></li>
+          </ul></dd>
+<dt><a name="reNotAlphaNumAscii" href="#reNotAlphaNumAscii"><span>reNotAlphaNumAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotAlphaNumAscii" href="regex/nodetype.html#reNotAlphaNumAscii">NodeKind.reNotAlphaNumAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotAlphaNumAscii" href="regex/types.html#reNotAlphaNumAscii">NodeKind.reNotAlphaNumAscii</a></li>
+          </ul></dd>
+<dt><a name="reNotDigit" href="#reNotDigit"><span>reNotDigit:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotDigit" href="regex/nodetype.html#reNotDigit">NodeKind.reNotDigit</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotDigit" href="regex/types.html#reNotDigit">NodeKind.reNotDigit</a></li>
+          </ul></dd>
+<dt><a name="reNotDigitAscii" href="#reNotDigitAscii"><span>reNotDigitAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotDigitAscii" href="regex/nodetype.html#reNotDigitAscii">NodeKind.reNotDigitAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotDigitAscii" href="regex/types.html#reNotDigitAscii">NodeKind.reNotDigitAscii</a></li>
+          </ul></dd>
+<dt><a name="reNotLookahead" href="#reNotLookahead"><span>reNotLookahead:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotLookahead" href="regex/nodetype.html#reNotLookahead">NodeKind.reNotLookahead</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotLookahead" href="regex/types.html#reNotLookahead">NodeKind.reNotLookahead</a></li>
+          </ul></dd>
+<dt><a name="reNotLookbehind" href="#reNotLookbehind"><span>reNotLookbehind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotLookbehind" href="regex/nodetype.html#reNotLookbehind">NodeKind.reNotLookbehind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotLookbehind" href="regex/types.html#reNotLookbehind">NodeKind.reNotLookbehind</a></li>
+          </ul></dd>
+<dt><a name="reNotSet" href="#reNotSet"><span>reNotSet:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotSet" href="regex/nodetype.html#reNotSet">NodeKind.reNotSet</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotSet" href="regex/types.html#reNotSet">NodeKind.reNotSet</a></li>
+          </ul></dd>
+<dt><a name="reNotUCC" href="#reNotUCC"><span>reNotUCC:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotUCC" href="regex/nodetype.html#reNotUCC">NodeKind.reNotUCC</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotUCC" href="regex/types.html#reNotUCC">NodeKind.reNotUCC</a></li>
+          </ul></dd>
+<dt><a name="reNotWhiteSpace" href="#reNotWhiteSpace"><span>reNotWhiteSpace:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWhiteSpace" href="regex/nodetype.html#reNotWhiteSpace">NodeKind.reNotWhiteSpace</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWhiteSpace" href="regex/types.html#reNotWhiteSpace">NodeKind.reNotWhiteSpace</a></li>
+          </ul></dd>
+<dt><a name="reNotWhiteSpaceAscii" href="#reNotWhiteSpaceAscii"><span>reNotWhiteSpaceAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWhiteSpaceAscii" href="regex/nodetype.html#reNotWhiteSpaceAscii">NodeKind.reNotWhiteSpaceAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWhiteSpaceAscii" href="regex/types.html#reNotWhiteSpaceAscii">NodeKind.reNotWhiteSpaceAscii</a></li>
+          </ul></dd>
+<dt><a name="reNotWordBoundary" href="#reNotWordBoundary"><span>reNotWordBoundary:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWordBoundary" href="regex/nodetype.html#reNotWordBoundary">NodeKind.reNotWordBoundary</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWordBoundary" href="regex/types.html#reNotWordBoundary">NodeKind.reNotWordBoundary</a></li>
+          </ul></dd>
+<dt><a name="reNotWordBoundaryAscii" href="#reNotWordBoundaryAscii"><span>reNotWordBoundaryAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWordBoundaryAscii" href="regex/nodetype.html#reNotWordBoundaryAscii">NodeKind.reNotWordBoundaryAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reNotWordBoundaryAscii" href="regex/types.html#reNotWordBoundaryAscii">NodeKind.reNotWordBoundaryAscii</a></li>
+          </ul></dd>
+<dt><a name="reOneOrMore" href="#reOneOrMore"><span>reOneOrMore:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reOneOrMore" href="regex/nodetype.html#reOneOrMore">NodeKind.reOneOrMore</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reOneOrMore" href="regex/types.html#reOneOrMore">NodeKind.reOneOrMore</a></li>
+          </ul></dd>
+<dt><a name="reOr" href="#reOr"><span>reOr:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reOr" href="regex/nodetype.html#reOr">NodeKind.reOr</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reOr" href="regex/types.html#reOr">NodeKind.reOr</a></li>
+          </ul></dd>
+<dt><a name="repetitionKind" href="#repetitionKind"><span>repetitionKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: repetitionKind" href="regex/nodetype.html#repetitionKind">nodetype: repetitionKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: repetitionKind" href="regex/types.html#repetitionKind">types: repetitionKind</a></li>
+          </ul></dd>
+<dt><a name="replace" href="#replace"><span>replace:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: replace(s: string; pattern: Regex; by: proc (m: RegexMatch; s: string): string;
+        limit = 0): string" href="regex.html#replace%2Cstring%2CRegex%2Cproc%28RegexMatch%2Cstring%29%2Cint">regex: replace(s: string; pattern: Regex; by: proc (m: RegexMatch; s: string): string;
+        limit = 0): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: replace(s: string; pattern: Regex; by: string; limit = 0): string" href="regex.html#replace%2Cstring%2CRegex%2Cstring%2Cint">regex: replace(s: string; pattern: Regex; by: string; limit = 0): string</a></li>
+          </ul></dd>
+<dt><a name="reRepRange" href="#reRepRange"><span>reRepRange:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reRepRange" href="regex/nodetype.html#reRepRange">NodeKind.reRepRange</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reRepRange" href="regex/types.html#reRepRange">NodeKind.reRepRange</a></li>
+          </ul></dd>
+<dt><a name="reSkip" href="#reSkip"><span>reSkip:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reSkip" href="regex/nodetype.html#reSkip">NodeKind.reSkip</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reSkip" href="regex/types.html#reSkip">NodeKind.reSkip</a></li>
+          </ul></dd>
+<dt><a name="reStart" href="#reStart"><span>reStart:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reStart" href="regex/nodetype.html#reStart">NodeKind.reStart</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reStart" href="regex/types.html#reStart">NodeKind.reStart</a></li>
+          </ul></dd>
+<dt><a name="reStartSym" href="#reStartSym"><span>reStartSym:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reStartSym" href="regex/nodetype.html#reStartSym">NodeKind.reStartSym</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reStartSym" href="regex/types.html#reStartSym">NodeKind.reStartSym</a></li>
+          </ul></dd>
+<dt><a name="reStartSymML" href="#reStartSymML"><span>reStartSymML:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reStartSymML" href="regex/nodetype.html#reStartSymML">NodeKind.reStartSymML</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reStartSymML" href="regex/types.html#reStartSymML">NodeKind.reStartSymML</a></li>
+          </ul></dd>
+<dt><a name="reUCC" href="#reUCC"><span>reUCC:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reUCC" href="regex/nodetype.html#reUCC">NodeKind.reUCC</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reUCC" href="regex/types.html#reUCC">NodeKind.reUCC</a></li>
+          </ul></dd>
+<dt><a name="reverse" href="#reverse"><span>reverse:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: reverse(capts: var Capts; a, b: int32): int32" href="regex/nfatype.html#reverse%2CCapts%2Cint32%2Cint32">nfatype: reverse(capts: var Capts; a, b: int32): int32</a></li>
+          </ul></dd>
+<dt><a name="reversedMatchImpl" href="#reversedMatchImpl"><span>reversedMatchImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfamatch: reversedMatchImpl(smA, smB: var Submatches; text: string; nfa: Nfa;
+                  look: var Lookaround; start, limit: int): int" href="regex/nfamatch.html#reversedMatchImpl%2CSubmatches%2CSubmatches%2Cstring%2CNfa%2CLookaround%2Cint%2Cint">nfamatch: reversedMatchImpl(smA, smB: var Submatches; text: string; nfa: Nfa;
+                  look: var Lookaround; start, limit: int): int</a></li>
+          </ul></dd>
+<dt><a name="reWhiteSpace" href="#reWhiteSpace"><span>reWhiteSpace:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWhiteSpace" href="regex/nodetype.html#reWhiteSpace">NodeKind.reWhiteSpace</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWhiteSpace" href="regex/types.html#reWhiteSpace">NodeKind.reWhiteSpace</a></li>
+          </ul></dd>
+<dt><a name="reWhiteSpaceAscii" href="#reWhiteSpaceAscii"><span>reWhiteSpaceAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWhiteSpaceAscii" href="regex/nodetype.html#reWhiteSpaceAscii">NodeKind.reWhiteSpaceAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWhiteSpaceAscii" href="regex/types.html#reWhiteSpaceAscii">NodeKind.reWhiteSpaceAscii</a></li>
+          </ul></dd>
+<dt><a name="reWord" href="#reWord"><span>reWord:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWord" href="regex/nodetype.html#reWord">NodeKind.reWord</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWord" href="regex/types.html#reWord">NodeKind.reWord</a></li>
+          </ul></dd>
+<dt><a name="reWordAscii" href="#reWordAscii"><span>reWordAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWordAscii" href="regex/nodetype.html#reWordAscii">NodeKind.reWordAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWordAscii" href="regex/types.html#reWordAscii">NodeKind.reWordAscii</a></li>
+          </ul></dd>
+<dt><a name="reWordBoundary" href="#reWordBoundary"><span>reWordBoundary:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWordBoundary" href="regex/nodetype.html#reWordBoundary">NodeKind.reWordBoundary</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWordBoundary" href="regex/types.html#reWordBoundary">NodeKind.reWordBoundary</a></li>
+          </ul></dd>
+<dt><a name="reWordBoundaryAscii" href="#reWordBoundaryAscii"><span>reWordBoundaryAscii:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWordBoundaryAscii" href="regex/nodetype.html#reWordBoundaryAscii">NodeKind.reWordBoundaryAscii</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reWordBoundaryAscii" href="regex/types.html#reWordBoundaryAscii">NodeKind.reWordBoundaryAscii</a></li>
+          </ul></dd>
+<dt><a name="rex" href="#rex"><span>rex:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: rex(s: string): RegexLit" href="regex.html#rex%2Cstring">regex: rex(s: string): RegexLit</a></li>
+          </ul></dd>
+<dt><a name="reZeroOrMore" href="#reZeroOrMore"><span>reZeroOrMore:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reZeroOrMore" href="regex/nodetype.html#reZeroOrMore">NodeKind.reZeroOrMore</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reZeroOrMore" href="regex/types.html#reZeroOrMore">NodeKind.reZeroOrMore</a></li>
+          </ul></dd>
+<dt><a name="reZeroOrOne" href="#reZeroOrOne"><span>reZeroOrOne:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="NodeKind.reZeroOrOne" href="regex/nodetype.html#reZeroOrOne">NodeKind.reZeroOrOne</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="NodeKind.reZeroOrOne" href="regex/types.html#reZeroOrOne">NodeKind.reZeroOrOne</a></li>
+          </ul></dd>
+<dt><a name="RpnExp" href="#RpnExp"><span>RpnExp:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: RpnExp" href="regex/types.html#RpnExp">types: RpnExp</a></li>
+          </ul></dd>
+<dt><a name="scan" href="#scan"><span>scan:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: scan[T](s: seq[T]): Scanner[T]" href="regex/scanner.html#scan%2Cseq%5BT%5D">scanner: scan[T](s: seq[T]): Scanner[T]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="scanner: scan(raw: string): Scanner[Rune]" href="regex/scanner.html#scan%2Cstring">scanner: scan(raw: string): Scanner[Rune]</a></li>
+          </ul></dd>
+<dt><a name="Scanner" href="#Scanner"><span>Scanner:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="scanner: Scanner" href="regex/scanner.html#Scanner">scanner: Scanner</a></li>
+          </ul></dd>
+<dt><a name="setLen" href="#setLen"><span>setLen:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: setLen(item: var SmLookaroundItem; size: int)" href="regex/nfatype.html#setLen%2CSmLookaroundItem%2Cint">nfatype: setLen(item: var SmLookaroundItem; size: int)</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nfatype: setLen(sm: var Submatches; size: int)" href="regex/nfatype.html#setLen%2CSubmatches%2Cint">nfatype: setLen(sm: var Submatches; size: int)</a></li>
+          </ul></dd>
+<dt><a name="shorthandKind" href="#shorthandKind"><span>shorthandKind:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: shorthandKind" href="regex/nodetype.html#shorthandKind">nodetype: shorthandKind</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: shorthandKind" href="regex/types.html#shorthandKind">types: shorthandKind</a></li>
+          </ul></dd>
+<dt><a name="SmLookaround" href="#SmLookaround"><span>SmLookaround:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: SmLookaround" href="regex/nfatype.html#SmLookaround">nfatype: SmLookaround</a></li>
+          </ul></dd>
+<dt><a name="SmLookaroundItem" href="#SmLookaroundItem"><span>SmLookaroundItem:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: SmLookaroundItem" href="regex/nfatype.html#SmLookaroundItem">nfatype: SmLookaroundItem</a></li>
+          </ul></dd>
+<dt><a name="split" href="#split"><span>split:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: split(s: string; sep: Regex): seq[string]" href="regex.html#split%2Cstring%2CRegex">regex: split(s: string; sep: Regex): seq[string]</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="regex: split(s: string; sep: Regex): string" href="regex.html#split.i%2Cstring%2CRegex">regex: split(s: string; sep: Regex): string</a></li>
+          </ul></dd>
+<dt><a name="splitIncl" href="#splitIncl"><span>splitIncl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: splitIncl(s: string; sep: Regex): seq[string]" href="regex.html#splitIncl%2Cstring%2CRegex">regex: splitIncl(s: string; sep: Regex): seq[string]</a></li>
+          </ul></dd>
+<dt><a name="startsWith" href="#startsWith"><span>startsWith:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: startsWith(s: string; pattern: Regex; start = 0): bool" href="regex.html#startsWith%2Cstring%2CRegex%2Cint">regex: startsWith(s: string; pattern: Regex; start = 0): bool</a></li>
+          </ul></dd>
+<dt><a name="startsWithImpl" href="#startsWithImpl"><span>startsWithImpl:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfamatch: startsWithImpl(text: string; regex: Regex; start: int): bool" href="regex/nfamatch.html#startsWithImpl%2Cstring%2CRegex%2Cint">nfamatch: startsWithImpl(text: string; regex: Regex; start: int): bool</a></li>
+          </ul></dd>
+<dt><a name="SubExp" href="#SubExp"><span>SubExp:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: SubExp" href="regex/types.html#SubExp">types: SubExp</a></li>
+          </ul></dd>
+<dt><a name="subExps" href="#subExps"><span>subExps:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfa: subExps(exp: RpnExp): RpnExp" href="regex/nfa.html#subExps%2CRpnExp">nfa: subExps(exp: RpnExp): RpnExp</a></li>
+          </ul></dd>
+<dt><a name="Submatches" href="#Submatches"><span>Submatches:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nfatype: Submatches" href="regex/nfatype.html#Submatches">nfatype: Submatches</a></li>
+          </ul></dd>
+<dt><a name="swapCase" href="#swapCase"><span>swapCase:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodematch: swapCase(r: Rune): Rune" href="regex/nodematch.html#swapCase%2CRune">nodematch: swapCase(r: Rune): Rune</a></li>
+          </ul></dd>
+<dt><a name="toAtoms" href="#toAtoms"><span>toAtoms:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="exptransformation: toAtoms(exp: Exp; groups: var GroupsCapture): AtomsExp" href="regex/exptransformation.html#toAtoms%2CExp%2CGroupsCapture">exptransformation: toAtoms(exp: Exp; groups: var GroupsCapture): AtomsExp</a></li>
+          </ul></dd>
+<dt><a name="toCharNode" href="#toCharNode"><span>toCharNode:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: toCharNode(r: Rune): Node" href="regex/nodetype.html#toCharNode%2CRune">nodetype: toCharNode(r: Rune): Node</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: toCharNode(r: Rune): Node" href="regex/types.html#toCharNode%2CRune">types: toCharNode(r: Rune): Node</a></li>
+          </ul></dd>
+<dt><a name="toPattern" href="#toPattern"><span>toPattern:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="regex: toPattern(s: string): Regex" href="regex.html#toPattern%2Cstring">regex: toPattern(s: string): Regex</a></li>
+          </ul></dd>
+<dt><a name="toRune" href="#toRune"><span>toRune:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="common: toRune(s: string): Rune" href="regex/common.html#toRune%2Cstring">common: toRune(s: string): Rune</a></li>
+          </ul></dd>
+<dt><a name="toString" href="#toString"><span>toString:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="nodetype: toString(n: Node): string" href="regex/nodetype.html#toString%2CNode">nodetype: toString(n: Node): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="nodetype: toString(n: seq[Node]): string" href="regex/nodetype.html#toString%2Cseq%5BNode%5D">nodetype: toString(n: seq[Node]): string</a></li>
+          <li><a class="reference external"
+          data-doc-search-tag="types: toString(n: seq[Node]): string" href="regex/types.html#toString%2Cseq%5BNode%5D">types: toString(n: seq[Node]): string</a></li>
+          </ul></dd>
+<dt><a name="transformExp" href="#transformExp"><span>transformExp:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="exptransformation: transformExp(exp: Exp; groups: var GroupsCapture): RpnExp" href="regex/exptransformation.html#transformExp%2CExp%2CGroupsCapture">exptransformation: transformExp(exp: Exp; groups: var GroupsCapture): RpnExp</a></li>
+          </ul></dd>
+<dt><a name="Transitions" href="#Transitions"><span>Transitions:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: Transitions" href="regex/types.html#Transitions">types: Transitions</a></li>
+          </ul></dd>
+<dt><a name="TransitionsAll" href="#TransitionsAll"><span>TransitionsAll:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: TransitionsAll" href="regex/types.html#TransitionsAll">types: TransitionsAll</a></li>
+          </ul></dd>
+<dt><a name="ZclosureStates" href="#ZclosureStates"><span>ZclosureStates:</span></a></dt><dd><ul class="simple">
+<li><a class="reference external"
+          data-doc-search-tag="types: ZclosureStates" href="regex/types.html#ZclosureStates">types: ZclosureStates</a></li>
+          </ul></dd>
+</dl>
+    <div class="row">
+      <div class="twelve-columns footer">
+        <span class="nim-sprite"></span>
+        <br/>
+        <small style="color: var(--hint);">Made with Nim. Generated: 2021-01-06 13:01:33 UTC</small>
+      </div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
diff --git a/regex.nimble b/regex.nimble
index 327d2e2..ca7b817 100644
--- a/regex.nimble
+++ b/regex.nimble
@@ -1,15 +1,14 @@
 # Package
 
-version = "0.17.0"
+version = "0.19.0"
 author = "Esteban Castro Borsani (@nitely)"
 description = "Linear time regex matching"
 license = "MIT"
 srcDir = "src"
 skipDirs = @["tests", "bench", "docs"]
 
-requires "nim >= 0.19.6"
+requires "nim >= 1.0.0"
 requires "unicodedb >= 0.7.2"
-requires "unicodeplus >= 0.5.0"
 
 task test, "Test":
   exec "nim c -r -o:bin/regex src/regex.nim"
@@ -23,7 +22,8 @@ task test, "Test":
   # js target should work in older versions, but
   # the docker image for CI has it since Nim 1.0.4,
   # so I'll only test it there
-  when (NimMajor, NimMinor, NimPatch) >= (1, 0, 4):
+  when (NimMajor, NimMinor, NimPatch) >= (1, 0, 4) and
+      (NimMajor, NimMinor) != (1, 4):  # issue #88
     exec "nim js -r src/regex.nim"
     exec "nim js -r tests/tests.nim"
     exec "nim js -r -d:forceRegexAtRuntime tests/tests.nim"
@@ -33,4 +33,5 @@ task test, "Test":
     exec "nim doc -o:./docs/ugh/ugh.html ./src/regex.nim"
 
 task docs, "Docs":
+  # xxx use --outdir:docs
   exec "nim doc --project -o:./docs ./src/regex.nim"
diff --git a/src/regex.nim b/src/regex.nim
index 4db61ff..98d1cf8 100644
--- a/src/regex.nim
+++ b/src/regex.nim
@@ -6,7 +6,7 @@ the regular expression. So, it can handle
 input from untrusted users. The syntax is similar to PCRE
 but lacks a few features that can not be implemented
 while keeping the space/time complexity guarantees,
-i.e.: backreferences and look-around assertions.
+ex: backreferences.
 
 Syntax
 ******
@@ -150,13 +150,15 @@ Lookaround Assertions
 #####################
 
 .. code-block::
-  (?=x)   A positive lookahead assertion
-  (?!x)   A negative lookahead assertion
-  (?<=x)  A positive lookbehind assertion
-  (?<!x)  A negative lookbehind assertion
+  (?=regex)   A positive lookahead assertion
+  (?!regex)   A negative lookahead assertion
+  (?<=regex)  A positive lookbehind assertion
+  (?<!regex)  A negative lookbehind assertion
 
-Lookaround assertions are limited to a single character
-at the moment.
+Any regex expression is a valid lookaround; groups
+are captured as well. Beware, lookarounds containing
+repetitions (``*``, ``+``, and ``{n,}``) may run in
+polynomial time.
 
 Examples
 ********
@@ -237,7 +239,7 @@ the scope, and it contains the submatches for every capture group.
     :test:
     var matched = false
     let text = "[my link](https://example.com)"
-    match text, rex"\[([a-z ]*)\]\((https?://[^)]+)\)":
+    match text, rex"\[([^\]]+)\]\((https?://[^)]+)\)":
       doAssert matches == @["my link", "https://example.com"]
       matched = true
     doAssert matched
@@ -249,11 +251,10 @@ import std/sequtils
 import std/unicode
 from std/strutils import addf
 
-import ./regex/nodetype
+import ./regex/types
 import ./regex/common
 import ./regex/compiler
 import ./regex/nfatype
-import ./regex/nfa
 import ./regex/nfafindall
 import ./regex/nfamatch
 when not defined(noRegexOpt):
@@ -508,50 +509,11 @@ func match*(
     doAssert "abcd".match(re"abcd", m)
     doAssert not "abcd".match(re"abc", m)
 
-  const f: MatchFlags = {}
-  result = matchImpl(s, pattern, m, f, start)
+  result = matchImpl(s, pattern, m, start)
 
 func match*(s: string, pattern: Regex): bool {.inline, raises: [].} =
   var m: RegexMatch
-  result = matchImpl(s, pattern, m, {mfNoCaptures})
-
-template containsImpl: untyped {.dirty.} =
-  const f = {mfShortestMatch, mfFindMatch, mfNoCaptures}
-  var m: RegexMatch
-  result = matchImpl(s, pattern, m, f)
-
-func contains*(s: string, pattern: Regex): bool {.inline, raises: [].} =
-  ##  search for the pattern anywhere
-  ##  in the string. It returns as soon
-  ##  as there is a match, even when the
-  ##  expression has repetitions
-  runnableExamples:
-    doAssert re"bc" in "abcd"
-    doAssert re"(23)+" in "23232"
-    doAssert re"^(23)+$" notin "23232"
-
-  containsImpl()
-
-template findImpl: untyped {.dirty.} =
-  matchImpl(s, pattern, m, {mfFindMatch}, start)
-
-func find*(
-  s: string,
-  pattern: Regex,
-  m: var RegexMatch,
-  start = 0
-): bool {.inline, raises: [].} =
-  ## search through the string looking for the first
-  ## location where there is a match
-  runnableExamples:
-    var m: RegexMatch
-    doAssert "abcd".find(re"bc", m) and
-      m.boundaries == 1 .. 2
-    doAssert not "abcd".find(re"de", m)
-    doAssert "2222".find(re"(22)*", m) and
-      m.group(0) == @[0 .. 1, 2 .. 3]
-
-  findImpl()
+  result = matchImpl(s, pattern, m)
 
 template runeIncAt(s: string, n: var int) =
   ## increment ``n`` up to
@@ -660,6 +622,42 @@ func findAndCaptureAll*(
   for m in s.findAll(pattern):
     result.add s[m.boundaries]
 
+# XXX find shortest match; disable captures
+func contains*(s: string, pattern: Regex): bool {.inline, raises: [].} =
+  ##  search for the pattern anywhere in the string
+  runnableExamples:
+    doAssert re"bc" in "abcd"
+    doAssert re"(23)+" in "23232"
+    doAssert re"^(23)+$" notin "23232"
+
+  for _ in findAllBounds(s, pattern):
+    return true
+  return false
+
+func find*(
+  s: string,
+  pattern: Regex,
+  m: var RegexMatch,
+  start = 0
+): bool {.inline, raises: [].} =
+  ## search through the string looking for the first
+  ## location where there is a match
+  runnableExamples:
+    var m: RegexMatch
+    doAssert "abcd".find(re"bc", m) and
+      m.boundaries == 1 .. 2
+    doAssert not "abcd".find(re"de", m)
+    doAssert "2222".find(re"(22)*", m) and
+      m.group(0) == @[0 .. 1, 2 .. 3]
+
+  m.clear()
+  for m2 in findAll(s, pattern, start):
+    m.captures.add m2.captures
+    m.namedGroups = m2.namedGroups
+    m.boundaries = m2.boundaries
+    return true
+  return false
+
 iterator split*(s: string, sep: Regex): string {.inline, raises: [].} =
   ## return not matched substrings
   runnableExamples:
@@ -731,26 +729,25 @@ func startsWith*(
   runnableExamples:
     doAssert "abc".startsWith(re"\w")
     doAssert not "abc".startsWith(re"\d")
-  var m: RegexMatch
-  result = matchImpl(s, pattern, m, {mfShortestMatch, mfNoCaptures}, start)
 
-template endsWithImpl: untyped {.dirty.} =
-  result = false
-  var
-    m: RegexMatch
-    i = 0
-  while i < s.len:
-    result = matchImpl(s, pattern, m, {mfNoCaptures}, i)
-    if result: return
-    s.runeIncAt(i)
+  startsWithImpl(s, pattern, start)
 
+# XXX use findAll and check last match bounds
 func endsWith*(s: string, pattern: Regex): bool {.inline, raises: [].} =
   ## return whether the string
   ## ends with the pattern or not
   runnableExamples:
     doAssert "abc".endsWith(re"\w")
     doAssert not "abc".endsWith(re"\d")
-  endsWithImpl()
+
+  result = false
+  var
+    m: RegexMatch
+    i = 0
+  while i < s.len:
+    result = match(s, pattern, m, i)
+    if result: return
+    s.runeIncAt(i)
 
 func flatCaptures(
   result: var seq[string],
@@ -831,12 +828,15 @@ func replace*(
     if limit > 0 and j == limit: break
   result.addsubstr(s, i)
 
+when not defined(nimHasEffectsOf):
+  {.pragma: effectsOf.}
+
 func replace*(
   s: string,
   pattern: Regex,
   by: proc (m: RegexMatch, s: string): string,
   limit = 0
-): string {.inline, raises: [].} =
+): string {.inline, raises: [], effectsOf: by.} =
   ## Replace matched substrings.
   ##
   ## If ``limit`` is given, at most ``limit``
@@ -870,7 +870,28 @@ func isInitialized*(re: Regex): bool {.inline, raises: [].} =
     re = re"foo"
     doAssert re.isInitialized
 
-  re.nfa.len > 0
+  re.nfa.s.len > 0
+
+func escapeRe*(s: string): string {.raises: [].} =
+  ## Escape special regex characters in ``s``
+  ## so that it can be matched verbatim
+  # The special char list is the same as re.escape
+  # in Python 3.7
+  #
+  # utf-8 ascii code-points cannot be part of multi-byte
+  # code-points, so we can read/match byte by byte
+  result = ""
+  for c in s:
+    case c
+    of ' ', '#', '$', '&', '(',
+        ')', '*', '+', '-', '.',
+        '?', '[', '\\', ']', '^',
+        '{', '|', '}', '~', char(9),
+        char(10), char(11), char(12), char(13):
+      result.add '\\'
+      result.add c
+    else:
+      result.add c
 
 proc toString(
   pattern: Regex,
@@ -884,7 +905,7 @@ proc toString(
     result = "[...]"
     return
   visited.incl(nIdx)
-  let n = pattern.nfa[nIdx]
+  let n = pattern.nfa.s[nIdx]
   result = "["
   result.add($n)
   for nn in n.next:
@@ -901,13 +922,14 @@ proc toString(pattern: Regex): string {.used.} =
 when isMainModule:
   import ./regex/parser
   import ./regex/exptransformation
+  import ./regex/dotgraph
 
   func toAtoms(s: string): string =
     var groups: GroupsCapture
     let atoms = s
       .parse
       .toAtoms(groups)
-    result = atoms.toString
+    result = atoms.s.toString
 
   func toNfaStr(s: string): string =
     result = re(s).toString
@@ -945,9 +967,7 @@ when isMainModule:
   doAssert r"a{0,0}".toNfaStr == r"a".toNfaStr
   doAssert r"a{1,2}".toNfaStr == r"aa?".toNfaStr
   doAssert r"a{2,4}".toNfaStr == r"aaa?a?".toNfaStr
-  doAssert r"a{,10}".toNfaStr == r"a?a?a?a?a?a?a?a?a?a?".toNfaStr
   doAssert r"a{0,10}".toNfaStr == r"a?a?a?a?a?a?a?a?a?a?".toNfaStr
-  doAssert r"a{,}".toNfaStr == r"a*".toNfaStr
   doAssert r"(a(b)){2}".toNfaStr == r"(a(b))(a(b))".toNfaStr
 
   # tascii_set
@@ -1085,6 +1105,40 @@ when isMainModule:
   doAssert match("abcabcabc", re"(?:(?:abc)){3}")
   doAssert match("abcabcabc", re"((abc)){3}")
 
+  doAssert match("", re"|")
+  doAssert match("a", re"a|")
+  doAssert match("", re"a|")
+  doAssert(not match("b", re"a|"))
+  doAssert match("b", re"|b")
+  doAssert match("", re"|b")
+  doAssert(not match("a", re"|b"))
+  doAssert match("", re"(|)")
+  doAssert match("a", re"(a|)")
+  doAssert match("", re"(a|)")
+  doAssert(not match("b", re"(a|)"))
+  doAssert match("b", re"(|b)")
+  doAssert match("", re"(|b)")
+  doAssert(not match("a", re"(|b)"))
+  doAssert match("", re"||")
+
+  doAssert match(" ", re"(?x)     (?-x) ")
+  doAssert match("aa", re"((?x)   a    )a")
+  doAssert match(" ", re"((?x)     ) ")
+  doAssert match(" ", re"(?x:(?x)     ) ")
+  doAssert match(" ", re"((?x:)) ")
+  doAssert match("A", re"(?xi)     a")
+  doAssert(not match("A", re"((?xi))     a"))
+  doAssert(not match("A", re"(?xi:(?xi)     )a"))
+
+  doAssert graph(re"^a+$") == """digraph graphname {
+    0 [label="q0";color=blue];
+    1 [label="q1";color=black];
+    2 [label="q2";color=blue];
+    0 -> 1 [label="a, {^}, i=0"];
+    1 -> 1 [label="a, i=0"];1 -> 2 [label="{eoe}, {$}, i=1"];
+}
+"""
+
   # subset of tests.nim
   proc raisesMsg(pattern: string): string =
     try:
@@ -1145,6 +1199,59 @@ when isMainModule:
     doAssert findAllBounds("#foo://#", re"[\w]+://") == @[1 .. 6]
     doAssert findAllBounds("abc\nabc\na", re"(?m)^a") ==
       @[0 .. 0, 4 .. 4, 8 .. 8]
+    doAssert match("ab", re"a(?=b)\w")
+    doAssert(not match("ab", re"a(?=x)\w"))
+    doAssert match("ab", re"\w(?<=a)b")
+    doAssert(not match("ab", re"\w(?<=x)b"))
+    doAssert match("aaab", re".*(?<=^(\w*?)(\w*?)(\w??)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3], @[4 .. 3]]
+    doAssert match("aaab", re".*(?<=^(\w*?)(\w*)(\w??)$)", m) and
+      m.captures == @[@[0 .. -1], @[0 .. 3], @[4 .. 3]]
+    doAssert match("aaab", re"(\w*)(\w??)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    doAssert match("aaab", re".*(?<=^(\w*)(\w??)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    doAssert match("aaab", re".*(?<=^(\w*)(\w?)$)", m) and
+      m.captures == @[@[0 .. 2], @[3 .. 3]]
+    doAssert match("aaab", re".*(?<=^(\d)\w+|(\w)\w{3}|(\w)\w{3}|(\w)\w+$)", m) and
+      m.captures == @[@[], @[0 .. 0], @[], @[]]
+    doAssert match("aaab", re".*(?<=^(\d)\w+|(\d)\w{3}|(\w)\w{3}|(\w)\w+$)", m) and
+      m.captures == @[@[], @[], @[0 .. 0], @[]]
+    doAssert match("aaab", re".*(?<=^(\d)\w+|(\d)\w{3}|(\d)\w{3}|(\w)\w+$)", m) and
+      m.captures == @[@[], @[], @[], @[0 .. 0]]
+    doAssert(not match("ab", re"\w(?<=a(?=b(?<=a)))b"))
+    doAssert(not match("ab", re"\w(?<=a(?<=a(?=b(?<=a))))b"))
+    doAssert match("ab", re"\w(?<=a(?=b(?<=b)))b")
+    doAssert match("ab", re"\w(?<=a(?<=a(?=b(?<=b))))b")
+    doAssert findAllBounds(r"1abab", re"(?<=\d\w*)ab") ==
+      @[1 .. 2, 3 .. 4]
+    doAssert findAllBounds(r"abab", re"(?<=\d\w*)ab").len == 0
+    doAssert findAllBounds(r"abab1", re"ab(?=\w*\d)") ==
+      @[0 .. 1, 2 .. 3]
+    doAssert findAllBounds(r"abab", re"ab(?=\w*\d)").len == 0
+    doAssert match("aΪ", re"a(?=Ϊ)\w")
+    doAssert match("Ϊb", re"Ϊ(?=b)\w")
+    doAssert match("弢Ⓐ", re"弢(?=Ⓐ)\w")
+    doAssert match("aΪ", re"\w(?<=a)Ϊ")
+    doAssert match("Ϊb", re"\w(?<=Ϊ)b")
+    doAssert match("弢Ⓐ", re"\w(?<=弢)Ⓐ")
+    block:  # Follows Nim re's behaviour
+      doAssert match("abc", re"(?<=a)bc", m, start = 1)
+      doAssert(not match("abc", re"(?<=x)bc", m, start = 1))
+      doAssert(not match("abc", re"^bc", m, start = 1))
+    doAssert startsWith("abc", re"b", start = 1)
+    doAssert startsWith("abc", re"(?<=a)b", start = 1)
+    doAssert startsWith("abc", re"b", start = 1)
+    doAssert(not startsWith("abc", re"(?<=x)b", start = 1))
+    doAssert(not startsWith("abc", re"^b", start = 1))
+    doAssert(not match("ab", re"ab(?=x)"))
+    doAssert(not match("ab", re"(?<=x)ab"))
+    doAssert match("ab", re"(?<=^)ab")
+    doAssert match("ab", re"ab(?=$)")
+    doAssert match("abcdefg", re"\w+(?<=(ab)(?=(cd)))\w+", m) and
+      m.captures == @[@[0 .. 1], @[2 .. 3]]
+    doAssert match("abcdefg", re"\w+(?<=(ab)(?=(cd)(?<=(cd))))\w+", m) and
+      m.captures == @[@[0 .. 1], @[2 .. 3], @[2 .. 3]]
     when canUseMacro:
       block:
         var m = false
@@ -1196,5 +1303,11 @@ when isMainModule:
           doAssert matches == @["my link", "https://example.com"]
           matched = true
         doAssert matched
+      block:
+        var matched = false
+        match "abcdefg", rex"\w+(?<=(ab)(?=(cd)))\w+":
+          doAssert matches == @["ab", "cd"]
+          matched = true
+        doAssert matched
 
   echo "ok regex.nim"
diff --git a/src/regex/common.nim b/src/regex/common.nim
index 5d796eb..9dfc5d6 100644
--- a/src/regex/common.nim
+++ b/src/regex/common.nim
@@ -35,6 +35,26 @@ proc `<=`*(x, y: Rune): bool =
 proc cmp*(x, y: Rune): int =
   x.int - y.int
 
+func bwRuneAt*(s: string, n: int): Rune =
+  ## Take rune ending at ``n``
+  doAssert n >= 0
+  doAssert n <= s.len-1
+  var n = n
+  while n > 0 and s[n].ord shr 6 == 0b10:
+    dec n
+  fastRuneAt(s, n, result, false)
+
+template bwFastRuneAt*(
+  s: string, n: var int, result: var Rune
+): untyped =
+  ## Take rune ending at ``n``
+  doAssert n > 0
+  doAssert n <= s.len
+  dec n
+  while n > 0 and s[n].ord shr 6 == 0b10:
+    dec n
+  fastRuneAt(s, n, result, false)
+
 proc `%%`*(
   formatstr: string,
   a: openArray[string]
diff --git a/src/regex/compiler.nim b/src/regex/compiler.nim
index 48d72e2..6552eae 100644
--- a/src/regex/compiler.nim
+++ b/src/regex/compiler.nim
@@ -1,23 +1,27 @@
 import ./parser
 import ./exptransformation
+import ./types
 import ./nfatype
 import ./nfa
 import ./litopt
+when defined(regexDotDir):
+  import ./dotgraph
 
 func reImpl*(s: string): Regex {.inline.} =
   var groups: GroupsCapture
   let rpn = s
     .parse
     .transformExp(groups)
-  var transitions: Transitions
-  let nfa = rpn.nfa2(transitions)
+  let nfa = rpn.nfa2()
   let opt = rpn.litopt2()
   result = Regex(
     nfa: nfa,
-    transitions: transitions,
     groupsCount: groups.count,
     namedGroups: groups.names,
     litOpt: opt)
+  when defined(regexDotDir) and (NimMajor, NimMinor) >= (1, 2):
+    const regexDotDir {.strdefine.} = ""
+    graphToFile(result, regexDotDir)
 
 func reCt*(s: string): Regex {.compileTime.} =
   reImpl(s)
diff --git a/src/regex/dotgraph.nim b/src/regex/dotgraph.nim
new file mode 100644
index 0000000..a1ddd61
--- /dev/null
+++ b/src/regex/dotgraph.nim
@@ -0,0 +1,49 @@
+import std/strutils
+when (NimMajor, NimMinor) >= (1, 2):
+  import std/hashes
+  import std/os
+
+import ./nfatype
+import ./types
+
+func color(n: Node): string =
+  case n.kind
+  of matchableKind: "black"
+  else: "blue"
+
+func graph*(nfa: Nfa): string =
+  result = "digraph graphname {\n"
+  let tab = "    "
+  for i, n in pairs nfa.s:
+    result.add tab
+    result.add($i & " [label=\"q" & $i & "\";color=" & n.color & "];")
+    result.add '\n'
+  for i, n in pairs nfa.s:
+    if n.next.len == 0:
+      continue
+    result.add tab
+    for i2, n2 in pairs n.next:
+      var t = ""
+      if nfa.t.allZ[i][i2] > -1:
+        for i3, z in pairs nfa.t.z[nfa.t.allZ[i][i2]]:
+          if i3 > 0: t &= ", "
+          t &= $z
+        t = ", {" & t & "}"
+      let label = ($nfa.s[n2] & t & ", i=" & $i2).replace(r"\", r"\\")
+      result.add($i & " -> " & $n2 & " [label=\"" & label & "\"];")
+    result.add '\n'
+  result.add "}\n"
+
+func graph*(regex: Regex): string =
+  result = graph(regex.nfa)
+
+when (NimMajor, NimMinor) >= (1, 2):
+  func graphToFile*(regex: Regex, dir: string) =
+    {.noSideEffect.}:
+      if dir.len > 0:
+        let content = graph(regex)
+        let fname = $hash(content) & ".dot"
+        try:
+          writeFile(dir / fname, content)
+        except IOError:
+          debugEcho "write file error"
diff --git a/src/regex/exptransformation.nim b/src/regex/exptransformation.nim
index a0cceb7..7bf013f 100644
--- a/src/regex/exptransformation.nim
+++ b/src/regex/exptransformation.nim
@@ -3,7 +3,8 @@ import std/sets
 import std/tables
 import std/algorithm
 
-import ./nodetype
+import ./exptype
+import ./types
 import ./common
 import ./scanner
 
@@ -23,10 +24,30 @@ func check(cond: bool, msg: string) =
   if not cond:
     raise newException(RegexError, msg)
 
-func greediness(expression: seq[Node]): seq[Node] =
+func fixEmptyOps(exp: Exp): Exp =
+  ## Handle "|", "(|)", "a|", "|b", "||", "a||b", ...
+  ## Handle "()"
+  result.s = newSeq[Node](exp.s.len)
+  result.s.setLen 0
+  for i in 0 .. exp.s.len-1:
+    if exp.s[i].kind == reOr:
+      if i-1 < 0 or exp.s[i-1].kind == reGroupStart:
+        result.s.add initSkipNode()
+      result.s.add exp.s[i]
+      if i+1 > exp.s.len-1 or exp.s[i+1].kind in {reGroupEnd, reOr}:
+        result.s.add initSkipNode()
+    elif exp.s[i].kind == reGroupStart:
+      result.s.add exp.s[i]
+      if i+1 > exp.s.len-1 or exp.s[i+1].kind == reGroupEnd:
+        result.s.add initSkipNode()
+    else:
+      result.s.add exp.s[i]
+
+func greediness(exp: Exp): Exp =
   ## apply greediness to an expression
-  result = newSeqOfCap[Node](expression.len)
-  var sc = expression.scan()
+  result.s = newSeq[Node](exp.s.len)
+  result.s.setLen 0
+  var sc = exp.s.scan()
   for n in sc.mitems():
     if n.kind in repetitionKind or
         n.kind == reZeroOrOne:
@@ -34,7 +55,7 @@ func greediness(expression: seq[Node]): seq[Node] =
       if sc.peek.kind == reZeroOrOne:
         n.isGreedy = false
         discard sc.next
-    result.add(n)
+    result.s.add n
 
 type
   GroupsCapture* = object
@@ -42,18 +63,18 @@ type
     names*: OrderedTable[string, int16]
 
 func fillGroups(
-  exp: seq[Node],
+  exp: Exp,
   groups: var GroupsCapture
-): seq[Node] =
+): Exp =
   ## populate group indices, names and capturing mark
   result = exp
   groups.names = initOrderedTable[string, int16](2)
   groups.count = 0'i16
   var gs = newSeq[int]()
-  for i, n in result.mpairs:
+  for i, n in mpairs result.s:
     case n.kind
-    of reGroupStart:
-      gs.add(i)
+    of groupStartKind:
+      gs.add i
       if n.isCapturing:
         n.idx = groups.count
         inc groups.count
@@ -66,8 +87,8 @@ func fillGroups(
         "Invalid capturing group. " &
         "Found too many closing symbols")
       let start = gs.pop()
-      n.isCapturing = result[start].isCapturing
-      n.idx = result[start].idx
+      n.isCapturing = result.s[start].isCapturing
+      n.idx = result.s[start].idx
     else:
       discard
     check(
@@ -192,36 +213,35 @@ func applyFlag(n: var Node, f: Flag) =
       flagVerbose,
       flagNotVerbose}
 
-func applyFlags(expression: seq[Node]): seq[Node] =
+func applyFlags(exp: Exp): Exp =
   ## apply flags to each group
-  result = newSeqOfCap[Node](expression.len)
+  result.s = newSeq[Node](exp.s.len)
+  result.s.setLen 0
   var flags = newSeq[seq[Flag]]()
-  var sc = expression.scan()
+  var sc = exp.s.scan()
   for n in sc.mitems():
     # (?flags)
     # Orphan flags are added to current group
     case n.kind
-    of reGroupStart:
-      if n.flags.len == 0:
-        flags.add(@[])
-        result.add(n)
-        continue
-      if sc.peek.kind == reGroupEnd:  # (?flags)
-        discard sc.next()
-        if flags.len > 0:
-          flags[flags.len - 1].add(n.flags)
-        else:
-          flags.add(n.flags)
-        continue  # skip (
-      flags.add(n.flags)
+    of groupStartKind:
+      flags.add n.flags
     of reGroupEnd:
       discard flags.pop()
+    of reFlags:
+      if flags.len > 0:
+        flags[flags.len-1].add n.flags
+      else:
+        flags.add n.flags
+      # XXX define skipKind = {reSkip, reFlags} in types,
+      #     instead of this hack
+      result.s.add Node(kind: reSkip)
+      continue  # skip node
     else:
       let ff = flags.squash()
       for f in Flag.low .. Flag.high:
         if ff[f]:
           applyFlag(n, f)
-    result.add(n)
+    result.s.add n
 
 func expandOneRepRange(subExpr: seq[Node], n: Node): seq[Node] =
   ## expand a repetition-range expression
@@ -255,24 +275,25 @@ func expandOneRepRange(subExpr: seq[Node], n: Node): seq[Node] =
       cp: "?".toRune,
       isGreedy: n.isGreedy))
 
-func expandRepRange(expression: seq[Node]): seq[Node] =
+func expandRepRange(exp: Exp): Exp =
   ## expand every repetition range
-  result = newSeqOfCap[Node](expression.len)
+  result.s = newSeq[Node](exp.s.len)
+  result.s.setLen 0
   var i: int
   var gi: int
-  for n in expression:
+  for n in exp.s:
     if n.kind != reRepRange:
-      result.add(n)
+      result.s.add n
       continue
     check(
-      result.len > 0,
+      result.s.len > 0,
       "Invalid repeition range, " &
       "nothing to repeat")
-    case result[^1].kind
+    case result.s[^1].kind
     of reGroupEnd:
       i = 0
       gi = 0
-      for ne in result.reversed:
+      for ne in result.s.reversed:
         inc i
         if ne.kind == reGroupEnd:
           inc gi
@@ -282,10 +303,10 @@ func expandRepRange(expression: seq[Node]): seq[Node] =
           break
         doAssert gi >= 0
       doAssert gi == 0
-      assert result[result.len-i].kind == reGroupStart
-      result.add(result[result.len-i .. result.len-1].expandOneRepRange(n))
+      assert result.s[result.s.len-i].kind == reGroupStart
+      result.s.add result.s[result.s.len-i .. result.s.len-1].expandOneRepRange(n)
     of matchableKind:
-      result.add(result[result.len-1 .. result.len-1].expandOneRepRange(n))
+      result.s.add result.s[result.s.len-1 .. result.s.len-1].expandOneRepRange(n)
     else:
       check(
         false, 
@@ -293,33 +314,34 @@ func expandRepRange(expression: seq[Node]): seq[Node] =
          "char, shorthand (i.e: \\w), group, or set " &
          "expected before repetition range"))
 
-func populateUid(exp: seq[Node]): seq[Node] =
+func populateUid(exp: Exp): Exp =
   check(
-    exp.high < NodeUid.high,
+    exp.s.high < NodeUid.high,
     ("The expression is too long, " &
      "limit is ~$#") %% $NodeUid.high)
   result = exp
   var uid = 1.NodeUid
-  for n in result.mitems:
+  for n in mitems result.s:
     n.uid = uid
     inc uid
 
-func joinAtoms(expression: seq[Node]): seq[Node] =
+func joinAtoms(exp: Exp): AtomsExp =
   ## Put a ``~`` joiner between atoms. An atom is
   ## a piece of expression that would loose
   ## meaning when breaking it up (i.e.: ``a~(b|c)*~d``)
-  result = newSeqOfCap[Node](expression.len * 2)
+  result.s = newSeq[Node](exp.s.len * 2)
+  result.s.setLen 0
   var atomsCount = 0
-  for n in expression:
+  for n in exp.s:
     case n.kind
-    of matchableKind, assertionKind:
+    of matchableKind, assertionKind - lookaroundKind, reSkip:
       inc atomsCount
       if atomsCount > 1:
         atomsCount = 1
-        result.add(initJoinerNode())
-    of reGroupStart:
+        result.s.add initJoinerNode()
+    of groupStartKind:
       if atomsCount > 0:
-        result.add(initJoinerNode())
+        result.s.add initJoinerNode()
       atomsCount = 0
     of reOr:
       atomsCount = 0
@@ -331,7 +353,7 @@ func joinAtoms(expression: seq[Node]): seq[Node] =
       inc atomsCount
     else:
       doAssert false
-    result.add(n)
+    result.s.add n
 
 type
   Associativity = enum
@@ -381,17 +403,17 @@ func popGreaterThan(ops: var seq[Node], op: Node): seq[Node] =
   while (ops.len > 0 and
       ops[ops.len - 1].kind in opKind and
       ops[ops.len - 1].kind.hasPrecedence(op.kind)):
-    result.add(ops.pop())
+    result.add ops.pop()
 
 func popUntilGroupStart(ops: var seq[Node]): seq[Node] =
   result = newSeqOfCap[Node](ops.len)
   while true:
     let op = ops.pop()
-    result.add(op)
+    result.add op
     if op.kind == reGroupStart:
       break
 
-func rpn(expression: seq[Node]): seq[Node] =
+func rpn(exp: AtomsExp): RpnExp =
   ## An adaptation of the Shunting-yard algorithm
   ## for producing `Reverse Polish Notation` out of
   ## an expression specified in infix notation.
@@ -400,31 +422,74 @@ func rpn(expression: seq[Node]): seq[Node] =
   ## the parsing of the regular expression into an NFA.
   ## Suffix notation removes nesting and so it can
   ## be parsed in a linear way instead of recursively
-  result = newSeqOfCap[Node](expression.len)
+  result.s = newSeq[Node](exp.s.len)
+  result.s.setLen 0
   var ops = newSeq[Node]()
-  for n in expression:
+  for n in exp.s:
     case n.kind
-    of matchableKind, assertionKind:
-      result.add(n)
+    of matchableKind, assertionKind, reSkip:
+      result.s.add n
     of reGroupStart:
-      ops.add(n)
+      ops.add n
     of reGroupEnd:
-      result.add(ops.popUntilGroupStart())
-      result.add(n)
+      result.s.add ops.popUntilGroupStart()
+      result.s.add n
     of opKind:
-      result.add(ops.popGreaterThan(n))
-      ops.add(n)
+      result.s.add ops.popGreaterThan(n)
+      ops.add n
     else:
       doAssert false
   # reverse ops
   for i in 1 .. ops.len:
-    result.add(ops[ops.len - i])
+    result.s.add ops[ops.len-i]
+
+func subExps(exp: AtomsExp, parentKind = reLookahead): AtomsExp =
+  ## Collect and convert lookaround sub-expressions to RPN
+  template n: untyped = result.s[^1]
+  result.s = newSeq[Node](exp.s.len)
+  result.s.setLen 0
+  var i = 0
+  var parens = newSeq[bool]()
+  while i < exp.s.len:
+    if exp.s[i].kind in lookaroundKind:
+      result.s.add exp.s[i]
+      inc i
+      parens.setLen 0
+      let i0 = i
+      while i < exp.s.len:
+        case exp.s[i].kind
+        of groupStartKind:
+          parens.add true
+        of reGroupEnd:
+          if parens.len > 0:
+            discard parens.pop()
+          else:
+            break
+        else:
+          discard
+        inc i
+      doAssert exp.s[i].kind == reGroupEnd
+      let atoms = AtomsExp(s: exp.s[i0 .. i-1])
+      n.subExp.rpn = atoms
+        .subExps(parentKind = n.kind)
+        .rpn
+      # Store whether the capts must be reversed
+      if parentKind in lookaheadKind:
+        n.subExp.reverseCapts = n.kind in lookbehindKind
+      else:
+        doAssert parentKind in lookbehindKind
+        n.subExp.reverseCapts = n.kind in lookaheadKind
+      inc i
+    else:
+      result.s.add exp.s[i]
+      inc i
 
 func toAtoms*(
-  exp: seq[Node],
+  exp: Exp,
   groups: var GroupsCapture
-): seq[Node] {.inline.} =
+): AtomsExp {.inline.} =
   result = exp
+    .fixEmptyOps
     .fillGroups(groups)
     .greediness
     .applyFlags
@@ -433,9 +498,10 @@ func toAtoms*(
     .joinAtoms
 
 func transformExp*(
-  exp: seq[Node],
+  exp: Exp,
   groups: var GroupsCapture
-): seq[Node] {.inline.} =
+): RpnExp {.inline.} =
   result = exp
     .toAtoms(groups)
+    .subExps
     .rpn
diff --git a/src/regex/exptype.nim b/src/regex/exptype.nim
new file mode 100644
index 0000000..7772b3f
--- /dev/null
+++ b/src/regex/exptype.nim
@@ -0,0 +1,7 @@
+import ./types
+
+type
+  Exp* = object
+    s*: seq[Node]
+  AtomsExp* = object
+    s*: seq[Node]
diff --git a/src/regex/litopt.nim b/src/regex/litopt.nim
index 45f636c..7285ca0 100644
--- a/src/regex/litopt.nim
+++ b/src/regex/litopt.nim
@@ -4,16 +4,11 @@
 ## within the input string. See issue #59.
 
 #[
-Only optimizations that are
-guaranteed to run in linear
-time are implemented.
-We must also ensure the matches
+Only optimizations that are guaranteed to run in linear
+time are implemented. We must also ensure the matches
 are not overlapped.
-I think the best way to understand
-how the current implementation works
-is by example. However, I'll describe
-some parts of the algorithm that
-may be useful to grasp first:
+
+Here’s a high-level description of the algorithm:
   * we pick a literal that is memchr'ed
     to skip parts of the text
   * the prefix is the regex part before
@@ -44,139 +39,9 @@ How is quadratic runtime avoided?
   * The `overlapTests` in tests.nim are good examples
     of this
 
-------------------------------------
-Examples
-
-Most of the optimizations for these examples
-are not implemented, may not get implemented,
-or are already part of the more general implemented
-optimization
-
-re"(?ms)^.+abc"
-can be optimized by running the match
-at every \n. We can do a quick memchr to find
-every \n.
-
-There is a gotcha, though. If we do this on
-an input such as `\n\n\n\n\n` the matcher will
-consume the whole string for every `\n`, hence
-runtime is quadratic.
-
-The solution is to run a special kind of find,
-instead of a regular match. We need a special find,
-because the regular find will always consume the
-whole string, so we'd only be able to skip the first
-part of the input until the first `\n`, instead
-of skipping multiple parts of the input.
-
-The special find works just like the regular one,
-except it stops when the current character of the
-input cannot be matched by the Regular Expression (RE).
-Once the special find stops, we can run a memchr from
-the index where the find stopped.
-
-Notice find returns non-overlapping matches,
-hence the next search must not process
-characters that are part of a previous matched string.
-The start of text cannot be within the boundaries
-of the previous match.
-
-^ There is a bunch of possible literal optimizations,
-  but this is the meat of it.
-
-re"\d\w+x"
-text: "xxxxxxxxxxx"
-This would take quadratic time,
-as the prefix matcher will match until
-the start of the string every time.
-The solution is disallow the optimization in
-cases where the literal can be matched by the
-prefix. Hence the literal becomes a delimiter
-for the prefix matcher.
-
-re"\wabc"
-This can be optimized the same way as
-the first example, except going back
-one character after running memchr.
-
-The runtime is again linear, every
-character can be consumed at most 2 times:
-one fordward (memchr), and one fordward
-(special find). The "go back" operation does
-not consumes characters, it just does
-index - len(prefix).
-
-The prefix may be longer than just one
-character, as long as the lenght of it
-is fixed we can just go back the lenght of
-the prefix and run a find. We can do
-this even when the prefix contain alternations
-as long as they have the same lenght, for
-example re"(x|y)abc".
-
-The alternative to going back X chars
-is to run the regex prefix in reverse, and
-then run the special find for the full regex.
-This would support prefixes with mixed
-alternation lengths (i.e: re"(\w\w|\d)foo").
-Since this is needed, the going back X
-chars may just be an optimal optimization
-(meaning I may not implement it).
-
-re"\d+abc"
-This can be optimized by doing a memchr
-for "a", running a special match for the
-regex prefix ("\d+") in reverse, and running
-the special find for the full regex.
-
-The special match is a regular match that returns
-the longest match.
-
-We cannot divide the regex in a prefix and suffix
-of "a", and just run that because that would
-run in cuadratic time (see the first "\n\n\n" input example).
-Also, we need to support captures.
-
-re"\w(a|b)"
-This can be optimized by running two scans,
-one for "a" and one for "b" at the start and
-after each match, and then trying to match the one
-with smaller char index first (i.e: the one
-that we found first).
-
-My experiments show PCRE do this with up to
-two literal alternations. When there are more
-than two alternations, it's likely better to
-generate a DFA. For example:
-re"foo|bar|baz|quz" would generate a DFA
-that matches re"f|b|q". We'd use the DFA
-instead of memchr.
-
-Single literals should be preferred over
-alternations. For example: re"\w(a|b)c" would
-memchr the "c" character. Meaning other listed
-optimizations are preferred.
-
----------------------------
-
-We should try to match the larger
-amount of literals and try to fail
-early. Let's say we have re"\d+abc",
-trying to match "a" and then an unbounded
-amount of chars at the left will likely take
-more time than trying to match "c", then
-"ab" at the left, since "a" will appear
-at least the same amount of times as "abc",
-but possibly more times.
-
-This translates to finding the largest amount
-of contiguous lits and picking the right most
-lit to memchr.
-
-However, this has the cost of potentially
-requiring a larger left part of the regex (to match the left side),
-so it may be better to find the first lit in the regex and then
-pick the last lit of its contiguous lits (if any).
+There used to be a list of regex examples here, but
+I wrote a blog post explaining things better, see
+https://nitely.github.io/2020/11/30/regex-literals-optimization.html
 
 ]#
 
@@ -184,7 +49,7 @@ import std/algorithm
 import std/sets
 import std/unicode
 
-import ./nodetype
+import ./types
 import ./nodematch
 import ./nfa
 
@@ -192,19 +57,18 @@ when (NimMajor, NimMinor, NimPatch) < (0, 20, 0):
   import common
 
 type
-  RpnExp = seq[Node]
-  LitNfa = Nfa
+  LitNfa = Enfa
   End = seq[int16]
 
 func combine(
-  nfa: var seq[Node],
+  eNfa: var Enfa,
   ends: var seq[End],
   org, target: int16
 ) =
   for e in ends[org]:
-    for i, ni in nfa[e].next.mpairs:
-      if nfa[ni].kind == reEoe:
-        ni = target
+    for i in mitems eNfa.s[e].next:
+      if eNfa.s[i].kind == reEoe:
+        i = target
   ends[org] = ends[target]
 
 const eoe = 0'i16
@@ -214,7 +78,7 @@ func update(
   ni: int16,
   next: openArray[int16]
 ) =
-  ends[ni].setLen(0)
+  ends[ni].setLen 0
   for n in next:
     if n == eoe:
         ends[ni].add ni
@@ -225,23 +89,24 @@ func update(
 # replace (...)+, (...)*, (...)?,
 # and (...|...) by skip nodes.
 # Based on Thompson's construction
-func toLitNfa(exp: RPNExp): LitNfa =
-  result = newSeqOfCap[Node](exp.len + 2)
-  result.add initEoeNode()
+func toLitNfa(exp: RpnExp): LitNfa =
+  result.s = newSeq[Node](exp.s.len + 2)
+  result.s.setLen 0
+  result.s.add initEoeNode()
   var
-    ends = newSeq[End](exp.len + 1)
+    ends = newSeq[End](exp.s.len + 1)
     states = newSeq[int16]()
-  if exp.len == 0:
+  if exp.s.len == 0:
     states.add eoe
-  for n in exp:
+  for n in exp.s:
     var n = n
     doAssert n.next.len == 0
-    let ni = result.len.int16
+    let ni = result.s.len.int16
     case n.kind
-    of matchableKind, assertionKind:
+    of matchableKind, assertionKind, reSkip:
       n.next.add eoe
       ends.update(ni, [eoe])
-      result.add n
+      result.s.add n
       states.add ni
     of reJoiner:
       let
@@ -253,12 +118,12 @@ func toLitNfa(exp: RPNExp): LitNfa =
       discard states.pop()
       discard states.pop()
       ends.update(ni, [eoe])
-      result.add initSkipNode([eoe])
+      result.s.add initSkipNode([eoe])
       states.add ni
     of reZeroOrMore, reZeroOrOne, reOneOrMore:
       discard states.pop()
       ends.update(ni, [eoe])
-      result.add initSkipNode([eoe])
+      result.s.add initSkipNode([eoe])
       states.add ni
     of reGroupStart:
       discard
@@ -267,18 +132,18 @@ func toLitNfa(exp: RPNExp): LitNfa =
     else:
       doAssert false
   doAssert states.len == 1
-  result.add initSkipNode(states)
+  result.s.add initSkipNode(states)
 
 type
   NodeIdx = int16
 
 func lonelyLit(exp: RpnExp): NodeIdx =
-  template state: untyped = litNfa[stateIdx]
+  template state: untyped = litNfa.s[stateIdx]
   result = -1
   let litNfa = exp.toLitNfa()
   var cpSeen = initHashSet[Rune](16)
   var lits = newSeq[int16]()
-  var stateIdx = litNfa.len.int16-1
+  var stateIdx = litNfa.s.len.int16-1
   while state.kind != reEoe:
     if state.kind == reChar and
         state.cp.int <= 127:  # XXX support unicode
@@ -292,35 +157,35 @@ func lonelyLit(exp: RpnExp): NodeIdx =
   # time, it seems sensible to limit the lits
   lits.setLen min(lits.len, 128)
   var litsTmp = newSeq[int16]()
-  for ni, n in exp.pairs:
+  for ni, n in pairs exp.s:
     # break after last lit of first lits sequence
-    if result > -1 and exp[result].uid+1 < n.uid:
+    if result > -1 and exp.s[result].uid+1 < n.uid:
       break
     if n.kind notin matchableKind:
       continue
     for nlit in lits:
-      doAssert n.uid <= litNfa[nlit].uid
-      if n.uid == litNfa[nlit].uid:
+      doAssert n.uid <= litNfa.s[nlit].uid
+      if n.uid == litNfa.s[nlit].uid:
         result = ni.NodeIdx
         #return
-      if not match(n, litNfa[nlit].cp):
+      if not match(n, litNfa.s[nlit].cp):
         litsTmp.add nlit
     swap lits, litsTmp
     litsTmp.setLen 0
 
 func prefix(eNfa: Enfa, uid: NodeUid): Enfa =
-  template state0: untyped = eNfa.len.int16-1
+  template state0: untyped = eNfa.s.len.int16-1
   result = eNfa
-  for n in result.mitems:
+  for n in result.s.mitems:
     n.next.setLen 0
   # reverse transitions; DFS
   var stack = @[(state0, -1'i16)]
   var visited: set[int16]
-  template state: untyped = eNfa[ni]
+  template state: untyped = eNfa.s[ni]
   while stack.len > 0:
     let (ni, pi) = stack.pop()
     if pi > -1:
-      result[ni].next.add pi
+      result.s[ni].next.add pi
     if ni in visited:
       continue
     visited.incl ni
@@ -329,52 +194,52 @@ func prefix(eNfa: Enfa, uid: NodeUid): Enfa =
       continue
     for mi in state.next:
       stack.add (mi, ni)
-  for n in result.mitems:
+  for n in mitems result.s:
     n.next.reverse
     n.isGreedy = true
   # Swap initial state by eoe
   var eoeIdx = -1'i16
-  for ni, n in result.pairs:
+  for ni, n in pairs result.s:
     if n.kind == reEoe:
       doAssert eoeIdx == -1
       eoeIdx = ni.int16
   doAssert eoeIdx != -1
-  for ni in eNfa[state0].next:
-    for i in 0 .. result[ni].next.len-1:
-      if result[ni].next[i] == state0:
-        result[ni].next[i] = eoeIdx
-  doAssert result[eoeIdx].kind == reEoe
-  doAssert result[state0].kind == reSkip
-  swap result[state0].kind, result[eoeIdx].kind
-  swap result[state0], result[eoeIdx]
+  for ni in eNfa.s[state0].next:
+    for i in 0 .. result.s[ni].next.len-1:
+      if result.s[ni].next[i] == state0:
+        result.s[ni].next[i] = eoeIdx
+  doAssert result.s[eoeIdx].kind == reEoe
+  doAssert result.s[state0].kind == reSkip
+  swap result.s[state0].kind, result.s[eoeIdx].kind
+  swap result.s[state0], result.s[eoeIdx]
   # cut
   var nIdx = -1
-  for ni, n in eNfa.pairs:
+  for ni, n in pairs eNfa.s:
     if n.uid == uid:
       doAssert nIdx == -1
       nIdx = ni
   doAssert nIdx != -1
-  result[state0].next = result[nIdx].next
+  result.s[state0].next = result.s[nIdx].next
 
 type
   LitOpt* = object
     lit*: Rune
     nfa*: Nfa
-    tns*: Transitions
 
 func canOpt*(litOpt: LitOpt): bool =
-  return litOpt.nfa.len > 0
+  return litOpt.nfa.s.len > 0
 
 func litopt2*(exp: RpnExp): LitOpt =
-  template litNode: untyped = exp[litIdx]
+  template litNode: untyped = exp.s[litIdx]
   let litIdx = exp.lonelyLit()
   if litIdx == -1:
     return
   result.lit = litNode.cp
   result.nfa = exp
+    .subExps
     .eNfa
     .prefix(litNode.uid)
-    .eRemoval(result.tns)
+    .eRemoval
 
 when isMainModule:
   from unicode import toUtf8, `$`
@@ -401,10 +266,9 @@ when isMainModule:
 
   func toNfa(s: string): Nfa =
     var groups: GroupsCapture
-    var transitions: Transitions
     result = s
       .rpn(groups)
-      .nfa2(transitions)
+      .nfa2
 
   proc toString(
     nfa: Nfa,
@@ -412,14 +276,14 @@ when isMainModule:
     visited: var set[int16]
   ): string =
     # XXX zero-match transitions are missing
-    if nfa[nIdx].kind == reEoe:
+    if nfa.s[nIdx].kind == reEoe:
       result = "eoe"
       return
     if nIdx in visited:
       result = "[...]"
       return
     visited.incl nIdx
-    let n = nfa[nIdx]
+    let n = nfa.s[nIdx]
     result = "["
     result.add $n.cp
     for nn in n.next:
@@ -489,9 +353,9 @@ when isMainModule:
   doAssert r"(a|ab)\w@&%".prefix.toString ==
     "[#, [&, [@, [w, [a, eoe], [b, [a, eoe]]]]]]"
   doAssert r"a?b".prefix.toString == r"a?".toNfa.toString
-  doAssert r"".prefix.len == 0
-  doAssert r"a?".prefix.len == 0
-  doAssert r"\w".prefix.len == 0
+  doAssert r"".prefix.s.len == 0
+  doAssert r"a?".prefix.s.len == 0
+  doAssert r"\w".prefix.s.len == 0
   doAssert r"(\w\d)*@".prefix.toString == r"(\d\w)*".toNfa.toString
   doAssert r"(\w\d)+@".prefix.toString == r"(\d\w)+".toNfa.toString
   # We search the start of the match, so greeddiness
diff --git a/src/regex/nfa.nim b/src/regex/nfa.nim
index ffc4a04..cf16427 100644
--- a/src/regex/nfa.nim
+++ b/src/regex/nfa.nim
@@ -1,6 +1,7 @@
 import std/deques
+import std/algorithm
 
-import ./nodetype
+import ./types
 import ./common
 
 func check(cond: bool, msg: string) =
@@ -8,26 +9,24 @@ func check(cond: bool, msg: string) =
     raise newException(RegexError, msg)
 
 type
-  Enfa* = seq[Node]
-  Nfa* = seq[Node]
   End = seq[int16]
-    ## store all the last
+    ## store the last
     ## states of a given state.
     ## Avoids having to recurse
-    ## a state to find its ends,
+    ## a state to find its end,
     ## but have to keep them up-to-date
 
 func combine(
-  nfa: var seq[Node],
+  eNfa: var Enfa,
   ends: var seq[End],
   org, target: int16
 ) =
   ## combine ends of ``org``
   ## with ``target``
   for e in ends[org]:
-    for i, ni in nfa[e].next.mpairs:
-      if nfa[ni].kind == reEOE:
-        ni = target
+    for i in mitems eNfa.s[e].next:
+      if eNfa.s[i].kind == reEOE:
+        i = target
   ends[org] = ends[target]
 
 const eoe = 0'i16
@@ -41,35 +40,36 @@ func update(
   ## to point to the end of the nodes in next.
   ## If a node in next is Eoe,
   ## the end of ``ni`` will point to itself
-  ends[ni].setLen(0)
+  ends[ni].setLen 0
   for n in next:
     if n == eoe:
-        ends[ni].add ni 
+      ends[ni].add ni 
     else:
-        ends[ni].add ends[n]
+      ends[ni].add ends[n]
 
-func eNfa*(expression: seq[Node]): Enfa {.raises: [RegexError].} =
+func eNfa*(exp: RpnExp): Enfa {.raises: [RegexError].} =
   ## Thompson's construction
-  result = newSeqOfCap[Node](expression.len + 2)
-  result.add initEOENode()
+  result.s = newSeq[Node](exp.s.len + 2)
+  result.s.setLen 0
+  result.s.add initEOENode()
   var
-    ends = newSeq[End](expression.len + 1)
+    ends = newSeq[End](exp.s.len + 1)
     states = newSeq[int16]()
-  if expression.len == 0:
+  if exp.s.len == 0:
     states.add eoe
-  for n in expression:
+  for n in exp.s:
     var n = n
     doAssert n.next.len == 0
     check(
-      result.high < int16.high,
+      result.s.high < int16.high,
       ("The expression is too long, " &
        "limit is ~$#") %% $int16.high)
-    let ni = result.len.int16
+    let ni = result.s.len.int16
     case n.kind
-    of matchableKind, assertionKind:
+    of matchableKind, assertionKind, reSkip:
       n.next.add eoe
       ends.update(ni, [eoe])
-      result.add n
+      result.s.add n
       states.add ni
     of reJoiner:
       let
@@ -87,7 +87,7 @@ func eNfa*(expression: seq[Node]): Enfa {.raises: [RegexError].} =
         stateA = states.pop()
       n.next.add [stateA, stateB]
       ends.update(ni, n.next)
-      result.add n
+      result.s.add n
       states.add ni
     of reZeroOrMore:
       check(
@@ -98,10 +98,10 @@ func eNfa*(expression: seq[Node]): Enfa {.raises: [RegexError].} =
       n.next.add [stateA, eoe]
       ends.update(ni, n.next)
       result.combine(ends, stateA, ni)
-      result.add n
+      result.s.add n
       states.add ni
       if not n.isGreedy:
-        swap(result[^1].next[0], result[^1].next[1])
+        swap result.s[^1].next[0], result.s[^1].next[1]
     of reOneOrMore:
       check(
         states.len >= 1,
@@ -111,10 +111,10 @@ func eNfa*(expression: seq[Node]): Enfa {.raises: [RegexError].} =
       n.next.add [stateA, eoe]
       ends.update(ni, n.next)
       result.combine(ends, stateA, ni)
-      result.add n
+      result.s.add n
       states.add stateA
       if not n.isGreedy:
-        swap(result[^1].next[0], result[^1].next[1])
+        swap result.s[^1].next[0], result.s[^1].next[1]
     of reZeroOrOne:
       check(
         states.len >= 1,
@@ -123,27 +123,27 @@ func eNfa*(expression: seq[Node]): Enfa {.raises: [RegexError].} =
       let stateA = states.pop()
       n.next.add [stateA, eoe]
       ends.update(ni, n.next)
-      result.add n
+      result.s.add n
       states.add ni
       if not n.isGreedy:
-        swap(result[^1].next[0], result[^1].next[1])
+        swap result.s[^1].next[0], result.s[^1].next[1]
     of reGroupStart:
       let stateA = states.pop()
       n.next.add stateA
       ends.update(ni, n.next)
-      result.add n
+      result.s.add n
       states.add ni
     of reGroupEnd:
       n.next.add eoe
       ends.update(ni, n.next)
       let stateA = states.pop()
       result.combine(ends, stateA, ni)
-      result.add n
+      result.s.add n
       states.add stateA
     else:
       doAssert(false, "Unhandled node: $#" %% $n.kind)
   doAssert states.len == 1
-  result.add initSkipNode(states)
+  result.s.add initSkipNode(states)
 
 type
   Zclosure = seq[int16]
@@ -160,59 +160,58 @@ func isTransitionZ(n: Node): bool {.inline.} =
 
 func teClosure(
   result: var TeClosure,
-  enfa: Enfa,
+  eNfa: Enfa,
   state: int16,
-  visited: var set[int16],
+  processing: var seq[int16],
   zTransitions: Zclosure
 ) =
   var zTransitionsCurr = zTransitions
-  if isTransitionZ(enfa[state]):
+  if isTransitionZ eNfa.s[state]:
     zTransitionsCurr.add state
-  if enfa[state].kind in matchableKind + {reEOE}:
-    result.add((state, zTransitionsCurr))
+  if eNfa.s[state].kind in matchableKind + {reEOE}:
+    result.add (state, zTransitionsCurr)
     return
-  for i, s in pairs enfa[state].next:
-    # Enter loops only once. Allows: "(a*)*" -> ["a", ""] 
-    if enfa[state].kind in repetitionKind:
-      if s in visited and i == int(not enfa[state].isGreedy):
-        continue
-      visited.incl s
-    teClosure(result, enfa, s, visited, zTransitionsCurr)
+  for i, s in pairs eNfa.s[state].next:
+    # Enter loops only once. "a", re"(a*)*" -> ["a", ""]
+    if eNfa.s[state].kind in repetitionKind:
+      if s notin processing or i == int(eNfa.s[state].isGreedy):
+        processing.add s
+        teClosure(result, eNfa, s, processing, zTransitionsCurr)
+        discard processing.pop()
+      # else skip loop
+    else:
+      teClosure(result, eNfa, s, processing, zTransitionsCurr)
 
 func teClosure(
   result: var TeClosure,
-  enfa: Enfa,
-  state: int16
+  eNfa: Enfa,
+  state: int16,
+  processing: var seq[int16]
 ) =
-  var visited: set[int16]
+  doAssert processing.len == 0
   var zclosure: Zclosure
-  for s in enfa[state].next:
-    teClosure(result, enfa, s, visited, zclosure)
+  for s in eNfa.s[state].next:
+    teClosure(result, eNfa, s, processing, zclosure)
 
-type
-  TransitionsAll* = seq[seq[int16]]
-  ZclosureStates* = seq[seq[Node]]
-  Transitions* = object
-    allZ*: TransitionsAll
-    z*: ZclosureStates
+when (NimMajor, NimMinor, NimPatch) < (1,4,0) and not declared(IndexDefect):
+  # avoids a warning
+  type IndexDefect = IndexError
 
-func eRemoval*(
-  eNfa: Enfa,
-  transitions: var Transitions
-): Nfa {.raises: [].} =
+func eRemoval*(eNfa: Enfa): Nfa {.raises: [].} =
   ## Remove e-transitions and return
   ## remaining state transtions and
   ## submatches, and zero matches.
   ## Transitions are added in matching order (BFS),
   ## which may help matching performance
   #echo eNfa
-  result = newSeqOfCap[Node](eNfa.len)
-  transitions.allZ.setLen eNfa.len
-  var statesMap = newSeq[int16](eNfa.len)
+  result.s = newSeq[Node](eNfa.s.len)
+  result.s.setLen 0
+  result.t.allZ.setLen eNfa.s.len
+  var statesMap = newSeq[int16](eNfa.s.len)
   for i in 0 .. statesMap.len-1:
     statesMap[i] = -1
-  let start = int16(eNfa.len-1)
-  result.add eNfa[start]
+  let start = int16(eNfa.s.len-1)
+  result.s.add eNfa.s[start]
   statesMap[start] = 0'i16
   var closure: TeClosure
   var zc: seq[Node]
@@ -221,36 +220,101 @@ func eRemoval*(
   var qu: set[int16]
   qu.incl start
   var qa: int16
+  var processing = newSeqOfCap[int16](8)
   while qw.len > 0:
     try:
       qa = qw.popLast()
-    except IndexError:
+    except IndexDefect:
       doAssert false
     closure.setLen 0
-    teClosure(closure, eNfa, qa)
-    result[statesMap[qa]].next.setLen 0
+    teClosure(closure, eNfa, qa, processing)
+    result.s[statesMap[qa]].next.setLen 0
     for qb, zclosure in closure.items:
       if statesMap[qb] == -1:
-        result.add eNfa[qb]
-        statesMap[qb] = result.len.int16-1
+        result.s.add eNfa.s[qb]
+        statesMap[qb] = result.s.len.int16-1
       doAssert statesMap[qb] > -1
       doAssert statesMap[qa] > -1
-      result[statesMap[qa]].next.add statesMap[qb]
-      transitions.allZ[statesMap[qa]].add -1'i16
+      result.s[statesMap[qa]].next.add statesMap[qb]
+      result.t.allZ[statesMap[qa]].add -1'i16
       zc.setLen 0
       for z in zclosure:
-        zc.add eNfa[z]
+        zc.add eNfa.s[z]
       if zc.len > 0:
-        transitions.z.add zc
-        transitions.allZ[statesMap[qa]][^1] = int16(transitions.z.len-1)
+        result.t.z.add zc
+        result.t.allZ[statesMap[qa]][^1] = int16(result.t.z.len-1)
       if qb notin qu:
         qu.incl qb
         qw.addFirst qb
-  transitions.allZ.setLen result.len
+  result.t.allZ.setLen result.s.len
+
+func reverse(eNfa: Enfa): Enfa =
+  template state0: untyped = int16(eNfa.s.len-1)
+  result = eNfa
+  for n in mitems result.s:
+    n.next.setLen 0
+  var stack = @[(state0, -1'i16)]
+  var visited: set[int16]
+  template state: untyped = eNfa.s[ni]
+  while stack.len > 0:
+    let (ni, pi) = stack.pop()
+    if pi > -1:
+      result.s[ni].next.add pi
+    if ni in visited:
+      continue
+    visited.incl ni
+    for mi in state.next:
+      stack.add (mi, ni)
+  for n in mitems result.s:
+    n.next.reverse
+  # fix loops greediness
+  for i, n in pairs eNfa.s:
+    case n.kind:
+    of reZeroOrMore:
+      if not n.isGreedy:
+        result.s[i].next.reverse
+    of reOneOrMore:
+      if not n.isGreedy:
+        result.s[n.next[1]].next.reverse
+    else:
+      discard
+  # Swap initial state by eoe
+  var eoeIdx = -1'i16
+  for i, n in pairs result.s:
+    if n.kind == reEoe:
+      doAssert eoeIdx == -1
+      eoeIdx = i.int16
+  doAssert eoeIdx != -1
+  for i in eNfa.s[state0].next:
+    for j in 0 .. result.s[i].next.len-1:
+      if result.s[i].next[j] == state0:
+        result.s[i].next[j] = eoeIdx
+  swap result.s[state0].next, result.s[eoeIdx].next
+  doAssert result.s[state0].kind == reSkip
+  doAssert result.s[eoeIdx].kind == reEoe
+  doAssert result.s[state0].next.len > 0
+  doAssert result.s[eoeIdx].next.len == 0
+
+func subExps*(exp: RpnExp): RpnExp =
+  result = exp
+  for n in mitems result.s:
+    case n.kind
+    of reLookahead, reNotLookahead:
+      n.subExp.nfa = n.subExp.rpn
+        .subExps
+        .eNfa
+        .eRemoval
+      n.subExp.rpn.s = newSeq[Node]()  # nullify
+    of reLookbehind, reNotLookbehind:
+      n.subExp.nfa = n.subExp.rpn
+        .subExps
+        .eNfa
+        .reverse
+        .eRemoval
+      n.subExp.rpn.s = newSeq[Node]()  # nullify
+    else:
+      discard
 
 # XXX rename to nfa when Nim v0.19 is dropped
-func nfa2*(
-  exp: seq[Node],
-  transitions: var Transitions
-): Nfa {.raises: [RegexError].} =
-  result = exp.eNfa.eRemoval(transitions)
+func nfa2*(exp: RpnExp): Nfa {.raises: [RegexError].} =
+  exp.subExps.eNfa.eRemoval
diff --git a/src/regex/nfafindall.nim b/src/regex/nfafindall.nim
index 2814da0..18c129d 100644
--- a/src/regex/nfafindall.nim
+++ b/src/regex/nfafindall.nim
@@ -15,15 +15,15 @@ match taking priority according to PCRE rules
 (longest-left match wins).
 
 This algorithm works the same way as calling
-nfamatch find repeatedly would, except it keeps
+nfamatch find repeatedly, except it keeps
 all possible matches and returns them as soon
 as the current character cannot match the regex,
 i.e: it's a safe point to return. This is just
 to avoid consuming too much memory if possible.
 
-The downside is it takes linear time in the length
-of the text to match + the regex. In most cases it
-should take less space, since the matches are index ranges.
+The downside is it takes linear space in the length
+of the text to match + the regex. In practice it almost always
+takes little space, since the matches are index ranges.
 
 The tricky part is to replace all overlapped
 temporary matches every time an Eoe is found,
@@ -31,24 +31,21 @@ then prune the next states (as they're overlapped),
 then try to match the initial state to the
 current character (next possible match). Other than
 that is the same algorithm as nfamatch.
+
+The "literals optimization" is also implemented here,
+see https://nitely.github.io/2020/11/30/regex-literals-optimization.html
+for the algorithm description
 ]#
 
 import std/unicode
 import std/tables
 from std/strutils import find
 
+import ./common
 import ./nodematch
-import ./nodetype
+import ./types
 import ./nfatype
-
-func bwRuneAt(s: string, n: int): Rune =
-  ## Take rune ending at ``n``
-  doAssert n >= 0
-  doAssert n <= s.len-1
-  var n = n
-  while n > 0 and s[n].ord shr 6 == 0b10:
-    dec n
-  fastRuneAt(s, n, result, false)
+import ./nfamatch
 
 type
   MatchItemIdx = int
@@ -62,6 +59,7 @@ type
     a, b: Submatches
     m: Matches
     c: Capts
+    look: Lookaround
 
 func len(ms: Matches): int {.inline.} =
   ms.i
@@ -87,14 +85,21 @@ func clear(ms: var Matches) {.inline.} =
 
 template initMaybeImpl(
   ms: var RegexMatches,
-  regex: Regex
+  size: int
 ) =
   if ms.a == nil:
     assert ms.b == nil
-    ms.a = newSubmatches(regex.nfa.len)
-    ms.b = newSubmatches(regex.nfa.len)
-  doAssert ms.a.cap >= regex.nfa.len and
-    ms.b.cap >= regex.nfa.len
+    ms.a = newSubmatches size
+    ms.b = newSubmatches size
+    ms.look = initLook()
+  doAssert ms.a.cap >= size and
+    ms.b.cap >= size
+
+template initMaybeImpl(
+  ms: var RegexMatches,
+  regex: Regex
+) =
+  initMaybeImpl(ms, regex.nfa.s.len)
 
 func hasMatches(ms: RegexMatches): bool {.inline.} =
   return ms.m.len > 0
@@ -136,18 +141,20 @@ func dummyMatch*(ms: var RegexMatches, i: int) {.inline.} =
 
 func submatch(
   ms: var RegexMatches,
+  text: string,
   regex: Regex,
   i: int,
   cPrev, c: int32
 ) {.inline.} =
-  template tns: untyped = regex.transitions
-  template nfa: untyped = regex.nfa
+  template tns: untyped = regex.nfa.t
+  template nfa: untyped = regex.nfa.s
   template smA: untyped = ms.a
   template smB: untyped = ms.b
   template capts: untyped = ms.c
   template n: untyped = ms.a[smi].ni
   template capt: untyped = ms.a[smi].ci
   template bounds: untyped = ms.a[smi].bounds
+  template look: untyped = ms.look
   smB.clear()
   var captx: int32
   var matched = true
@@ -172,8 +179,10 @@ func submatch(
               bound: i,
               idx: z.idx)
             captx = (capts.len-1).int32
-          of assertionKind:
+          of assertionKind - lookaroundKind:
             matched = match(z, cPrev.Rune, c.Rune)
+          of lookaroundKind:
+            lookAroundTpl()
           else:
             assert false
             discard
@@ -208,14 +217,14 @@ func findSomeImpl*(
     iPrev = start.int
     optFlag = mfFindMatchOpt in flags
   smA.add (0'i16, -1'i32, i .. i-1)
-  if 0 <= start-1 and start-1 <= len(text)-1:
+  if start-1 in 0 .. text.len-1:
     cPrev = bwRuneAt(text, start-1).int32
-  while i < len(text):
+  while i < text.len:
     #debugEcho "it= ", i, " ", cPrev
     fastRuneAt(text, i, c, true)
     #c = text[i].Rune
     #i += 1
-    submatch(ms, regex, iPrev, cPrev, c.int32)
+    submatch(ms, text, regex, iPrev, cPrev, c.int32)
     if smA.len == 0:
       # avoid returning right before final zero-match
       if i < len(text):
@@ -229,7 +238,7 @@ func findSomeImpl*(
     smA.add (0'i16, -1'i32, i .. i-1)
     iPrev = i
     cPrev = c.int32
-  submatch(ms, regex, iPrev, cPrev, -1'i32)
+  submatch(ms, text, regex, iPrev, cPrev, -1'i32)
   doAssert smA.len == 0
   if ms.hasMatches():
     #debugEcho "m= ", ms.m.s
@@ -241,105 +250,6 @@ func findSomeImpl*(
 # there is an explanation of how this work
 # in litopt.nim, move this there?
 
-template initMaybeImpl(
-  ms: var RegexMatches,
-  size: int
-) =
-  if ms.a == nil:
-    assert ms.b == nil
-    ms.a = newSubmatches size
-    ms.b = newSubmatches size
-  doAssert ms.a.cap >= size and
-    ms.b.cap >= size
-
-template bwFastRuneAt(
-  s: string, n: var int, result: var Rune
-) =
-  ## Take rune ending at ``n``
-  doAssert n > 0
-  doAssert n <= s.len-1
-  dec n
-  while n > 0 and s[n].ord shr 6 == 0b10:
-    dec n
-  fastRuneAt(s, n, result, false)
-
-func submatch2(
-  smA, smB: var Submatches,
-  regex: Regex,
-  i: int,
-  cPrev, c: int32
-) =
-  template nfa: untyped = regex.litOpt.nfa
-  template tns: untyped = regex.litOpt.tns
-  smB.clear()
-  var matched = true
-  for n, capt, bounds in smA.items:
-    if nfa[n].kind == reEoe:
-      smB.add (n, capt, bounds)
-      break
-    for nti, nt in nfa[n].next.pairs:
-      if smB.hasState(nt):
-        continue
-      #debugEcho nfa[nt].kind
-      if nfa[nt].kind != reEoe and not match(nfa[nt], c.Rune):
-        continue
-      matched = true
-      if tns.allZ[n][nti] > -1:
-        for z in tns.z[tns.allZ[n][nti]]:
-          if z.kind in assertionKind:
-            matched = match(z, c.Rune, cPrev.Rune)
-          if not matched:
-            break
-      if matched:
-        smB.add (nt, capt, i .. bounds.b)
-        if nfa[nt].kind == reEoe:
-          swap smA, smB
-          return
-  swap smA, smB
-
-func matchPrefixImpl(
-  text: string,
-  regex: Regex,
-  smA, smB: var Submatches,
-  start, limit: Natural = 0
-): int {.inline.} =
-  template nfa: untyped = regex.litOpt.nfa
-  doAssert start < len(text)
-  doAssert start >= limit
-  smA.clear()
-  smB.clear()
-  var
-    c = Rune(-1)
-    cPrev = text.runeAt(start).int32
-    i = start.int
-    iPrev = start.int
-  #debugEcho cPrev.Rune
-  smA.add (0'i16, -1'i32, i .. i-1)
-  while i > limit:
-    bwFastRuneAt(text, i, c)
-    #i -= 1
-    #c = text[i].Rune
-    #debugEcho "txt.Rune=", c
-    #debugEcho "txt.i=", i
-    submatch2(smA, smB, regex, iPrev, cPrev, c.int32)
-    if smA.len == 0:
-      return -1
-    if nfa[smA[0].ni].kind == reEoe:
-      return smA[0].bounds.a
-    iPrev = i
-    cPrev = c.int32
-  if i > 0:
-    # limit can be part of the match, there is no overlap
-    bwFastRuneAt(text, i, c)
-    #debugEcho "c=", c, " limit=", limit
-  else:
-    c = Rune(-1)
-  submatch2(smA, smB, regex, iPrev, cPrev, c.int32)
-  for n, capt, bounds in smA.items:
-    if nfa[n].kind == reEoe:
-      return bounds.a
-  return -1
-
 func findSomeOptImpl*(
   text: string,
   regex: Regex,
@@ -347,11 +257,12 @@ func findSomeOptImpl*(
   start: Natural
 ): int =
   template regexSize: untyped =
-    max(regex.litOpt.nfa.len, regex.nfa.len)
+    max(regex.litOpt.nfa.s.len, regex.nfa.s.len)
   template opt: untyped = regex.litOpt
   template smA: untyped = ms.a
   template smB: untyped = ms.b
-  doAssert opt.nfa.len > 0
+  template look: untyped = ms.look
+  doAssert opt.nfa.s.len > 0
   initMaybeImpl(ms, regexSize)
   ms.clear()
   var limit = start.int
@@ -367,7 +278,7 @@ func findSomeOptImpl*(
     #debugEcho "litIdx=", litIdx
     doAssert litIdx >= i
     i = litIdx
-    i = matchPrefixImpl(text, regex, smA, smB, i, limit)
+    i = reversedMatchImpl(smA, smB, text, opt.nfa, look, i, limit)
     if i == -1:
       #debugEcho "not.Match=", i
       i = litIdx+1
diff --git a/src/regex/nfamacro.nim b/src/regex/nfamacro.nim
index f67d00d..f462712 100644
--- a/src/regex/nfamacro.nim
+++ b/src/regex/nfamacro.nim
@@ -6,9 +6,10 @@ import std/tables
 import std/sets
 
 import pkg/unicodedb/properties
-import pkg/unicodedb/types
+import pkg/unicodedb/types as utypes
 
-import ./nodetype
+import ./common
+import ./types
 import ./nfatype
 import ./compiler
 
@@ -26,6 +27,17 @@ macro defForVars(idns: varargs[untyped]): untyped =
       idn, newEmptyNode(), newCall("genSym", newLit nskForVar, newLit $idn))
   return newStmtList lets
 
+type
+  Sig = proc (
+    smA, smB, capts, captIdx, matched, text, start: NimNode,
+    nfa: Nfa,
+    look: Lookaround,
+    flags: set[MatchFlag]
+  ): NimNode {.noSideEffect, raises: [].}
+  Lookaround = object
+    ahead, behind: Sig
+    smL: NimNode
+
 # todo: can not use unicodeplus due to
 # https://github.com/nim-lang/Nim/issues/7059
 func swapCase(r: Rune): Rune =
@@ -200,7 +212,6 @@ func genWordBoundaryAscii(cA, cB: NimNode): NimNode =
       (`cB` != -1'i32 and `wordMatchB`)
 
 func genMatch(n: Node, cA, cB: NimNode): NimNode =
-  let cpLit = newLit n.cp.int32
   case n.kind
   of reStart, reStartSym:
     quote do: `cA` == -1'i32
@@ -220,32 +231,64 @@ func genMatch(n: Node, cA, cB: NimNode): NimNode =
   of reNotWordBoundaryAscii:
     let wordBoundary = genWordBoundaryAscii(cA, cB)
     quote do: not `wordBoundary`
-  of reLookahead:
-    quote do: `cpLit` == `cB`
-  of reNotLookahead:
-    quote do: `cpLit` != `cB`
-  of reLookbehind:
-    quote do: `cpLit` == `cA`
-  of reNotLookbehind:
-    quote do: `cpLit` != `cA`
   else:
     doAssert false
     quote do: false
 
+func genLookaroundMatch(
+  capts, captx, matched, charIdx, text: NimNode,
+  n: Node,
+  look: Lookaround
+): NimNode =
+  template nfa: untyped = n.subExp.nfa
+  template smL: untyped = look.smL
+  let smlA = quote do: lastA(`smL`)
+  let smlB = quote do: lastB(`smL`)
+  var flags = {mfAnchored}
+  if n.subExp.reverseCapts:
+    flags.incl mfReverseCapts
+  var lookaroundStmt = case n.kind
+    of reLookahead, reNotLookahead:
+      look.ahead(
+        smlA, smlB, capts, captx, matched,
+        text, charIdx, nfa, look, flags)
+    else:
+      doAssert n.kind in {reLookbehind, reNotLookbehind}
+      look.behind(
+        smlA, smlB, capts, captx, matched,
+        text, charIdx, nfa, look, flags)
+  if n.kind in {reNotLookahead, reNotLookbehind}:
+    lookaroundStmt = quote do:
+      `lookaroundStmt`
+      `matched` = not `matched`
+  let nfaLenLit = newLit nfa.s.len
+  result = quote do:
+    grow `smL`
+    `smL`.last.setLen `nfaLenLit`
+    `lookaroundStmt`
+    removeLast `smL`
+
 func genMatchedBody(
   smB, ntLit, capt, bounds, matched, captx,
-  capts, charIdx, cPrev, c: NimNode,
+  capts, charIdx, cPrev, c, text: NimNode,
   i, nti: int,
-  regex: Regex
+  nfa: Nfa,
+  look: Lookaround,
+  flags: set[MatchFlag]
 ): NimNode =
-  if regex.transitions.allZ[i][nti] == -1'i16:
+  template t: untyped = nfa.t
+  let bounds2 = if mfBwMatch in flags:
+    quote do: `charIdx` .. `bounds`.b
+  else:
+    quote do: `bounds`.a .. `charIdx`-1
+  if t.allZ[i][nti] == -1'i16:
     return quote do:
-      add(`smB`, (`ntLit`, `capt`, `bounds`.a .. `charIdx`-1))
+      add(`smB`, (`ntLit`, `capt`, `bounds2`))
   var matchedBody: seq[NimNode]
   matchedBody.add quote do:
     `matched` = true
     `captx` = `capt`
-  for z in regex.transitions.z[regex.transitions.allZ[i][nti]]:
+  for z in t.z[t.allZ[i][nti]]:
     case z.kind
     of groupKind:
       let zIdx = newLit z.idx
@@ -255,23 +298,33 @@ func genMatchedBody(
           bound: `charIdx`,
           idx: `zIdx`))
         `captx` = (len(`capts`) - 1).int32
-    of assertionKind:
-      # https://github.com/nim-lang/Nim/issues/13266
-      #let zLit = newLit z
-      let matchCond = genMatch(`z`, `cPrev`, `c`)
+    of assertionKind - lookaroundKind:
+      let matchCond = if mfBwMatch in flags:
+        genMatch(z, c, cPrev)
+      else:
+        genMatch(z, cPrev, c)
       matchedBody.add quote do:
         `matched` = `matched` and `matchCond`
+    of lookaroundKind:
+      let matchStmt = genLookaroundMatch(
+        capts, captx, matched, charIdx, text, z, look)
+      matchedBody.add quote do:
+        if `matched`:
+          `matchStmt`
     else:
       doAssert false
   matchedBody.add quote do:
     if `matched`:
-      add(`smB`, (`ntLit`, `captx`, `bounds`.a .. `charIdx`-1))
+      add(`smB`, (`ntLit`, `captx`, `bounds2`))
   return newStmtList matchedBody
 
-func genSubmatch(
+func genNextState(
   n, capt, bounds, smB, c, matched, captx,
-  capts, charIdx, cPrev: NimNode,
-  regex: Regex
+  capts, charIdx, cPrev, text: NimNode,
+  nfa: Nfa,
+  look: Lookaround,
+  flags: set[MatchFlag],
+  eoeOnly: bool
 ): NimNode =
   #[
     case n
@@ -287,130 +340,208 @@ func genSubmatch(
     else:
       error
   ]#
+  template s: untyped = nfa.s
   result = newStmtList()
   var caseStmtN: seq[NimNode]
   caseStmtN.add n
-  for i in 0 .. regex.nfa.len-1:
-    if regex.nfa[i].kind == reEoe:
+  for i in 0 .. s.len-1:
+    if s[i].kind == reEoe:
       continue
     var branchBodyN: seq[NimNode]
-    for nti, nt in regex.nfa[i].next.pairs:
-      let matchCond = case regex.nfa[nt].kind
+    for nti, nt in s[i].next.pairs:
+      if eoeOnly and s[nt].kind != reEoe:
+        continue
+      let matchCond = case s[nt].kind
         of reEoe:
           quote do: `c` == -1'i32
         of reInSet:
-          let m = genSetMatch(c, regex.nfa[nt])
+          let m = genSetMatch(c, s[nt])
           quote do: `c` >= 0'i32 and `m`
         of reNotSet:
-          let m = genSetMatch(c, regex.nfa[nt])
+          let m = genSetMatch(c, s[nt])
           quote do: `c` >= 0'i32 and not `m`
         else:
-          let m = genMatch(c, regex.nfa[nt])
+          let m = genMatch(c, s[nt])
           quote do: `c` >= 0'i32 and `m`
       let ntLit = newLit nt
       let matchedBodyStmt = genMatchedBody(
         smB, ntLit, capt, bounds, matched, captx,
-        capts, charIdx, cPrev, c,
-        i, nti, regex)
-      branchBodyN.add quote do:
-        if not hasState(`smB`, `ntLit`) and `matchCond`:
-          `matchedBodyStmt`
-    doAssert branchBodyN.len > 0
-    caseStmtN.add newTree(nnkOfBranch,
-      newLit i.int16,
-      newStmtList(
-        branchBodyN))
-  doAssert caseStmtN.len > 1
-  caseStmtN.add newTree(nnkElse,
-    quote do:
-      doAssert false
-      discard)
-  result.add newTree(nnkCaseStmt, caseStmtN)
-  when defined(reDumpMacro):
-    echo "==== genSubmatch ===="
-    echo repr(result)
-
-func submatch(
-  smA, smB, c,
-  capts, charIdx, cPrev,
-  captx, matched: NimNode,
-  regex: Regex
-): NimNode =
-  defForVars n, capt, bounds
-  let genSubmatchCall = genSubmatch(
-    n, capt, bounds, smB, c, matched, captx,
-    capts, charIdx, cPrev, regex)
-  result = quote do:
-    `smB`.clear()
-    for `n`, `capt`, `bounds` in `smA`.items:
-      `genSubmatchCall`
-    swap `smA`, `smB`
-
-func genSubmatchEoe(
-  n, capt, bounds, smB, matched, captx,
-  capts, charIdx, cPrev: NimNode,
-  regex: Regex
-): NimNode =
-  # This is the same as genSubmatch
-  # but just for EOE states
-  #[
-    case n
-    of 0:
-      if not smB.hasState(1):
-        if c == -1:
-          smB.add((1, capt, bounds))
-    of 1:
-      ...
-    else:
-      discard
-  ]#
-  result = newStmtList()
-  var caseStmtN: seq[NimNode]
-  caseStmtN.add n
-  for i in 0 .. regex.nfa.len-1:
-    if regex.nfa[i].kind == reEoe:
-      continue
-    var branchBodyN: seq[NimNode]
-    for nti, nt in regex.nfa[i].next.pairs:
-      if regex.nfa[nt].kind == reEoe:
-        let ntLit = newLit nt
-        let cLit = newLit -1'i32
-        let matchedBodyStmt = genMatchedBody(
-          smB, ntLit, capt, bounds, matched, captx,
-          capts, charIdx, cPrev, cLit,
-          i, nti, regex)
+        capts, charIdx, cPrev, c, text,
+        i, nti, nfa, look, flags)
+      if mfAnchored in flags and s[nt].kind == reEoe:
         branchBodyN.add quote do:
           if not hasState(`smB`, `ntLit`):
             `matchedBodyStmt`
+      else:
+        branchBodyN.add quote do:
+          if not hasState(`smB`, `ntLit`) and `matchCond`:
+            `matchedBodyStmt`
+    doAssert eoeOnly or branchBodyN.len > 0
     if branchBodyN.len > 0:
       caseStmtN.add newTree(nnkOfBranch,
         newLit i.int16,
         newStmtList(
           branchBodyN))
   doAssert caseStmtN.len > 1
+  let elseAssertion = if eoeOnly:
+    newEmptyNode()
+  else:
+    quote do: doAssert false
   caseStmtN.add newTree(nnkElse,
-    quote do: discard)
+    quote do:
+      `elseAssertion`
+      discard)
   result.add newTree(nnkCaseStmt, caseStmtN)
   when defined(reDumpMacro):
-    echo "==== genSubmatchEoe ===="
+    echo "==== genNextState ===="
     echo repr(result)
 
-func submatchEoe(
-  smA, smB,
-  capts, charIdx, cPrev,
-  captx, matched: NimNode,
-  regex: Regex
+func nextState(
+  smA, smB, c, capts, charIdx, cPrev,
+  captx, matched, eoe, text: NimNode,
+  nfa: Nfa,
+  look: Lookaround,
+  flags: set[MatchFlag],
+  eoeOnly = false
 ): NimNode =
   defForVars n, capt, bounds
-  let genSubmatchEoeCall = genSubmatchEoe(
-    n, capt, bounds, smB, matched, captx,
-    capts, charIdx, cPrev, regex)
+  let eoeBailOut = if mfAnchored in flags:
+    quote do:
+      if `n` == `eoe`:
+        if not hasState(`smB`, `n`):
+          add(`smB`, (`n`, `capt`, `bounds`))
+        break
+  else:
+    newEmptyNode()
+  let nextStateStmt = genNextState(
+    n, capt, bounds, smB, c, matched, captx,
+    capts, charIdx, cPrev, text, nfa, look,
+    flags, eoeOnly)
   result = quote do:
     `smB`.clear()
     for `n`, `capt`, `bounds` in `smA`.items:
-      `genSubmatchEoeCall`
+      `eoeBailOut`
+      `nextStateStmt`
     swap `smA`, `smB`
 
+func eoeIdx(nfa: Nfa): int16 =
+  for i in 0 .. nfa.s.len-1:
+    if nfa.s[i].kind == reEoe:
+      return i.int16
+  doAssert false
+
+func matchImpl(
+  smA, smB, capts, captIdx, matched, text, start: NimNode,
+  nfa: Nfa,
+  look: Lookaround,
+  flags: set[MatchFlag]
+): NimNode =
+  defVars c, i, cPrev, captx
+  let eoe = newLit nfa.eoeIdx
+  let c2 = quote do: int32(`c`)
+  let nextStateStmt = nextState(
+    smA, smB, c2, capts, i, cPrev, captx,
+    matched, eoe, text, nfa, look, flags)
+  let cEoe = newLit -1'i32
+  let nextStateEoeStmt = nextState(
+    smA, smB, cEoe, capts, i, cPrev, captx,
+    matched, eoe, text, nfa, look, flags, eoeOnly = true)
+  let eoeBailOutStmt = if mfAnchored in flags:
+    quote do:
+      if `smA`[0].ni == `eoe`:
+        break
+  else:
+    newEmptyNode()
+  let captsStmt = if mfReverseCapts in flags:
+    quote do:
+      `captIdx` = reverse(`capts`, `smA`[0].ci, `captIdx`)
+  else:
+    quote do:
+      `captIdx` = `smA`[0].ci
+  result = quote do:
+    var
+      `c` = Rune(-1)
+      `cPrev` = -1'i32
+      `i` = `start`
+      iNext = `start`
+      `captx` {.used.} = -1'i32
+    if `start`-1 in 0 .. `text`.len-1:
+      `cPrev` = bwRuneAt(`text`, `start`-1).int32
+    clear(`smA`)
+    add(`smA`, (0'i16, `captIdx`, `i` .. `i`-1))
+    while `i` < `text`.len:
+      fastRuneAt(`text`, iNext, `c`, true)
+      `nextStateStmt`
+      if `smA`.len == 0:
+        break
+      `eoeBailOutStmt`
+      `i` = iNext
+      `cPrev` = `c2`
+    `c` = Rune(-1)
+    `nextStateEoeStmt`
+    if `smA`.len > 0:
+      doAssert `smA`[0].ni == `eoe`
+      `captsStmt`
+    `matched` = `smA`.len > 0
+
+func reversedMatchImpl(
+  smA, smB, capts, captIdx, matched, text, start: NimNode,
+  nfa: Nfa,
+  look: Lookaround,
+  flags: set[MatchFlag]
+): NimNode =
+  defVars c, i, cPrev, captx
+  let flags = flags + {mfAnchored, mfBwMatch}
+  let eoe = newLit nfa.eoeIdx
+  let c2 = quote do: int32(`c`)
+  let nextStateStmt = nextState(
+    smA, smB, c2, capts, i, cPrev, captx,
+    matched, eoe, text, nfa, look, flags)
+  #let limit0 = limit.kind in nnkLiterals and limit.intVal == 0
+  let cEoe = newLit -1'i32
+  let nextStateEoeStmt = nextState(
+    smA, smB, cEoe, capts, i, cPrev, captx,
+    matched, eoe, text, nfa, look, flags, eoeOnly = true)
+  let captsStmt = if mfReverseCapts in flags:
+    quote do:
+      `captIdx` = reverse(`capts`, `smA`[0].ci, `captIdx`)
+  else:
+    quote do:
+      `captIdx` = `smA`[0].ci
+  result = quote do:
+    #doAssert `start` >= `limit`
+    var
+      `c` = Rune(-1)
+      `cPrev` = -1'i32
+      `i` = `start`
+      iNext = `start`
+      `captx` {.used.} = -1'i32
+    if `start` in 0 .. `text`.len-1:
+      `cPrev` = runeAt(`text`, `start`).int32
+    clear(`smA`)
+    add(`smA`, (0'i16, `captIdx`, `i` .. `i`-1))
+    while iNext > 0:
+      bwFastRuneAt(`text`, iNext, `c`)
+      `nextStateStmt`
+      if `smA`.len == 0:
+        break
+      if `smA`[0].ni == `eoe`:
+        break
+      `i` = iNext
+      `cPrev` = `c2`
+    `c` = Rune(-1)
+    `nextStateEoeStmt`
+    if `smA`.len > 0:
+      doAssert `smA`[0].ni == `eoe`
+      `captsStmt`
+    `matched` = `smA`.len > 0
+
+template look(smL: NimNode): untyped =
+  Lookaround(
+    ahead: matchImpl,
+    behind: reversedMatchImpl,
+    smL: smL)
+
 template constructSubmatches2(
   captures, txt, capts, capt, size: untyped
 ): untyped =
@@ -432,40 +563,28 @@ proc matchImpl*(text, expLit, body: NimNode): NimNode =
   if not (expLit.kind == nnkCallStrLit and $expLit[0] == "rex"):
     error "not a regex literal; only rex\"regex\" is allowed", expLit
   let exp = expLit[1]
-  defVars smA, smB, c, capts, iPrev, cPrev, captx, matched
-  let c2 = quote do: int32(`c`)
+  defVars smA, smB, capts, capt, matched, smL
   let regex = reCt(exp.strVal)
-  let submatchCall = submatch(
-    smA, smB, c2, capts, iPrev, cPrev, captx, matched, regex)
-  let submatchEoeCall = submatchEoe(
-    smA, smB, capts, iPrev, cPrev, captx, matched, regex)
-  let nfaLenLit = newLit regex.nfa.len
+  let startLit = newLit 0
+  let flags: set[MatchFlag] = {}
+  let matchImplStmt = matchImpl(
+    smA, smB, capts, capt, matched,
+    text, startLit, regex.nfa, look(smL), flags)
+  let nfaLenLit = newLit regex.nfa.s.len
   let nfaGroupsLen = regex.groupsCount
   result = quote do:
     block:
       var
-        `smA`, `smB`: Submatches
-        `c` = Rune(-1)
-        `cPrev` = -1'i32
-        `iPrev` = 0
-        `capts` {.used.}: Capts
-        `captx` {.used.}: int32
-        `matched` {.used.}: bool
-        i = 0
-      `smA` = newSubmatches `nfaLenLit`
-      `smB` = newSubmatches `nfaLenLit`
-      add(`smA`, (0'i16, -1'i32, 0 .. -1))
-      while i < len(`text`):
-        fastRuneAt(`text`, i, `c`, true)
-        `submatchCall`
-        if `smA`.len == 0:
-          break
-        `iPrev` = i
-        `cPrev` = `c2`
-      `submatchEoeCall`
-      if `smA`.len > 0:
+        `smA` = newSubmatches `nfaLenLit`
+        `smB` = newSubmatches `nfaLenLit`
+        `capts`: Capts
+        `capt` = -1'i32
+        `matched` = false
+        `smL` {.used.}: SmLookaround
+      `matchImplStmt`
+      if `matched`:
         var matches {.used, inject.}: seq[string]
         when `nfaGroupsLen` > 0:
           constructSubmatches2(
-            matches, `text`, `capts`, `smA`[0].ci, `nfaGroupsLen`)
+            matches, `text`, `capts`, `capt`, `nfaGroupsLen`)
         `body`
diff --git a/src/regex/nfamatch.nim b/src/regex/nfamatch.nim
index db779c0..54b6f2c 100644
--- a/src/regex/nfamatch.nim
+++ b/src/regex/nfamatch.nim
@@ -8,51 +8,91 @@
 import std/unicode
 import std/tables
 
+import ./common
 import ./nodematch
-import ./nodetype
+import ./types
 import ./nfatype
 
-template findMatchBailOut: untyped {.dirty.} =
-  if nfa[n].kind == reEoe:
-    if not smB.hasState n:
-      smB.add (n, capt, bounds)
-    # first Eoe in SmA wins, it's pointless to
-    # keep matching further than the last Eoe
-    break
+type
+  AheadSig = proc (
+    smA, smB: var Submatches,
+    capts: var Capts,
+    captIdx: var int32,
+    text: string,
+    nfa: Nfa,
+    look: var Lookaround,
+    start: int,
+    flags: set[MatchFlag]
+  ): bool {.noSideEffect, raises: [].}
+  BehindSig = proc (
+    smA, smB: var Submatches,
+    capts: var Capts,
+    captIdx: var int32,
+    text: string,
+    nfa: Nfa,
+    look: var Lookaround,
+    start, limit: int,
+    flags: set[MatchFlag]
+  ): int {.noSideEffect, raises: [].}
+  Lookaround* = object
+    ahead*: AheadSig
+    behind*: BehindSig
+    smL*: SmLookaround
 
-template notEoe: untyped {.dirty.} =
-  when mfFindMatch in flags:
-    nfa[nt].kind != reEoe
+template lookAroundTpl*: untyped {.dirty.} =
+  template smL: untyped = look.smL
+  template smLa: untyped = smL.lastA
+  template smLb: untyped = smL.lastB
+  template zNfa: untyped = z.subExp.nfa
+  let flags2 = if z.subExp.reverseCapts:
+    {mfAnchored, mfReverseCapts}
   else:
-    true
+    {mfAnchored}
+  smL.grow()
+  smL.last.setLen zNfa.s.len
+  matched = case z.kind
+  of reLookahead:
+    look.ahead(
+      smLa, smLb, capts, captx,
+      text, zNfa, look, i, flags2)
+  of reNotLookahead:
+    not look.ahead(
+      smLa, smLb, capts, captx,
+      text, zNfa, look, i, flags2)
+  of reLookbehind:
+    look.behind(
+      smLa, smLb, capts, captx,
+      text, zNfa, look, i, 0, flags2) != -1
+  of reNotLookbehind:
+    look.behind(
+      smLa, smLb, capts, captx,
+      text, zNfa, look, i, 0, flags2) == -1
+  else:
+    doAssert false
+    false
+  smL.removeLast()
 
-func submatch(
-  smA, smB: var Submatches,
-  capts: var Capts,
-  regex: Regex,
-  i: int,
-  cPrev, c, c2: int32,
-  flags: static MatchFlags,
-) {.inline.} =
-  template t: untyped = regex.transitions
-  template nfa: untyped = regex.nfa
+template nextStateTpl(bwMatch = false): untyped {.dirty.} =
+  template bounds2: untyped =
+    when bwMatch: i .. bounds.b else: bounds.a .. i-1
   smB.clear()
-  var captx: int32
-  var matched = true
-  for n, capt, bounds in smA.items:
-    when mfFindMatch in flags:
-      findMatchBailOut()
-    for nti, nt in nfa[n].next.pairs:
+  for n, capt, bounds in items smA:
+    if anchored and nfa.s[n].kind == reEoe:
+      if not smB.hasState n:
+        smB.add (n, capt, bounds)
+      break
+    for nti, nt in pairs nfa.s[n].next:
       if smB.hasState nt:
         continue
-      if notEoe() and not match(nfa[nt], c2.Rune):
-        continue
-      if t.allZ[n][nti] == -1'i16:
-        smB.add (nt, capt, bounds.a .. i-1)
+      if not match(nfa.s[nt], c):
+        if not (anchored and nfa.s[nt].kind == reEoe):
+          continue
+      if nfa.t.allZ[n][nti] == -1'i16:
+        smB.add (nt, capt, bounds2)
         continue
       matched = true
       captx = capt
-      for z in t.z[t.allZ[n][nti]]:
+      for z in nfa.t.z[nfa.t.allZ[n][nti]]:
         if not matched:
           break
         case z.kind
@@ -62,83 +102,154 @@ func submatch(
             bound: i,
             idx: z.idx)
           captx = (capts.len-1).int32
-        of assertionKind:
-          matched = match(z, cPrev.Rune, c.Rune)
+        of assertionKind - lookaroundKind:
+          when bwMatch:
+            matched = match(z, c, cPrev.Rune)
+          else:
+            matched = match(z, cPrev.Rune, c)
+        of lookaroundKind:
+          lookAroundTpl()
         else:
-          assert false
+          doAssert false
           discard
       if matched:
-        smB.add (nt, captx, bounds.a .. i-1)
+        smB.add (nt, captx, bounds2)
   swap smA, smB
 
-template shortestMatch: untyped {.dirty.} =
-  submatch(smA, smB, capts, regex, iPrev, cPrev, c.int32, -1'i32, flags)
+func matchImpl(
+  smA, smB: var Submatches,
+  capts: var Capts,
+  captIdx: var int32,
+  text: string,
+  nfa: Nfa,
+  look: var Lookaround,
+  start = 0,
+  flags: set[MatchFlag] = {}
+): bool =
+  var
+    c = Rune(-1)
+    cPrev = -1'i32
+    i = start
+    iNext = start
+    captx = -1'i32
+    matched = false
+    anchored = mfAnchored in flags
+  if start-1 in 0 .. text.len-1:
+    cPrev = bwRuneAt(text, start-1).int32
+  smA.clear()
+  smA.add (0'i16, captIdx, i .. i-1)
+  while i < text.len:
+    fastRuneAt(text, iNext, c, true)
+    nextStateTpl()
+    if smA.len == 0:
+      return false
+    if anchored and nfa.s[smA[0].ni].kind == reEoe:
+      break
+    i = iNext
+    cPrev = c.int32
+  c = Rune(-1)
+  nextStateTpl()
   if smA.len > 0:
-    return true
-  swap smA, smB
+    if mfReverseCapts in flags:
+      captIdx = reverse(capts, smA[0].ci, captIdx)
+    else:
+      captIdx = smA[0].ci
+  return smA.len > 0
 
-template findMatch: untyped {.dirty.} =
-  when mfFindMatchOpt in flags:
+func reversedMatchImpl(
+  smA, smB: var Submatches,
+  capts: var Capts,
+  captIdx: var int32,
+  text: string,
+  nfa: Nfa,
+  look: var Lookaround,
+  start: int,
+  limit = 0,
+  flags: set[MatchFlag] = {}
+): int =
+  #doAssert start < len(text)
+  doAssert start >= limit
+  var
+    c = Rune(-1)
+    cPrev = -1'i32
+    i = start
+    iNext = start
+    captx: int32
+    matched = false
+    anchored = true
+  if start in 0 .. text.len-1:
+    cPrev = text.runeAt(start).int32
+  smA.clear()
+  smA.add (0'i16, captIdx, i .. i-1)
+  while iNext > limit:
+    bwFastRuneAt(text, iNext, c)
+    nextStateTpl(bwMatch = true)
     if smA.len == 0:
-      # XXX needed on exit too
-      m.boundaries = i .. i-1
-      return false
-  smA.add((0'i16, -1'i32, i .. i-1))
-  if regex.nfa[smA[0][0]].kind == reEoe:
-    constructSubmatches(m.captures, capts, smA[0][1], regex.groupsCount)
-    if regex.namedGroups.len > 0:
-      m.namedGroups = regex.namedGroups
-    m.boundaries = smA[0].bounds
-    return true
+      return -1
+    if nfa.s[smA[0].ni].kind == reEoe:
+      break
+    i = iNext
+    cPrev = c.int32
+  c = Rune(-1)
+  if iNext > 0:
+    bwFastRuneAt(text, iNext, c)
+  nextStateTpl(bwMatch = true)
+  for n, capt, bounds in items smA:
+    if nfa.s[n].kind == reEoe:
+      if mfReverseCapts in flags:
+        captIdx = reverse(capts, capt, captIdx)
+      else:
+        captIdx = capt
+      return bounds.a
+  return -1
 
-func bwRuneAt(s: string, n: int): Rune =
-  ## Take rune ending at ``n``
-  doAssert n >= 0
-  doAssert n <= s.len-1
-  var n = n
-  while n > 0 and s[n].ord shr 6 == 0b10:
-    dec n
-  fastRuneAt(s, n, result, false)
+func reversedMatchImpl*(
+  smA, smB: var Submatches,
+  text: string,
+  nfa: Nfa,
+  look: var Lookaround,
+  start, limit: int
+): int =
+  var capts: Capts
+  var captIdx = -1'i32
+  reversedMatchImpl(
+    smA, smB, capts, captIdx, text, nfa, look, start, limit)
+
+template initLook*: Lookaround =
+  Lookaround(
+    ahead: matchImpl,
+    behind: reversedMatchImpl)
 
 func matchImpl*(
   text: string,
   regex: Regex,
   m: var RegexMatch,
-  flags: static MatchFlags,
   start = 0
-): bool {.inline.} =
+): bool =
   m.clear()
   var
-    smA, smB: Submatches
+    smA = newSubmatches(regex.nfa.s.len)
+    smB = newSubmatches(regex.nfa.s.len)
     capts: Capts
-    c = Rune(-1)
-    cPrev = -1'i32
-    i = start
-    iPrev = start
-  smA = newSubmatches(regex.nfa.len)
-  smB = newSubmatches(regex.nfa.len)
-  smA.add (0'i16, -1'i32, start .. start-1)
-  when mfFindMatch in flags:
-    if 0 <= start-1 and start-1 <= len(text)-1:
-      cPrev = bwRuneAt(text, start-1).int32
-  while i < len(text):
-    fastRuneAt(text, i, c, true)
-    when mfShortestMatch in flags:
-      shortestMatch()
-    submatch(smA, smB, capts, regex, iPrev, cPrev, c.int32, c.int32, flags)
-    when mfFindMatch in flags:
-      findMatch()
-    if smA.len == 0:
-      return false
-    iPrev = i
-    cPrev = c.int32
-  submatch(smA, smB, capts, regex, iPrev, cPrev, -1'i32, -1'i32, flags)
-  if smA.len == 0:
-    when mfFindMatchOpt in flags:
-      m.boundaries = i .. i-1
-    return false
-  constructSubmatches(m.captures, capts, smA[0].ci, regex.groupsCount)
-  if regex.namedGroups.len > 0:
-    m.namedGroups = regex.namedGroups
-  m.boundaries = smA[0].bounds
-  return true
+    capt = -1'i32
+    look = initLook()
+  result = matchImpl(
+    smA, smB, capts, capt, text, regex.nfa, look, start)
+  if result:
+    constructSubmatches(
+      m.captures, capts, capt, regex.groupsCount)
+    if regex.namedGroups.len > 0:
+      m.namedGroups = regex.namedGroups
+    m.boundaries = smA[0].bounds
+
+func startsWithImpl*(text: string, regex: Regex, start: int): bool =
+  # XXX optimize mfShortestMatch, mfNoCaptures
+  template flags: untyped = {mfAnchored, mfShortestMatch, mfNoCaptures}
+  var
+    smA = newSubmatches(regex.nfa.s.len)
+    smB = newSubmatches(regex.nfa.s.len)
+    capts: Capts
+    capt = -1'i32
+    look = initLook()
+  result = matchImpl(
+    smA, smB, capts, capt, text, regex.nfa, look, start, flags)
diff --git a/src/regex/nfatype.nim b/src/regex/nfatype.nim
index f9f52d5..2d9cb26 100644
--- a/src/regex/nfatype.nim
+++ b/src/regex/nfatype.nim
@@ -4,7 +4,7 @@ import std/tables
 import std/sets
 import std/algorithm
 
-import ./nfa
+import ./types
 import ./litopt
 
 type
@@ -41,13 +41,24 @@ func constructSubmatches*(
   for c in captures.mitems:
     c.reverse()
 
+func reverse*(capts: var Capts, a, b: int32): int32 =
+  ## reverse capture indices from a to b; return head
+  doAssert a >= b
+  var capt = a
+  var parent = b
+  while capt != b:
+    let p = capts[capt].parent
+    capts[capt].parent = parent
+    parent = capt
+    capt = p
+  return parent
+
 type
   RegexLit* = distinct string
     ## raw regex literal string
   Regex* = object
     ## a compiled regular expression
     nfa*: Nfa
-    transitions*: Transitions
     groupsCount*: int16
     namedGroups*: OrderedTable[string, int16]
     #flags*: set[RegexFlag]
@@ -57,6 +68,9 @@ type
     mfNoCaptures
     mfFindMatch
     mfFindMatchOpt
+    mfAnchored
+    mfBwMatch
+    mfReverseCapts
   MatchFlags* = set[MatchFlag]
   RegexMatch* = object
     ## result from matching operations
@@ -128,5 +142,46 @@ iterator items*(sm: Submatches): PState {.inline.} =
 func cap*(sm: Submatches): int {.inline.} =
   sm.ss.len
 
+func setLen*(sm: var Submatches, size: int) {.inline.} =
+  sm.ss.setLen size
+
 when defined(release):
   {.pop.}
+
+# XXX maybe store the lookaround number + count, and use a fixed
+#     size seq to reduce allocations
+type
+  SmLookaroundItem* = object
+    a, b: Submatches
+  SmLookaround* = object
+    s: seq[SmLookaroundItem]
+    i: int
+
+func setLen*(item: var SmLookaroundItem, size: int) {.inline.} =
+  if item.a == nil:
+    doAssert item.b == nil
+    item.a = newSubmatches size
+    item.b = newSubmatches size
+  else:
+    doAssert item.b != nil
+    item.a.setLen size
+    item.b.setLen size
+
+template last*(sm: var SmLookaround): untyped =
+  sm.s[sm.i-1]
+
+template lastA*(sm: var SmLookaround): untyped =
+  last(sm).a
+
+template lastB*(sm: var SmLookaround): untyped =
+  last(sm).b
+
+func grow*(sm: var SmLookaround) {.inline.} =
+  doAssert sm.i <= sm.s.len
+  if sm.i == sm.s.len:
+    sm.s.setLen(max(1, sm.s.len) * 2)
+  sm.i += 1
+
+func removeLast*(sm: var SmLookaround) {.inline.} =
+  doAssert sm.i > 0
+  sm.i -= 1
diff --git a/src/regex/nodematch.nim b/src/regex/nodematch.nim
index 94baac0..2bda7d8 100644
--- a/src/regex/nodematch.nim
+++ b/src/regex/nodematch.nim
@@ -2,15 +2,17 @@ import std/unicode
 import std/sets
 
 import pkg/unicodedb/properties
-import pkg/unicodedb/types
-import pkg/unicodeplus
+import pkg/unicodedb/types as utypes
 
-import ./nodetype
+import ./types
 import ./common
 
-func isWord*(r: Rune): bool {.inline.} =
+func isWord(r: Rune): bool {.inline.} =
   utmWord in unicodeTypes(r)
 
+func isDecimal(r: Rune): bool {.inline.} =
+  utmDecimal in unicodeTypes(r)
+
 func isWordAscii(r: Rune): bool {.inline.} =
   ## return ``true`` if the given
   ## rune is in ``[A-Za-z0-9]`` range
@@ -60,14 +62,6 @@ func match*(n: Node, r: Rune, nxt: Rune): bool {.inline.} =
     isWordBoundaryAscii(r, nxt)
   of reNotWordBoundaryAscii:
     not isWordBoundaryAscii(r, nxt)
-  of reLookahead:
-    n.cp == nxt
-  of reNotLookahead:
-    n.cp != nxt
-  of reLookbehind:
-    n.cp == r
-  of reNotLookbehind:
-    n.cp != r
   else:
     assert false
     false
diff --git a/src/regex/parser.nim b/src/regex/parser.nim
index b1d0d95..9975b5f 100644
--- a/src/regex/parser.nim
+++ b/src/regex/parser.nim
@@ -5,7 +5,8 @@ import std/parseutils
 
 import pkg/unicodedb/properties
 
-import ./nodetype
+import ./exptype
+import ./types
 import ./common
 import ./scanner
 
@@ -427,31 +428,52 @@ func parseSet(sc: Scanner[Rune]): Node =
     hasEnd,
     "Invalid set. Missing `]`")
 
+func noRepeatCheck(sc: Scanner[Rune]) =
+  ## Check next symbol is not a repetition
+  let startPos = sc.pos
+  let hasDoubleQ = sc.peek == '?'.Rune and sc.peek(1) == '?'.Rune
+  prettyCheck(
+    sc.peek notin ['*'.Rune, '+'.Rune] and not hasDoubleQ,
+    "Invalid repetition. There's nothing to repeat")
+
 func parseRepRange(sc: Scanner[Rune]): Node =
   ## parse a repetition range ``{n,m}``
+  # This is not PCRE compatible. PCRE allows
+  # {,} and {,1} to be parsed as chars instead of a
+  # repetition range, we raise an error instead.
+  # Range limit can be defined with the `reRepRangeLimit` param.
+  if sc.peek.int != ','.ord and
+      sc.peek.int notin '0'.ord .. '9'.ord:
+    return Node(kind: reChar, cp: '{'.Rune)
   let startPos = sc.pos
   var
     first, last: string
     hasFirst = false
     curr = ""
   for cp in sc:
-    if cp == "}".toRune:
+    if cp == '}'.Rune:
       last = curr
       break
-    if cp == ",".toRune:
+    if cp == ','.Rune:
       first = curr
       curr = ""
+      prettyCheck(
+        not hasFirst, "Invalid repetition range. Expected {n,m}")
       hasFirst = true
       continue
     prettyCheck(
       cp.int in '0'.ord .. '9'.ord,
       "Invalid repetition range. Range can only contain digits")
-    curr.add(char(cp.int))
+    curr.add char(cp.int)
+  prettyCheck(
+    sc.prev == '}'.Rune,
+    "Invalid repetition range. Missing closing symbol `}`")
   if not hasFirst:  # {n}
     first = curr
-  if first.len == 0:  # {,m} or {,}
-    first.add('0')
-  if last.len == 0:  # {n,} or {,}
+  prettyCheck(
+    first.len > 0,
+    "Invalid repetition range. Expected {n}, {n,m}, or {n,}")
+  if last.len == 0:  # {n,}
     last = "-1"
   var
     firstNum: int
@@ -473,15 +495,17 @@ func parseRepRange(sc: Scanner[Rune]): Node =
     "Invalid repetition range. Max value is $#" %% $int16.high)
   # for perf reasons. This becomes a?a?a?...
   # too many parallel states
+  const reRepRangeLimit {.intdefine.} = 100
   prettyCheck(
-    not (lastNum - firstNum > 100),
+    not (lastNum - firstNum > reRepRangeLimit),
     ("Invalid repetition range. " &
-     "Expected 100 repetitions or less, " &
-     "but found: $#") %% $(lastNum - firstNum))
+     "Expected $# repetitions or less, " &
+     "but found: $#") %% [$reRepRangeLimit, $(lastNum - firstNum)])
   result = Node(
     kind: reRepRange,
     min: firstNum.int16,
     max: lastNum.int16)
+  noRepeatCheck sc
 
 func toFlag(r: Rune): Flag =
   result = case r
@@ -523,11 +547,6 @@ func toNegFlag(r: Rune): Flag =
       ("Invalid group flag, found -$# " &
        "but expected one of: -i, -m, -s, -U or -u") %% $r)
 
-template checkEmptyGroup() {.dirty.} =
-  prettyCheck(
-    peek(sc) != toRune(")"),
-    "Invalid group. Empty group is not allowed")
-
 func parseGroupTag(sc: Scanner[Rune]): Node =
   ## parse a special group (name, flags, non-captures).
   ## Return a regular ``reGroupStart``
@@ -535,14 +554,12 @@ func parseGroupTag(sc: Scanner[Rune]): Node =
   # A regular group
   let startPos = sc.pos
   if sc.peek != "?".toRune:
-    checkEmptyGroup()
     result = initGroupStart()
     return
   discard sc.next()  # Consume "?"
   case sc.peek
   of ":".toRune:
     discard sc.next()
-    checkEmptyGroup()
     result = initGroupStart(isCapturing = false)
   of "P".toRune:
     discard sc.next()
@@ -570,7 +587,6 @@ func parseGroupTag(sc: Scanner[Rune]): Node =
     prettyCheck(
       sc.prev == ">".toRune,
       "Invalid group name. Missing `>`")
-    checkEmptyGroup()
     result = initGroupStart(name)
   of "i".toRune,
       "m".toRune,
@@ -583,36 +599,36 @@ func parseGroupTag(sc: Scanner[Rune]): Node =
       flags: seq[Flag] = @[]
       isNegated = false
     for cp in sc:
-      if cp == ":".toRune:
-        checkEmptyGroup()
+      if cp == ":".toRune or cp == ")".toRune:
         break
       if cp == "-".toRune:
         isNegated = true
         continue
       if isNegated:
-        flags.add(toNegFlag(cp))
+        flags.add toNegFlag(cp)
       else:
-        flags.add(toFlag(cp))
-      if sc.peek == ")".toRune:
-        break
-    result = initGroupStart(
-      flags = flags,
-      isCapturing = false)
+        flags.add toFlag(cp)
+    result = if sc.prev == ")".toRune:
+      Node(kind: reFlags, flags: flags)
+    else:
+      initGroupStart(
+        flags = flags,
+        isCapturing = false)
   #reLookahead,
   #reLookbehind,
-  of "=".toRune, "<".toRune, "!".toRune:
+  of '='.Rune, '<'.Rune, '!'.Rune:
     var lookAroundKind: NodeKind
     case sc.peek
-    of "=".toRune:
+    of '='.Rune:
       lookAroundKind = reLookahead
-    of "!".toRune:
+    of '!'.Rune:
       lookAroundKind = reNotLookahead
-    of "<".toRune:
+    of '<'.Rune:
       discard sc.next()
       case sc.peek:
-      of "=".toRune:
+      of '='.Rune:
         lookAroundKind = reLookbehind
-      of "!".toRune:
+      of '!'.Rune:
         lookAroundKind = reNotLookbehind
       else:
         prettyCheck(
@@ -620,30 +636,12 @@ func parseGroupTag(sc: Scanner[Rune]): Node =
           "Invalid lookabehind, expected `<=` or `<!` symbol")
     else:
       doAssert false
-    doAssert sc.peek in ["=".toRune, "!".toRune]
+    doAssert sc.peek in ['='.Rune, '!'.Rune]
     discard sc.next
-    # todo: support sets and more
-    case sc.peek
-    of "\\".toRune:
-      let n = parseEscapedSeq(sc)
-      prettyCheck(
-        n.kind == reChar,
-        "Invalid lookaround. A " &
-        "character was expected, but " &
-        "found a special symbol")
-      result = Node(kind: lookAroundKind, cp: n.cp)
-    else:
-      prettyCheck(
-        not sc.finished,
-        "Invalid lookaround. A character " &
-        "was expected, but found nothing (end of string)")
-      result = Node(kind: lookAroundKind, cp: sc.next())
     prettyCheck(
-      sc.peek == ")".toRune,
-      "Invalid lookaround, expected closing symbol. " &
-      "Beware lookaround is currently limited to " &
-      "match one single character")
-    discard sc.next()
+      sc.peek != ')'.Rune,
+      "Empty lookaround is not allowed")
+    result = Node(kind: lookAroundKind)
   else:
     prettyCheck(
       false,
@@ -663,10 +661,13 @@ func subParse(sc: Scanner[Rune]): Node =
   of "|".toRune:
     Node(kind: reOr, cp: r)
   of "*".toRune:
+    noRepeatCheck sc
     Node(kind: reZeroOrMore, cp: r)
   of "+".toRune:
+    noRepeatCheck sc
     Node(kind: reOneOrMore, cp: r)
   of "?".toRune:
+    noRepeatCheck sc
     Node(kind: reZeroOrOne, cp: r)
   of ")".toRune:
     Node(kind: reGroupEnd, cp: r)
@@ -709,37 +710,45 @@ func verbosity(
   case n.kind:
   of reGroupStart:
     if vb.len > 0:
-      vb.add(vb[vb.high])
+      vb.add vb[vb.len-1]
     else:
-      vb.add(false)
+      vb.add false
     for f in n.flags:
       case f:
       of flagVerbose:
-        vb[vb.high] = true
+        vb[vb.len-1] = true
       of flagNotVerbose:
-        vb[vb.high] = false
+        vb[vb.len-1] = false
       else:
         discard
-    if sc.peek == ")".toRune:  # (?flags)
-      if vb.len > 1:  # set outter group
-        vb[vb.high - 1] = vb[vb.high]
-      else:
-        vb.add(vb[vb.high])
   of reGroupEnd:
     if vb.len > 0:
       discard vb.pop()
     # else: unbalanced parentheses,
     # it'll raise later
+  of reFlags:
+    if vb.len == 0:
+      vb.add false
+    # else set outter group
+    for f in n.flags:
+      case f:
+      of flagVerbose:
+        vb[vb.len-1] = true
+      of flagNotVerbose:
+        vb[vb.len-1] = false
+      else:
+        discard
   else:
     discard
 
-func parse*(expression: string): seq[Node] =
+func parse*(expression: string): Exp =
   ## convert a ``string`` regex expression
   ## into a ``Node`` expression
-  result = newSeqOfCap[Node](expression.len)
+  result.s = newSeq[Node](expression.len)
+  result.s.setLen 0
   var vb = newSeq[bool]()
   let sc = expression.scan()
   for _ in sc:
     if sc.skipWhiteSpace(vb): continue
-    result.add(sc.subParse())
-    vb.verbosity(sc, result[^1])
+    result.s.add sc.subParse()
+    vb.verbosity(sc, result.s[^1])
diff --git a/src/regex/scanner.nim b/src/regex/scanner.nim
index 1bd7d82..c33183b 100644
--- a/src/regex/scanner.nim
+++ b/src/regex/scanner.nim
@@ -1,6 +1,6 @@
 import std/unicode
 
-import ./nodetype
+import ./types
 import ./common
 
 type
@@ -68,6 +68,12 @@ iterator peek*[T](sc: Scanner[T]): (T, T) =
   for s in sc:
     yield (s, sc.peek)
 
+func peek*(sc: Scanner[Rune], n: int): Rune =
+  if sc.pos+n > sc.s.len-1:
+    invalidRune
+  else:
+    sc.s[sc.pos+n]
+
 func find*(sc: Scanner[Rune], r: Rune): int =
   ## return number of consumed chars.
   ## The scanner's position is not moved.
diff --git a/src/regex/nodetype.nim b/src/regex/types.nim
similarity index 69%
rename from src/regex/nodetype.nim
rename to src/regex/types.nim
index 0c0448d..569a1dd 100644
--- a/src/regex/nodetype.nim
+++ b/src/regex/types.nim
@@ -5,12 +5,39 @@ when NimMajor >= 1:
 import std/unicode
 import std/sets
 from std/algorithm import sorted
+from std/sequtils import toSeq
 
 import pkg/unicodedb/properties
 
 import ./common
 
+# XXX split nfatype.nim and nodetype.nim
+#     once acyclic imports are supported
+# XXX refactor transitions, add tIdx: int16
+#     to Node, make TransitionsAll dense;
+#     remove z and store transition Nodes in
+#     the NFA; flatten TransitionsAll to seq[int16]
+#     + delimiter (-1'i16) or set first bit of
+#     every last tn idx
+
 type
+  # exptype.nim
+  RpnExp* = object
+    s*: seq[Node]
+
+  # nfatype.nim
+  Enfa* = object
+    s*: seq[Node]
+  TransitionsAll* = seq[seq[int16]]
+  ZclosureStates* = seq[seq[Node]]
+  Transitions* = object
+    allZ*: TransitionsAll
+    z*: ZclosureStates
+  Nfa* = object
+    s*: seq[Node]
+    t*: Transitions
+
+  # nodetype.nim
   Flag* = enum
     flagCaseInsensitive,  # i
     flagNotCaseInsensitive,  # -i
@@ -30,6 +57,7 @@ type
     reJoiner,  # ~
     reGroupStart,  # (
     reGroupEnd,  # )
+    reFlags,  # (?flags)
     reOr,  # |
     reZeroOrMore,  # *
     reOneOrMore,  # +
@@ -91,6 +119,13 @@ type
     shorthands*: seq[Node]
     # reUCC, reNotUCC
     cc*: UnicodeCategorySet
+    # reLookahead, reLookbehind,
+    # reNotLookahead, reNotLookbehind
+    subExp*: SubExp
+  SubExp* = object
+    nfa*: Nfa
+    rpn*: RpnExp
+    reverseCapts*: bool
 
 func toCharNode*(r: Rune): Node =
   ## return a ``Node`` that is meant to be matched
@@ -142,13 +177,17 @@ func initGroupStart*(
     flags: flags,
     isCapturing: isCapturing)
 
+func initSkipNode*(): Node =
+  result = Node(
+    kind: reSkip,
+    cp: "#".toRune)
+
 func initSkipNode*(next: openArray[int16]): Node =
   ## Return a dummy node that should be skipped
   ## while traversing the NFA
   result = Node(
     kind: reSkip,
-    cp: "#".toRune)
-  result.next.add next
+    cp: "#".toRune, next: toSeq(next))
 
 func isEmpty*(n: Node): bool =
   ## check if a set ``Node`` is empty
@@ -181,6 +220,17 @@ const
     reLookbehind,
     reNotLookahead,
     reNotLookbehind}
+  lookaroundKind* = {
+    reLookahead,
+    reLookbehind,
+    reNotLookahead,
+    reNotLookbehind}
+  lookaheadKind* = {
+    reLookahead,
+    reNotLookahead}
+  lookbehindKind* = {
+    reLookbehind,
+    reNotLookbehind}
   shorthandKind* = {
     reWord,
     reDigit,
@@ -226,39 +276,44 @@ const
   groupKind* = {
     reGroupStart,
     reGroupEnd}
+  groupStartKind* = {reGroupStart} + lookaroundKind
 
-func toString*(n: Node): string =
+func `$`*(n: Node): string =
   ## return the string representation
   ## of a `Node`. The string is always
   ## equivalent to the original
   ## expression but not necessarily equal
-  # Note this is not complete. Just
-  # what's needed for debugging so far
   case n.kind
-  of reZeroOrMore,
-      reOneOrMore,
-      reZeroOrOne:
-    if not n.isGreedy:
-      n.cp.toUTF8 & "?"
-    else:
-      n.cp.toUTF8
-  of reRepRange:
-    "#"  # Invalid
-  of reStart:
-    "\\A"
-  of reEnd:
-    "\\z"
-  of reWordBoundary:
-    "\\b"
-  of reNotWordBoundary:
-    "\\B"
-  of shorthandKind:
-    '\\' & n.cp.toUTF8
+  of reChar, reCharCi: $n.cp
+  of reJoiner: "~"
+  of reGroupStart: "("
+  of reGroupEnd: ")"
+  of reFlags: "(?flags)"
+  of reOr: "|"
+  of reZeroOrMore: "*" & (if n.isGreedy: "" else: "?")
+  of reOneOrMore: "+" & (if n.isGreedy: "" else: "?")
+  of reZeroOrOne: "?" & (if n.isGreedy: "" else: "?")
+  of reRepRange: "{" & $n.min & "," & $n.max & "}"
+  of reStartSym, reStartSymML: "^"
+  of reEndSym, reEndSymML: "$"
+  of reStart: r"\A"
+  of reEnd: r"\z"
+  of reWordBoundary, reWordBoundaryAscii: r"\b"
+  of reNotWordBoundary, reNotWordBoundaryAscii: r"\B"
+  of reWord, reWordAscii: r"\w"
+  of reDigit, reDigitAscii: r"\d"
+  of reWhiteSpace, reWhiteSpaceAscii: r"\s"
+  of reUCC: r"\pN"
+  of reNotAlphaNum, reNotAlphaNumAscii: r"\W"
+  of reNotDigit, reNotDigitAscii: r"\D"
+  of reNotWhiteSpace, reNotWhiteSpaceAscii: r"\S"
+  of reNotUCC: r"\PN"
+  of reAny, reAnyNl, reAnyAscii, reAnyNlAscii: "."
   of reInSet, reNotSet:
     var str = ""
-    str.add('[')
+    str.add '['
     if n.kind == reNotSet:
-      str.add('^')
+      str.add '^'
     var
       cps = newSeq[Rune](n.cps.len)
       i = 0
@@ -266,21 +321,21 @@ func toString*(n: Node): string =
       cps[i] = cp
       inc i
     for cp in cps.sorted(cmp):
-      str.add(cp.toUTF8)
+      str.add $cp
     for sl in n.ranges:
-      str.add(sl.a.toUTF8 & '-' & sl.b.toUTF8)
+      str.add($sl.a & '-' & $sl.b)
     for nn in n.shorthands:
-      str.add(nn.toString)
-    str.add(']')
+      str.add $nn
+    str.add ']'
     str
-  of reSkip:
-    "SKIP"
-  of reEOE:
-    "EOE"
-  else:
-    n.cp.toUTF8
+  of reLookahead: "(?=...)"
+  of reLookbehind: "(?<=...)"
+  of reNotLookahead: "(?!...)"
+  of reNotLookbehind: "(?<!...)"
+  of reSkip: r"{skip}"
+  of reEoe: r"{eoe}"
 
 func toString*(n: seq[Node]): string =
   result = newStringOfCap(n.len)
   for nn in n:
-    result.add(nn.toString)
+    result.add $nn
diff --git a/tests/tests.nim b/tests/tests.nim
index 63720ca..15ee3f1 100644
--- a/tests/tests.nim
+++ b/tests/tests.nim
@@ -16,8 +16,8 @@ template test(desc: string, body: untyped): untyped =
         echo "[CT/RT] " & desc
       body)()
 
-template check(conditions: bool) =
-  doAssert(conditions)
+template check(condition: bool) =
+  doAssert(condition)
 
 template expect(exception: typedesc, body: untyped): untyped =
   doAssertRaises(exception):
@@ -74,21 +74,20 @@ func findAllCapt(s: string, reg: Regex): seq[seq[seq[Slice[int]]]] =
 
 when (NimMajor, NimMinor) >= (1, 1):
   template matchMacro(s, r: untyped): untyped =
-    block:
-      var m = false
-      match s, r:
-        m = true
-      m
+    (func (): bool =
+      result = false
+      let exp = s
+      match exp, r:
+        result = true)()
 
   template matchMacroCapt(s, r: untyped): untyped =
-    block:
+    (func (): seq[string] =
       var m = false
-      var c: seq[string]
-      match s, r:
+      let exp = s
+      match exp, r:
         m = true
-        c = matches
-      check m
-      c
+        result = matches
+      check m)()
 
   test "tmatch_macro":
     block hasOwnScope:
@@ -141,6 +140,19 @@ when (NimMajor, NimMinor) >= (1, 1):
       match txt, rex"(\w)+":
         m = true
       check m
+    block:
+      (func () = 
+        var m = false
+        var txt = "abc"
+        match txt, rex"(\w)+":
+          m = true
+        check m)()
+    block:
+      var m = false
+      match "abcdefg", rex"\w+(?<=(ab)(?=(cd)))\w+":
+        check matches == @["ab", "cd"]
+        m = true
+      check m
   
   test "tmatch_macro_captures":
     check matchMacroCapt("ab", rex"(a)b") == @["a"]
@@ -180,6 +192,24 @@ when (NimMajor, NimMinor) >= (1, 1):
     check matchMacroCapt("aaaa", rex"(a*)(a*)") == @["aaaa", ""]
     check matchMacroCapt("aaaa", rex"(a*?)(a*?)") == @["", "aaaa"]
     check matchMacroCapt("aaaa", rex"(a)*(a)") == @["a", "a"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab))\w+") == @["ab"]
+    check matchMacroCapt("abcdefg", rex"\w+(?=(cd))\w+") == @["cd"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab))\w+(?<=(fg))") ==
+      @["ab", "fg"]
+    check matchMacroCapt("abcdefg", rex"\w+(?=(cd))\w+(?=(ef))\w+") ==
+      @["cd", "ef"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab))\w+(?=(ef))\w+") ==
+      @["ab", "ef"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)cd(?<=(cd)))\w+") ==
+      @["ab", "cd"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)(?<=(ab)))\w+") ==
+      @["ab", "ab"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)(?=(cd)))\w+") ==
+      @["ab", "cd"]
+    check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)(?=(cd)(?<=(cd))))\w+") ==
+      @["ab", "cd", "cd"]
+    check matchMacroCapt("abcdefg", rex"\w+(?=(cd)(?<=(cd)))\w+") ==
+      @["cd", "cd"]
 
   test "tmatch_macro_misc":
     check matchMacro("abc", rex"\w+")
@@ -198,16 +228,12 @@ when (NimMajor, NimMinor) >= (1, 1):
     check(not matchMacro("a", rex"b"))
     check(not matchMacro("a", rex""))
     check matchMacro(" \"word\" ", rex"\s"".*""\s")
-    check matchMacro("aaa", rex"a**")
     check matchMacro("aaa", rex"(a*)*")
     check matchMacro("aaabbbaaa", rex"((a*|b*))*")
-    check matchMacro("aaa", rex"a*****")
     check matchMacro("aaa", rex"(a?)*")
     check matchMacro("aaaa", rex"((a)*(a)*)*")
-    check matchMacro("aaa", rex"a**")
     check matchMacro("aaa", rex"(a*)*")
     check matchMacro("aaabbbaaa", rex"((a*|b*))*")
-    check matchMacro("aaa", rex"a*****")
     check matchMacro("aaa", rex"(a?)*")
     check matchMacro("aaaa", rex"((a)*(a)*)*")
     check matchMacro("<TAG>two</TAG>", rex"<TAG>.*?</TAG>")
@@ -245,13 +271,13 @@ when (NimMajor, NimMinor) >= (1, 1):
     check matchMacro("650-253-0001", rex"[0-9]+..*")
     check(not matchMacro("abc-253-0001", rex"[0-9]+..*"))
     check(not matchMacro("6", rex"[0-9]+..*"))
-    check matchMacro("", rex"(11)*+(111)*")
-    check matchMacro("11", rex"(11)*+(111)*")
-    check matchMacro("111", rex"(11)*+(111)*")
-    check matchMacro("11111", rex"(11)*+(111)*")
-    check matchMacro("1111111", rex"(11)*+(111)*")
-    check matchMacro("1111111111", rex"(11)*+(111)*")
-    check(not matchMacro("1", rex"(11)*+(111)*"))
+    check matchMacro("", rex"((11)*)+(111)*")
+    check matchMacro("11", rex"((11)*)+(111)*")
+    check matchMacro("111", rex"((11)*)+(111)*")
+    check matchMacro("11111", rex"((11)*)+(111)*")
+    check matchMacro("1111111", rex"((11)*)+(111)*")
+    check matchMacro("1111111111", rex"((11)*)+(111)*")
+    check(not matchMacro("1", rex"((11)*)+(111)*"))
     check(not matchMacro("", rex"(11)+(111)*"))
     check matchMacro("11", rex"(11)+(111)*")
     check(not matchMacro("111", rex"(11)+(111)*"))
@@ -275,6 +301,198 @@ when (NimMajor, NimMinor) >= (1, 1):
     check matchMacro("111111", rex"(11)*|(111)*")
     check(not matchMacro("1", rex"(11)*|(111)*"))
 
+  test "tmacro_full_lookarounds":
+    check matchMacro("ab", rex"a(?=b)\w")
+    check(not matchMacro("ab", rex"a(?=x)\w"))
+    check(not matchMacro("ab", rex"ab(?=x)"))
+    check matchMacro("ab", rex"ab(?=$)")
+    check matchMacro("abc", rex"a(?=b)\w+")
+    check matchMacroCapt("abcdefg", rex"a(?=(bc))\w+") ==
+      @["bc"]
+    check matchMacro("ab", rex"\w(?<=a)b")
+    check(not matchMacro("ab", rex"\w(?<=x)b"))
+    check(not matchMacro("ab", rex"(?<=x)ab"))
+    check matchMacro("ab", rex"(?<=^)ab")
+    check matchMacro("abc", rex"\w\w(?<=(b))c")
+    check matchMacroCapt("abc", rex"\w\w(?<=(b))c") ==
+      @["b"]
+    check matchMacro("abc", rex"\w\w(?<=(ab))c")
+    check matchMacroCapt("abc", rex"\w\w(?<=(ab))c") ==
+      @["ab"]
+    check matchMacro("a", rex"\w(?<=a)")
+    check(not matchMacro("a", rex"\w(?=a)"))
+    check matchMacro("ab", rex"\w(?<=a(?<=a))b")
+    check matchMacro("ab", rex"\w(?<=a(?<=a(?<=a)))b")
+    check matchMacro("ab", rex"\w(?<=a(?=b))b")
+    check(not matchMacro("ab", rex"\w(?=b(?=b))b"))
+    check(not matchMacro("ab", rex"\w(?<=a(?=b(?=b)))b"))
+    check matchMacro("ab", rex"\w(?<=a(?<=a)(?=b))b")
+    check matchMacro("ab", rex"\w(?<=a(?<=a(?=b)))b")
+    check(not matchMacro("ab", rex"\w(?<=(?<=a)a)b"))
+    check matchMacro("aab", rex"\w\w(?<=aa(?=b))b")
+    block:
+      check matchMacroCapt("aaab", rex"(\w*)(\w*?)") ==
+        @["aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*)(\w*?)$)") ==
+        @["aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*)(\w*)$)") ==
+        @["", "aaab"]
+      check matchMacroCapt("aaab", rex"(\w*?)(\w*)(\w*?)") ==
+        @["", "aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w*)(\w*?)$)") ==
+        @["", "aaab", ""]
+      check matchMacroCapt("aaab", rex"(\w*)(\w??)") ==
+        @["aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*)(\w??)$)") ==
+        @["aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*)(\w?)$)") ==
+        @["aaa", "b"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w?)(\w*?)$)") ==
+        @["aaa", "b", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w??)(\w*?)$)") ==
+        @["aaab", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w??)(\w*?)$)") ==
+        @["a", "aab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w?)(\w*?)$)") ==
+        @["a", "aab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w??)$)") ==
+        @["aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*)(\w??)$)") ==
+        @["aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w?)$)") ==
+        @["aaa", "b"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*)(\w?)$)") ==
+        @["aaa", "b"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w*?)(\w??)$)") ==
+        @["aaab", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*?)(\w*)(\w??)$)") ==
+        @["", "aaab", ""]
+    block:
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+|(\w)\w+$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\w)\w+$)") ==
+        @["", "a"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+|(\w)\w+|(\w)\w+$)") ==
+        @["a", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\w)\w+|(\w)\w+$)") ==
+        @["", "a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\d)\w+|(\w)\w+$)") ==
+        @["", "", "a"]
+    block:
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\w)\w+|(\w)\w+)+?$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\w)\w+)+?$)") ==
+        @["", "a"]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\w)\w+|(\w)\w+|(\w)\w+)+?$)") ==
+        @["a", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\w)\w+|(\w)\w+)+?$)") ==
+        @["", "a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\d)\w+|(\w)\w+)+?$)") ==
+        @["", "", "a"]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\w)\w+|(\w)\w+)*?$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\w)\w+)*?$)") ==
+        @["", "a"]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\w)\w+|(\w)\w+|(\w)\w+)*?$)") ==
+        @["a", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\w)\w+|(\w)\w+)*?$)") ==
+        @["", "a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\d)\w+|(\w)\w+)*?$)") ==
+        @["", "", "a"]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\w)\w+|(\w)\w+)??$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\w)\w+)??$)") ==
+        @["", "a"]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\w)\w+|(\w)\w+|(\w)\w+)??$)") ==
+        @["a", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\w)\w+|(\w)\w+)??$)") ==
+        @["", "a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(?:(\d)\w+|(\d)\w+|(\w)\w+)??$)") ==
+        @["", "", "a"]
+    block:
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+?|(\w)\w+?$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+|(\w)\w+$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+?|(\w)\w+$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+|(\w)\w+?$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w+|\w{4}|\w{4}|\w+)*$)") ==
+        @["aaab"]
+      check matchMacroCapt("aaab", rex"(\w*|\w{4}|\w{4}|\w*)*") ==
+        @[""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*|\w{4}|\w{4}|\w*)*$)") ==
+        @["aaab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w+|\w{4}|\w{4}|\w+)+$)") ==
+        @["aaab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w)\w+|\w{4}|\w{4}|(\w)\w+$)") ==
+        @["a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\w{4})|(\w{4})|(\w)\w+$)") ==
+        @["", "aaab", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\w)\w{3}|(\w)\w{3}|(\w)\w+$)") ==
+        @["", "a", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\d)\w{3}|(\w)\w{3}|(\w)\w+$)") ==
+        @["", "", "a", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\d)\w+|(\d)\w{3}|(\d)\w{3}|(\w)\w+$)") ==
+        @["", "", "", "a"]
+      check matchMacroCapt("aaab", rex"(\w*|\w{4}|\w{4}|\w*)+") ==
+        @[""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*|\w{4}|\w{4}|\w*)+$)") ==
+        @["aaab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w+)|(\w{4})|(\w{10})$)") ==
+        @["aaab", "", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w{10})|(\w{4})|(\w+)$)") ==
+        @["", "aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^((\w{10})|(\w{4})|(\w+))+$)") ==
+        @["aaab", "", "aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^((\w{10})|(\w{4})|(\w+))*$)") ==
+        @["aaab", "", "aaab", ""]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w+|\w{4}|\w{4}|\w+)*?$)") ==
+        @["aaab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w*|\w{4}|\w{4}|\w*)*?$)") ==
+        @["aaab"]
+      check matchMacroCapt("aaab", rex".*(?<=^(\w+|\w{4}|\w{4}|\w+)+?$)") ==
+        @["aaab"]
+    check(not matchMacro("ab", rex"\w(?<=a(?=b(?<=a)))b"))
+    check(not matchMacro("ab", rex"\w(?<=a(?<=a(?=b(?<=a))))b"))
+    check matchMacro("ab", rex"\w(?<=a(?=b(?<=b)))b")
+    check matchMacro("ab", rex"\w(?<=a(?<=a(?=b(?<=b))))b")
+    block:
+      template asterisk: untyped = rex".*(?<=(?<!\\)(?:\\\\)*)\*"
+      check matchMacro(r"*", asterisk)
+      check(not matchMacro(r"\*", asterisk))
+      check matchMacro(r"\\*", asterisk)
+      check(not matchMacro(r"\\\*", asterisk))
+      check matchMacro(r"\\\\*", asterisk)
+      check(not matchMacro(r"\\\\\*", asterisk))
+    block:
+      check matchMacro(r"弢b", rex"弢(?=b)\w")
+      check matchMacro(r"a弢", rex"a(?=弢)\w")
+      check matchMacro(r"Ⓐb", rex"Ⓐ(?=b)\w")
+      check matchMacro(r"aⒶ", rex"a(?=Ⓐ)\w")
+      check matchMacro(r"Ⓐb", rex"Ⓐ(?=b)\w")
+      check matchMacro(r"aΪ", rex"a(?=Ϊ)\w")
+      check matchMacro(r"Ϊb", rex"Ϊ(?=b)\w")
+      check matchMacro(r"弢Ⓐ", rex"弢(?=Ⓐ)\w")
+    block:
+      check matchMacro(r"a弢", rex"\w(?<=a)弢")
+      check matchMacro(r"弢b", rex"\w(?<=弢)b")
+      check matchMacro(r"aⒶ", rex"\w(?<=a)Ⓐ")
+      check matchMacro(r"Ⓐb", rex"\w(?<=Ⓐ)b")
+      check matchMacro(r"aΪ", rex"\w(?<=a)Ϊ")
+      check matchMacro(r"Ϊb", rex"\w(?<=Ϊ)b")
+      check matchMacro(r"弢Ⓐ", rex"\w(?<=弢)Ⓐ")
+    block:
+      check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)cd(?<=(cd)))\w+") ==
+        @["ab", "cd"]
+      check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)(?=(cd)))\w+") ==
+        @["ab", "cd"]
+      check matchMacroCapt("abcdefg", rex"\w+(?<=(ab)(?=(cd)(?<=(cd))))\w+") ==
+        @["ab", "cd", "cd"]
+      check matchMacroCapt("abcdefg", rex"\w+(?=(cd)(?<=(cd)))\w+") ==
+        @["cd", "cd"]
+
 test "tfull_match":
   check "".isMatch(re"")
   check "a".isMatch(re"a")
@@ -294,10 +512,38 @@ test "tfull_match":
   check " \"word\" ".isMatch(re"\s"".*""\s")
 
 test "trepetition_cycle":
-  check "aaa".isMatch(re"a**")
+  check "**".isMatch(re"\**")
+  check "++".isMatch(re"\++")
+  check "??".isMatch(re"\?+")
+  check "??".isMatch(re"\?*")
+  check "?".isMatch(re"\??")
+  check "?".isMatch(re"\???")
+  check "**".isMatch(re"\**?")
+  check "++".isMatch(re"\++?")
+  check "??".isMatch(re"\?+?")
+  check "??".isMatch(re"\?*?")
+  check raises(r"a**")
+  check raises(r"a++")
+  check raises(r"a*+")
+  check raises(r"a+*")
+  check raises(r"a?+")
+  check raises(r"a?*")
+  check raises(r"a??+")
+  check raises(r"a??*")
+  check raises(r"a*??")
+  check raises(r"a+??")
+  check raises(r"a???")
+  check raises(r"a{1,}*")
+  check raises(r"a{1}*")
+  check raises(r"a{1,}+")
+  check raises(r"a{1}+")
+  check raises(r"a{1,}??")
+  check raises(r"a{1}??")
+  check(not raises(r"a{1,}?"))
+  check(not raises(r"a{1}?"))
   check "aaa".isMatch(re"(a*)*")
   check "aaabbbaaa".isMatch(re"((a*|b*))*")
-  check "aaa".isMatch(re"a*****")
+  check raises(r"a*****")
   check raises(r"a*{,}")
   check "aaa".isMatch(re"(a?)*")
   check "aaaa".isMatch(re"((a)*(a)*)*")
@@ -374,6 +620,15 @@ test "trepetition_cycle":
   check findAllBounds("@", re"(a*?)+@") == @[0 .. 0]
   check findAllBounds("@", re"(a*?)+?@") == @[0 .. 0]
 
+test "talternations":
+  check raises(r"a|?")
+  check raises(r"a|?b")
+  check raises(r"?|?")
+  check raises(r"a|*")
+  check raises(r"a|*b")
+  check raises(r"a|+")
+  check raises(r"a|+b")
+
 test "tcaptures":
   check "ab".matchWithCapt(re"(a)b") == @[@["a"]]
   check "aa".matchWithCapt(re"(a)*") == @[@["a", "a"]]
@@ -647,11 +902,9 @@ test "tnot_set":
 test "trepetition_range":
   check(not "".isMatch(re"a{0}"))
   check(not "".isMatch(re"a{0,0}"))
-  check(not "".isMatch(re"a{,0}"))
-  check "".isMatch(re"a{,2}")
+  check "".isMatch(re"a{0,2}")
   check "a".isMatch(re"a{0}")
   check "a".isMatch(re"a{0,0}")
-  check "a".isMatch(re"a{,0}")
   check "a".isMatch(re"a{1}")
   check "aa".isMatch(re"a{2}")
   check "aaa".isMatch(re"a{3}")
@@ -667,47 +920,49 @@ test "trepetition_range":
   check "aaa".isMatch(re"a{1,}")
   check "aaaaaaaaaa".isMatch(re"a{1,}")
   check "aa".isMatch(re"a{2,}")
-  check "a".isMatch(re"a{,}")
-  check "aa".isMatch(re"a{,}")
-  check "aaaaaaaaaa".isMatch(re"a{,}")
-  check "".isMatch(re"a{,}")
   check "aaaaaaaaaa".isMatch(re"a{0,}")
   check "".isMatch(re"a{0,}")
   check(not "a".isMatch(re"a{2,}"))
+  check "a{a,1}".isMatch(re"a{a,1}")
+  check(not "a".isMatch(re"a{a,1}"))
+  check(not "a1".isMatch(re"a{a,1}"))
+  check "a{".isMatch(re"a{")
+  check "a{{".isMatch(re"a{{")
+  check "a{}".isMatch(re"a{}")
   check raises(r"a*{,}")
   check raises(r"a*{0}")
   check raises(r"a*{1}")
-  check "aaa".matchWithCapt(re"(a){,}") ==
+  check "aaa".matchWithCapt(re"(a){0,}") ==
     @[@["a", "a", "a"]]
-  check "aaa".matchWithCapt(re"(a{,}){,}") == @[@["aaa", ""]]
+  check "aaa".matchWithCapt(re"(a{0,}){0,}") == @[@["aaa", ""]]
   check "aaaaa".matchWithCapt(re"(a){5}") ==
     @[@["a", "a", "a", "a", "a"]]
   check "a".matchWithCapt(re"(a){1,5}") == @[@["a"]]
   check "aaa".matchWithCapt(re"(a){1,5}") ==
     @[@["a", "a", "a"]]
-  check "".matchWithCapt(re"(a){,}") ==
+  check "".matchWithCapt(re"(a){0,}") ==
     @[newSeq[string]()]
-  check "aaa".matchWithCapt(re"(a{,}){,}") == @[@["aaa", ""]]
-  check "aaa".matchWithCapt(re"(a{1}){,}") ==
+  check "aaa".matchWithCapt(re"(a{0,}){0,}") == @[@["aaa", ""]]
+  check "aaa".matchWithCapt(re"(a{1}){0,}") ==
     @[@["a", "a", "a"]]
-  check "aaaa".matchWithCapt(re"(a{2}){,}") ==
+  check "aaaa".matchWithCapt(re"(a{2}){0,}") ==
     @[@["aa", "aa"]]
-  check "aaaa".matchWithCapt(re"(a{,3}){,}") ==
+  check "aaaa".matchWithCapt(re"(a{0,3}){0,}") ==
     @[@["aaa", "a", ""]]
-  check "".matchWithCapt(re"(a{,3}){,}") ==
+  check "".matchWithCapt(re"(a{0,3}){0,}") ==
     @[@[""]]
-  check "aaa".matchWithCapt(re"(a{1,}){,}") ==
+  check "aaa".matchWithCapt(re"(a{1,}){0,}") ==
     @[@["aaa"]]
-  check "".matchWithCapt(re"(a{1,}){,}") ==
+  check "".matchWithCapt(re"(a{1,}){0,}") ==
     @[newSeq[string]()]
   check(not "".isMatch(re"(a{1,})"))
   check "a".matchWithCapt(re"(a{1,})") == @[@["a"]]
   check "aaa".matchWithCapt(re"(a{1,})") == @[@["aaa"]]
   check "abab".matchWithCapt(re"(a(b)){2}") ==
     @[@["ab", "ab"], @["b", "b"]]
-  check raisesMsg(r"a{bad}") ==
+  check raisesMsg(r"a{0,bad}") ==
     "Invalid repetition range. Range can only contain digits\n" &
-    "a{bad}\n" &
+    "a{0,bad}\n" &
     " ^"
   check raisesMsg(r"a{1111111111}") ==
     "Invalid repetition range. Max value is 32767\n" &
@@ -720,8 +975,15 @@ test "trepetition_range":
     " ^"
   check(not raises(r"a{1,101}"))
   check raises(r"a{0,a}")
-  check raises(r"a{a,1}")
-  check raises(r"a{-1}")
+  check raises(r"a{,}")
+  check raises(r"a{,1}")
+  check raises(r"a{1x}")
+  check raises(r"a{1,x}")
+  check raises(r"a{1")
+  check raises(r"a{1,")
+  check raises(r"a{1,,}")
+  check raises(r"a{1,,2}")
+  check raises(r"a{1,,,2}")
   check raisesMsg(r"{10}") ==
     "Invalid repeition range, " &
     "nothing to repeat"
@@ -764,13 +1026,13 @@ test "tgreediness":
     @[@["a"], @["a", "a"], @[]]
   check "aaa".matchWithCapt(re"(a)+?(a)+?(a)?") ==
     @[@["a"], @["a"], @["a"]]
-  check "aaa".matchWithCapt(re"(a){,}(a){,}(a){,}") ==
+  check "aaa".matchWithCapt(re"(a){0,}(a){0,}(a){0,}") ==
     @[@["a", "a", "a"], @[], @[]]
-  check "aaa".matchWithCapt(re"(a){,}?(a){,}(a){,}?") ==
+  check "aaa".matchWithCapt(re"(a){0,}?(a){0,}(a){0,}?") ==
     @[@[], @["a", "a", "a"], @[]]
-  check "aaa".matchWithCapt(re"(a){,}?(a){,}?(a){,}") ==
+  check "aaa".matchWithCapt(re"(a){0,}?(a){0,}?(a){0,}") ==
     @[@[], @[], @["a", "a", "a"]]
-  check "aaa".matchWithCapt(re"(a){,}?(a){,}?(a){,}?") ==
+  check "aaa".matchWithCapt(re"(a){0,}?(a){0,}?(a){0,}?") ==
     @[@[], @[], @["a", "a", "a"]]
   check "aaa".matchWithCapt(re"(a){1,}(a){1,}(a)?") ==
     @[@["a", "a"], @["a"], @[]]
@@ -893,10 +1155,6 @@ test "tnamed_groups":
   check raisesMsg(r"(b(a)") ==
     "Invalid capturing group. " &
     "Found too many opening symbols"
-  check raisesMsg(r"a()") ==
-    "Invalid group. Empty group is not allowed\n" &
-    "a()\n" &
-    " ^"
   check raisesMsg(r"a(?P<asd)") ==
     "Invalid group name. Expected char in " &
     "{'a'..'z', 'A'..'Z', '0'..'9', '-', '_'}, " &
@@ -1070,13 +1328,6 @@ test "tflags":
     "abc(?q)\n" &
     "   ^"
 
-test "tor_op":
-  check raisesMsg(r"|") ==
-    "Invalid OR conditional, nothing " &
-    "to match at right/left side of the condition"
-  check raises(r"abc|")
-  check raises(r"|abc")
-
 test "tescaped_sequences":
   check "\x07".isMatch(re"\a")
   check "\x0C".isMatch(re"\f")
@@ -1300,6 +1551,10 @@ test "tstarts_with":
   check "abc".startsWith(re"(a|b)")
   check "bc".startsWith(re"(a|b)")
   check(not "c".startsWith(re"(a|b)"))
+  check startsWith("abc", re"b", start = 1)
+  check startsWith("abc", re"(?<=a)b", start = 1)
+  check(not startsWith("abc", re"(?<=x)b", start = 1))
+  check(not startsWith("abc", re"^b", start = 1))
 
 test "tends_with":
   check "abc".endsWith(re"bc")
@@ -1667,6 +1922,244 @@ test "tnegative_look_around":
   check(not "ab".isMatch(re"\w(?<!a)b"))
   check "ab".matchWithCapt(re"(\w(?<!c))b") == @[@["a"]]
 
+test "tfull_lookarounds":
+  var m: RegexMatch
+  check match("ab", re"a(?=b)\w")
+  check(not match("ab", re"a(?=x)\w"))
+  check(not match("ab", re"ab(?=x)"))
+  check match("ab", re"ab(?=$)")
+  check match("abc", re"a(?=b)\w+")
+  check match("abc", re"a(?=(bc))\w+", m) and
+    m.captures == @[@[1 .. 2]]
+  check match("ab", re"\w(?<=a)b")
+  check(not match("ab", re"\w(?<=x)b"))
+  check(not match("ab", re"(?<=x)ab"))
+  check match("ab", re"(?<=^)ab")
+  check match("abc", re"\w\w(?<=(b))c")
+  check match("abc", re"\w\w(?<=(b))c", m) and
+    m.captures == @[@[1 .. 1]]
+  check match("abc", re"\w\w(?<=(ab))c")
+  check match("abc", re"\w\w(?<=(ab))c", m) and
+    m.captures == @[@[0 .. 1]]
+  check match("a", re"\w(?<=a)")
+  check(not match("a", re"\w(?=a)"))
+  check match("ab", re"\w(?<=a(?<=a))b")
+  check match("ab", re"\w(?<=a(?<=a(?<=a)))b")
+  check match("ab", re"\w(?<=a(?=b))b")
+  check(not match("ab", re"\w(?=b(?=b))b"))  # JS, D
+  check(not match("ab", re"\w(?<=a(?=b(?=b)))b"))  # JS, D
+  check match("ab", re"\w(?<=a(?<=a)(?=b))b")
+  check match("ab", re"\w(?<=a(?<=a(?=b)))b")
+  check(not match("ab", re"\w(?<=(?<=a)a)b"))  # JS, D
+  check match("aab", re"\w\w(?<=aa(?=b))b")
+  block:
+    check match("aaab", re"(\w*)(\w*?)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*)(\w*?)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*)(\w*)$)", m) and
+      m.captures == @[@[0 .. -1], @[0 .. 3]]
+    check match("aaab", re"(\w*?)(\w*)(\w*?)", m) and
+      m.captures == @[@[0 .. -1], @[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w*)(\w*?)$)", m) and
+      m.captures == @[@[0 .. -1], @[0 .. 3], @[4 .. 3]]
+    check match("aaab", re"(\w*)(\w??)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*)(\w??)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*)(\w?)$)", m) and
+      m.captures == @[@[0 .. 2], @[3 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w?)(\w*?)$)", m) and
+      m.captures == @[@[0 .. 2], @[3 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w??)(\w*?)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w??)(\w*?)$)", m) and
+      m.captures == @[@[0 .. 0], @[1 .. 3]]
+    check match("aaab", re".*(?<=^(\w?)(\w*?)$)", m) and
+      m.captures == @[@[0 .. 0], @[1 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w??)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*)(\w??)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w?)$)", m) and
+      m.captures == @[@[0 .. 2], @[3 .. 3]]
+    check match("aaab", re".*(?<=^(\w*)(\w?)$)", m) and
+      m.captures == @[@[0 .. 2], @[3 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w*?)(\w??)$)", m) and
+      m.captures == @[@[0 .. 3], @[4 .. 3], @[4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*?)(\w*)(\w??)$)", m) and
+      m.captures == @[@[0 .. -1], @[0 .. 3], @[4 .. 3]]
+  block:
+    check match("aaab", re".*(?<=^(\w)\w+|(\w)\w+$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\w)\w+$)", m) and
+      m.captures == @[@[], @[0 .. 0]]
+    check match("aaab", re".*(?<=^(\w)\w+|(\w)\w+|(\w)\w+$)", m) and
+      m.captures == @[@[0 .. 0], @[], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\w)\w+|(\w)\w+$)", m) and
+      m.captures == @[@[], @[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\d)\w+|(\w)\w+$)", m) and
+      m.captures == @[@[], @[], @[0 .. 0]]
+  block:
+    check match("aaab", re".*(?<=^(?:(\w)\w+|(\w)\w+)+?$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\w)\w+)+?$)", m) and
+      m.captures == @[@[], @[0 .. 0]]
+    check match("aaab", re".*(?<=^(?:(\w)\w+|(\w)\w+|(\w)\w+)+?$)", m) and
+      m.captures == @[@[0 .. 0], @[], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\w)\w+|(\w)\w+)+?$)", m) and
+      m.captures == @[@[], @[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\d)\w+|(\w)\w+)+?$)", m) and
+      m.captures == @[@[], @[], @[0 .. 0]]
+    check match("aaab", re".*(?<=^(?:(\w)\w+|(\w)\w+)*?$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\w)\w+)*?$)", m) and
+      m.captures == @[@[], @[0 .. 0]]
+    check match("aaab", re".*(?<=^(?:(\w)\w+|(\w)\w+|(\w)\w+)*?$)", m) and
+      m.captures == @[@[0 .. 0], @[], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\w)\w+|(\w)\w+)*?$)", m) and
+      m.captures == @[@[], @[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\d)\w+|(\w)\w+)*?$)", m) and
+      m.captures == @[@[], @[], @[0 .. 0]]
+    check match("aaab", re".*(?<=^(?:(\w)\w+|(\w)\w+)??$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\w)\w+)??$)", m) and
+      m.captures == @[@[], @[0 .. 0]]
+    check match("aaab", re".*(?<=^(?:(\w)\w+|(\w)\w+|(\w)\w+)??$)", m) and
+      m.captures == @[@[0 .. 0], @[], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\w)\w+|(\w)\w+)??$)", m) and
+      m.captures == @[@[], @[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(?:(\d)\w+|(\d)\w+|(\w)\w+)??$)", m) and
+      m.captures == @[@[], @[], @[0 .. 0]]
+  block:
+    check match("aaab", re".*(?<=^(\w)\w+?|(\w)\w+?$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\w)\w+|(\w)\w+$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\w)\w+?|(\w)\w+$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\w)\w+|(\w)\w+?$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\w+|\w{4}|\w{4}|\w+)*$)", m) and
+      m.captures == @[@[0 .. 3]]
+    check match("aaab", re"(\w*|\w{4}|\w{4}|\w*)*", m) and
+      m.captures == @[@[0 .. 3, 4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*|\w{4}|\w{4}|\w*)*$)", m) and
+      m.captures == @[@[0 .. -1, 0 .. 3]]
+    check match("aaab", re".*(?<=^(\w+|\w{4}|\w{4}|\w+)+$)", m) and
+      m.captures == @[@[0 .. 3]]
+    check match("aaab", re".*(?<=^(\w)\w+|\w{4}|\w{4}|(\w)\w+$)", m) and
+      m.captures == @[@[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\w{4})|(\w{4})|(\w)\w+$)", m) and
+      m.captures == @[@[], @[0 .. 3], @[], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\w)\w{3}|(\w)\w{3}|(\w)\w+$)", m) and
+      m.captures == @[@[], @[0 .. 0], @[], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\d)\w{3}|(\w)\w{3}|(\w)\w+$)", m) and
+      m.captures == @[@[], @[], @[0 .. 0], @[]]
+    check match("aaab", re".*(?<=^(\d)\w+|(\d)\w{3}|(\d)\w{3}|(\w)\w+$)", m) and
+      m.captures == @[@[], @[], @[], @[0 .. 0]]
+    check match("aaab", re"(\w*|\w{4}|\w{4}|\w*)+", m) and
+      m.captures == @[@[0 .. 3, 4 .. 3]]
+    check match("aaab", re".*(?<=^(\w*|\w{4}|\w{4}|\w*)+$)", m) and
+      m.captures == @[@[0 .. -1, 0 .. 3]]
+    check match("aaab", re".*(?<=^(\w+)|(\w{4})|(\w{10})$)", m) and
+      m.captures == @[@[0 .. 3], @[], @[]]
+    check match("aaab", re".*(?<=^(\w{10})|(\w{4})|(\w+)$)", m) and
+      m.captures == @[@[], @[0 .. 3], @[]]
+    check match("aaab", re".*(?<=^((\w{10})|(\w{4})|(\w+))+$)", m) and
+      m.captures == @[@[0 .. 3], @[], @[0 .. 3], @[]]
+    check match("aaab", re".*(?<=^((\w{10})|(\w{4})|(\w+))*$)", m) and
+      m.captures == @[@[0 .. 3], @[], @[0 .. 3], @[]]
+    check match("aaab", re".*(?<=^(\w+|\w{4}|\w{4}|\w+)*?$)", m) and
+      m.captures == @[@[0 .. 3]]
+    check match("aaab", re".*(?<=^(\w*|\w{4}|\w{4}|\w*)*?$)", m) and
+      m.captures == @[@[0 .. 3]]
+    check match("aaab", re".*(?<=^(\w+|\w{4}|\w{4}|\w+)+?$)", m) and
+      m.captures == @[@[0 .. 3]]
+  check findAllBounds(r"1abab", re"(?<=\d\w*)ab") ==
+    @[1 .. 2, 3 .. 4]
+  check findAllBounds(r"abab", re"(?<=\d\w*)ab").len == 0
+  check findAllBounds(r"abab1", re"ab(?=\w*\d)") ==
+    @[0 .. 1, 2 .. 3]
+  check findAllBounds(r"abab", re"ab(?=\w*\d)").len == 0
+  check findAllBounds("foo\nbar\nbar", re"bar(?=$)") ==
+    @[8 .. 10]
+  check findAllBounds("foo\nbar\nbar", re"(?m)bar(?=$)") ==
+    @[4 .. 6, 8 .. 10]
+  check findAllBounds("bar\nfoo\nbar", re"(?<=^)bar") ==
+    @[0 .. 2]
+  check findAllBounds("bar\nfoo\nbar", re"(?m)(?<=^)bar") ==
+    @[0 .. 2, 8 .. 10]
+  block:
+    # There is a difference in how nesting is
+    # handled by JS vs D; in D all of them start
+    # from the outermost one, while in JS they
+    # start from the outer one/parent. I think the JS way
+    # is less mind blending, and it makes more sense to me
+    #
+    # These 2 match in D, but not in JS
+    check(not match("ab", re"\w(?<=a(?=b(?<=a)))b"))  # JS, !D
+    check(not match("ab", re"\w(?<=a(?<=a(?=b(?<=a))))b"))  # JS, !D
+    # These 2 match in JS, but not in D
+    check match("ab", re"\w(?<=a(?=b(?<=b)))b")  # JS, !D
+    check match("ab", re"\w(?<=a(?<=a(?=b(?<=b))))b")  # JS, !D
+  block:
+    let asterisk = re"(?<=(?<!\\)(?:\\\\)*)\*"
+    check findAllBounds(r"*foo*", asterisk) ==
+      @[0 .. 0, 4 .. 4]
+    check findAllBounds(r"\*foo\*", asterisk).len == 0
+    check findAllBounds(r"\\*foo\\*", asterisk) ==
+      @[2 .. 2, 8 .. 8]
+    check findAllBounds(r"\\\*foo\\\*", asterisk).len == 0
+    check findAllBounds(r"\\\\*foo\\\\*", asterisk) ==
+      @[4 .. 4, 12 .. 12]
+    check findAllBounds(r"\\\\\*foo\\\\\*", asterisk).len == 0
+  block:
+    let asterisk = re".*(?<=(?<!\\)(?:\\\\)*)\*"
+    check match(r"*", asterisk)
+    check(not match(r"\*", asterisk))
+    check match(r"\\*", asterisk)
+    check(not match(r"\\\*", asterisk))
+    check match(r"\\\\*", asterisk)
+    check(not match(r"\\\\\*", asterisk))
+  block:
+    check findAllBounds("foobarbaz", re"(?<=o)b") == @[3 .. 3]
+    check findAllBounds("foobar", re"o(?=b)") == @[2 .. 2]
+    check findAllBounds("100 in USD100", re"(?<=USD)\d{3}") ==
+      @[10 .. 12]
+    check findAllBounds("100 in USD100", re"\d{3}(?<=USD\d{3})") ==
+      @[10 .. 12]
+  block:
+    check match("弢b", re"弢(?=b)\w")
+    check match("a弢", re"a(?=弢)\w")
+    check match("Ⓐb", re"Ⓐ(?=b)\w")
+    check match("aⒶ", re"a(?=Ⓐ)\w")
+    check match("Ⓐb", re"Ⓐ(?=b)\w")
+    check match("aΪ", re"a(?=Ϊ)\w")
+    check match("Ϊb", re"Ϊ(?=b)\w")
+    check match("弢Ⓐ", re"弢(?=Ⓐ)\w")
+  block:
+    check match("a弢", re"\w(?<=a)弢")
+    check match("弢b", re"\w(?<=弢)b")
+    check match("aⒶ", re"\w(?<=a)Ⓐ")
+    check match("Ⓐb", re"\w(?<=Ⓐ)b")
+    check match("aΪ", re"\w(?<=a)Ϊ")
+    check match("Ϊb", re"\w(?<=Ϊ)b")
+    check match("弢Ⓐ", re"\w(?<=弢)Ⓐ")
+  block:  # Follows Nim re's behaviour
+    check(not match("abc", re"^bc", m, start = 1))
+    check match("abc", re"(?<=a)bc", m, start = 1)
+    check(not match("abc", re"(?<=x)bc", m, start = 1))
+  block:
+    check match("abcdefg", re"\w+(?<=(ab)cd(?<=(cd)))\w+", m) and
+      m.captures == @[@[0 .. 1], @[2 .. 3]]
+    check match("abcdefg", re"\w+(?<=(ab)(?=(cd)))\w+", m) and
+      m.captures == @[@[0 .. 1], @[2 .. 3]]
+    check match("abcdefg", re"\w+(?<=(ab)(?=(cd)(?<=(cd))))\w+", m) and
+      m.captures == @[@[0 .. 1], @[2 .. 3], @[2 .. 3]]
+    check match("abcdefg", re"\w+(?=(cd)(?<=(cd)))\w+", m) and
+      m.captures == @[@[2 .. 3], @[2 .. 3]]
+
 test "tpretty_errors":
   block:
     var exp = ""
@@ -2176,21 +2669,25 @@ test "tmisc2_5":
   check match("650-253-0001", re"[0-9]+..*", m)
   check(not match("abc-253-0001", re"[0-9]+..*", m))
   check(not match("6", re"[0-9]+..*", m))
-  block:
-    const re1 = re"(11)*+(111)*"
-    check match("", re1)
-    check match("11", re1)
-    check match("111", re1)
-    check match("11111", re1)
-    check match("1111111", re1)
-    check match("1111111111", re1)
-    check(not match("1", re1))
-  block:
-    const re1 = re"(11)+(111)*"
-    check(not match("", re1))
-    check match("11", re1)
-    check(not match("111", re1))
-    check match("11111", re1)
+  # VM registry error on Nim < 1.1 (devel)
+  when not defined(runTestAtCT) or (NimMajor, NimMinor) > (1, 0):
+    block:
+      const re1 = re"((11)*)+(111)*"
+      check match("", re1)
+      check match("11", re1)
+      check match("111", re1)
+      check match("11111", re1)
+      check match("1111111", re1)
+      check match("1111111111", re1)
+      check(not match("1", re1))
+    block:
+      const re1 = re"(11)+(111)*"
+      check(not match("", re1))
+      check match("11", re1)
+      check(not match("111", re1))
+      check match("11111", re1)
+
+test "tmisc2_6":
   block:
     const re1 = re"(aabb)(ab)*"
     check match("aabb", re1)
@@ -2293,8 +2790,8 @@ test "tmisc3":
       m.boundaries == 11 .. 10
     # start is out of bounds, but this is what Nim's re
     # does, nre throws an error
-    check find("foo\nbar\nbar", re"(?m)$", m, start=12) and
-      m.boundaries == 12 .. 11
+    #check find("foo\nbar\nbar", re"(?m)$", m, start=12) and
+    #  m.boundaries == 12 .. 11
   # XXX make this return false?
   check match("abc", re"(?m)$", m, start=50)
   check match("abc", re"(?m)^", m, start=50)
@@ -2350,3 +2847,121 @@ test "tmisc3":
   check findAndCaptureAll(
     "He was carefully disguised but captured quickly by police.",
     re"\w+ly") == @["carefully", "quickly"]
+
+test "fix#83":
+  block:
+    let pattern = "^src/(?:[^\\/]*(?:\\/|$))*[^/]*\\.nim$"
+    check "src/dir/foo.nim".match(pattern.re)
+  check match("foo", re"(?:$)*\w*")
+  check match("foo", re"($)*\w*")
+  check match("foo", re"^*\w*")
+  check match("foo", re"([^/]*$)*\w*")
+  check match("src/dir/foo.nim", re"^src/(?:[^/]*(?:/|$))*[^/]*\.nim$")
+  check(not match("foo", re"$($*)*(\w*)"))
+  check(not match("foo", re"$($$*$*)*(\w*)"))
+  check(not match("foo", re"($|$)($*)*(\w*)"))
+  check(not match("foo", re"($|$$)($*)*(\w*)"))
+  check(not match("foo", re"($$|$)($*)*(\w*)"))
+  check(not match("foo", re"($|$)(\w*)"))
+  check(not match("foo", re"($|$$)(\w*)"))
+  check(not match("foo", re"($$|$)(\w*)"))
+  check(not match("foo", re"(^$|$)(\w*)"))
+  check(not match("foo", re"($|^$)(\w*)"))
+  check match("", re"$*\w*")
+  check match("foo", re"($*?)(\w*)")
+  check match("foo", re"($*)(\w*)")
+  check match("foox", re"($*)(\w*)x")
+  check match("foo", re"(a*?$*?)*?(\w*)")
+  check match("foox", re"(a*$*)*(\w*)x")
+  check match("aaa", re"($|^)(a*)")
+  check match("aaa", re"(^|$)(a*)")
+  block:
+    check findAllBounds("aaaxaaa", re"^(a*)") == @[0 .. 2]
+    check findAllBounds("aaaxaaa", re"$(a*)") == @[7 .. 6]
+    check findAllBounds("aaaxaaa", re"($|^)(a*)") == @[0 .. 2, 7 .. 6]
+    check findAllBounds("aaaxaaa", re"(^|$)(a*)") == @[0 .. 2, 7 .. 6]
+  when (NimMajor, NimMinor) >= (1, 1):
+    check matchMacroCapt("foo", rex"($*?)(\w*)") == @["", "foo"]
+    check matchMacroCapt("foo", rex"($*)(\w*)") == @["", "foo"]
+    check matchMacroCapt("foox", rex"($*)(\w*)x") == @["", "foo"]
+    check matchMacroCapt("foo", rex"(a*?$*?)*?(\w*)") == @["", "foo"]
+    check matchMacroCapt("foox", rex"(a*$*)*(\w*)x") == @["", "foo"]
+    check matchMacroCapt("aaa", rex"($|^)(a*)") == @["", "aaa"]
+    check matchMacroCapt("aaa", rex"(^|$)(a*)") == @["", "aaa"]
+
+test "escapeRe":
+  check escapeRe("abc") == "abc"
+  check escapeRe("123") == "123"
+  check escapeRe("!") == "!"
+  check escapeRe("*") == r"\*"
+  check escapeRe" #$&()*+-.?[\]^{|}~" ==
+    r"\ \#\$\&\(\)\*\+\-\.\?\[\\\]\^\{\|\}\~"
+  check escapeRe("\L") == "\\\L"
+  check escapeRe"aΪⒶ弢" == "aΪⒶ弢"
+  check escapeRe"$Ϊ$Ⓐ$弢$" == r"\$Ϊ\$Ⓐ\$弢\$"
+  check match("$", re(escapeRe"$"))
+  block:
+    var s = ""
+    for c in 0 .. 255:
+      s.add c.char
+    discard re(escapeRe(s))
+
+test "issue_98":
+  check match("", re"|")
+  check match("a", re"a|")
+  check match("", re"a|")
+  check(not match("b", re"a|"))
+  check match("b", re"|b")
+  check match("", re"|b")
+  check(not match("a", re"|b"))
+  check match("", re"(|)")
+  check match("a", re"(a|)")
+  check match("", re"(a|)")
+  check(not match("b", re"(a|)"))
+  check match("b", re"(|b)")
+  check match("", re"(|b)")
+  check(not match("a", re"(|b)"))
+  check match("", re"||")
+  check match("a", re"a||")
+  check match("", re"a||")
+  check match("b", re"||b")
+  check match("", re"||b")
+  check match("", re"a||b")
+  check match("a", re"a||b")
+  check match("b", re"a||b")
+  check match("", re"|||")
+  check match("a", re"a|||")
+  check match("", re"a|||")
+  check match("b", re"|||b")
+  check match("", re"|||b")
+  check match("a", re"a|||b")
+  check match("b", re"a|||b")
+  check match("", re"(||)")
+  check match("a", re"(a||)")
+  check match("", re"(a||)")
+  check match("b", re"(||b)")
+  check match("", re"(||b)")
+  check match("1.1.1.1", re"(\d+)\.(\d+)(\.(\d+)|)(\.(\d+)|)")
+  check match("1.1.1", re"(\d+)\.(\d+)(\.(\d+)|)(\.(\d+)|)")
+  check match("1.1", re"(\d+)\.(\d+)(\.(\d+)|)(\.(\d+)|)")
+
+test "issue_101":
+  var m: RegexMatch
+  check match("TXT1/TXT2.1", re"(TXT1)/TXT2()\.(\d+)")
+  check match("TXT1/TXT2.1", re"(TXT1)/TXT2(?:)\.(\d+)")
+  check match("TXT1/TXT2.1", re"(TXT1)/TXT2(?i:)\.(\d+)")
+  check match("TXT1/TXT2.1", re"(TXT1)/TXT2(?P<foo>)\.(\d+)")
+  check match("TXT1/TXT2.1", re"(TXT1)/TXT2()\.(\d+)", m) and
+    m.captures == @[@[0 .. 3], @[9 .. 8], @[10 .. 10]]
+  check match(" ", re"(?x)     (?-x) ")
+  check match("aa", re"((?x)a    )a")
+  check match("aa", re"((?x)   a    )a")
+  check match(" ", re"((?x)) ")
+  check match(" ", re"((?x)     ) ")
+  check match(" ", re"(?x:(?x)     ) ")
+  check match(" ", re"(?x:) ")
+  check match(" ", re"(?x:   ) ")
+  check match(" ", re"((?x:)) ")
+  check match("A", re"(?xi)     a")
+  check(not match("A", re"((?xi))     a"))
+  check(not match("A", re"(?xi:(?xi)     )a"))