[Pkg-javascript-commits] [node-regexpu-core] 01/02: New upstream version 4.1.2+ds
Julien Puydt
julien.puydt at laposte.net
Sat Sep 9 16:44:54 UTC 2017
This is an automated email from the git hooks/post-receive script.
jpuydt-guest pushed a commit to branch master
in repository node-regexpu-core.
commit a53bb2da9f8e2bd3584b4407977ddcd2bada3371
Author: Julien Puydt <julien.puydt at laposte.net>
Date: Sat Sep 9 18:24:09 2017 +0200
New upstream version 4.1.2+ds
---
.editorconfig | 12 +
.gitattributes | 2 +
.gitignore | 17 +
.travis.yml | 17 +
LICENSE-MIT.txt | 20 +
README.md | 109 +++
package-lock.json | 1257 ++++++++++++++++++++++++++++++++
package.json | 68 ++
property-escapes.md | 330 +++++++++
rewrite-pattern.js | 270 +++++++
scripts/character-class-escape-sets.js | 135 ++++
scripts/iu-mappings.js | 179 +++++
tests/tests.js | 760 +++++++++++++++++++
13 files changed, 3176 insertions(+)
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..6f9f40f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = tab
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[{README.md,.travis.yml}]
+indent_style = space
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..0a91f75
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+# Automatically normalize line endings for all text-based files
+* text=auto
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..444ec4d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+# Coverage report
+coverage
+
+# Installed npm modules
+node_modules
+
+# Folder view configuration files
+.DS_Store
+Desktop.ini
+
+# Thumbnail cache files
+._*
+Thumbs.db
+
+# Files that might appear on external disks
+.Spotlight-V100
+.Trashes
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..eaf74ce
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,17 @@
+sudo: false
+language: node_js
+node_js:
+ - '4'
+ - '5'
+ - '6'
+ - '7'
+ - '8'
+script:
+ - 'if [ "${TRAVIS_NODE_VERSION}" = "8" ]; then
+ npm run build;
+ fi'
+ - 'npm test'
+after_script:
+ - 'istanbul cover --report html node_modules/.bin/_mocha tests -- -u exports -R spec && codecov'
+git:
+ depth: 1
diff --git a/LICENSE-MIT.txt b/LICENSE-MIT.txt
new file mode 100644
index 0000000..a41e0a7
--- /dev/null
+++ b/LICENSE-MIT.txt
@@ -0,0 +1,20 @@
+Copyright Mathias Bynens <https://mathiasbynens.be/>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..45da73b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,109 @@
+# regexpu-core [![Build status](https://travis-ci.org/mathiasbynens/regexpu-core.svg?branch=master)](https://travis-ci.org/mathiasbynens/regexpu-core) [![Code coverage status](https://img.shields.io/codecov/c/github/mathiasbynens/regexpu-core.svg)](https://codecov.io/gh/mathiasbynens/regexpu-core) [![Dependency status](https://gemnasium.com/mathiasbynens/regexpu-core.svg)](https://gemnasium.com/mathiasbynens/regexpu-core)
+
+_regexpu_ is a source code transpiler that enables the use of ES6 Unicode regular expressions in JavaScript-of-today (ES5).
+
+_regexpu-core_ contains _regexpu_’s core functionality, i.e. `rewritePattern(pattern, flag)`, which enables rewriting regular expressions that make use of [the ES6 `u` flag](https://mathiasbynens.be/notes/es6-unicode-regex) into equivalent ES5-compatible regular expression patterns.
+
+## Installation
+
+To use _regexpu-core_ programmatically, install it as a dependency via [npm](https://www.npmjs.com/):
+
+```bash
+npm install regexpu-core --save
+```
+
+Then, `require` it:
+
+```js
+const rewritePattern = require('regexpu-core');
+```
+
+## API
+
+This module exports a single function named `rewritePattern`.
+
+### `rewritePattern(pattern, flags, options)`
+
+This function takes a string that represents a regular expression pattern as well as a string representing its flags, and returns an ES5-compatible version of the pattern.
+
+```js
+rewritePattern('foo.bar', 'u');
+// → 'foo(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\uDC00-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF])bar'
+
+rewritePattern('[\\u{1D306}-\\u{1D308}a-z]', 'u');
+// → '(?:[a-z]|\\uD834[\\uDF06-\\uDF08])'
+
+rewritePattern('[\\u{1D306}-\\u{1D308}a-z]', 'ui');
+// → '(?:[a-z\\u017F\\u212A]|\\uD834[\\uDF06-\\uDF08])'
+```
+
+_regexpu-core_ can rewrite non-ES6 regular expressions too, which is useful to demonstrate how their behavior changes once the `u` and `i` flags are added:
+
+```js
+// In ES5, the dot operator only matches BMP symbols:
+rewritePattern('foo.bar');
+// → 'foo(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uFFFF])bar'
+
+// But with the ES6 `u` flag, it matches astral symbols too:
+rewritePattern('foo.bar', 'u');
+// → 'foo(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\uDC00-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF])bar'
+```
+
+The optional `options` argument recognizes the following properties:
+
+#### `dotAllFlag` (default: `false`)
+
+Setting this option to `true` enables experimental support for [the `s` (`dotAll`) flag](https://github.com/mathiasbynens/es-regexp-dotall-flag).
+
+```js
+rewritePattern('.');
+// → '[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uFFFF]'
+
+rewritePattern('.', '', {
+ 'dotAllFlag': true
+});
+// → '[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uFFFF]'
+
+rewritePattern('.', 's', {
+ 'dotAllFlag': true
+});
+// → '[\\0-\\uFFFF]'
+
+rewritePattern('.', 'su', {
+ 'dotAllFlag': true
+});
+// → '(?:[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])'
+```
+
+#### `unicodePropertyEscape` (default: `false`)
+
+Setting this option to `true` enables [experimental support for Unicode property escapes](property-escapes.md):
+
+```js
+rewritePattern('\\p{Block=Aegean_Numbers}', 'u', {
+ 'unicodePropertyEscape': true
+});
+// → '(?:\\uD800[\\uDD00-\\uDD3F])'
+```
+
+#### `useUnicodeFlag` (default: `false`)
+
+Setting this option to `true` enables the use of Unicode code point escapes of the form `\u{…}`. Note that in regular expressions, such escape sequences only work correctly when the ES6 `u` flag is set. Enabling this setting often results in more compact output, although there are cases (such as `\p{Lu}`) where it actually _increases_ the output size.
+
+```js
+rewritePattern('\\p{Block=Aegean_Numbers}', 'u', {
+ 'unicodePropertyEscape': true,
+ 'useUnicodeFlag': true
+});
+// → '[\\u{10100}-\\u{1013F}]'
+```
+
+## Author
+
+| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
+|---|
+| [Mathias Bynens](https://mathiasbynens.be/) |
+
+## License
+
+_regexpu-core_ is available under the [MIT](https://mths.be/mit) license.
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..660df26
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1257 @@
+{
+ "name": "regexpu-core",
+ "version": "4.1.2",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+ "dev": true
+ },
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "json-stable-stringify": "1.0.1"
+ }
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2",
+ "longest": "1.0.1",
+ "repeat-string": "1.6.1"
+ }
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+ "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "1.0.3"
+ }
+ },
+ "argv": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
+ "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+ "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
+ "dev": true
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+ "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+ "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "tweetnacl": "0.14.5"
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "browser-stdout": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
+ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true,
+ "optional": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "align-text": "0.1.4",
+ "lazy-cache": "1.0.4"
+ }
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "center-align": "0.1.3",
+ "right-align": "0.1.3",
+ "wordwrap": "0.0.2"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "codecov": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/codecov/-/codecov-2.3.0.tgz",
+ "integrity": "sha1-rSWixuBELRN0DZ1N27mj4nFDMPQ=",
+ "dev": true,
+ "requires": {
+ "argv": "0.0.2",
+ "request": "2.81.0",
+ "urlgrey": "0.4.4"
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
+ "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
+ "dev": true,
+ "requires": {
+ "graceful-readlink": "1.0.1"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true,
+ "optional": true
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "diff": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz",
+ "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+ "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "jsbn": "0.1.1"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escodegen": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+ "dev": true,
+ "requires": {
+ "esprima": "2.7.3",
+ "estraverse": "1.9.3",
+ "esutils": "2.0.2",
+ "optionator": "0.8.2",
+ "source-map": "0.2.0"
+ }
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+ "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "requires": {
+ "asynckit": "0.4.0",
+ "combined-stream": "1.0.5",
+ "mime-types": "2.1.16"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "graceful-readlink": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
+ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+ "dev": true
+ },
+ "growl": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
+ "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
+ "dev": true
+ },
+ "handlebars": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
+ "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
+ "dev": true,
+ "requires": {
+ "async": "1.5.2",
+ "optimist": "0.6.1",
+ "source-map": "0.4.4",
+ "uglify-js": "2.8.29"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ }
+ }
+ },
+ "har-schema": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+ "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+ "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+ "dev": true,
+ "requires": {
+ "ajv": "4.11.8",
+ "har-schema": "1.0.5"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.10.1",
+ "cryptiles": "2.0.5",
+ "hoek": "2.16.3",
+ "sntp": "1.0.9"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "0.2.0",
+ "jsprim": "1.4.1",
+ "sshpk": "1.13.1"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "is-buffer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
+ "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "istanbul": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
+ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9",
+ "async": "1.5.2",
+ "escodegen": "1.8.1",
+ "esprima": "2.7.3",
+ "glob": "5.0.15",
+ "handlebars": "4.0.10",
+ "js-yaml": "3.8.4",
+ "mkdirp": "0.5.1",
+ "nopt": "3.0.6",
+ "once": "1.4.0",
+ "resolve": "1.1.7",
+ "supports-color": "3.2.3",
+ "which": "1.2.14",
+ "wordwrap": "1.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ }
+ }
+ },
+ "js-yaml": {
+ "version": "3.8.4",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz",
+ "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=",
+ "dev": true,
+ "requires": {
+ "argparse": "1.0.9",
+ "esprima": "3.1.3"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+ "dev": true
+ }
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true,
+ "optional": true
+ },
+ "jsesc": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz",
+ "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "0.0.0"
+ }
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+ "dev": true
+ },
+ "json3": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+ "dev": true
+ },
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.5"
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "dev": true,
+ "optional": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2"
+ }
+ },
+ "lodash": {
+ "version": "4.17.4",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
+ "dev": true
+ },
+ "lodash._baseassign": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
+ "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
+ "dev": true,
+ "requires": {
+ "lodash._basecopy": "3.0.1",
+ "lodash.keys": "3.1.2"
+ }
+ },
+ "lodash._basecopy": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
+ "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
+ "dev": true
+ },
+ "lodash._basecreate": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
+ "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=",
+ "dev": true
+ },
+ "lodash._getnative": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+ "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
+ "dev": true
+ },
+ "lodash._isiterateecall": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
+ "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
+ "dev": true
+ },
+ "lodash.create": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
+ "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
+ "dev": true,
+ "requires": {
+ "lodash._baseassign": "3.2.0",
+ "lodash._basecreate": "3.0.3",
+ "lodash._isiterateecall": "3.0.9"
+ }
+ },
+ "lodash.isarguments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+ "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
+ "dev": true
+ },
+ "lodash.isarray": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+ "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
+ "dev": true
+ },
+ "lodash.keys": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+ "dev": true,
+ "requires": {
+ "lodash._getnative": "3.9.1",
+ "lodash.isarguments": "3.1.0",
+ "lodash.isarray": "3.0.4"
+ }
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz",
+ "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz",
+ "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.29.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ }
+ }
+ },
+ "mocha": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz",
+ "integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==",
+ "dev": true,
+ "requires": {
+ "browser-stdout": "1.3.0",
+ "commander": "2.9.0",
+ "debug": "2.6.8",
+ "diff": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.1",
+ "growl": "1.9.2",
+ "json3": "3.3.2",
+ "lodash.create": "3.1.1",
+ "mkdirp": "0.5.1",
+ "supports-color": "3.1.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ }
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.9"
+ }
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.10",
+ "wordwrap": "0.0.3"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "dev": true
+ }
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "0.1.3",
+ "fast-levenshtein": "2.0.6",
+ "levn": "0.3.0",
+ "prelude-ls": "1.1.2",
+ "type-check": "0.3.2",
+ "wordwrap": "1.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+ "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+ "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+ "dev": true
+ },
+ "regenerate": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz",
+ "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA="
+ },
+ "regenerate-unicode-properties": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-5.1.1.tgz",
+ "integrity": "sha512-oaZXgyhHR9VYnYFzPRdO+k7tHaUXO5jPqfFYnaC5kIW9NQ0kVwb5rt8x5CEC0LCZ7WRIUy7zIrCF7R2xIbjiRA==",
+ "requires": {
+ "regenerate": "1.3.2"
+ }
+ },
+ "regexpu-fixtures": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/regexpu-fixtures/-/regexpu-fixtures-2.1.1.tgz",
+ "integrity": "sha1-qDaM8+3EfmIVORQi7qhkHDFsGo8=",
+ "dev": true
+ },
+ "regjsgen": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.3.0.tgz",
+ "integrity": "sha1-DuSj6SdkMM2iXx54nqbBW4ewy0M="
+ },
+ "regjsparser": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.2.1.tgz",
+ "integrity": "sha1-w3h1U/rwTndcMCEC7zRtmVAA7Bw=",
+ "requires": {
+ "jsesc": "0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
+ }
+ }
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.81.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+ "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.12.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "4.2.1",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.16",
+ "oauth-sign": "0.8.2",
+ "performance-now": "0.2.0",
+ "qs": "6.4.0",
+ "safe-buffer": "5.1.1",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.6.0",
+ "uuid": "3.1.0"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "align-text": "0.1.4"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
+ "dev": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.16.3"
+ }
+ },
+ "source-map": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+ "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": "1.0.1"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+ "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "dev": true,
+ "requires": {
+ "asn1": "0.2.3",
+ "assert-plus": "1.0.0",
+ "bcrypt-pbkdf": "1.0.1",
+ "dashdash": "1.14.1",
+ "ecc-jsbn": "0.1.1",
+ "getpass": "0.1.7",
+ "jsbn": "0.1.1",
+ "tweetnacl": "0.14.5"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
+ "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
+ "dev": true,
+ "requires": {
+ "has-flag": "1.0.0"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
+ "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "dev": true,
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "1.1.2"
+ }
+ },
+ "uglify-js": {
+ "version": "2.8.29",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "source-map": "0.5.6",
+ "uglify-to-browserify": "1.0.2",
+ "yargs": "3.10.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "dev": true,
+ "optional": true
+ },
+ "unicode-10.0.0": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/unicode-10.0.0/-/unicode-10.0.0-0.7.4.tgz",
+ "integrity": "sha512-TXvlDZJxOQ7DVMl0fvlUe+VrDxEvv9yxnAyXHReiBOsKlqGTOgV79eKWOHURH7ySmuxncq0boRzZx63z/elPeA==",
+ "dev": true
+ },
+ "unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.2.tgz",
+ "integrity": "sha512-tIHxB3DR9aS8uArhzIja8y0LQDvWx7DZIRkHJtLPnM29x/m0sNiMF9FYsxIASpkj85qfBvMWBsFURZoHIX6ceA=="
+ },
+ "unicode-match-property-ecmascript": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.3.tgz",
+ "integrity": "sha512-nFcaBFcr08UQNF15ZgI5ISh3yUnQm7SJRRxwYrL5VYX46pS+6Q7TCTv4zbK+j6/l7rQt0mMiTL2zpmeygny6rA==",
+ "requires": {
+ "unicode-canonical-property-names-ecmascript": "1.0.2",
+ "unicode-property-aliases-ecmascript": "1.0.3"
+ }
+ },
+ "unicode-match-property-value-ecmascript": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.1.tgz",
+ "integrity": "sha512-lM8B0FDZQh9yYGgiabRQcyWicB27VLOolSBRIxsO7FeQPtg+79Oe7sC8Mzr8BObDs+G9CeYmC/shHo6OggNEog=="
+ },
+ "unicode-property-aliases-ecmascript": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.3.tgz",
+ "integrity": "sha512-TdDmDOTxEf2ad1g3ZBpM6cqKIb2nJpVlz1Q++casDryKz18tpeMBhSng9hjC1CTQCkOV9Rw2knlSB6iRo7ad1w=="
+ },
+ "unicode-tr51": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-tr51/-/unicode-tr51-9.0.0.tgz",
+ "integrity": "sha512-dqQFvT+4Oc8kHseEBB2a/xMKJcPz7jUvkUfw4AG7YUoyhjBl6/lCpHoSEHBXA199Bv804Ob8lB2O7WTqsyai2A==",
+ "dev": true
+ },
+ "urlgrey": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz",
+ "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "1.3.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ }
+ }
+ },
+ "which": {
+ "version": "1.2.14",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
+ "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
+ "dev": true,
+ "requires": {
+ "isexe": "2.0.0"
+ }
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "dev": true,
+ "optional": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "camelcase": "1.2.1",
+ "cliui": "2.1.0",
+ "decamelize": "1.2.0",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..86c3628
--- /dev/null
+++ b/package.json
@@ -0,0 +1,68 @@
+{
+ "name": "regexpu-core",
+ "version": "4.1.2",
+ "description": "regexpu’s core functionality (i.e. `rewritePattern(pattern, flag)`), capable of translating ES6 Unicode regular expressions to ES5.",
+ "homepage": "https://mths.be/regexpu",
+ "main": "rewrite-pattern.js",
+ "engines": {
+ "node": ">=4"
+ },
+ "keywords": [
+ "codegen",
+ "desugaring",
+ "ecmascript",
+ "es5",
+ "es6",
+ "harmony",
+ "javascript",
+ "refactoring",
+ "regex",
+ "regexp",
+ "regular expressions",
+ "rewriting",
+ "syntax",
+ "transformation",
+ "transpile",
+ "transpiler",
+ "unicode"
+ ],
+ "license": "MIT",
+ "author": {
+ "name": "Mathias Bynens",
+ "url": "https://mathiasbynens.be/"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mathiasbynens/regexpu-core.git"
+ },
+ "bugs": "https://github.com/mathiasbynens/regexpu-core/issues",
+ "files": [
+ "LICENSE-MIT.txt",
+ "rewrite-pattern.js",
+ "data/character-class-escape-sets.js",
+ "data/iu-mappings.js"
+ ],
+ "scripts": {
+ "build": "node scripts/iu-mappings.js && node scripts/character-class-escape-sets.js",
+ "test": "mocha tests",
+ "cover": "istanbul cover --report html node_modules/.bin/_mocha tests -- -u exports -R spec"
+ },
+ "dependencies": {
+ "regenerate": "^1.3.2",
+ "regenerate-unicode-properties": "^5.1.1",
+ "regjsgen": "^0.3.0",
+ "regjsparser": "^0.2.1",
+ "unicode-match-property-ecmascript": "^1.0.3",
+ "unicode-match-property-value-ecmascript": "^1.0.1"
+ },
+ "devDependencies": {
+ "codecov": "^2.3.0",
+ "istanbul": "^0.4.5",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.4",
+ "mocha": "^3.5.0",
+ "regexpu-fixtures": "^2.1.1",
+ "unicode-10.0.0": "^0.7.4",
+ "unicode-tr51": "^9.0.0"
+ }
+}
diff --git a/property-escapes.md b/property-escapes.md
new file mode 100644
index 0000000..881f139
--- /dev/null
+++ b/property-escapes.md
@@ -0,0 +1,330 @@
+# Unicode property escapes in _regexpu_
+
+To opt-in to experimental support for [Unicode property escapes](https://github.com/mathiasbynens/es-regexp-unicode-property-escapes), enable [the `unicodePropertyEscape` option](README.md#unicodepropertyescape-default-false).
+
+```js
+rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', {
+ 'unicodePropertyEscape': true
+});
+// → '(?:\\uD811[\\uDC00-\\uDE46])'
+```
+
+If you’re targeting ES6 environments exclusively, consider enabling [the `useUnicodeFlag` option](README.md#useunicodeflag-default-false) for simpler (but not necessarily more compact) output.
+
+```js
+rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', {
+ 'unicodePropertyEscape': true,
+ 'useUnicodeFlag': true
+});
+// → '[\\u{14400}-\\u{14646}]'
+```
+
+[An online demo is available.](https://mothereff.in/regexpu#input=var+regex+%3D+/%5Cp%7BScript_Extensions%3DGreek%7D/u%3B&unicodePropertyEscape=1)
+
+Note that this feature is non-standard. This implementation may or may not reflect what eventually gets specified.
+
+What follows is an exhaustive overview of the Unicode properties and values that _regexpu_ supports in `\p{…}` and `\P{…}` expressions in regular expressions with the `u` flag.
+
+## Non-binary properties
+
+### `General_Category`
+
+Possible values:
+
+```sh
+$ node -e 'require("regenerate-unicode-properties").get("General_Category").forEach(c => { console.log(`\\p{${c}}`); })'
+\p{Cased_Letter}
+\p{Close_Punctuation}
+\p{Connector_Punctuation}
+\p{Control}
+\p{Currency_Symbol}
+\p{Dash_Punctuation}
+\p{Decimal_Number}
+\p{Enclosing_Mark}
+\p{Final_Punctuation}
+\p{Format}
+\p{Initial_Punctuation}
+\p{Letter}
+\p{Letter_Number}
+\p{Line_Separator}
+\p{Lowercase_Letter}
+\p{Mark}
+\p{Math_Symbol}
+\p{Modifier_Letter}
+\p{Modifier_Symbol}
+\p{Nonspacing_Mark}
+\p{Number}
+\p{Open_Punctuation}
+\p{Other}
+\p{Other_Letter}
+\p{Other_Number}
+\p{Other_Punctuation}
+\p{Other_Symbol}
+\p{Paragraph_Separator}
+\p{Private_Use}
+\p{Punctuation}
+\p{Separator}
+\p{Space_Separator}
+\p{Spacing_Mark}
+\p{Surrogate}
+\p{Symbol}
+\p{Titlecase_Letter}
+\p{Unassigned}
+\p{Uppercase_Letter}
+```
+
+Note that the `General_Category=` prefix may be used, e.g. `\p{General_Category=Cased_Letter}`.
+
+Category aliases may be used, e.g. `\p{Lc}` or `\p{General_Category=Lc}`, although IMHO it’s more readable to stick to the canonical category names listed above.
+
+### `Script` & `Script_Extensions`
+
+The sets of possible values for `Script` and `Script_Extensions` are identical:
+
+```sh
+$ node -e 'require("regenerate-unicode-properties").get("Script_Extensions").forEach(s => { console.log(`\\p{Script_Extensions=${s}}`); })'
+\p{Script_Extensions=Adlam}
+\p{Script_Extensions=Ahom}
+\p{Script_Extensions=Anatolian_Hieroglyphs}
+\p{Script_Extensions=Arabic}
+\p{Script_Extensions=Armenian}
+\p{Script_Extensions=Avestan}
+\p{Script_Extensions=Balinese}
+\p{Script_Extensions=Bamum}
+\p{Script_Extensions=Bassa_Vah}
+\p{Script_Extensions=Batak}
+\p{Script_Extensions=Bengali}
+\p{Script_Extensions=Bhaiksuki}
+\p{Script_Extensions=Bopomofo}
+\p{Script_Extensions=Brahmi}
+\p{Script_Extensions=Braille}
+\p{Script_Extensions=Buginese}
+\p{Script_Extensions=Buhid}
+\p{Script_Extensions=Canadian_Aboriginal}
+\p{Script_Extensions=Carian}
+\p{Script_Extensions=Caucasian_Albanian}
+\p{Script_Extensions=Chakma}
+\p{Script_Extensions=Cham}
+\p{Script_Extensions=Cherokee}
+\p{Script_Extensions=Common}
+\p{Script_Extensions=Coptic}
+\p{Script_Extensions=Cuneiform}
+\p{Script_Extensions=Cypriot}
+\p{Script_Extensions=Cyrillic}
+\p{Script_Extensions=Deseret}
+\p{Script_Extensions=Devanagari}
+\p{Script_Extensions=Duployan}
+\p{Script_Extensions=Egyptian_Hieroglyphs}
+\p{Script_Extensions=Elbasan}
+\p{Script_Extensions=Ethiopic}
+\p{Script_Extensions=Georgian}
+\p{Script_Extensions=Glagolitic}
+\p{Script_Extensions=Gothic}
+\p{Script_Extensions=Grantha}
+\p{Script_Extensions=Greek}
+\p{Script_Extensions=Gujarati}
+\p{Script_Extensions=Gurmukhi}
+\p{Script_Extensions=Han}
+\p{Script_Extensions=Hangul}
+\p{Script_Extensions=Hanunoo}
+\p{Script_Extensions=Hatran}
+\p{Script_Extensions=Hebrew}
+\p{Script_Extensions=Hiragana}
+\p{Script_Extensions=Imperial_Aramaic}
+\p{Script_Extensions=Inherited}
+\p{Script_Extensions=Inscriptional_Pahlavi}
+\p{Script_Extensions=Inscriptional_Parthian}
+\p{Script_Extensions=Javanese}
+\p{Script_Extensions=Kaithi}
+\p{Script_Extensions=Kannada}
+\p{Script_Extensions=Katakana}
+\p{Script_Extensions=Kayah_Li}
+\p{Script_Extensions=Kharoshthi}
+\p{Script_Extensions=Khmer}
+\p{Script_Extensions=Khojki}
+\p{Script_Extensions=Khudawadi}
+\p{Script_Extensions=Lao}
+\p{Script_Extensions=Latin}
+\p{Script_Extensions=Lepcha}
+\p{Script_Extensions=Limbu}
+\p{Script_Extensions=Linear_A}
+\p{Script_Extensions=Linear_B}
+\p{Script_Extensions=Lisu}
+\p{Script_Extensions=Lycian}
+\p{Script_Extensions=Lydian}
+\p{Script_Extensions=Mahajani}
+\p{Script_Extensions=Malayalam}
+\p{Script_Extensions=Mandaic}
+\p{Script_Extensions=Manichaean}
+\p{Script_Extensions=Marchen}
+\p{Script_Extensions=Masaram_Gondi}
+\p{Script_Extensions=Meetei_Mayek}
+\p{Script_Extensions=Mende_Kikakui}
+\p{Script_Extensions=Meroitic_Cursive}
+\p{Script_Extensions=Meroitic_Hieroglyphs}
+\p{Script_Extensions=Miao}
+\p{Script_Extensions=Modi}
+\p{Script_Extensions=Mongolian}
+\p{Script_Extensions=Mro}
+\p{Script_Extensions=Multani}
+\p{Script_Extensions=Myanmar}
+\p{Script_Extensions=Nabataean}
+\p{Script_Extensions=New_Tai_Lue}
+\p{Script_Extensions=Newa}
+\p{Script_Extensions=Nko}
+\p{Script_Extensions=Nushu}
+\p{Script_Extensions=Ogham}
+\p{Script_Extensions=Ol_Chiki}
+\p{Script_Extensions=Old_Hungarian}
+\p{Script_Extensions=Old_Italic}
+\p{Script_Extensions=Old_North_Arabian}
+\p{Script_Extensions=Old_Permic}
+\p{Script_Extensions=Old_Persian}
+\p{Script_Extensions=Old_South_Arabian}
+\p{Script_Extensions=Old_Turkic}
+\p{Script_Extensions=Oriya}
+\p{Script_Extensions=Osage}
+\p{Script_Extensions=Osmanya}
+\p{Script_Extensions=Pahawh_Hmong}
+\p{Script_Extensions=Palmyrene}
+\p{Script_Extensions=Pau_Cin_Hau}
+\p{Script_Extensions=Phags_Pa}
+\p{Script_Extensions=Phoenician}
+\p{Script_Extensions=Psalter_Pahlavi}
+\p{Script_Extensions=Rejang}
+\p{Script_Extensions=Runic}
+\p{Script_Extensions=Samaritan}
+\p{Script_Extensions=Saurashtra}
+\p{Script_Extensions=Sharada}
+\p{Script_Extensions=Shavian}
+\p{Script_Extensions=Siddham}
+\p{Script_Extensions=SignWriting}
+\p{Script_Extensions=Sinhala}
+\p{Script_Extensions=Sora_Sompeng}
+\p{Script_Extensions=Soyombo}
+\p{Script_Extensions=Sundanese}
+\p{Script_Extensions=Syloti_Nagri}
+\p{Script_Extensions=Syriac}
+\p{Script_Extensions=Tagalog}
+\p{Script_Extensions=Tagbanwa}
+\p{Script_Extensions=Tai_Le}
+\p{Script_Extensions=Tai_Tham}
+\p{Script_Extensions=Tai_Viet}
+\p{Script_Extensions=Takri}
+\p{Script_Extensions=Tamil}
+\p{Script_Extensions=Tangut}
+\p{Script_Extensions=Telugu}
+\p{Script_Extensions=Thaana}
+\p{Script_Extensions=Thai}
+\p{Script_Extensions=Tibetan}
+\p{Script_Extensions=Tifinagh}
+\p{Script_Extensions=Tirhuta}
+\p{Script_Extensions=Ugaritic}
+\p{Script_Extensions=Vai}
+\p{Script_Extensions=Warang_Citi}
+\p{Script_Extensions=Yi}
+\p{Script_Extensions=Zanabazar_Square}
+```
+
+Note that script name aliases may be used as well, e.g. `\p{Script_Extensions=Aghb}`, although IMHO it’s more readable to stick to the canonical script names listed above.
+
+## Binary properties
+
+The following binary properties are supported:
+
+```sh
+$ node -e 'require("regenerate-unicode-properties").get("Binary_Property").forEach(p => { console.log(`\\p{${p}}`); })'
+\p{ASCII}
+\p{ASCII_Hex_Digit}
+\p{Alphabetic}
+\p{Any}
+\p{Assigned}
+\p{Bidi_Control}
+\p{Bidi_Mirrored}
+\p{Case_Ignorable}
+\p{Cased}
+\p{Changes_When_Casefolded}
+\p{Changes_When_Casemapped}
+\p{Changes_When_Lowercased}
+\p{Changes_When_NFKC_Casefolded}
+\p{Changes_When_Titlecased}
+\p{Changes_When_Uppercased}
+\p{Dash}
+\p{Default_Ignorable_Code_Point}
+\p{Deprecated}
+\p{Diacritic}
+\p{Emoji}
+\p{Emoji_Component}
+\p{Emoji_Modifier}
+\p{Emoji_Modifier_Base}
+\p{Emoji_Presentation}
+\p{Extended_Pictographic}
+\p{Extender}
+\p{Grapheme_Base}
+\p{Grapheme_Extend}
+\p{Hex_Digit}
+\p{IDS_Binary_Operator}
+\p{IDS_Trinary_Operator}
+\p{ID_Continue}
+\p{ID_Start}
+\p{Ideographic}
+\p{Join_Control}
+\p{Logical_Order_Exception}
+\p{Lowercase}
+\p{Math}
+\p{Noncharacter_Code_Point}
+\p{Pattern_Syntax}
+\p{Pattern_White_Space}
+\p{Quotation_Mark}
+\p{Radical}
+\p{Regional_Indicator}
+\p{Sentence_Terminal}
+\p{Soft_Dotted}
+\p{Terminal_Punctuation}
+\p{Unified_Ideograph}
+\p{Uppercase}
+\p{Variation_Selector}
+\p{White_Space}
+\p{XID_Continue}
+\p{XID_Start}
+```
+
+Note that property name aliases may be used as well, e.g. `\p{AHex}`, although IMHO it’s more readable to stick to the canonical property names listed above.
+
+### Unsupported properties
+
+The abovementioned list of properties and values goes a long way towards fulfilling [UTR18 requirement RL2.7](http://unicode.org/reports/tr18/#RL2.7). However, the following properties are not currently supported:
+
+* `Age`
+* `Bidi_Class`
+* `Bidi_Mirroring_Glyph`
+* `Bidi_Paired_Bracket_Type`
+* `Bidi_Paired_Bracket`
+* `Block`
+* `Canonical_Combining_Class`
+* `Case_Folding`
+* `Decomposition_Mapping`
+* `Decomposition_Type`
+* `East_Asian_Width`
+* `Grapheme_Cluster_Break`
+* `Hangul_Syllable_Type`
+* `Joining_Group`
+* `Joining_Type`
+* `Line_Break`
+* `Lowercase_Mapping`
+* `Name` & `Name_Alias`
+* `NFC_Quick_Check`
+* `NFD_Quick_Check`
+* `NFKC_Casefold`
+* `NFKC_Quick_Check`
+* `NFKD_Quick_Check`
+* `Numeric_Type`
+* `Numeric_Value`
+* `Sentence_Break`
+* `Simple_Case_Folding`
+* `Simple_Lowercase_Mapping`
+* `Simple_Titlecase_Mapping`
+* `Simple_Uppercase_Mapping`
+* `Titlecase_Mapping`
+* `Uppercase_Mapping`
+* `Word_Break`
diff --git a/rewrite-pattern.js b/rewrite-pattern.js
new file mode 100644
index 0000000..380d4d3
--- /dev/null
+++ b/rewrite-pattern.js
@@ -0,0 +1,270 @@
+'use strict';
+
+const generate = require('regjsgen').generate;
+const parse = require('regjsparser').parse;
+const regenerate = require('regenerate');
+const unicodeMatchProperty = require('unicode-match-property-ecmascript');
+const unicodeMatchPropertyValue = require('unicode-match-property-value-ecmascript');
+const iuMappings = require('./data/iu-mappings.js');
+const ESCAPE_SETS = require('./data/character-class-escape-sets.js');
+
+// Prepare a Regenerate set containing all code points, used for negative
+// character classes (if any).
+const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
+// Without the `u` flag, the range stops at 0xFFFF.
+// https://mths.be/es6#sec-pattern-semantics
+const BMP_SET = regenerate().addRange(0x0, 0xFFFF);
+
+// Prepare a Regenerate set containing all code points that are supposed to be
+// matched by `/./u`. https://mths.be/es6#sec-atom
+const DOT_SET_UNICODE = UNICODE_SET.clone() // all Unicode code points
+ .remove(
+ // minus `LineTerminator`s (https://mths.be/es6#sec-line-terminators):
+ 0x000A, // Line Feed <LF>
+ 0x000D, // Carriage Return <CR>
+ 0x2028, // Line Separator <LS>
+ 0x2029 // Paragraph Separator <PS>
+ );
+// Prepare a Regenerate set containing all code points that are supposed to be
+// matched by `/./` (only BMP code points).
+const DOT_SET = DOT_SET_UNICODE.clone()
+ .intersection(BMP_SET);
+
+const getCharacterClassEscapeSet = (character, unicode, ignoreCase) => {
+ if (unicode) {
+ if (ignoreCase) {
+ return ESCAPE_SETS.UNICODE_IGNORE_CASE.get(character);
+ }
+ return ESCAPE_SETS.UNICODE.get(character);
+ }
+ return ESCAPE_SETS.REGULAR.get(character);
+};
+
+const getDotSet = (unicode, dotAll) => {
+ if (dotAll) {
+ return unicode ? UNICODE_SET : BMP_SET;
+ }
+ return unicode ? DOT_SET_UNICODE : DOT_SET;
+};
+
+const getUnicodePropertyValueSet = (property, value) => {
+ const path = value ?
+ `${ property }/${ value }` :
+ `Binary_Property/${ property }`;
+ try {
+ return require(`regenerate-unicode-properties/${ path }.js`);
+ } catch (exception) {
+ throw new Error(
+ `Failed to recognize value \`${ value }\` for property ` +
+ `\`${ property }\`.`
+ );
+ }
+};
+
+const handleLoneUnicodePropertyNameOrValue = (value) => {
+ // It could be a `General_Category` value or a binary property.
+ // Note: `unicodeMatchPropertyValue` throws on invalid values.
+ try {
+ const property = 'General_Category';
+ const category = unicodeMatchPropertyValue(property, value);
+ return getUnicodePropertyValueSet(property, category);
+ } catch (exception) {}
+ // It’s not a `General_Category` value, so check if it’s a binary
+ // property. Note: `unicodeMatchProperty` throws on invalid properties.
+ const property = unicodeMatchProperty(value);
+ return getUnicodePropertyValueSet(property);
+};
+
+const getUnicodePropertyEscapeSet = (value, isNegative) => {
+ const parts = value.split('=');
+ const firstPart = parts[0];
+ let set;
+ if (parts.length == 1) {
+ set = handleLoneUnicodePropertyNameOrValue(firstPart);
+ } else {
+ // The pattern consists of two parts, i.e. `Property=Value`.
+ const property = unicodeMatchProperty(firstPart);
+ const value = unicodeMatchPropertyValue(property, parts[1]);
+ set = getUnicodePropertyValueSet(property, value);
+ }
+ if (isNegative) {
+ return UNICODE_SET.clone().remove(set);
+ }
+ return set.clone();
+};
+
+// Given a range of code points, add any case-folded code points in that range
+// to a set.
+regenerate.prototype.iuAddRange = function(min, max) {
+ const $this = this;
+ do {
+ const folded = caseFold(min);
+ if (folded) {
+ $this.add(folded);
+ }
+ } while (++min <= max);
+ return $this;
+};
+
+const update = (item, pattern) => {
+ let tree = parse(pattern, config.useUnicodeFlag ? 'u' : '');
+ switch (tree.type) {
+ case 'characterClass':
+ case 'group':
+ case 'value':
+ // No wrapping needed.
+ break;
+ default:
+ // Wrap the pattern in a non-capturing group.
+ tree = wrap(tree, pattern);
+ }
+ Object.assign(item, tree);
+};
+
+const wrap = (tree, pattern) => {
+ // Wrap the pattern in a non-capturing group.
+ return {
+ 'type': 'group',
+ 'behavior': 'ignore',
+ 'body': [tree],
+ 'raw': `(?:${ pattern })`
+ };
+};
+
+const caseFold = (codePoint) => {
+ return iuMappings.get(codePoint) || false;
+};
+
+const processCharacterClass = (characterClassItem, regenerateOptions) => {
+ let set = regenerate();
+ for (const item of characterClassItem.body) {
+ switch (item.type) {
+ case 'value':
+ set.add(item.codePoint);
+ if (config.ignoreCase && config.unicode && !config.useUnicodeFlag) {
+ const folded = caseFold(item.codePoint);
+ if (folded) {
+ set.add(folded);
+ }
+ }
+ break;
+ case 'characterClassRange':
+ const min = item.min.codePoint;
+ const max = item.max.codePoint;
+ set.addRange(min, max);
+ if (config.ignoreCase && config.unicode && !config.useUnicodeFlag) {
+ set.iuAddRange(min, max);
+ }
+ break;
+ case 'characterClassEscape':
+ set.add(getCharacterClassEscapeSet(
+ item.value,
+ config.unicode,
+ config.ignoreCase
+ ));
+ break;
+ case 'unicodePropertyEscape':
+ set.add(getUnicodePropertyEscapeSet(item.value, item.negative));
+ break;
+ // The `default` clause is only here as a safeguard; it should never be
+ // reached. Code coverage tools should ignore it.
+ /* istanbul ignore next */
+ default:
+ throw new Error(`Unknown term type: ${ item.type }`);
+ }
+ }
+ if (characterClassItem.negative) {
+ set = (config.unicode ? UNICODE_SET : BMP_SET).clone().remove(set);
+ }
+ update(characterClassItem, set.toString(regenerateOptions));
+ return characterClassItem;
+};
+
+const processTerm = (item, regenerateOptions) => {
+ switch (item.type) {
+ case 'dot':
+ update(
+ item,
+ getDotSet(config.unicode, config.dotAll).toString(regenerateOptions)
+ );
+ break;
+ case 'characterClass':
+ item = processCharacterClass(item, regenerateOptions);
+ break;
+ case 'unicodePropertyEscape':
+ update(
+ item,
+ getUnicodePropertyEscapeSet(item.value, item.negative)
+ .toString(regenerateOptions)
+ );
+ break;
+ case 'characterClassEscape':
+ update(
+ item,
+ getCharacterClassEscapeSet(
+ item.value,
+ config.unicode,
+ config.ignoreCase
+ ).toString(regenerateOptions)
+ );
+ break;
+ case 'alternative':
+ case 'disjunction':
+ case 'group':
+ case 'quantifier':
+ item.body = item.body.map(term => {
+ return processTerm(term, regenerateOptions);
+ });
+ break;
+ case 'value':
+ const codePoint = item.codePoint;
+ const set = regenerate(codePoint);
+ if (config.ignoreCase && config.unicode && !config.useUnicodeFlag) {
+ const folded = caseFold(codePoint);
+ if (folded) {
+ set.add(folded);
+ }
+ }
+ update(item, set.toString(regenerateOptions));
+ break;
+ case 'anchor':
+ case 'empty':
+ case 'group':
+ case 'reference':
+ // Nothing to do here.
+ break;
+ // The `default` clause is only here as a safeguard; it should never be
+ // reached. Code coverage tools should ignore it.
+ /* istanbul ignore next */
+ default:
+ throw new Error(`Unknown term type: ${ item.type }`);
+ }
+ return item;
+};
+
+const config = {
+ 'ignoreCase': false,
+ 'unicode': false,
+ 'dotAll': false,
+ 'useUnicodeFlag': false
+};
+const rewritePattern = (pattern, flags, options) => {
+ const regjsparserFeatures = {
+ 'unicodePropertyEscape': options && options.unicodePropertyEscape
+ };
+ config.ignoreCase = flags && flags.includes('i');
+ config.unicode = flags && flags.includes('u');
+ const supportDotAllFlag = options && options.dotAllFlag;
+ config.dotAll = supportDotAllFlag && flags && flags.includes('s');
+ config.useUnicodeFlag = options && options.useUnicodeFlag;
+ const regenerateOptions = {
+ 'hasUnicodeFlag': config.useUnicodeFlag,
+ 'bmpOnly': !config.unicode
+ };
+ const tree = parse(pattern, flags, regjsparserFeatures);
+ // Note: `processTerm` mutates `tree`.
+ processTerm(tree, regenerateOptions);
+ return generate(tree);
+};
+
+module.exports = rewritePattern;
diff --git a/scripts/character-class-escape-sets.js b/scripts/character-class-escape-sets.js
new file mode 100644
index 0000000..1f4c21a
--- /dev/null
+++ b/scripts/character-class-escape-sets.js
@@ -0,0 +1,135 @@
+'use strict';
+
+const fs = require('fs');
+const jsesc = require('jsesc');
+const regenerate = require('regenerate');
+
+const Zs = require('unicode-10.0.0/General_Category/Space_Separator/code-points.js');
+
+const iuMappings = require('../data/iu-mappings.js');
+
+const caseFold = (codePoint) => {
+ return iuMappings.get(codePoint) || false;
+};
+
+// Prepare a Regenerate set containing all code points, used for negative
+// character classes (if any).
+const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
+// Without the `u` flag, the range stops at 0xFFFF.
+// https://mths.be/es#sec-pattern-semantics
+const BMP_SET = regenerate().addRange(0x0, 0xFFFF);
+
+const ESCAPE_CHARS = {};
+const ESCAPE_CHARS_UNICODE = {};
+const ESCAPE_CHARS_UNICODE_IGNORE_CASE = {};
+const addCharacterClassEscape = (lower, set) => {
+ ESCAPE_CHARS[lower] = ESCAPE_CHARS_UNICODE[lower] = set;
+ const upper = lower.toUpperCase();
+ ESCAPE_CHARS[upper] = BMP_SET.clone().remove(set);
+ ESCAPE_CHARS_UNICODE[upper] = UNICODE_SET.clone().remove(set);
+ // Check if one or more symbols in this set fold to another one. If so,
+ // a copy of the set including the mapped symbols is created for use with
+ // regular expressions that have both the `u` and `i` flags set.
+ const codePoints = set.toArray();
+ const iuSet = regenerate();
+ let containsFoldingSymbols = false;
+ for (const codePoint of codePoints) {
+ let folded = caseFold(codePoint);
+ if (folded) {
+ containsFoldingSymbols = true;
+ iuSet.add(folded);
+ folded = caseFold(folded);
+ if (folded) {
+ iuSet.add(folded);
+ }
+ }
+ }
+ const iuLowerSet = containsFoldingSymbols ?
+ iuSet.clone().add(set) :
+ set;
+ const iuUpperSet = UNICODE_SET.clone().remove(iuLowerSet);
+ ESCAPE_CHARS_UNICODE_IGNORE_CASE[lower] = iuLowerSet;
+ ESCAPE_CHARS_UNICODE_IGNORE_CASE[upper] = iuUpperSet;
+}
+
+// Prepare a Regenerate set for every existing character class escape.
+// https://mths.be/es#sec-characterclassescape
+addCharacterClassEscape(
+ 'd', // `\d` and `\D`
+ regenerate().addRange('0', '9')
+);
+addCharacterClassEscape(
+ 's', // `\s` and `\S`
+ regenerate(
+ // https://mths.be/es#sec-white-space
+ 0x0009,
+ 0x000B,
+ 0x000C,
+ 0x0020,
+ 0x00A0,
+ 0xFEFF,
+ Zs,
+ // https://mths.be/es#sec-line-terminators
+ 0x000A,
+ 0x000D,
+ 0x2028,
+ 0x2029
+ )
+);
+addCharacterClassEscape(
+ 'w', // `\w` and `\W`
+ regenerate('_').addRange('a', 'z').addRange('A', 'Z').addRange('0', '9')
+);
+
+/*----------------------------------------------------------------------------*/
+
+const codePointToString = (codePoint) => {
+ return '0x' + codePoint.toString(16).toUpperCase();
+};
+
+// Regenerate plugin that turns a set into some JavaScript source code that
+// generates that set.
+regenerate.prototype.toCode = function() {
+ const data = this.data;
+ // Iterate over the data per `(start, end)` pair.
+ let index = 0;
+ let start;
+ let end;
+ const length = data.length;
+ const loneCodePoints = [];
+ const ranges = [];
+ while (index < length) {
+ start = data[index];
+ end = data[index + 1] - 1; // Note: the `- 1` makes `end` inclusive.
+ if (start == end) {
+ loneCodePoints.push(codePointToString(start));
+ } else {
+ ranges.push(
+ 'addRange(' + codePointToString(start) +
+ ', ' + codePointToString(end) + ')'
+ );
+ }
+ index += 2;
+ }
+ return 'regenerate(' + loneCodePoints.join(', ') + ')' +
+ (ranges.length ? '\n\t\t.' + ranges.join('\n\t\t.') : '');
+};
+
+const stringify = (name, object) => {
+ const source = 'exports.' + name + ' = new Map([\n\t' + Object.keys(object).map((character) => {
+ const set = object[character];
+ return '[' + jsesc(character, { 'wrap': true }) + ', ' + set.toCode() + ']';
+ }).join(',\n\t') + '\n]);';
+ return source;
+};
+
+const source = [
+ '// Generated using `npm run build`. Do not edit.\n' +
+ `'use strict';\n\nconst regenerate = require('regenerate');`,
+ stringify('REGULAR', ESCAPE_CHARS),
+ stringify('UNICODE', ESCAPE_CHARS_UNICODE),
+ stringify('UNICODE_IGNORE_CASE', ESCAPE_CHARS_UNICODE_IGNORE_CASE)
+].join('\n\n');
+
+// Save the precompiled sets to a static file.
+fs.writeFileSync('data/character-class-escape-sets.js', source + '\n');
diff --git a/scripts/iu-mappings.js b/scripts/iu-mappings.js
new file mode 100644
index 0000000..a85852f
--- /dev/null
+++ b/scripts/iu-mappings.js
@@ -0,0 +1,179 @@
+'use strict';
+
+const fs = require('fs');
+const _ = require('lodash');
+const jsesc = require('jsesc');
+
+const hex = (number) => {
+ return `0x${ number.toString(16).toUpperCase() }`;
+};
+
+const writeMap = (fileName, map) => {
+ // Sort map by key.
+ const sortedMap = new Map([...map].sort((a, b) => a[0] - b[0]));
+ fs.writeFileSync(
+ fileName,
+ `module.exports = ${ jsesc(sortedMap, {
+ 'compact': false,
+ 'numbers': 'hexadecimal'
+ }) };\n`
+ );
+}
+
+// Given two code points, check if both are in the ASCII range and if one is
+// the uppercased version of the other. In that case, ES5 engines know about
+// this mapping, so it’s only needed to include one of the two in a
+// case-insensitive regular expression.
+const isES5CasedVariant = (a, b) => {
+ return (a < 0x80 && b < 0x80) &&
+ (oneWayMappings.get(a) == b || oneWayMappings.get(b) == a);
+};
+
+const extend = (map, key, value, callback) => {
+ if (map.has(key)) {
+ const currentValue = map.get(key);
+ if (Array.isArray(currentValue)) {
+ if (currentValue.indexOf(value) > -1) {
+ return;
+ }
+ if (callback) {
+ const skip = currentValue.some((codePoint) => {
+ return callback(codePoint, value);
+ });
+ if (skip) {
+ return;
+ }
+ }
+ currentValue.push(value);
+ } else {
+ if (currentValue == value) {
+ return;
+ }
+ if (callback) {
+ if (callback(currentValue, value)) {
+ return;
+ }
+ }
+ map.set(key, [currentValue, value]);
+ }
+ } else {
+ map.set(key, value);
+ }
+};
+
+// From <http://unicode.org/Public/UCD/latest/ucd/CaseFolding.txt>:
+//
+// The status field is:
+// C: common case folding, common mappings shared by both simple and full
+// mappings.
+// F: full case folding, mappings that cause strings to grow in length. Multiple
+// characters are separated by spaces.
+// S: simple case folding, mappings to single characters where different from F.
+// T: special case for uppercase I and dotted uppercase I
+// - For non-Turkic languages, this mapping is normally not used.
+// - For Turkic languages (tr, az), this mapping can be used instead of the
+// normal mapping for these characters. Note that the Turkic mappings do
+// not maintain canonical equivalence without additional processing.
+// See the discussions of case mapping in the Unicode Standard for more
+// information.
+//
+// Usage:
+// A. To do a simple case folding, use the mappings with status C + S.
+// B. To do a full case folding, use the mappings with status C + F.
+
+const commonMappings = require('unicode-10.0.0/Case_Folding/C/code-points.js');
+const simpleMappings = require('unicode-10.0.0/Case_Folding/S/code-points.js');
+
+// We want the `C` mappings in both directions (i.e. `A` should fold to `a`
+// and `a` to `A`), and the `S` mappings in both directions (i.e. `ẞ` should
+// fold to `ß` and `ß` to `ẞ`). Let’s start with the simple case folding (in
+// one direction) first, then filter the set, and then deal with the inverse.
+const oneWayMappings = new Map();
+for (const [from, to] of commonMappings) {
+ oneWayMappings.set(from, to);
+}
+for (const [from, to] of simpleMappings) {
+ oneWayMappings.set(from, to);
+}
+// Note: various code points can fold into the same code point, so it’s not
+// possible to simply invert `oneWayMappings` — some entries would be lost in
+// the process.
+
+// In case-insignificant matches when `Unicode` is `true` (i.e. when the `u`
+// flag is enabled), all characters are implicitly case-folded using the
+// simple mapping provided by the Unicode standard immediately before they
+// are compared. The simple mapping always maps to a single code point, so it
+// does not map, for example, `ß` (U+00DF) to `SS`. It may however map a code
+// point outside the Basic Latin range to a character within, for example, `ſ`
+// (U+017F) to `s`. Such characters are not mapped if `Unicode` is `false`.
+// This prevents Unicode code points such as U+017F and U+212A from matching
+// regular expressions such as `/[a‑z]/i`, but they will match `/[a‑z]/ui`.
+// https://mths.be/es6#sec-runtime-semantics-canonicalize-abstract-operation
+// Get the mappings that are unique to regular expressions that have both the
+// `i` and `u` flags set. In addition to the above, this includes all mappings
+// for astral code points.
+const filteredMappings = new Map();
+for (const [from, to] of oneWayMappings) {
+ // Case folding is applied to both the pattern and the string being matched.
+ // Because of that e.g. `/[A-Z]/iu` matches U+017F and U+212A, just like
+ // `/[a-z]/iu` would, even though no symbol in the range from `A` to `Z`
+ // folds to U+017F or U+212A directly. Since we’re only transpiling regular
+ // expressions and not strings, we have to account for this in regular
+ // expressions only. This can be done as per this example:
+ // 1. `oneWayMappings` already maps `S` to `s`. (83 → 115)
+ // 2. `oneWayMappings` already maps `ſ` to `s`. (383 → 115)
+ // 3. So, in the generated mappings, make sure `S` maps to `ſ`. (83 → 383)
+ // Check if there are any other code points that map to the same `to` value.
+ for (const [otherFrom, otherTo] of oneWayMappings) {
+ if (otherFrom != from && otherTo == to) {
+ // Note: we could use `extend` here, but it’s not necessary as there can
+ // only be a single value for the key `from` at this point.
+ filteredMappings.set(from, otherFrom);
+ }
+ }
+ if (
+ // Include astral code points.
+ (from > 0xFFFF || to > 0xFFFF) ||
+ // Exclude ES5 mappings as per the above comment.
+ // https://mths.be/es6#sec-runtime-semantics-canonicalize-abstract-operation
+ (
+ // TODO: Make this not depend on the engine in which this build script
+ // runs. (If V8 has a bug, then the generated data has the same bug.)
+ !RegExp(String.fromCodePoint(from), 'i').test(String.fromCodePoint(to))
+ )
+ ) {
+ extend(filteredMappings, from, to);
+ } else {
+ const stringFrom = String.fromCodePoint(from);
+ const stringTo = String.fromCodePoint(to);
+ const code = `/${
+ jsesc(stringFrom)
+ }/i.test(${
+ jsesc(stringTo, { 'wrap': true })
+ })`;
+ console.log(
+ `Skipping ${ hex(from) } → ${ hex(to) } since ${ code } is already \`true\`.`
+ );
+ // The following snippet was used to create https://mths.be/demo/regex-i.
+ // https://github.com/mathiasbynens/regexpu-core/issues/7#issuecomment-225894534
+ // console.log(
+ // `console.assert(${ code }, ${ JSON.stringify(code) });`
+ // );
+ }
+}
+
+// Create a new object containing all `filteredMappings` and their inverse.
+const iuMappings = new Map();
+for (const [from, to] of filteredMappings) {
+ if (Array.isArray(to)) {
+ for (const codePoint of to) {
+ extend(iuMappings, from, codePoint, isES5CasedVariant);
+ extend(iuMappings, codePoint, from, isES5CasedVariant);
+ }
+ } else {
+ extend(iuMappings, from, to, isES5CasedVariant);
+ extend(iuMappings, to, from, isES5CasedVariant);
+ }
+}
+
+writeMap('data/iu-mappings.js', iuMappings);
diff --git a/tests/tests.js b/tests/tests.js
new file mode 100644
index 0000000..66150ae
--- /dev/null
+++ b/tests/tests.js
@@ -0,0 +1,760 @@
+'use strict';
+
+const assert = require('assert');
+const regenerate = require('regenerate');
+const rewritePattern = require('../rewrite-pattern.js');
+const fixtures = require('regexpu-fixtures');
+
+const BMP_SET = regenerate().addRange(0x0, 0xFFFF);
+const BMP_PATTERN = BMP_SET.toString({ 'bmpOnly': true });
+const UNICODE_SET = regenerate().addRange(0x0, 0x10FFFF);
+const UNICODE_PATTERN = UNICODE_SET.toString();
+
+describe('rewritePattern', () => {
+ for (const fixture of fixtures) {
+ const pattern = fixture.pattern;
+ for (const flag of fixture.flags) {
+ it('rewrites `/' + pattern + '/' + flag + '` correctly', () => {
+ assert.equal(rewritePattern(pattern, flag), fixture.transpiled);
+ });
+ }
+ }
+});
+
+const unicodePropertyEscapeFixtures = [
+ // http://unicode.org/reports/tr18/#RL1.2 item 1
+ {
+ 'path': 'General_Category/Uppercase_Letter',
+ 'expressions': [
+ 'gc=Lu',
+ 'gc=Uppercase_Letter',
+ 'General_Category=Lu',
+ 'General_Category=Uppercase_Letter',
+ 'Lu',
+ 'Uppercase_Letter'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 2a
+ {
+ 'path': 'Script/Greek',
+ 'expressions': [
+ 'sc=Grek',
+ 'sc=Greek',
+ 'Script=Grek',
+ 'Script=Greek'
+ ]
+ },
+ {
+ 'path': 'Script/Hiragana',
+ 'expressions': [
+ 'sc=Hira',
+ 'sc=Hiragana',
+ 'Script=Hira',
+ 'Script=Hiragana'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 2b
+ {
+ 'path': 'Script_Extensions/Greek',
+ 'expressions': [
+ 'scx=Grek',
+ 'scx=Greek',
+ 'Script_Extensions=Grek',
+ 'Script_Extensions=Greek'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 3
+ {
+ 'path': 'Binary_Property/Alphabetic',
+ 'expressions': [
+ 'Alpha',
+ 'Alphabetic'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 4
+ {
+ 'path': 'Binary_Property/Uppercase',
+ 'expressions': [
+ 'Upper',
+ 'Uppercase'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 5
+ {
+ 'path': 'Binary_Property/Lowercase',
+ 'expressions': [
+ 'Lower',
+ 'Lowercase'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 6
+ {
+ 'path': 'Binary_Property/White_Space',
+ 'expressions': [
+ 'WSpace',
+ 'White_Space'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 7
+ {
+ 'path': 'Binary_Property/Noncharacter_Code_Point',
+ 'expressions': [
+ 'NChar',
+ 'Noncharacter_Code_Point'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 8
+ {
+ 'path': 'Binary_Property/Default_Ignorable_Code_Point',
+ 'expressions': [
+ 'DI',
+ 'Default_Ignorable_Code_Point'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 9a
+ {
+ 'path': 'Binary_Property/Any',
+ 'expressions': [
+ 'Any'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 9b
+ {
+ 'path': 'Binary_Property/ASCII',
+ 'expressions': [
+ 'ASCII'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL1.2 item 9c
+ {
+ 'path': 'Binary_Property/Assigned',
+ 'expressions': [
+ 'Assigned'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/ASCII_Hex_Digit',
+ 'expressions': [
+ 'ASCII_Hex_Digit',
+ 'AHex'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ // {
+ // 'path': 'Bidi_Class/Arabic_Letter',
+ // 'expressions': [
+ // 'bc=AL',
+ // 'bc=Arabic_Letter',
+ // 'Bidi_Class=AL',
+ // 'Bidi_Class=Arabic_Letter'
+ // ]
+ // },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Bidi_Control',
+ 'expressions': [
+ 'Bidi_C',
+ 'Bidi_Control'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ // {
+ // 'path': 'Block/Alphabetic_Presentation_Forms',
+ // 'expressions': [
+ // 'blk=Alphabetic_PF',
+ // 'blk=Alphabetic_Presentation_Forms',
+ // 'Block=Alphabetic_PF',
+ // 'Block=Alphabetic_Presentation_Forms'
+ // ]
+ // },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Bidi_Mirrored',
+ 'expressions': [
+ 'Bidi_M',
+ 'Bidi_Mirrored'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Case_Ignorable',
+ 'expressions': [
+ 'CI',
+ 'Case_Ignorable',
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Cased',
+ 'expressions': [
+ 'Cased'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Changes_When_NFKC_Casefolded',
+ 'expressions': [
+ 'CWKCF',
+ 'Changes_When_NFKC_Casefolded'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Changes_When_Casefolded',
+ 'expressions': [
+ 'CWCF',
+ 'Changes_When_Casefolded'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Changes_When_Casemapped',
+ 'expressions': [
+ 'CWCM',
+ 'Changes_When_Casemapped'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Changes_When_Lowercased',
+ 'expressions': [
+ 'CWL',
+ 'Changes_When_Lowercased'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Changes_When_Titlecased',
+ 'expressions': [
+ 'CWT',
+ 'Changes_When_Titlecased'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Changes_When_Uppercased',
+ 'expressions': [
+ 'CWU',
+ 'Changes_When_Uppercased'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Dash',
+ 'expressions': [
+ 'Dash'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Deprecated',
+ 'expressions': [
+ 'Dep',
+ 'Deprecated'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Diacritic',
+ 'expressions': [
+ 'Dia',
+ 'Diacritic'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Extender',
+ 'expressions': [
+ 'Ext',
+ 'Extender'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Grapheme_Base',
+ 'expressions': [
+ 'Gr_Base',
+ 'Grapheme_Base'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Grapheme_Extend',
+ 'expressions': [
+ 'Gr_Ext',
+ 'Grapheme_Extend'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Hex_Digit',
+ 'expressions': [
+ 'Hex',
+ 'Hex_Digit'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/ID_Continue',
+ 'expressions': [
+ 'IDC',
+ 'ID_Continue'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/ID_Start',
+ 'expressions': [
+ 'IDS',
+ 'ID_Start'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Ideographic',
+ 'expressions': [
+ 'Ideo',
+ 'Ideographic'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/IDS_Binary_Operator',
+ 'expressions': [
+ 'IDSB',
+ 'IDS_Binary_Operator'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/IDS_Trinary_Operator',
+ 'expressions': [
+ 'IDST',
+ 'IDS_Trinary_Operator'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Join_Control',
+ 'expressions': [
+ 'Join_C',
+ 'Join_Control'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Logical_Order_Exception',
+ 'expressions': [
+ 'LOE',
+ 'Logical_Order_Exception'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Math',
+ 'expressions': [
+ 'Math'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Pattern_Syntax',
+ 'expressions': [
+ 'Pat_Syn',
+ 'Pattern_Syntax'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Pattern_White_Space',
+ 'expressions': [
+ 'Pat_WS',
+ 'Pattern_White_Space'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Quotation_Mark',
+ 'expressions': [
+ 'QMark',
+ 'Quotation_Mark'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Radical',
+ 'expressions': [
+ 'Radical'
+ ]
+ },
+ {
+ 'path': 'Binary_Property/Regional_Indicator',
+ 'expressions': [
+ 'RI',
+ 'Regional_Indicator'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Soft_Dotted',
+ 'expressions': [
+ 'SD',
+ 'Soft_Dotted'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Sentence_Terminal',
+ 'expressions': [
+ 'STerm',
+ 'Sentence_Terminal'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Terminal_Punctuation',
+ 'expressions': [
+ 'Term',
+ 'Terminal_Punctuation'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Unified_Ideograph',
+ 'expressions': [
+ 'UIdeo',
+ 'Unified_Ideograph'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/Variation_Selector',
+ 'expressions': [
+ 'VS',
+ 'Variation_Selector'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/XID_Continue',
+ 'expressions': [
+ 'XIDC',
+ 'XID_Continue'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ {
+ 'path': 'Binary_Property/XID_Start',
+ 'expressions': [
+ 'XIDS',
+ 'XID_Start'
+ ]
+ },
+ // http://unicode.org/reports/tr18/#RL2.7
+ // {
+ // 'path': 'Bidi_Paired_Bracket_Type/Open',
+ // 'expressions': [
+ // 'bpt=o',
+ // 'bpt=Open',
+ // 'Bidi_Paired_Bracket_Type=o',
+ // 'Bidi_Paired_Bracket_Type=Open'
+ // ]
+ // },
+ // {
+ // 'path': 'Block/Superscripts_And_Subscripts',
+ // 'expressions': [
+ // 'blk=Super_And_Sub',
+ // 'blk=Superscripts_And_Subscripts',
+ // 'Block=Super_And_Sub',
+ // 'Block=Superscripts_And_Subscripts'
+ // ]
+ // },
+ // http://unicode.org/reports/tr51/
+ {
+ 'path': 'Emoji',
+ 'expressions': [
+ 'Emoji'
+ ]
+ },
+ // http://unicode.org/reports/tr51/
+ {
+ 'path': 'Emoji_Component',
+ 'expressions': [
+ 'Emoji_Component'
+ ]
+ },
+ // http://unicode.org/reports/tr51/
+ {
+ 'path': 'Emoji_Modifier',
+ 'expressions': [
+ 'Emoji_Modifier'
+ ]
+ },
+ // http://unicode.org/reports/tr51/
+ {
+ 'path': 'Emoji_Modifier_Base',
+ 'expressions': [
+ 'Emoji_Modifier_Base'
+ ]
+ },
+ // http://unicode.org/reports/tr51/
+ {
+ 'path': 'Emoji_Presentation',
+ 'expressions': [
+ 'Emoji_Presentation'
+ ]
+ },
+ // http://unicode.org/reports/tr51/proposed.html
+ {
+ 'path': 'Extended_Pictographic',
+ 'expressions': [
+ 'Extended_Pictographic'
+ ]
+ },
+];
+
+const getPropertyValuePattern = (path) => {
+ const codePoints =
+ (path == 'Extended_Pictographic' || path.startsWith('Emoji')) ?
+ require(`unicode-tr51/${ path }.js`) :
+ require(`unicode-10.0.0/${ path }/code-points.js`);
+ return {
+ 'p': regenerate(codePoints).toString(),
+ 'P': UNICODE_SET.clone().remove(codePoints).toString()
+ };
+};
+
+describe('unicodePropertyEscapes', () => {
+ const features = {
+ 'unicodePropertyEscape': true
+ };
+ for (const fixture of unicodePropertyEscapeFixtures) {
+ const expected = getPropertyValuePattern(fixture.path);
+ for (const pattern of fixture.expressions) {
+ const p = `\\p{${ pattern }}`;
+ it('rewrites `/' + p + '/u` correctly', () => {
+ const transpiled = rewritePattern(p, 'u', features);
+ assert(
+ transpiled == expected.p ||
+ transpiled == '(?:' + expected.p + ')'
+ );
+ });
+ const P = `\\P{${ pattern }}`;
+ it('rewrites `/' + P + '/u` correctly', () => {
+ const transpiled = rewritePattern(P, 'u', features);
+ assert(
+ transpiled == expected.P ||
+ transpiled == '(?:' + expected.P + ')'
+ );
+ });
+ }
+ }
+ it('transpiles Unicode property escapes within various constructions', () => {
+ assert.equal(
+ rewritePattern('\\p{ASCII_Hex_Digit}', 'u', features),
+ '[0-9A-Fa-f]'
+ );
+ assert.equal(
+ rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', features),
+ '(?:\\uD811[\\uDC00-\\uDE46])'
+ );
+ assert.equal(
+ rewritePattern('\\p{ASCII_Hex_Digit}+', 'u', features),
+ '[0-9A-Fa-f]+'
+ );
+ assert.equal(
+ rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}+', 'u', features),
+ '(?:\\uD811[\\uDC00-\\uDE46])+'
+ );
+ assert.equal(
+ rewritePattern('[\\p{ASCII_Hex_Digit}_]', 'u', features),
+ '[0-9A-F_a-f]'
+ );
+ assert.equal(
+ rewritePattern('[\\P{Script_Extensions=Anatolian_Hieroglyphs}]', 'u', features),
+ '(?:[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uD810\\uD812-\\uDBFF][\\uDC00-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])'
+ );
+ assert.equal(
+ rewritePattern('[\\p{Script_Extensions=Anatolian_Hieroglyphs}_]', 'u', features),
+ '(?:_|\\uD811[\\uDC00-\\uDE46])'
+ );
+ assert.equal(
+ rewritePattern('[\\P{Script_Extensions=Anatolian_Hieroglyphs}_]', 'u', features),
+ '(?:[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uD810\\uD812-\\uDBFF][\\uDC00-\\uDFFF]|\\uD811[\\uDE47-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])'
+ );
+ assert.equal(
+ rewritePattern('(?:\\p{ASCII_Hex_Digit})', 'u', features),
+ '(?:[0-9A-Fa-f])'
+ );
+ assert.equal(
+ rewritePattern('(?:\\p{Script_Extensions=Anatolian_Hieroglyphs})', 'u', features),
+ '(?:(?:\\uD811[\\uDC00-\\uDE46]))'
+ );
+ });
+ it('throws without the `u` flag', () => {
+ assert.throws(() => {
+ rewritePattern('\\p{ASCII_Hex_Digit}', '', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{ASCII_Hex_Digit}', '', features);
+ }, Error);
+ });
+ it('throws without the `unicodePropertyEscape` feature enabled', () => {
+ assert.throws(() => {
+ rewritePattern('\\p{ASCII_Hex_Digit}', 'u');
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{ASCII_Hex_Digit}', 'u');
+ }, Error);
+ });
+ it('throws on unknown binary properties', () => {
+ assert.throws(() => {
+ rewritePattern('\\p{UnknownBinaryProperty}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{UnknownBinaryProperty}', 'u', features);
+ }, Error);
+ });
+ it('throws on explicitly unsupported properties', () => {
+ // https://github.com/tc39/proposal-regexp-unicode-property-escapes/issues/27
+ assert.throws(() => {
+ rewritePattern('\\P{Composition_Exclusion}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\p{Expands_On_NFC}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\p{Expands_On_NFD}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\p{Expands_On_NFKC}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\p{Expands_On_NFKD}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\p{FC_NFKC_Closure}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\p{Full_Composition_Exclusion}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Grapheme_Link}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Hyphen}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_Alphabetic}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_Default_Ignorable_Code_Point}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_Grapheme_Extend}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_ID_Continue}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_ID_Start}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_Lowercase}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_Math}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Other_Uppercase}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{Prepended_Concatenation_Mark}', 'u', features);
+ }, Error);
+ });
+ it('throws on non-binary properties without a value', () => {
+ assert.throws(() => {
+ rewritePattern('\\p{General_Category}', 'u', features);
+ }, Error);
+ });
+ it('throws on unknown property values', () => {
+ assert.throws(() => {
+ rewritePattern('\\p{General_Category=UnknownCategory}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{General_Category=UnknownCategory}', 'u', features);
+ }, Error);
+ });
+ it('throws when loose matching is attempted', () => {
+ assert.throws(() => {
+ rewritePattern('\\p{gc=uppercaseletter}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\p{Block=Superscripts and Subscripts}', 'u', features);
+ }, Error);
+ assert.throws(() => {
+ rewritePattern('\\P{_-_lOwEr_C-A_S-E_-_}', 'u', features);
+ }, Error);
+ });
+ it('simplifies the output using Unicode code point escapes when `useUnicodeFlag` is enabled', () => {
+ assert.equal(
+ rewritePattern('\\p{Script_Extensions=Anatolian_Hieroglyphs}', 'u', {
+ 'unicodePropertyEscape': true,
+ 'useUnicodeFlag': true
+ }),
+ '[\\u{14400}-\\u{14646}]'
+ );
+ });
+ assert.equal(
+ rewritePattern('\u03B8', 'iu'),
+ '[\\u03B8\\u03F4]'
+ );
+ assert.equal(
+ rewritePattern('\u03B8', 'iu', {
+ 'useUnicodeFlag': true
+ }),
+ '\\u03B8'
+ );
+});
+
+const dotAllFlagFixtures = [
+ {
+ 'pattern': '.',
+ 'flags': 's',
+ 'expected': BMP_PATTERN
+ },
+ {
+ 'pattern': '.',
+ 'flags': 'gimsy',
+ 'expected': BMP_PATTERN
+ },
+ {
+ 'pattern': '.',
+ 'flags': 'su',
+ 'expected': UNICODE_PATTERN
+ },
+ {
+ 'pattern': '.',
+ 'flags': 'gimsuy',
+ 'expected': UNICODE_PATTERN
+ }
+];
+
+describe('dotAllFlag', () => {
+ const features = {
+ 'dotAllFlag': true
+ };
+ for (const fixture of dotAllFlagFixtures) {
+ const pattern = fixture.pattern;
+ const flags = fixture.flags;
+ it('rewrites `/' + pattern + '/' + flags + '` correctly', () => {
+ const transpiled = rewritePattern(pattern, flags, features);
+ const expected = fixture.expected;
+ assert(
+ transpiled == expected ||
+ transpiled == '(?:' + expected + ')'
+ );
+ });
+ }
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-regexpu-core.git
More information about the Pkg-javascript-commits
mailing list