Comparing version 1.0.2 to 1.0.3
@@ -28,8 +28,5 @@ ## History | ||
[Unreleased]: https://github.com/jonschlinkert/nanomatch/compare/0.1.0...HEAD | ||
[0.2.0]: https://github.com/jonschlinkert/nanomatch/compare/0.1.0...0.2.0 | ||
[Unreleased]: https://github.com/generate/generate/compare/0.1.0...HEAD | ||
[0.2.0]: https://github.com/generate/generate/compare/0.1.0...0.2.0 | ||
[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog | ||
[common-config]: https://github.com/jonschlinkert/common-config | ||
60
index.js
@@ -116,7 +116,7 @@ 'use strict'; | ||
while (++idx < len) { | ||
var ele = list[idx]; | ||
var unix = unixify(ele); | ||
var origPath = list[idx]; | ||
if (ele === pattern || unix === pattern || isMatch(unix)) { | ||
matches.push((options && options.unixify === false) ? ele : unix); | ||
if (origPath === pattern || isMatch(origPath)) { | ||
var unixPath = unixify(origPath); | ||
matches.push(utils.value(origPath, unixPath, options, pattern)); | ||
} | ||
@@ -171,10 +171,7 @@ } | ||
if (pattern === str) { | ||
var equals = utils.equalsPattern(options); | ||
if (equals(str)) { | ||
return true; | ||
} | ||
if (utils.isSimpleChar(pattern) || utils.isSlash(pattern)) { | ||
return str === pattern; | ||
} | ||
var isMatch = memoize('isMatch', pattern, options, nanomatch.matcher); | ||
@@ -206,10 +203,7 @@ return isMatch(str); | ||
var unixify = utils.unixify(opts); | ||
var unixified = utils.arrayify(list).map(function(fp) { | ||
return unixify(fp, opts); | ||
}); | ||
list = utils.arrayify(list); | ||
var matches = utils.diff(unixified, nanomatch(unixified, patterns, opts)); | ||
var matches = utils.diff(list, nanomatch(list, patterns, opts)); | ||
if (ignore) { | ||
matches = utils.diff(matches, nanomatch(unixified, ignore)); | ||
matches = utils.diff(matches, nanomatch(list, ignore)); | ||
} | ||
@@ -240,3 +234,2 @@ | ||
nanomatch.any = function(list, patterns, options) { | ||
var unixify = utils.unixify(options); | ||
var isMatch = memoize('any', patterns, options, nanomatch.matcher); | ||
@@ -251,5 +244,4 @@ | ||
if (ele === './' || ele === '') continue; | ||
var unix = unixify(ele); | ||
if (isMatch(unix)) { | ||
if (isMatch(ele)) { | ||
if (options && options.ignore && nanomatch.not(ele, options.ignored)) { | ||
@@ -278,3 +270,3 @@ continue; | ||
* @param {String} `str` The string to match. | ||
* @param {String} `pattern` Glob pattern to use for matching. | ||
* @param {String|Array} `patterns` Glob pattern to use for matching. | ||
* @param {Object} `options` Any [options](#options) to change how matches are performed | ||
@@ -285,9 +277,16 @@ * @return {Boolean} Returns true if the patter matches any part of `str`. | ||
nanomatch.contains = function(str, pattern, options) { | ||
if (pattern === str) { | ||
return true; | ||
} | ||
nanomatch.contains = function(str, patterns, options) { | ||
if (typeof patterns === 'string') { | ||
if (patterns === '') { | ||
return false; | ||
} | ||
if (utils.isSimpleChar(pattern)) { | ||
return str === pattern; | ||
var equals = utils.equalsPattern(patterns, options); | ||
if (equals(str)) { | ||
return true; | ||
} | ||
var contains = utils.containsPattern(patterns, options); | ||
if (contains(str)) { | ||
return true; | ||
} | ||
} | ||
@@ -299,4 +298,3 @@ | ||
opts.contains = true; | ||
return nanomatch(str, pattern, opts).length > 0; | ||
return nanomatch(str, patterns, opts).length > 0; | ||
}; | ||
@@ -397,11 +395,11 @@ | ||
function test(regex) { | ||
var equals = utils.equalsPattern(options); | ||
var unixify = utils.unixify(options); | ||
return function(str) { | ||
// don't unixify unless necessary | ||
if (str === pattern) { | ||
if (equals(str)) { | ||
return true; | ||
} | ||
var ele = unixify(str); | ||
if (ele === pattern || regex.test(ele)) { | ||
if (regex.test(unixify(str))) { | ||
return true; | ||
@@ -408,0 +406,0 @@ } |
@@ -32,2 +32,5 @@ 'use strict'; | ||
}) | ||
.set('quoted', function(node) { | ||
return this.emit(node.val, node); | ||
}) | ||
@@ -97,10 +100,4 @@ /** | ||
if (inner === '\\\\') { | ||
inner = '/'; | ||
} else { | ||
inner = inner.replace(/\\+(?=\w|$)/g, '\\\\'); | ||
if (inner === ']-') { | ||
inner = '\\]\\-'; | ||
} | ||
if (inner === ']-') { | ||
inner = '\\]\\-'; | ||
} | ||
@@ -219,2 +216,3 @@ | ||
var prev = this.prev(); | ||
var next = this.next(); | ||
var type = prev.type; | ||
@@ -230,5 +228,6 @@ | ||
if (type === 'bracket' && this.options.bash !== true) { | ||
if (prev.nodes && prev.nodes[1].type !== 'posix') { | ||
return this.emit('*?', node); | ||
if (type === 'bracket' && this.options.bash === false) { | ||
var str = next && next.type === 'bracket' ? star : '*?'; | ||
if (!prev.nodes || prev.nodes[1].type !== 'posix') { | ||
return this.emit(str, node); | ||
} | ||
@@ -235,0 +234,0 @@ } |
@@ -44,2 +44,22 @@ 'use strict'; | ||
/** | ||
* Quoted strings | ||
*/ | ||
.capture('quoted', function() { | ||
if (this.parsed) return; | ||
var pos = this.position(); | ||
var m = this.match(/^["']/); | ||
if (!m) return; | ||
var quote = m[0]; | ||
var tok = advanceTo(this.input, quote); | ||
this.consume(tok.len); | ||
return pos({ | ||
type: 'quoted', | ||
val: tok.val | ||
}); | ||
}) | ||
/** | ||
* Escape: "\\." | ||
@@ -203,3 +223,3 @@ */ | ||
var pos = this.position(); | ||
var m = this.match(/^\[((?!\\)[^!^])\]/); | ||
var m = this.match(/^\[([^!^\\])\]/); | ||
if (!m) return; | ||
@@ -219,3 +239,3 @@ | ||
var pos = this.position(); | ||
var m = this.match(/^(?:\[([!^]?)([^\]]{2,}|\]\-)(\]|[^*+?]+)|\[)/); | ||
var m = this.match(/^(?:\[([!^]?)([^\]]+|\]\-)(\]|[^*+?]+)|\[)/); | ||
if (!m) return; | ||
@@ -283,2 +303,35 @@ | ||
/** | ||
* Advance to the next non-escaped character | ||
*/ | ||
function advanceTo(input, endChar) { | ||
var ch = input.charAt(0); | ||
var tok = { len: 1 }; | ||
var val = ''; | ||
var idx = 0; | ||
function advance() { | ||
if (ch !== '\\') val += '\\' + ch; | ||
ch = input.charAt(++idx); | ||
tok.len++; | ||
if (ch === '\\') { | ||
advance(); | ||
advance(); | ||
} | ||
} | ||
while (ch && ch !== endChar) { | ||
advance(); | ||
} | ||
if (ch !== endChar) { | ||
throw new Error('unclosed: ' + endChar); | ||
} | ||
tok.val = val; | ||
return tok; | ||
} | ||
/** | ||
* Create text regex | ||
@@ -285,0 +338,0 @@ */ |
147
lib/utils.js
@@ -5,3 +5,2 @@ 'use strict'; | ||
var path = require('path'); | ||
var cache = {}; | ||
@@ -20,2 +19,17 @@ /** | ||
/** | ||
* Returns true if the platform is windows, or `path.sep` is `\\`. | ||
* This is defined as a function to allow `path.sep` to be set in unit tests, | ||
* or by the user, if there is a reason to do so. | ||
* @return {Boolean} | ||
*/ | ||
utils.isWindows = function() { | ||
return path.sep === '\\' || process.platform === 'win32'; | ||
}; | ||
/** | ||
* Return the last element from an array | ||
*/ | ||
utils.last = function(arr, n) { | ||
@@ -147,3 +161,3 @@ return arr[arr.length - (n || 1)]; | ||
utils.escapeRegex = function(str) { | ||
return str.replace(/[\-\[\]{}()^$|\s*+?.\\\/]/g, '\\$&'); | ||
return str.replace(/[-[\]{}()^$|*+?.\\\/\s]/g, '\\$&'); | ||
}; | ||
@@ -174,21 +188,21 @@ | ||
/** | ||
* Strip backslashes from a string. | ||
* Normalize slashes in the given filepath. | ||
* | ||
* @param {String} `str` | ||
* @param {String} `filepath` | ||
* @return {String} | ||
*/ | ||
utils.unescape = function(str) { | ||
return utils.normalize(str.replace(/\\(\W)/g, '$1')); | ||
utils.toPosixPath = function(str) { | ||
return str.replace(/\\+/g, '/'); | ||
}; | ||
/** | ||
* Normalize slashes in the given filepath. | ||
* Strip backslashes before special characters in a string. | ||
* | ||
* @param {String} `filepath` | ||
* @param {String} `str` | ||
* @return {String} | ||
*/ | ||
utils.normalize = function(str) { | ||
return str.replace(/\\(?![!*+?[\](){}])/g, '/'); | ||
utils.unescape = function(str) { | ||
return utils.toPosixPath(str.replace(/\\(?=[*+?!.])/g, '')); | ||
}; | ||
@@ -203,3 +217,3 @@ | ||
utils.stripDrive = function(fp) { | ||
return path.sep === '\\' ? fp.replace(/^[a-z]:[\\\/]?/i, '/') : fp; | ||
return utils.isWindows() ? fp.replace(/^[a-z]:[\\\/]+?/i, '/') : fp; | ||
}; | ||
@@ -214,3 +228,10 @@ | ||
utils.stripPrefix = function(str) { | ||
return str.replace(/^\.[\\\/]+/, ''); | ||
if (str.charAt(0) !== '.') { | ||
return str; | ||
} | ||
var ch = str.charAt(1); | ||
if (ch === '\\' || ch === '/') { | ||
return str.slice(2); | ||
} | ||
return str; | ||
}; | ||
@@ -248,2 +269,20 @@ | ||
/** | ||
* Returns true if the given (original) filepath or unixified path are equal | ||
* to the given pattern. | ||
*/ | ||
utils._equals = function(filepath, unixPath, pattern) { | ||
return pattern === filepath || pattern === unixPath; | ||
}; | ||
/** | ||
* Returns true if the given (original) filepath or unixified path contain | ||
* the given pattern. | ||
*/ | ||
utils._contains = function(filepath, unixPath, pattern) { | ||
return filepath.indexOf(pattern) !== -1 || unixPath.indexOf(pattern) !== -1; | ||
}; | ||
/** | ||
* Returns a function that returns true if the given | ||
@@ -258,9 +297,11 @@ * pattern is the same as a given `filepath` | ||
var unixify = utils.unixify(options); | ||
options = options || {}; | ||
return function(filepath) { | ||
filepath = utils.stripPrefix(filepath); | ||
if (options && options.nocase === true) { | ||
filepath = filepath.toLowerCase(); | ||
return function fn(filepath) { | ||
var equal = utils._equals(filepath, unixify(filepath), pattern); | ||
if (equal === true || options.nocase !== true) { | ||
return equal; | ||
} | ||
return pattern === filepath || pattern === unixify(filepath); | ||
var lower = filepath.toLowerCase(); | ||
return utils._equals(lower, unixify(lower), pattern); | ||
}; | ||
@@ -279,9 +320,11 @@ }; | ||
var unixify = utils.unixify(options); | ||
options = options || {}; | ||
return function(filepath) { | ||
filepath = utils.stripPrefix(filepath); | ||
if (options && options.nocase === true) { | ||
return unixify(filepath.toLowerCase()).indexOf(pattern) !== -1; | ||
} else { | ||
return unixify(filepath).indexOf(pattern) !== -1; | ||
var contains = utils._contains(filepath, unixify(filepath), pattern); | ||
if (contains === true || options.nocase !== true) { | ||
return contains; | ||
} | ||
var lower = filepath.toLowerCase(); | ||
return utils._contains(lower, unixify(lower), pattern); | ||
}; | ||
@@ -305,35 +348,43 @@ }; | ||
/** | ||
* Normalize all slashes in a file path or glob pattern to | ||
* forward slashes. | ||
* Returns the given value unchanced. | ||
* @return {any} | ||
*/ | ||
utils.unixify = function(options) { | ||
var type = path.sep === '\\' ? 'backslash' : 'slash'; | ||
var key = utils.createKey('unixify' + type, options); | ||
utils.identity = function(val) { | ||
return val; | ||
}; | ||
if (cache.hasOwnProperty(key)) { | ||
return cache[key]; | ||
/** | ||
* Determines the filepath to return based on the provided options. | ||
* @return {any} | ||
*/ | ||
utils.value = function(origPath, unixPath, options) { | ||
if (typeof options === 'undefined' || options.unixify !== false) { | ||
return unixPath; | ||
} | ||
return origPath; | ||
}; | ||
var unixify = function(filepath) { | ||
return utils.stripPrefix(filepath); | ||
}; | ||
/** | ||
* Returns a function that normalizes slashes in a string to forward | ||
* slashes, strips `./` from beginning of paths, and optionally unescapes | ||
* special characters. | ||
* @return {Function} | ||
*/ | ||
utils.unixify = function(options) { | ||
options = options || {}; | ||
if (type === 'backslash' || options.unixify !== false) { | ||
unixify = function(filepath) { | ||
return utils.stripPrefix(utils.normalize(filepath)); | ||
}; | ||
} | ||
if (options.unescape === true) { | ||
var fn = function(filepath) { | ||
return unixify(utils.unescape(filepath)); | ||
}; | ||
cache[key] = fn; | ||
return fn; | ||
} | ||
cache[key] = unixify; | ||
return unixify; | ||
return function(filepath) { | ||
if (utils.isWindows() || options.unixify === true) { | ||
filepath = utils.toPosixPath(filepath); | ||
} | ||
if (options.stripPrefix !== false) { | ||
filepath = utils.stripPrefix(filepath); | ||
} | ||
if (options.unescape === true) { | ||
filepath = utils.unescape(filepath); | ||
} | ||
return filepath; | ||
}; | ||
}; |
{ | ||
"name": "nanomatch", | ||
"description": "Fast, minimal glob matcher for node.js. Similar to micromatch, minimatch and multimatch, but complete Bash 4.3 wildcard support only (no support for exglobs, posix brackets or braces)", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"homepage": "https://github.com/jonschlinkert/nanomatch", | ||
@@ -43,3 +43,2 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"gulp": "^3.9.1", | ||
"gulp-eslint": "^3.0.1", | ||
"gulp-format-md": "^0.1.11", | ||
@@ -46,0 +45,0 @@ "gulp-istanbul": "^1.1.1", |
189
README.md
@@ -11,4 +11,5 @@ # nanomatch [![NPM version](https://img.shields.io/npm/v/nanomatch.svg?style=flat)](https://www.npmjs.com/package/nanomatch) [![NPM monthly downloads](https://img.shields.io/npm/dm/nanomatch.svg?style=flat)](https://npmjs.org/package/nanomatch) [![NPM total downloads](https://img.shields.io/npm/dt/nanomatch.svg?style=flat)](https://npmjs.org/package/nanomatch) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/nanomatch.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/nanomatch) [![Windows Build Status](https://img.shields.io/appveyor/ci/jonschlinkert/nanomatch.svg?style=flat&label=AppVeyor)](https://ci.appveyor.com/project/jonschlinkert/nanomatch) | ||
- [API](#api) | ||
* [options](#options) | ||
- [Options](#options) | ||
* [options.basename](#optionsbasename) | ||
* [options.bash](#optionsbash) | ||
* [options.cache](#optionscache) | ||
@@ -90,2 +91,5 @@ * [options.dot](#optionsdot) | ||
<details> | ||
<summary><strong>nanomatch</strong></summary> | ||
### [nanomatch](index.js#L39) | ||
@@ -112,2 +116,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>.match</strong></summary> | ||
### [.match](index.js#L102) | ||
@@ -134,2 +143,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>.isMatch</strong></summary> | ||
### [.isMatch](index.js#L165) | ||
@@ -158,4 +172,9 @@ | ||
### [.not](index.js#L199) | ||
</details> | ||
<details> | ||
<summary><strong>.not</strong></summary> | ||
### [.not](index.js#L196) | ||
Returns a list of strings that _DO NOT MATCH_ any of the given `patterns`. | ||
@@ -180,4 +199,9 @@ | ||
### [.any](index.js#L236) | ||
</details> | ||
<details> | ||
<summary><strong>.any</strong></summary> | ||
### [.any](index.js#L230) | ||
Returns true if the given `string` matches any of the given glob `patterns`. | ||
@@ -204,4 +228,9 @@ | ||
### [.contains](index.js#L279) | ||
</details> | ||
<details> | ||
<summary><strong>.contains</strong></summary> | ||
### [.contains](index.js#L271) | ||
Returns true if the given `string` contains the given pattern. Similar to [.isMatch](#isMatch) but the pattern can match any part of the string. | ||
@@ -212,3 +241,3 @@ | ||
* `str` **{String}**: The string to match. | ||
* `pattern` **{String}**: Glob pattern to use for matching. | ||
* `patterns` **{String|Array}**: Glob pattern to use for matching. | ||
* `options` **{Object}**: Any [options](#options) to change how matches are performed | ||
@@ -229,4 +258,9 @@ * `returns` **{Boolean}**: Returns true if the patter matches any part of `str`. | ||
### [.matchKeys](index.js#L328) | ||
</details> | ||
<details> | ||
<summary><strong>.matchKeys</strong></summary> | ||
### [.matchKeys](index.js#L326) | ||
Filter the keys of the given object with the given `glob` pattern and `options`. Does not attempt to match nested keys. If you need this feature, use [glob-object](https://github.com/jonschlinkert/glob-object) instead. | ||
@@ -252,4 +286,9 @@ | ||
### [.matcher](index.js#L357) | ||
</details> | ||
<details> | ||
<summary><strong>.matcher</strong></summary> | ||
### [.matcher](index.js#L355) | ||
Returns a memoized matcher function from the given glob `pattern` and `options`. The returned function takes a string to match as its only argument and returns true if the string is a match. | ||
@@ -276,4 +315,9 @@ | ||
### [.makeRe](index.js#L423) | ||
</details> | ||
<details> | ||
<summary><strong>.makeRe</strong></summary> | ||
### [.makeRe](index.js#L421) | ||
Create a regular expression from the given glob `pattern`. | ||
@@ -297,4 +341,9 @@ | ||
### [.create](index.js#L484) | ||
</details> | ||
<details> | ||
<summary><strong>.create</strong></summary> | ||
### [.create](index.js#L482) | ||
Parses the given glob `pattern` and returns an object with the compiled `output` and optional source `map`. | ||
@@ -340,4 +389,9 @@ | ||
### [.parse](index.js#L523) | ||
</details> | ||
<details> | ||
<summary><strong>.parse</strong></summary> | ||
### [.parse](index.js#L521) | ||
Parse the given `str` with the given `options`. | ||
@@ -374,4 +428,9 @@ | ||
### [.compile](index.js#L576) | ||
</details> | ||
<details> | ||
<summary><strong>.compile</strong></summary> | ||
### [.compile](index.js#L574) | ||
Compile the given `ast` or string with the given `options`. | ||
@@ -409,4 +468,9 @@ | ||
### [.clearCache](index.js#L599) | ||
</details> | ||
<details> | ||
<summary><strong>.clearCache</strong></summary> | ||
### [.clearCache](index.js#L597) | ||
Clear the regex cache. | ||
@@ -420,2 +484,9 @@ | ||
</details> | ||
## Options | ||
<details> | ||
<summary><strong>basename</strong></summary> | ||
### options.basename | ||
@@ -439,2 +510,30 @@ | ||
</details> | ||
<details> | ||
<summary><strong>bash</strong></summary> | ||
### options.bash | ||
Enabled by default, this option enforces bash-like behavior with stars immediately following a bracket expression. Bash bracket expressions are similar to regex character classes, but unlike regex, a star following a bracket expression **does not repeat the bracketed characters**. Instead, the star is treated the same as an other star. | ||
Type: `Boolean` | ||
Default: `true` | ||
**Example** | ||
```js | ||
var files = ['abc', 'ajz']; | ||
console.log(nm(files, '[a-c]*')); | ||
//=> ['abc', 'ajz'] | ||
console.log(nm(files, '[a-c]*', {bash: false})); | ||
``` | ||
</details> | ||
<details> | ||
<summary><strong>cache</strong></summary> | ||
### options.cache | ||
@@ -448,2 +547,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>dot</strong></summary> | ||
### options.dot | ||
@@ -457,2 +561,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>failglob</strong></summary> | ||
### options.failglob | ||
@@ -466,2 +575,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>ignore</strong></summary> | ||
### options.ignore | ||
@@ -475,2 +589,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>matchBase</strong></summary> | ||
### options.matchBase | ||
@@ -480,2 +599,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>nocase</strong></summary> | ||
### options.nocase | ||
@@ -489,2 +613,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>nodupes</strong></summary> | ||
### options.nodupes | ||
@@ -510,2 +639,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>nonegate</strong></summary> | ||
### options.nonegate | ||
@@ -519,2 +653,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>nonull</strong></summary> | ||
### options.nonull | ||
@@ -524,2 +663,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>nullglob</strong></summary> | ||
### options.nullglob | ||
@@ -533,2 +677,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>snapdragon</strong></summary> | ||
### options.snapdragon | ||
@@ -542,2 +691,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>unescape</strong></summary> | ||
### options.unescape | ||
@@ -563,2 +717,7 @@ | ||
</details> | ||
<details> | ||
<summary><strong>unixify</strong></summary> | ||
### options.unixify | ||
@@ -582,2 +741,4 @@ | ||
</details> | ||
## Features | ||
@@ -616,3 +777,3 @@ | ||
| **Related library** | **Matching Type** | **Example** | **Description** | | ||
| --- | --- | --- | --- | --- | --- | | ||
| --- | --- | --- | --- | | ||
| `nanomatch` (you are here) | Wildcards | `*` | [Filename expansion](https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html#Filename-Expansion), also referred to as globbing and pathname expansion, allows the use of [wildcards](#features) for matching. | | ||
@@ -754,2 +915,2 @@ | [expand-tilde](https://github.com/jonschlinkert/expand-tilde) | Tildes | `~` | [Tilde expansion](https://www.gnu.org/software/bash/manual/html_node/Tilde-Expansion.html#Tilde-Expansion) converts the leading tilde in a file path to the user home directory. | | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.3, on March 14, 2017._ | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.5.0, on April 06, 2017._ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
76099
17
10
1651
884