[Pkg-javascript-commits] [node-to-regex-range] 02/07: New upstream version 3.0.0

Julien Puydt julien.puydt at laposte.net
Sat Nov 25 16:46:26 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-to-regex-range.

commit f2c1225919e45c16fc8481391d64e26584f1a73e
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Sat Nov 25 17:21:46 2017 +0100

    New upstream version 3.0.0
---
 .editorconfig         |  13 ---
 .eslintrc.json        | 122 ----------------------
 .gitattributes        |  10 --
 .gitignore            |  21 ----
 .travis.yml           |  12 ---
 .verb.md              |  41 --------
 LICENSE               |   2 +-
 README.md             | 276 ++++++++++++++++++++++++++++++++++++++++++--------
 bower.json            |  38 -------
 example.js            |  17 ----
 index.js              | 258 +++++++++++++++++++++++++++++-----------------
 package.json          |  36 +++++--
 test/support/index.js |  14 ---
 test/test.js          | 174 -------------------------------
 14 files changed, 424 insertions(+), 610 deletions(-)

diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 818e072..0000000
--- a/.editorconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-end_of_line = lf
-charset = utf-8
-indent_size = 2
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[{**/{actual,fixtures,expected,templates}/**,*.md}]
-trim_trailing_whitespace = false
-insert_final_newline = false
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index 948dbdb..0000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,122 +0,0 @@
-{
-  "ecmaFeatures": {
-    "modules": true,
-    "experimentalObjectRestSpread": true
-  },
-
-  "env": {
-    "browser": false,
-    "es6": true,
-    "node": true,
-    "mocha": true
-  },
-
-  "globals": {
-    "document": false,
-    "navigator": false,
-    "window": false
-  },
-
-  "rules": {
-    "accessor-pairs": 2,
-    "arrow-spacing": [2, { "before": true, "after": true }],
-    "block-spacing": [2, "always"],
-    "brace-style": [2, "1tbs", { "allowSingleLine": true }],
-    "comma-dangle": [2, "never"],
-    "comma-spacing": [2, { "before": false, "after": true }],
-    "comma-style": [2, "last"],
-    "constructor-super": 2,
-    "curly": [2, "multi-line"],
-    "dot-location": [2, "property"],
-    "eol-last": 2,
-    "eqeqeq": [2, "allow-null"],
-    "generator-star-spacing": [2, { "before": true, "after": true }],
-    "handle-callback-err": [2, "^(err|error)$" ],
-    "indent": [2, 2, { "SwitchCase": 1 }],
-    "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
-    "keyword-spacing": [2, { "before": true, "after": true }],
-    "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
-    "new-parens": 2,
-    "no-array-constructor": 2,
-    "no-caller": 2,
-    "no-class-assign": 2,
-    "no-cond-assign": 2,
-    "no-const-assign": 2,
-    "no-control-regex": 2,
-    "no-debugger": 2,
-    "no-delete-var": 2,
-    "no-dupe-args": 2,
-    "no-dupe-class-members": 2,
-    "no-dupe-keys": 2,
-    "no-duplicate-case": 2,
-    "no-empty-character-class": 2,
-    "no-eval": 2,
-    "no-ex-assign": 2,
-    "no-extend-native": 2,
-    "no-extra-bind": 2,
-    "no-extra-boolean-cast": 2,
-    "no-extra-parens": [2, "functions"],
-    "no-fallthrough": 2,
-    "no-floating-decimal": 2,
-    "no-func-assign": 2,
-    "no-implied-eval": 2,
-    "no-inner-declarations": [2, "functions"],
-    "no-invalid-regexp": 2,
-    "no-irregular-whitespace": 2,
-    "no-iterator": 2,
-    "no-label-var": 2,
-    "no-labels": 2,
-    "no-lone-blocks": 2,
-    "no-mixed-spaces-and-tabs": 2,
-    "no-multi-spaces": 2,
-    "no-multi-str": 2,
-    "no-multiple-empty-lines": [2, { "max": 1 }],
-    "no-native-reassign": 0,
-    "no-negated-in-lhs": 2,
-    "no-new": 2,
-    "no-new-func": 2,
-    "no-new-object": 2,
-    "no-new-require": 2,
-    "no-new-wrappers": 2,
-    "no-obj-calls": 2,
-    "no-octal": 2,
-    "no-octal-escape": 2,
-    "no-proto": 0,
-    "no-redeclare": 2,
-    "no-regex-spaces": 2,
-    "no-return-assign": 2,
-    "no-self-compare": 2,
-    "no-sequences": 2,
-    "no-shadow-restricted-names": 2,
-    "no-spaced-func": 2,
-    "no-sparse-arrays": 2,
-    "no-this-before-super": 2,
-    "no-throw-literal": 2,
-    "no-trailing-spaces": 0,
-    "no-undef": 2,
-    "no-undef-init": 2,
-    "no-unexpected-multiline": 2,
-    "no-unneeded-ternary": [2, { "defaultAssignment": false }],
-    "no-unreachable": 2,
-    "no-unused-vars": [2, { "vars": "all", "args": "none" }],
-    "no-useless-call": 0,
-    "no-with": 2,
-    "one-var": [0, { "initialized": "never" }],
-    "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }],
-    "padded-blocks": [0, "never"],
-    "quotes": [2, "single", "avoid-escape"],
-    "radix": 2,
-    "semi": [2, "always"],
-    "semi-spacing": [2, { "before": false, "after": true }],
-    "space-before-blocks": [2, "always"],
-    "space-before-function-paren": [2, "never"],
-    "space-in-parens": [2, "never"],
-    "space-infix-ops": 2,
-    "space-unary-ops": [2, { "words": true, "nonwords": false }],
-    "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
-    "use-isnan": 2,
-    "valid-typeof": 2,
-    "wrap-iife": [2, "any"],
-    "yoda": [2, "never"]
-  }
-}
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index 660957e..0000000
--- a/.gitattributes
+++ /dev/null
@@ -1,10 +0,0 @@
-# Enforce Unix newlines
-* text eol=lf
-
-# binaries
-*.ai binary
-*.psd binary
-*.jpg binary
-*.gif binary
-*.png binary
-*.jpeg binary
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 7988154..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,21 +0,0 @@
-# always ignore files
-*.DS_Store
-*.sublime-*
-
-# test related, or directories generated by tests
-test/actual
-actual
-coverage
-
-# npm
-node_modules
-npm-debug.log
-
-# misc
-_gh_pages
-benchmark
-bower_components
-vendor
-temp
-tmp
-TODO.md
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 04a029e..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-sudo: false
-language: node_js
-node_js:
-  - node
-  - '6'
-  - '5'
-  - '0.12'
-matrix:
-  fast_finish: true
-  allow_failures:
-    - node_js: '4'
-    - node_js: '0.12'
diff --git a/.verb.md b/.verb.md
deleted file mode 100644
index 3bd4294..0000000
--- a/.verb.md
+++ /dev/null
@@ -1,41 +0,0 @@
-## Bower
-
-{%= include("install-bower", {save: true}) %}
-
-## Notes
-
-Inspired by the python lib [range-regex](https://github.com/dimka665/range-regex), it has never been easier to validate numbers and number ranges with regex!
-
-The [unit tests generate 850,000 patterns](./test/test.js) to provide brute-force validation that the generated regex-ranges are correct.
-
-## Usage
-
-```js
-var toRegexRange = require('{%= name %}');
-
-var re = new RegExp(toRegexRange('1', '99'));
-re.test('50');
-//=> true
-```
-
-**Examples**
-
-```js
-toRegexRange('111', '555');
-//=> '11[1-9]|1[2-9]\d|[2-4]\d{2}|5[0-4]\d|55[0-5]'
-toRegexRange('5', '5');
-//=> '5'
-toRegexRange('5', '6');
-//=> '[5-6]'
-toRegexRange('51', '229');
-//=> '5[1-9]|[6-9]\d|1\d{2}|2[0-2]\d'
-```
-
-When the `min` is larger than the `max`, a regex logical `or` is returned:
-
-```js
-toRegexRange('51', '29');
-//=> '51|29'
-```
-
-Currently this does not support steps (increments) or zero-padding.
diff --git a/LICENSE b/LICENSE
index 1e49edf..e33d14b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015-2016, Jon Schlinkert.
+Copyright (c) 2015-2017, Jon Schlinkert.
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index a414318..c1de879 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
-# to-regex-range [![NPM version](https://img.shields.io/npm/v/to-regex-range.svg?style=flat)](https://www.npmjs.com/package/to-regex-range) [![NPM downloads](https://img.shields.io/npm/dm/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![Build Status](https://img.shields.io/travis/jonschlinkert/to-regex-range.svg?style=flat)](https://travis-ci.org/jonschlinkert/to-regex-range)
+# to-regex-range [![NPM version](https://img.shields.io/npm/v/to-regex-range.svg?style=flat)](https://www.npmjs.com/package/to-regex-range) [![NPM monthly downloads](https://img.shields.io/npm/dm/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![NPM total downloads](https://img.shields.io/npm/dt/to-regex-range.svg?style=flat)](https://npmjs.org/package/to-regex-range) [![Linux Build Status](https://img.shields.io/travis/micromatch/to-regex-range.svg?style=flat& [...]
 
-> Returns a regex-compatible range from two numbers, min and max, with 855,412 generated unit tests to validate it's accuracy! Useful for creating regular expressions to validate numbers, ranges, years, etc. Returns a string, allowing the returned value to be used in regular expressions generated by other libraries.
+> Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions.
+
+Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
 
 ## Install
 
@@ -10,96 +12,284 @@ Install with [npm](https://www.npmjs.com/):
 $ npm install --save to-regex-range
 ```
 
-## Bower
+<details>
+<summary><strong>What does this do?</strong></summary>
 
-Install with [bower](http://bower.io/)
+<br>
 
-```sh
-$ bower install to-regex-range --save
+This libary generates the `source` string to be passed to `new RegExp()` for matching a range of numbers.
+
+**Example**
+
+```js
+var toRegexRange = require('to-regex-range');
+var regex = new RegExp(toRegexRange('15', '95'));
 ```
 
-## Notes
+A string is returned so that you can do whatever you need with it before passing it to `new RegExp()` (like adding `^` or `$` boundaries, defining flags, or combining it another string).
+
+<br>
+
+</details>
+
+<details>
+<summary><strong>Why use this library?</strong></summary>
+
+<br>
+
+### Convenience
+
+Creating regular expressions for matching numbers gets deceptively complicated pretty fast.
+
+For example, let's say you need a validation regex for matching part of a user-id, postal code, social security number, tax id, etc:
+
+* regex for matching `1` => `/1/` (easy enough)
+* regex for matching `1` through `5` => `/[1-5]/` (not bad...)
+* regex for matching `1` or `5` => `/(1|5)/` (still easy...)
+* regex for matching `1` through `50` => `/([1-9]|[1-4][0-9]|50)/` (uh-oh...)
+* regex for matching `1` through `55` => `/([1-9]|[1-4][0-9]|5[0-5])/` (no prob, I can do this...)
+* regex for matching `1` through `555` => `/([1-9]|[1-9][0-9]|[1-4][0-9]{2}|5[0-4][0-9]|55[0-5])/` (maybe not...)
+* regex for matching `0001` through `5555` => `/(0{3}[1-9]|0{2}[1-9][0-9]|0[1-9][0-9]{2}|[1-4][0-9]{3}|5[0-4][0-9]{2}|55[0-4][0-9]|555[0-5])/` (okay, I get the point!)
+
+The numbers are contrived, but they're also really basic. In the real world you might need to generate a regex on-the-fly for validation.
+
+**Learn more**
+
+If you're interested in learning more about [character classes](http://www.regular-expressions.info/charclass.html) and other regex features, I personally have always found [regular-expressions.info](http://www.regular-expressions.info/charclass.html) to be pretty useful.
+
+### Heavily tested
+
+As of November 01, 2017, this library runs [2,783,483 test assertions](./test/test.js) against generated regex-ranges to provide brute-force verification that results are indeed correct.
+
+Tests run in ~870ms on my MacBook Pro, 2.5 GHz Intel Core i7.
+
+### Highly optimized
+
+Generated regular expressions are highly optimized:
+
+* duplicate sequences and character classes are reduced using quantifiers
+* smart enough to use `?` conditionals when number(s) or range(s) can be positive or negative
+* uses fragment caching to avoid processing the same exact string more than once
 
-Inspired by the python lib [range-regex](https://github.com/dimka665/range-regex), it has never been easier to validate numbers and number ranges with regex!
+<br>
 
-The [unit tests generate 850,000 patterns](./test/test.js) to provide brute-force validation that the generated regex-ranges are correct.
+</details>
 
 ## Usage
 
+Add this library to your javascript application with the following line of code
+
 ```js
 var toRegexRange = require('to-regex-range');
+```
+
+The main export is a function that takes two integers: the `min` value and `max` value (formatted as strings or numbers).
+
+```js
+var source = toRegexRange('15', '95');
+//=> 1[5-9]|[2-8][0-9]|9[0-5]
+
+var re = new RegExp('^' + source + '$');
+console.log(re.test('14')); //=> false
+console.log(re.test('50')); //=> true
+console.log(re.test('94')); //=> true
+console.log(re.test('96')); //=> false
+```
+
+## Options
+
+### options.capture
+
+**Type**: `boolean`
+
+**Deafault**: `undefined`
+
+Wrap the returned value in parentheses when there is more than one regex condition. Useful when you're dynamically generating ranges.
+
+```js
+console.log(toRegexRange('-10', '10'));
+//=> -[1-9]|-?10|[0-9]
+
+console.log(toRegexRange('-10', '10', {capture: true}));
+//=> (-[1-9]|-?10|[0-9])
+```
+
+### options.shorthand
+
+**Type**: `boolean`
+
+**Deafault**: `undefined`
+
+Use the regex shorthand for `[0-9]`:
+
+```js
+console.log(toRegexRange('0', '999999'));
+//=> [0-9]|[1-9][0-9]{1,5}
+
+console.log(toRegexRange('0', '999999', {shorthand: true}));
+//=> \d|[1-9]\d{1,5}
+```
+
+### options.relaxZeros
+
+**Type**: `boolean`
+
+**Default**: `true`
+
+This option only applies to **negative zero-padded ranges**. By default, when a negative zero-padded range is defined, the number of leading zeros is relaxed using `-0*`.
+
+```js
+console.log(toRegexRange('-001', '100'));
+//=> -0*1|0{2}[0-9]|0[1-9][0-9]|100
 
-var re = new RegExp(toRegexRange('1', '99'));
-re.test('50');
-//=> true
+console.log(toRegexRange('-001', '100', {relaxZeros: false}));
+//=> -0{2}1|0{2}[0-9]|0[1-9][0-9]|100
 ```
 
-**Examples**
+<details>
+<summary><strong>Why are zeros relaxed for negative zero-padded ranges by default?</strong></summary>
+
+Consider the following.
 
 ```js
-toRegexRange('111', '555');
-//=> '11[1-9]|1[2-9]\d|[2-4]\d{2}|5[0-4]\d|55[0-5]'
-toRegexRange('5', '5');
-//=> '5'
-toRegexRange('5', '6');
-//=> '[5-6]'
-toRegexRange('51', '229');
-//=> '5[1-9]|[6-9]\d|1\d{2}|2[0-2]\d'
+var regex = toRegexRange('-001', '100');
 ```
 
-When the `min` is larger than the `max`, a regex logical `or` is returned:
+_Note that `-001` and `100` are both three digits long_.
+
+In most zero-padding implementations, only a single leading zero is enough to indicate that zero-padding should be applied. Thus, the leading zeros would be "corrected" on the negative range in the example to `-01`, instead of `-001`, to make total length of each string no greater than the length of the largest number in the range (in other words, `-001` is 4 digits, but `100` is only three digits).
+
+If zeros were not relaxed by default, you might expect the resulting regex of the above pattern to match `-001` - given that it's defined that way in the arguments - _but it wouldn't_. It would, however, match `-01`. This gets even more ambiguous with large ranges, like `-01` to `1000000`.
+
+Thus, we relax zeros by default to provide a more predictable experience for users.
+
+</details>
+
+## Examples
+
+| **Range** | **Result** | **Compile time** | 
+| --- | --- | --- |
+| `toRegexRange('5, 5')` | `5` | _33μs_ |
+| `toRegexRange('5, 6')` | `5\|6` | _53μs_ |
+| `toRegexRange('29, 51')` | `29\|[34][0-9]\|5[01]` | _699μs_ |
+| `toRegexRange('31, 877')` | `3[1-9]\|[4-9][0-9]\|[1-7][0-9]{2}\|8[0-6][0-9]\|87[0-7]` | _711μs_ |
+| `toRegexRange('111, 555')` | `11[1-9]\|1[2-9][0-9]\|[2-4][0-9]{2}\|5[0-4][0-9]\|55[0-5]` | _62μs_ |
+| `toRegexRange('-10, 10')` | `-[1-9]\|-?10\|[0-9]` | _74μs_ |
+| `toRegexRange('-100, -10')` | `-1[0-9]\|-[2-9][0-9]\|-100` | _49μs_ |
+| `toRegexRange('-100, 100')` | `-[1-9]\|-?[1-9][0-9]\|-?100\|[0-9]` | _45μs_ |
+| `toRegexRange('001, 100')` | `0{2}[1-9]\|0[1-9][0-9]\|100` | _158μs_ |
+| `toRegexRange('0010, 1000')` | `0{2}1[0-9]\|0{2}[2-9][0-9]\|0[1-9][0-9]{2}\|1000` | _61μs_ |
+| `toRegexRange('1, 2')` | `1\|2` | _10μs_ |
+| `toRegexRange('1, 5')` | `[1-5]` | _24μs_ |
+| `toRegexRange('1, 10')` | `[1-9]\|10` | _23μs_ |
+| `toRegexRange('1, 100')` | `[1-9]\|[1-9][0-9]\|100` | _30μs_ |
+| `toRegexRange('1, 1000')` | `[1-9]\|[1-9][0-9]{1,2}\|1000` | _52μs_ |
+| `toRegexRange('1, 10000')` | `[1-9]\|[1-9][0-9]{1,3}\|10000` | _47μs_ |
+| `toRegexRange('1, 100000')` | `[1-9]\|[1-9][0-9]{1,4}\|100000` | _44μs_ |
+| `toRegexRange('1, 1000000')` | `[1-9]\|[1-9][0-9]{1,5}\|1000000` | _49μs_ |
+| `toRegexRange('1, 10000000')` | `[1-9]\|[1-9][0-9]{1,6}\|10000000` | _63μs_ |
+
+## Heads up!
+
+**Order of arguments**
+
+When the `min` is larger than the `max`, values will be flipped to create a valid range:
 
 ```js
 toRegexRange('51', '29');
-//=> '51|29'
 ```
 
-Currently this does not support steps (increments) or zero-padding.
+Is effectively flipped to:
 
-## About
+```js
+toRegexRange('29', '51');
+//=> 29|[3-4][0-9]|5[0-1]
+```
 
-### Related projects
+**Steps / increments**
 
-* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://github.com/jonschlinkert/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.")
-* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to… [more](https://github.com/jonschlinkert/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range "Fill in a range of numbers or letters, optionally passing an increment or multiplier to use.")
-* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/jonschlinkert/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.")
-* [repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.")
-* [repeat-string](https://www.npmjs.com/package/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string. | [homepage](https://github.com/jonschlinkert/repeat-string "Repeat the given string n times. Fastest implementation for repeating a string.")
+This library does not support steps (increments). A pr to add support would be welcome.
 
-### Contributing
+## History
+
+### v2.0.0 - 2017-04-21
+
+**New features**
+
+Adds support for zero-padding!
+
+### v1.0.0
+
+**Optimizations**
+
+Repeating ranges are now grouped using quantifiers. rocessing time is roughly the same, but the generated regex is much smaller, which should result in faster matching.
+
+## Attribution
+
+Inspired by the python library [range-regex](https://github.com/dimka665/range-regex).
+
+## About
+
+<details>
+<summary><strong>Contributing</strong></summary>
 
 Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
 
-### Building docs
+</details>
 
-_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_
+<details>
+<summary><strong>Running Tests</strong></summary>
 
-To generate the readme and API documentation with [verb](https://github.com/verbose/verb):
+Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
 
 ```sh
-$ npm install -g verb verb-generate-readme && verb
+$ npm install && npm test
 ```
 
-### Running tests
+</details>
 
-Install dev dependencies:
+<details>
+<summary><strong>Building docs</strong></summary>
+
+_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
+
+To generate the readme, run the following command:
 
 ```sh
-$ npm install -d && npm test
+$ npm install -g verbose/verb#dev verb-generate-readme && verb
 ```
 
+</details>
+
+### Related projects
+
+You might also be interested in these projects:
+
+* [expand-range](https://www.npmjs.com/package/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used… [more](https://github.com/jonschlinkert/expand-range) | [homepage](https://github.com/jonschlinkert/expand-range "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. Used by [micromatch].")
+* [fill-range](https://www.npmjs.com/package/fill-range): Fill in a range of numbers or letters, optionally passing an increment or `step` to… [more](https://github.com/jonschlinkert/fill-range) | [homepage](https://github.com/jonschlinkert/fill-range "Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`")
+* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/micromatch/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.")
+* [repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.")
+* [repeat-string](https://www.npmjs.com/package/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string. | [homepage](https://github.com/jonschlinkert/repeat-string "Repeat the given string n times. Fastest implementation for repeating a string.")
+
+### Contributors
+
+| **Commits** | **Contributor** | 
+| --- | --- |
+| 51 | [jonschlinkert](https://github.com/jonschlinkert) |
+| 2 | [realityking](https://github.com/realityking) |
+
 ### Author
 
 **Jon Schlinkert**
 
 * [github/jonschlinkert](https://github.com/jonschlinkert)
-* [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
+* [twitter/jonschlinkert](https://twitter.com/jonschlinkert)
 
 ### License
 
-Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert).
-Released under the [MIT license](https://github.com/jonschlinkert/to-regex-range/blob/master/LICENSE).
+Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert).
+Released under the [MIT License](LICENSE).
 
 ***
 
-_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.1.30, on September 14, 2016._
\ No newline at end of file
+_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on November 01, 2017._
\ No newline at end of file
diff --git a/bower.json b/bower.json
deleted file mode 100644
index 28ae064..0000000
--- a/bower.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
-  "name": "to-regex-range",
-  "description": "Returns a regex-compatible range from two numbers, min and max. Useful for creating regular expressions to validate numbers, ranges, years, etc.",
-  "repository": "jonschlinkert/to-regex-range",
-  "license": "MIT",
-  "homepage": "https://github.com/jonschlinkert/to-regex-range",
-  "authors": [
-    "Jon Schlinkert (https://github.com/jonschlinkert)"
-  ],
-  "main": [
-    "index.js"
-  ],
-  "dependencies": {
-    "is-number": "^2.0.2",
-    "repeat-string": "^1.5.2"
-  },
-  "devDependencies": {
-    "mocha": "*",
-    "should": "*"
-  },
-  "keywords": [
-    "alpha",
-    "alphabetical",
-    "bash",
-    "brace",
-    "expand",
-    "expansion",
-    "glob",
-    "match",
-    "matches",
-    "matching",
-    "number",
-    "numerical",
-    "range",
-    "ranges",
-    "sh"
-  ]
-}
diff --git a/example.js b/example.js
deleted file mode 100644
index c927ace..0000000
--- a/example.js
+++ /dev/null
@@ -1,17 +0,0 @@
-var toRegexRange = require('./');
-
-console.log(toRegexRange('111', '555'));
-//=> '11[1-9]|1[2-9]\d|[2-4]\d{2}|5[0-4]\d|55[0-5]'
-console.log(toRegexRange('5', '5'));
-//=> '5'
-console.log(toRegexRange('5', '6'));
-//=> '[5-6]'
-console.log(toRegexRange('51', '229'));
-//=> '5[1-9]|[6-9]\d|1\d{2}|2[0-2]\d'
-console.log(toRegexRange('51', '29'));
-//=> '51|29'
-
-console.log(toRegexRange('1991', '2015'));
-var re = new RegExp(toRegexRange('1', '99'));
-console.log(re.test('50'));
-// => true
diff --git a/index.js b/index.js
index d7487c6..1754f4c 100644
--- a/index.js
+++ b/index.js
@@ -1,92 +1,100 @@
 /*!
- * to-regex-range <https://github.com/jonschlinkert/to-regex-range>
+ * to-regex-range <https://github.com/micromatch/to-regex-range>
  *
- * Copyright (c) 2015, Jon Schlinkert.
- * Licensed under the MIT License.
+ * Copyright (c) 2015-2017, Jon Schlinkert.
+ * Released under the MIT License.
  */
 
 'use strict';
 
 var repeat = require('repeat-string');
 var isNumber = require('is-number');
-var cache = {range: {}, rangeToPattern: {}};
+var cache = {};
 
-function toRegexRange(min, max) {
+function toRegexRange(min, max, options) {
   if (isNumber(min) === false) {
     throw new RangeError('toRegexRange: first argument is invalid.');
   }
 
-  if (typeof max === 'undefined') {
-    return '' + min;
+  if (typeof max === 'undefined' || min === max) {
+    return String(min);
   }
 
   if (isNumber(max) === false) {
     throw new RangeError('toRegexRange: second argument is invalid.');
   }
 
-  var key = min + ':' + max;
-  if (cache.range.hasOwnProperty(key)) {
-    return cache.range[key];
+  options = options || {};
+  var relax = String(options.relaxZeros);
+  var shorthand = String(options.shorthand);
+  var capture = String(options.capture);
+  var key = min + ':' + max + '=' + relax + shorthand + capture;
+  if (cache.hasOwnProperty(key)) {
+    return cache[key].result;
   }
 
-  var a = min;
-  var b = max;
+  var a = Math.min(min, max);
+  var b = Math.max(min, max);
 
-  if (min > 0 && max > 0) {
-    a = Math.min(min, max);
-    b = Math.max(min, max);
-  }
-
-  if (a === b) {
-    return a;
-  }
-
-  if (a > b) {
-    return a + '|' + b;
+  if (Math.abs(a - b) === 1) {
+    var result = min + '|' + max;
+    if (options.capture) {
+      return '(' + result + ')';
+    }
+    return result;
   }
 
-  a = String(a);
-  b = String(b);
+  var isPadded = padding(min) || padding(max);
   var positives = [];
   var negatives = [];
 
-  if (a < 0) {
-    var newMin = 1;
-    if (b < 0) {
-      newMin = Math.abs(b);
-    }
+  var tok = {min: min, max: max, a: a, b: b};
+  if (isPadded) {
+    tok.isPadded = isPadded;
+    tok.maxLen = String(tok.max).length;
+  }
 
+  if (a < 0) {
+    var newMin = b < 0 ? Math.abs(b) : 1;
     var newMax = Math.abs(a);
-    negatives = splitToPatterns(newMin, newMax);
-    a = 0;
+    negatives = splitToPatterns(newMin, newMax, tok, options);
+    a = tok.a = 0;
   }
+
   if (b >= 0) {
-    positives = splitToPatterns(a, b);
+    positives = splitToPatterns(a, b, tok, options);
   }
 
-  var res = siftPatterns(negatives, positives);
-  cache.range[key] = res;
-  return res;
+  tok.negatives = negatives;
+  tok.positives = positives;
+  tok.result = siftPatterns(negatives, positives, options);
+
+  if (options.capture && (positives.length + negatives.length) > 1) {
+    tok.result = '(' + tok.result + ')';
+  }
+
+  cache[key] = tok;
+  return tok.result;
 }
 
-function siftPatterns(negatives, positives) {
-  var onlyNegative = filterPatterns(negatives, positives, '-');
-  var onlyPositive = filterPatterns(positives, negatives, '');
-  var intersected = filterPatterns(negatives, positives, '-?', true);
-  var subpatterns = onlyNegative.concat(intersected || []).concat(onlyPositive || []);
+function siftPatterns(neg, pos, options) {
+  var onlyNegative = filterPatterns(neg, pos, '-', false, options) || [];
+  var onlyPositive = filterPatterns(pos, neg, '', false, options) || [];
+  var intersected = filterPatterns(neg, pos, '-?', true, options) || [];
+  var subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
   return subpatterns.join('|');
 }
 
 function splitToRanges(min, max) {
-  min = +min;
-  max = +max;
+  min = Number(min);
+  max = Number(max);
 
   var nines = 1;
   var stops = [max];
   var stop = +countNines(min, nines);
 
   while (min <= stop && stop <= max) {
-    stops = add(stops, stop);
+    stops = push(stops, stop);
     nines += 1;
     stop = +countNines(min, nines);
   }
@@ -95,7 +103,7 @@ function splitToRanges(min, max) {
   stop = countZeros(max + 1, zeros) - 1;
 
   while (min < stop && stop <= max) {
-    stops = add(stops, stop);
+    stops = push(stops, stop);
     zeros += 1;
     stop = countZeros(max + 1, zeros) - 1;
   }
@@ -104,11 +112,16 @@ function splitToRanges(min, max) {
   return stops;
 }
 
-function rangeToPattern(start, stop) {
-  var key = start + ':' + stop;
+/**
+ * Convert a range to a regex pattern
+ * @param {Number} `start`
+ * @param {Number} `stop`
+ * @return {String}
+ */
 
-  if (cache.rangeToPattern.hasOwnProperty(key)) {
-    return cache.rangeToPattern[key];
+function rangeToPattern(start, stop, options) {
+  if (start === stop) {
+    return {pattern: String(start), digits: []};
   }
 
   var zipped = zip(String(start), String(stop));
@@ -118,9 +131,9 @@ function rangeToPattern(start, stop) {
   var digits = 0;
 
   while (++i < len) {
-    var current = zipped[i];
-    var startDigit = current[0];
-    var stopDigit = current[1];
+    var numbers = zipped[i];
+    var startDigit = numbers[0];
+    var stopDigit = numbers[1];
 
     if (startDigit === stopDigit) {
       pattern += startDigit;
@@ -134,85 +147,144 @@ function rangeToPattern(start, stop) {
   }
 
   if (digits) {
-    pattern += '[0-9]';
+    pattern += options.shorthand ? '\\d' : '[0-9]';
   }
 
-  if (digits > 1) {
-    pattern += limit(digits);
-  }
-
-  cache.rangeToPattern[key] = pattern;
-  return pattern;
-}
-
-/**
- * Zip strings (`for in` can be used on string characters)
- */
-
-function zip(a, b) {
-  var arr = [];
-  for (var ch in a) arr.push([a[ch], b[ch]]);
-  return arr;
+  return { pattern: pattern, digits: [digits] };
 }
 
-function splitToPatterns(min, max) {
+function splitToPatterns(min, max, tok, options) {
   var ranges = splitToRanges(min, max);
   var len = ranges.length;
   var idx = -1;
 
+  var tokens = [];
   var start = min;
-  var subpatterns = new Array(len);
+  var prev;
 
   while (++idx < len) {
     var range = ranges[idx];
-    subpatterns[idx] = rangeToPattern(start, range);
+    var obj = rangeToPattern(start, range, options);
+    var zeros = '';
+
+    if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
+      if (prev.digits.length > 1) {
+        prev.digits.pop();
+      }
+      prev.digits.push(obj.digits[0]);
+      prev.string = prev.pattern + toQuantifier(prev.digits);
+      start = range + 1;
+      continue;
+    }
+
+    if (tok.isPadded) {
+      zeros = padZeros(range, tok);
+    }
+
+    obj.string = zeros + obj.pattern + toQuantifier(obj.digits);
+    tokens.push(obj);
     start = range + 1;
+    prev = obj;
   }
-  return subpatterns;
+
+  return tokens;
 }
 
-function filterPatterns(arr, comparison, prefix, intersection) {
-  var len = arr.length, i = -1;
-  var intersected = [];
+function filterPatterns(arr, comparison, prefix, intersection, options) {
   var res = [];
 
-  while (++i < len) {
-    var ele = arr[i];
-    if (!intersection && comparison.indexOf(ele) === -1) {
+  for (var i = 0; i < arr.length; i++) {
+    var tok = arr[i];
+    var ele = tok.string;
+
+    if (options.relaxZeros !== false) {
+      if (prefix === '-' && ele.charAt(0) === '0') {
+        if (ele.charAt(1) === '{') {
+          ele = '0*' + ele.replace(/^0\{\d+\}/, '');
+        } else {
+          ele = '0*' + ele.slice(1);
+        }
+      }
+    }
+
+    if (!intersection && !contains(comparison, 'string', ele)) {
       res.push(prefix + ele);
     }
-    if (intersection && comparison.indexOf(ele) !== -1) {
-      intersected.push(prefix + ele);
+
+    if (intersection && contains(comparison, 'string', ele)) {
+      res.push(prefix + ele);
     }
   }
-  return intersection ? intersected : res;
+  return res;
 }
 
-function countNines(num, len) {
-  return String(num).slice(0, -len) + repeat('9', len);
+/**
+ * Zip strings (`for in` can be used on string characters)
+ */
+
+function zip(a, b) {
+  var arr = [];
+  for (var ch in a) arr.push([a[ch], b[ch]]);
+  return arr;
+}
+
+function compare(a, b) {
+  return a > b ? 1 : b > a ? -1 : 0;
+}
+
+function push(arr, ele) {
+  if (arr.indexOf(ele) === -1) arr.push(ele);
+  return arr;
+}
+
+function contains(arr, key, val) {
+  for (var i = 0; i < arr.length; i++) {
+    if (arr[i][key] === val) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function countNines(min, len) {
+  return String(min).slice(0, -len) + repeat('9', len);
 }
 
 function countZeros(integer, zeros) {
   return integer - (integer % Math.pow(10, zeros));
 }
 
-function limit(str) {
-  return '{' + str + '}';
+function toQuantifier(digits) {
+  var start = digits[0];
+  var stop = digits[1] ? (',' + digits[1]) : '';
+  if (!stop && (!start || start === 1)) {
+    return '';
+  }
+  return '{' + start + stop + '}';
 }
 
 function toCharacterClass(a, b) {
-  return '[' + a + '-' + b + ']';
+  return '[' + a + ((b - a === 1) ? '' : '-') + b + ']';
 }
 
-function compare(a, b) {
-  return a - b;
+function padding(str) {
+  return /^-?(0+)\d/.exec(str);
 }
 
-function add(arr, ele) {
-  if (arr.indexOf(ele) === -1) {
-    arr.push(ele);
+function padZeros(val, tok) {
+  if (tok.isPadded) {
+    var diff = Math.abs(tok.maxLen - String(val).length);
+    switch (diff) {
+      case 0:
+        return '';
+      case 1:
+        return '0';
+      default: {
+        return '0{' + diff + '}';
+      }
+    }
   }
-  return arr;
+  return val;
 }
 
 /**
diff --git a/package.json b/package.json
index 9c1bd1f..2a2f239 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,16 @@
 {
   "name": "to-regex-range",
-  "description": "Returns a regex-compatible range from two numbers, min and max, with 855,412 generated unit tests to validate it's accuracy! Useful for creating regular expressions to validate numbers, ranges, years, etc. Returns a string, allowing the returned value to be used in regular expressions generated by other libraries.",
-  "version": "0.2.0",
-  "homepage": "https://github.com/jonschlinkert/to-regex-range",
+  "description": "Pass two numbers, get a regex-compatible source string for matching ranges. Validated against more than 2.78 million test assertions.",
+  "version": "3.0.0",
+  "homepage": "https://github.com/micromatch/to-regex-range",
   "author": "Jon Schlinkert (https://github.com/jonschlinkert)",
-  "repository": "jonschlinkert/to-regex-range",
+  "contributors": [
+    "Jon Schlinkert (http://twitter.com/jonschlinkert)",
+    "Rouven Weßling (www.rouvenwessling.de)"
+  ],
+  "repository": "micromatch/to-regex-range",
   "bugs": {
-    "url": "https://github.com/jonschlinkert/to-regex-range/issues"
+    "url": "https://github.com/micromatch/to-regex-range/issues"
   },
   "license": "MIT",
   "files": [
@@ -20,18 +24,22 @@
     "test": "mocha"
   },
   "dependencies": {
-    "is-number": "^2.1.0",
-    "repeat-string": "^1.5.4"
+    "is-number": "^4.0.0",
+    "repeat-string": "^1.6.1"
   },
   "devDependencies": {
-    "gulp-format-md": "^0.1.9",
-    "mocha": "^2.4.5"
+    "fill-range": "^5.0.0",
+    "gulp-format-md": "^1.0.0",
+    "mocha": "^3.5.0",
+    "text-table": "^0.2.0",
+    "time-diff": "^0.3.1"
   },
   "keywords": [
     "alpha",
     "alphabetical",
     "bash",
     "brace",
+    "date",
     "expand",
     "expansion",
     "glob",
@@ -43,7 +51,10 @@
     "range",
     "ranges",
     "regex",
-    "sh"
+    "sequence",
+    "sh",
+    "to",
+    "year"
   ],
   "verb": {
     "related": {
@@ -66,8 +77,11 @@
     "lint": {
       "reflinks": true
     },
+    "helpers": [
+      "./examples.js"
+    ],
     "reflinks": [
-      "verb"
+      "micromatch"
     ]
   }
 }
diff --git a/test/support/index.js b/test/support/index.js
deleted file mode 100644
index 619e13d..0000000
--- a/test/support/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-
-var utils = module.exports;
-
-// TODO: publish as lib
-utils.toRange = function toRange(start, stop, step) {
-  step = step || 1;
-  var arr = new Array((stop - start) / step);
-  var num = 0;
-
-  for (var i = start; i <= stop; i += step) {
-    arr[num++] = i;
-  }
-  return arr;
-};
diff --git a/test/test.js b/test/test.js
deleted file mode 100644
index b7dcdff..0000000
--- a/test/test.js
+++ /dev/null
@@ -1,174 +0,0 @@
-'use strict';
-
-require('mocha');
-var assert = require('assert');
-var utils = require('./support');
-var toRange = require('..');
-var count = 0;
-
-function toRegex(min, max) {
-  return new RegExp('^(' + toRange(min, max) + ')$');
-}
-
-function match(min, max) {
-  var regex = toRegex(min, max);
-  return function(num) {
-    return regex.test(String(num));
-  };
-}
-
-function verifyRange(min, max, from, to) {
-  var isMatch = match(min, max);
-  var range = utils.toRange(from, to);
-  var len = range.length, i = -1;
-
-  while (++i < len) {
-    var num = range[i];
-    if (min <= num && num <= max) {
-      assert(isMatch(num));
-    } else {
-      assert(!isMatch(num));
-    }
-    count++;
-  }
-}
-
-describe('range', function() {
-  it('should throw an error when the first arg is invalid:', function() {
-    assert.throws(function() {
-      toRange();
-    }, /toRegexRange: first argument is invalid/);
-  });
-
-  it('should throw an error when the second arg is invalid:', function() {
-    assert.throws(function() {
-      toRange(1, {});
-    }, /toRegexRange: second argument is invalid/);
-  });
-});
-
-describe('minimum / maximum', function() {
-  it('should reverse `min/max` when the min is larger than the max:', function() {
-    assert.equal(toRange(55, 10), '1[0-9]|[2-4][0-9]|5[0-5]');
-  });
-});
-
-describe('ranges', function() {
-  it('should return the number when only one argument is passed:', function() {
-    assert.equal(toRange(5), '5');
-  });
-
-  it('should not return a range when both numbers are the same:', function() {
-    assert.equal(toRange(5, 5), '5');
-  });
-
-  it('should support ranges than 10:', function() {
-    assert.equal(toRange(1, 5), '[1-5]');
-  });
-
-  it('should support strings:', function() {
-    assert.equal(toRange('1', '5'), '[1-5]');
-    assert.equal(toRange('10', '50'), '1[0-9]|[2-4][0-9]|50');
-  });
-
-  it('should generate regular expressions from the given pattern', function() {
-    assert.equal(toRange(1, 1), '1');
-    assert.equal(toRange(0, 1), '[0-1]');
-    assert.equal(toRange(-1, -1), '-1');
-    assert.equal(toRange(-1, -10), '-1|-10');
-    assert.equal(toRange(-1, 0), '-1|0');
-    assert.equal(toRange(-1, 1), '-1|[0-1]');
-    assert.equal(toRange(-4, -2), '-[2-4]');
-    assert.equal(toRange(-3, 1), '-[1-3]|[0-1]');
-    assert.equal(toRange(-2, 0), '-[1-2]|0');
-    assert.equal(toRange(0, 2), '[0-2]');
-    assert.equal(toRange(-1, 3), '-1|[0-3]');
-    assert.equal(toRange(65666, 65667), '6566[6-7]');
-    assert.equal(toRange(12, 3456), '1[2-9]|[2-9][0-9]|[1-9][0-9]{2}|[1-2][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6]');
-    assert.equal(toRange(1, 3456), '[1-9]|[1-9][0-9]|[1-9][0-9]{2}|[1-2][0-9]{3}|3[0-3][0-9]{2}|34[0-4][0-9]|345[0-6]');
-    assert.equal(toRange(1, 10), '[1-9]|10');
-    assert.equal(toRange(1, 19), '[1-9]|1[0-9]');
-    assert.equal(toRange(1, 99), '[1-9]|[1-9][0-9]');
-  });
-
-  it('should optimize regexes', function() {
-    assert.equal(toRange(-9, 9), '-[1-9]|[0-9]');
-    assert.equal(toRange(-19, 19), '-[1-9]|-?1[0-9]|[0-9]');
-    assert.equal(toRange(-29, 29), '-[1-9]|-?[1-2][0-9]|[0-9]');
-    assert.equal(toRange(-99, 99), '-[1-9]|-?[1-9][0-9]|[0-9]');
-    assert.equal(toRange(-999, 999), '-[1-9]|-?[1-9][0-9]|-?[1-9][0-9]{2}|[0-9]');
-    assert.equal(toRange(-9999, 9999), '-[1-9]|-?[1-9][0-9]|-?[1-9][0-9]{2}|-?[1-9][0-9]{3}|[0-9]');
-  });
-});
-
-describe('validate ranges', function() {
-  after(function() {
-    var num = (+(+(count).toFixed(2))).toLocaleString();
-    console.log();
-    console.log('   ', num, 'patterns tested');
-  });
-
-  it('should support equal numbers:', function() {
-    verifyRange(1, 1, 0, 100);
-    verifyRange(65443, 65443, 65000, 66000);
-    verifyRange(192, 1000, 0, 1000);
-  });
-
-  it('should support large numbers:', function() {
-    verifyRange(100019999300000, 100020000300000, 100019999999999, 100020000100000);
-  });
-
-  it('should support repeated digits:', function() {
-    verifyRange(10331, 20381, 0, 99999);
-  });
-
-  it('should support repeated zeros:', function() {
-    verifyRange(10031, 20081, 0, 59999);
-    verifyRange(10000, 20000, 0, 59999);
-  });
-
-  it('should support zero one:', function() {
-    verifyRange(10301, 20101, 0, 99999);
-  });
-
-  it('should support repetead ones:', function() {
-    verifyRange(102, 111, 0, 1000);
-  });
-
-  it('should support small diffs:', function() {
-    verifyRange(102, 110, 0, 1000);
-    verifyRange(102, 130, 0, 1000);
-  });
-
-  it('should support random ranges:', function() {
-    verifyRange(4173, 7981, 0, 99999);
-  });
-
-  it('should support one digit numbers:', function() {
-    verifyRange(3, 7, 0, 99);
-  });
-
-  it('should support one digit at bounds:', function() {
-    verifyRange(1, 9, 0, 1000);
-  });
-
-  it('should support power of ten:', function() {
-    verifyRange(1000, 8632, 0, 99999);
-  });
-
-  it('should work with numbers of varying lengths:', function() {
-    verifyRange(1030, 20101, 0, 99999);
-    verifyRange(13, 8632, 0, 10000);
-  });
-
-  it('should support small ranges:', function() {
-    verifyRange(9, 11, 0, 100);
-    verifyRange(19, 21, 0, 100);
-  });
-
-  it('should support big ranges:', function() {
-    verifyRange(90, 98009, 0, 98999);
-    verifyRange(999, 10000, 1, 20000);
-  });
-});
-

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-to-regex-range.git



More information about the Pkg-javascript-commits mailing list