Comparing version 1.5.0 to 1.6.0
@@ -0,3 +1,9 @@ | ||
## version 1.6.0 (2017-06-26) | ||
* Adds `Parsimmon.seqObj(...args)` | ||
## version 1.5.0 (2017-06-17) | ||
NOTE: Code was completed on 2017-06-17, but due to human error, was not published on npm until 2017-06-26. | ||
* Adds `parser.sepBy(separator)` alias for `Parsimmon.sepBy(parser, separator)` | ||
@@ -4,0 +10,0 @@ * Adds `parser.sepBy1(separator)` alias for `Parsimmon.sepBy1(parser, separator)` |
{ | ||
"name": "parsimmon", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"description": "A monadic LL(infinity) parser combinator library", | ||
@@ -20,5 +20,4 @@ "keywords": [ | ||
"main": "src/parsimmon.js", | ||
"browser": "build/parsimmon.browser.min.js", | ||
"browser": "build/parsimmon.umd.min.js", | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"eslint": "^3.6.0", | ||
@@ -29,3 +28,3 @@ "mkdirp": "^0.5.1", | ||
"rimraf": "^2.5.4", | ||
"uglify-js": "2.x" | ||
"webpack": "^2.6.1" | ||
}, | ||
@@ -35,5 +34,3 @@ "license": "MIT", | ||
"prebuild": "rimraf build && mkdirp build", | ||
"build": "npm run build:browser && npm run build:browser.min", | ||
"build:browser": "ncp src/parsimmon.js build/parsimmon.browser.js", | ||
"build:browser.min": "uglifyjs --mangle < src/parsimmon.js > build/parsimmon.browser.min.js", | ||
"build": "webpack -p", | ||
"prepublishOnly": "npm run test && npm run build", | ||
@@ -43,5 +40,5 @@ "lint": "eslint .", | ||
"pretest": "npm run lint", | ||
"test": "mocha --ui tdd --reporter dot test/intro.js test/*.test.js", | ||
"watch:test": "mocha --ui tdd --reporter min --watch test/intro.js test/*.test.js" | ||
"test": "mocha --ui tdd --reporter dot test/setup.js test/core/*.test.js test/laws/*.test.js", | ||
"watch:test": "mocha --ui tdd --reporter min --watch test/setup.js test/core/*.test.js test/laws/*.test.js" | ||
} | ||
} |
@@ -15,2 +15,22 @@ <a href="https://travis-ci.org/jneen/parsimmon"><img alt="Build Status" src="https://api.travis-ci.org/jneen/parsimmon.svg"></a> | ||
<!-- | ||
Parsimmon is officially tested against Node.js 4.x and higher. It should also work in [browsers with ES5 support][es5] (IE9* and up). | ||
If you need IE8 support, you may be able to get Parsimmon to work by using [es5-shim][], but this is **not officially supported**. Alternately, you can use an older version of Parsimmon which supports IE8. | ||
\* _IE9 does not support "strict mode", but Parsimmon does not require it._ | ||
## Module usage | ||
``` | ||
npm install --save parsimmon | ||
``` | ||
## Browser usage | ||
To download the latest browser build, use the [unpkg version][]. Parsimmon is exposed as a global variable called `Parsimmon`. For more information on how to use unpkg, see the [unpkg homepage][]. | ||
--> | ||
## API Documentation | ||
@@ -84,3 +104,3 @@ | ||
Parsimmon is also compatible with [fantasyland][]. It is a Semigroup, an Applicative Functor, and a Monad. | ||
Parsimmon is also compatible with [fantasyland][]. It implements Semigroup, Apply, Applicative, Functor, Chain, and Monad. | ||
@@ -103,1 +123,3 @@ [@bd82]: https://github.com/bd82 | ||
[perf]: https://sap.github.io/chevrotain/performance/ | ||
[es5]: https://kangax.github.io/compat-table/es5/ | ||
[es5-shim]: https://github.com/es-shims/es5-shim |
1342
src/parsimmon.js
@@ -1,795 +0,795 @@ | ||
/* global module, define */ | ||
'use strict'; | ||
// This unsightly UMD-module header is here to make this code work without | ||
// modification with CommonJS, AMD, and browser globals. | ||
(function(root, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
// AMD. Register as an anonymous module. | ||
define([], factory); | ||
} else if (typeof module === 'object' && module.exports) { | ||
// Node. Does not work with strict CommonJS, but | ||
// only CommonJS-like environments that support module.exports, | ||
// like Node. | ||
module.exports = factory(); | ||
} else { | ||
// Browser globals (root is window). | ||
root.Parsimmon = factory(); | ||
function Parsimmon(action) { | ||
if (!(this instanceof Parsimmon)) { | ||
return new Parsimmon(action); | ||
} | ||
}(this, function() { | ||
'use strict'; | ||
this._ = action; | ||
} | ||
// The Parser object is a wrapper for a parser function. | ||
// Externally, you use one to parse a string by calling | ||
// var result = SomeParser.parse('Me Me Me! Parse Me!'); | ||
// You should never call the constructor, rather you should | ||
// construct your Parser from the base parsers and the | ||
// parser combinator methods. | ||
function Parsimmon(action) { | ||
if (!(this instanceof Parsimmon)) { | ||
return new Parsimmon(action); | ||
} | ||
this._ = action; | ||
} | ||
var _ = Parsimmon.prototype; | ||
function isParser(obj) { | ||
return obj instanceof Parsimmon; | ||
} | ||
// -*- Helpers -*- | ||
var _ = Parsimmon.prototype; | ||
function isParser(obj) { | ||
return obj instanceof Parsimmon; | ||
} | ||
function makeSuccess(index, value) { | ||
return { | ||
status: true, | ||
index: index, | ||
value: value, | ||
furthest: -1, | ||
expected: [] | ||
}; | ||
} | ||
function isArray(x) { | ||
return {}.toString.call(x) === '[object Array]'; | ||
} | ||
function makeFailure(index, expected) { | ||
return { | ||
status: false, | ||
index: -1, | ||
value: null, | ||
furthest: index, | ||
expected: [expected] | ||
}; | ||
function makeSuccess(index, value) { | ||
return { | ||
status: true, | ||
index: index, | ||
value: value, | ||
furthest: -1, | ||
expected: [] | ||
}; | ||
} | ||
function makeFailure(index, expected) { | ||
return { | ||
status: false, | ||
index: -1, | ||
value: null, | ||
furthest: index, | ||
expected: [expected] | ||
}; | ||
} | ||
function mergeReplies(result, last) { | ||
if (!last) { | ||
return result; | ||
} | ||
if (result.furthest > last.furthest) { | ||
return result; | ||
} | ||
var expected = (result.furthest === last.furthest) | ||
? unsafeUnion(result.expected, last.expected) | ||
: last.expected; | ||
return { | ||
status: result.status, | ||
index: result.index, | ||
value: result.value, | ||
furthest: last.furthest, | ||
expected: expected | ||
}; | ||
} | ||
function mergeReplies(result, last) { | ||
if (!last) { | ||
return result; | ||
} | ||
if (result.furthest > last.furthest) { | ||
return result; | ||
} | ||
var expected = (result.furthest === last.furthest) | ||
? unsafeUnion(result.expected, last.expected) | ||
: last.expected; | ||
return { | ||
status: result.status, | ||
index: result.index, | ||
value: result.value, | ||
furthest: last.furthest, | ||
expected: expected | ||
}; | ||
function makeLineColumnIndex(input, i) { | ||
var lines = input.slice(0, i).split('\n'); | ||
// Note that unlike the character offset, the line and column offsets are | ||
// 1-based. | ||
var lineWeAreUpTo = lines.length; | ||
var columnWeAreUpTo = lines[lines.length - 1].length + 1; | ||
return { | ||
offset: i, | ||
line: lineWeAreUpTo, | ||
column: columnWeAreUpTo | ||
}; | ||
} | ||
// Returns the sorted set union of two arrays of strings. Note that if both | ||
// arrays are empty, it simply returns the first array, and if exactly one | ||
// array is empty, it returns the other one unsorted. This is safe because | ||
// expectation arrays always start as [] or [x], so as long as we merge with | ||
// this function, we know they stay in sorted order. | ||
function unsafeUnion(xs, ys) { | ||
// Exit early if either array is empty (common case) | ||
var xn = xs.length; | ||
var yn = ys.length; | ||
if (xn === 0) { | ||
return ys; | ||
} else if (yn === 0) { | ||
return xs; | ||
} | ||
// Returns the sorted set union of two arrays of strings. Note that if both | ||
// arrays are empty, it simply returns the first array, and if exactly one | ||
// array is empty, it returns the other one unsorted. This is safe because | ||
// expectation arrays always start as [] or [x], so as long as we merge with | ||
// this function, we know they stay in sorted order. | ||
function unsafeUnion(xs, ys) { | ||
// Exit early if either array is empty (common case) | ||
var xn = xs.length; | ||
var yn = ys.length; | ||
if (xn === 0) { | ||
return ys; | ||
} else if (yn === 0) { | ||
return xs; | ||
// Two non-empty arrays: do the full algorithm | ||
var obj = {}; | ||
for (var i = 0; i < xn; i++) { | ||
obj[xs[i]] = true; | ||
} | ||
for (var j = 0; j < yn; j++) { | ||
obj[ys[j]] = true; | ||
} | ||
var keys = []; | ||
for (var k in obj) { | ||
if (obj.hasOwnProperty(k)) { | ||
keys.push(k); | ||
} | ||
// Two non-empty arrays: do the full algorithm | ||
var obj = {}; | ||
for (var i = 0; i < xn; i++) { | ||
obj[xs[i]] = true; | ||
} | ||
for (var j = 0; j < yn; j++) { | ||
obj[ys[j]] = true; | ||
} | ||
var keys = []; | ||
for (var k in obj) { | ||
if (obj.hasOwnProperty(k)) { | ||
keys.push(k); | ||
} | ||
} | ||
keys.sort(); | ||
return keys; | ||
} | ||
keys.sort(); | ||
return keys; | ||
} | ||
// For ensuring we have the right argument types | ||
function assertParser(p) { | ||
if (!isParser(p)) { | ||
throw new Error('not a parser: ' + p); | ||
} | ||
function assertParser(p) { | ||
if (!isParser(p)) { | ||
throw new Error('not a parser: ' + p); | ||
} | ||
} | ||
// TODO: Switch to Array.isArray eventually. | ||
function assertArray(x) { | ||
if ({}.toString.call(x) !== '[object Array]') { | ||
throw new Error('not an array: ' + x); | ||
} | ||
// TODO[ES5]: Switch to Array.isArray eventually. | ||
function assertArray(x) { | ||
if (!isArray(x)) { | ||
throw new Error('not an array: ' + x); | ||
} | ||
} | ||
function assertNumber(x) { | ||
if (typeof x !== 'number') { | ||
throw new Error('not a number: ' + x); | ||
} | ||
function assertNumber(x) { | ||
if (typeof x !== 'number') { | ||
throw new Error('not a number: ' + x); | ||
} | ||
} | ||
function assertRegexp(x) { | ||
if (!(x instanceof RegExp)) { | ||
throw new Error('not a regexp: '+x); | ||
} | ||
var f = flags(x); | ||
for (var i = 0; i < f.length; i++) { | ||
var c = f.charAt(i); | ||
// Only allow regexp flags [imu] for now, since [g] and [y] specifically | ||
// mess up Parsimmon. If more non-stateful regexp flags are added in the | ||
// future, this will need to be revisited. | ||
if (c != 'i' && c != 'm' && c != 'u') { | ||
throw new Error('unsupported regexp flag "' + c + '": ' + x); | ||
} | ||
} | ||
function assertRegexp(x) { | ||
if (!(x instanceof RegExp)) { | ||
throw new Error('not a regexp: '+x); | ||
} | ||
function assertFunction(x) { | ||
if (typeof x !== 'function') { | ||
throw new Error('not a function: ' + x); | ||
var f = flags(x); | ||
for (var i = 0; i < f.length; i++) { | ||
var c = f.charAt(i); | ||
// Only allow regexp flags [imu] for now, since [g] and [y] specifically | ||
// mess up Parsimmon. If more non-stateful regexp flags are added in the | ||
// future, this will need to be revisited. | ||
if (c !== 'i' && c !== 'm' && c !== 'u') { | ||
throw new Error('unsupported regexp flag "' + c + '": ' + x); | ||
} | ||
} | ||
} | ||
function assertString(x) { | ||
if (typeof x !== 'string') { | ||
throw new Error('not a string: ' + x); | ||
} | ||
function assertFunction(x) { | ||
if (typeof x !== 'function') { | ||
throw new Error('not a function: ' + x); | ||
} | ||
} | ||
function formatExpected(expected) { | ||
if (expected.length === 1) { | ||
return expected[0]; | ||
} | ||
return 'one of ' + expected.join(', '); | ||
function assertString(x) { | ||
if (typeof x !== 'string') { | ||
throw new Error('not a string: ' + x); | ||
} | ||
} | ||
function formatGot(input, error) { | ||
var index = error.index; | ||
var i = index.offset; | ||
if (i === input.length) { | ||
return ', got the end of the input'; | ||
} | ||
var prefix = (i > 0 ? '\'...' : '\''); | ||
var suffix = (input.length - i > 12 ? '...\'' : '\''); | ||
return ' at line ' + index.line + ' column ' + index.column | ||
+ ', got ' + prefix + input.slice(i, i + 12) + suffix; | ||
function formatExpected(expected) { | ||
if (expected.length === 1) { | ||
return expected[0]; | ||
} | ||
return 'one of ' + expected.join(', '); | ||
} | ||
function formatError(input, error) { | ||
return 'expected ' + | ||
formatExpected(error.expected) + | ||
formatGot(input, error); | ||
function formatGot(input, error) { | ||
var index = error.index; | ||
var i = index.offset; | ||
if (i === input.length) { | ||
return ', got the end of the input'; | ||
} | ||
var prefix = (i > 0 ? '\'...' : '\''); | ||
var suffix = (input.length - i > 12 ? '...\'' : '\''); | ||
return ' at line ' + index.line + ' column ' + index.column | ||
+ ', got ' + prefix + input.slice(i, i + 12) + suffix; | ||
} | ||
_.parse = function(input) { | ||
if (typeof input !== 'string') { | ||
throw new Error('.parse must be called with a string as its argument'); | ||
} | ||
var result = this.skip(eof)._(input, 0); | ||
function formatError(input, error) { | ||
return 'expected ' + | ||
formatExpected(error.expected) + | ||
formatGot(input, error); | ||
} | ||
return result.status ? { | ||
status: true, | ||
value: result.value | ||
} : { | ||
status: false, | ||
index: makeLineColumnIndex(input, result.furthest), | ||
expected: result.expected | ||
}; | ||
}; | ||
function flags(re) { | ||
var s = '' + re; | ||
return s.slice(s.lastIndexOf('/') + 1); | ||
} | ||
_.tryParse = function(str) { | ||
var result = this.parse(str); | ||
if (result.status) { | ||
return result.value; | ||
} else { | ||
var msg = formatError(str, result); | ||
var err = new Error(msg); | ||
err.type = 'ParsimmonError'; | ||
err.result = result; | ||
throw err; | ||
} | ||
}; | ||
function anchoredRegexp(re) { | ||
return RegExp('^(?:' + re.source + ')', flags(re)); | ||
} | ||
// [Parsimmon a] -> Parsimmon [a] | ||
function seq() { | ||
var parsers = [].slice.call(arguments); | ||
var numParsers = parsers.length; | ||
// -*- Combinators -*- | ||
function seq() { | ||
var parsers = [].slice.call(arguments); | ||
var numParsers = parsers.length; | ||
for (var j = 0; j < numParsers; j += 1) { | ||
assertParser(parsers[j]); | ||
} | ||
return Parsimmon(function(input, i) { | ||
var result; | ||
var accum = new Array(numParsers); | ||
for (var j = 0; j < numParsers; j += 1) { | ||
assertParser(parsers[j]); | ||
result = mergeReplies(parsers[j]._(input, i), result); | ||
if (!result.status) { | ||
return result; | ||
} | ||
accum[j] = result.value; | ||
i = result.index; | ||
} | ||
return Parsimmon(function(input, i) { | ||
var result; | ||
var accum = new Array(numParsers); | ||
for (var j = 0; j < numParsers; j += 1) { | ||
result = mergeReplies(parsers[j]._(input, i), result); | ||
if (!result.status) { | ||
return result; | ||
return mergeReplies(makeSuccess(i, accum), result); | ||
}); | ||
} | ||
function seqObj() { | ||
var seenKeys = {}; | ||
var totalKeys = 0; | ||
var parsers = [].slice.call(arguments); | ||
var numParsers = parsers.length; | ||
for (var j = 0; j < numParsers; j += 1) { | ||
var p = parsers[j]; | ||
if (isParser(p)) { | ||
continue; | ||
} | ||
if (isArray(p)) { | ||
var isWellFormed = | ||
p.length === 2 && | ||
typeof p[0] === 'string' && | ||
isParser(p[1]); | ||
if (isWellFormed) { | ||
var key = p[0]; | ||
if (seenKeys[key]) { | ||
throw new Error('seqObj: duplicate key ' + key); | ||
} | ||
accum[j] = result.value; | ||
i = result.index; | ||
seenKeys[key] = true; | ||
totalKeys++; | ||
continue; | ||
} | ||
return mergeReplies(makeSuccess(i, accum), result); | ||
}); | ||
} | ||
function seqMap() { | ||
var args = [].slice.call(arguments); | ||
if (args.length === 0) { | ||
throw new Error('seqMap needs at least one argument'); | ||
} | ||
var mapper = args.pop(); | ||
assertFunction(mapper); | ||
return seq.apply(null, args).map(function(results) { | ||
return mapper.apply(null, results); | ||
}); | ||
throw new Error( | ||
'seqObj arguments must be parsers or ' + | ||
'[string, parser] array pairs.' | ||
); | ||
} | ||
// Revisit this with Object.keys and .bind when we drop ES3 support. | ||
function createLanguage(parsers) { | ||
var language = {}; | ||
for (var key in parsers) { | ||
if ({}.hasOwnProperty.call(parsers, key)) { | ||
(function(key) { | ||
var func = function() { | ||
return parsers[key](language); | ||
}; | ||
language[key] = lazy(func); | ||
}(key)); | ||
if (totalKeys === 0) { | ||
throw new Error('seqObj expects at least one named parser, found zero'); | ||
} | ||
return Parsimmon(function(input, i) { | ||
var result; | ||
var accum = {}; | ||
for (var j = 0; j < numParsers; j += 1) { | ||
var name; | ||
var parser; | ||
if (isArray(parsers[j])) { | ||
name = parsers[j][0]; | ||
parser = parsers[j][1]; | ||
} else { | ||
name = null; | ||
parser = parsers[j]; | ||
} | ||
result = mergeReplies(parser._(input, i), result); | ||
if (!result.status) { | ||
return result; | ||
} | ||
if (name) { | ||
accum[name] = result.value; | ||
} | ||
i = result.index; | ||
} | ||
return language; | ||
} | ||
return mergeReplies(makeSuccess(i, accum), result); | ||
}); | ||
} | ||
/** | ||
* Allows to add custom primitive parsers | ||
*/ | ||
function custom(parsingFunction) { | ||
return Parsimmon(parsingFunction(makeSuccess, makeFailure)); | ||
function seqMap() { | ||
var args = [].slice.call(arguments); | ||
if (args.length === 0) { | ||
throw new Error('seqMap needs at least one argument'); | ||
} | ||
var mapper = args.pop(); | ||
assertFunction(mapper); | ||
return seq.apply(null, args).map(function(results) { | ||
return mapper.apply(null, results); | ||
}); | ||
} | ||
function alt() { | ||
var parsers = [].slice.call(arguments); | ||
var numParsers = parsers.length; | ||
if (numParsers === 0) { | ||
return fail('zero alternates'); | ||
// TODO[ES5]: Revisit this with Object.keys and .bind. | ||
function createLanguage(parsers) { | ||
var language = {}; | ||
for (var key in parsers) { | ||
if ({}.hasOwnProperty.call(parsers, key)) { | ||
(function(key) { | ||
var func = function() { | ||
return parsers[key](language); | ||
}; | ||
language[key] = lazy(func); | ||
}(key)); | ||
} | ||
for (var j = 0; j < numParsers; j += 1) { | ||
assertParser(parsers[j]); | ||
} | ||
return Parsimmon(function(input, i) { | ||
var result; | ||
for (var j = 0; j < parsers.length; j += 1) { | ||
result = mergeReplies(parsers[j]._(input, i), result); | ||
if (result.status) return result; | ||
} | ||
return result; | ||
}); | ||
} | ||
return language; | ||
} | ||
function sepBy(parser, separator) { | ||
// Argument asserted by sepBy1 | ||
return sepBy1(parser, separator).or(succeed([])); | ||
function alt() { | ||
var parsers = [].slice.call(arguments); | ||
var numParsers = parsers.length; | ||
if (numParsers === 0) { | ||
return fail('zero alternates'); | ||
} | ||
for (var j = 0; j < numParsers; j += 1) { | ||
assertParser(parsers[j]); | ||
} | ||
return Parsimmon(function(input, i) { | ||
var result; | ||
for (var j = 0; j < parsers.length; j += 1) { | ||
result = mergeReplies(parsers[j]._(input, i), result); | ||
if (result.status) { | ||
return result; | ||
} | ||
} | ||
return result; | ||
}); | ||
} | ||
function sepBy1(parser, separator) { | ||
assertParser(parser); | ||
assertParser(separator); | ||
var pairs = separator.then(parser).many(); | ||
return parser.chain(function(r) { | ||
return pairs.map(function(rs) { | ||
return [r].concat(rs); | ||
}); | ||
function sepBy(parser, separator) { | ||
// Argument asserted by sepBy1 | ||
return sepBy1(parser, separator).or(succeed([])); | ||
} | ||
function sepBy1(parser, separator) { | ||
assertParser(parser); | ||
assertParser(separator); | ||
var pairs = separator.then(parser).many(); | ||
return parser.chain(function(r) { | ||
return pairs.map(function(rs) { | ||
return [r].concat(rs); | ||
}); | ||
} | ||
}); | ||
} | ||
// -*- primitive combinators -*- // | ||
_.or = function(alternative) { | ||
return alt(this, alternative); | ||
}; | ||
// -*- Core Parsing Methods -*- | ||
_.trim = function(parser) { | ||
return this.wrap(parser, parser); | ||
_.parse = function(input) { | ||
if (typeof input !== 'string') { | ||
throw new Error('.parse must be called with a string as its argument'); | ||
} | ||
var result = this.skip(eof)._(input, 0); | ||
if (result.status) { | ||
return { | ||
status: true, | ||
value: result.value | ||
}; | ||
} | ||
return { | ||
status: false, | ||
index: makeLineColumnIndex(input, result.furthest), | ||
expected: result.expected | ||
}; | ||
}; | ||
_.wrap = function(leftParser, rightParser) { | ||
return seqMap( | ||
leftParser, | ||
this, | ||
rightParser, | ||
function(left, middle) { | ||
return middle; | ||
} | ||
); | ||
}; | ||
// -*- Other Methods -*- | ||
_.thru = function(wrapper) { | ||
return wrapper(this); | ||
}; | ||
_.tryParse = function(str) { | ||
var result = this.parse(str); | ||
if (result.status) { | ||
return result.value; | ||
} else { | ||
var msg = formatError(str, result); | ||
var err = new Error(msg); | ||
err.type = 'ParsimmonError'; | ||
err.result = result; | ||
throw err; | ||
} | ||
}; | ||
_.then = function(next) { | ||
if (typeof next === 'function') { | ||
throw new Error('chaining features of .then are no longer supported, use .chain instead'); | ||
_.or = function(alternative) { | ||
return alt(this, alternative); | ||
}; | ||
_.trim = function(parser) { | ||
return this.wrap(parser, parser); | ||
}; | ||
_.wrap = function(leftParser, rightParser) { | ||
return seqMap( | ||
leftParser, | ||
this, | ||
rightParser, | ||
function(left, middle) { | ||
return middle; | ||
} | ||
assertParser(next); | ||
return seq(this, next).map(function(results) { return results[1]; }); | ||
}; | ||
); | ||
}; | ||
// -*- optimized iterative combinators -*- // | ||
// equivalent to: | ||
// _.many = function() { | ||
// return this.times(0, Infinity); | ||
// }; | ||
// or, more explicitly: | ||
// _.many = function() { | ||
// var self = this; | ||
// return self.then(function(x) { | ||
// return self.many().then(function(xs) { | ||
// return [x].concat(xs); | ||
// }); | ||
// }).or(succeed([])); | ||
// }; | ||
_.many = function() { | ||
var self = this; | ||
_.thru = function(wrapper) { | ||
return wrapper(this); | ||
}; | ||
return Parsimmon(function(input, i) { | ||
var accum = []; | ||
var result = undefined; | ||
_.then = function(next) { | ||
assertParser(next); | ||
return seq(this, next).map(function(results) { return results[1]; }); | ||
}; | ||
for (;;) { | ||
result = mergeReplies(self._(input, i), result); | ||
if (result.status) { | ||
i = result.index; | ||
accum.push(result.value); | ||
} else { | ||
return mergeReplies(makeSuccess(i, accum), result); | ||
} | ||
} | ||
}); | ||
}; | ||
_.many = function() { | ||
var self = this; | ||
_.tie = function() { | ||
return this.map(function(args) { | ||
assertArray(args); | ||
var s = ''; | ||
for (var i = 0; i < args.length; i++) { | ||
assertString(args[i]); | ||
s += args[i]; | ||
return Parsimmon(function(input, i) { | ||
var accum = []; | ||
var result = undefined; | ||
for (;;) { | ||
result = mergeReplies(self._(input, i), result); | ||
if (result.status) { | ||
i = result.index; | ||
accum.push(result.value); | ||
} else { | ||
return mergeReplies(makeSuccess(i, accum), result); | ||
} | ||
return s; | ||
}); | ||
}; | ||
} | ||
}); | ||
}; | ||
// equivalent to: | ||
// _.times = function(min, max) { | ||
// if (arguments.length < 2) max = min; | ||
// var self = this; | ||
// if (min > 0) { | ||
// return self.then(function(x) { | ||
// return self.times(min - 1, max - 1).then(function(xs) { | ||
// return [x].concat(xs); | ||
// }); | ||
// }); | ||
// } | ||
// else if (max > 0) { | ||
// return self.then(function(x) { | ||
// return self.times(0, max - 1).then(function(xs) { | ||
// return [x].concat(xs); | ||
// }); | ||
// }).or(succeed([])); | ||
// } | ||
// else return succeed([]); | ||
// }; | ||
_.times = function(min, max) { | ||
var self = this; | ||
if (arguments.length < 2) { | ||
max = min; | ||
_.tie = function() { | ||
return this.map(function(args) { | ||
assertArray(args); | ||
var s = ''; | ||
for (var i = 0; i < args.length; i++) { | ||
assertString(args[i]); | ||
s += args[i]; | ||
} | ||
assertNumber(min); | ||
assertNumber(max); | ||
return Parsimmon(function(input, i) { | ||
var accum = []; | ||
var result = undefined; | ||
var prevResult = undefined; | ||
for (var times = 0; times < min; times += 1) { | ||
result = self._(input, i); | ||
prevResult = mergeReplies(result, prevResult); | ||
if (result.status) { | ||
i = result.index; | ||
accum.push(result.value); | ||
} else { | ||
return prevResult; | ||
} | ||
return s; | ||
}); | ||
}; | ||
_.times = function(min, max) { | ||
var self = this; | ||
if (arguments.length < 2) { | ||
max = min; | ||
} | ||
assertNumber(min); | ||
assertNumber(max); | ||
return Parsimmon(function(input, i) { | ||
var accum = []; | ||
var result = undefined; | ||
var prevResult = undefined; | ||
for (var times = 0; times < min; times += 1) { | ||
result = self._(input, i); | ||
prevResult = mergeReplies(result, prevResult); | ||
if (result.status) { | ||
i = result.index; | ||
accum.push(result.value); | ||
} else { | ||
return prevResult; | ||
} | ||
for (; times < max; times += 1) { | ||
result = self._(input, i); | ||
prevResult = mergeReplies(result, prevResult); | ||
if (result.status) { | ||
i = result.index; | ||
accum.push(result.value); | ||
} else { | ||
break; | ||
} | ||
} | ||
for (; times < max; times += 1) { | ||
result = self._(input, i); | ||
prevResult = mergeReplies(result, prevResult); | ||
if (result.status) { | ||
i = result.index; | ||
accum.push(result.value); | ||
} else { | ||
break; | ||
} | ||
return mergeReplies(makeSuccess(i, accum), prevResult); | ||
}); | ||
}; | ||
} | ||
return mergeReplies(makeSuccess(i, accum), prevResult); | ||
}); | ||
}; | ||
// -*- higher-level combinators -*- // | ||
_.result = function(res) { | ||
return this.map(function() { | ||
return res; | ||
}); | ||
}; | ||
_.result = function(res) { | ||
return this.map(function() { | ||
return res; | ||
}); | ||
}; | ||
_.atMost = function(n) { | ||
return this.times(0, n); | ||
}; | ||
_.atMost = function(n) { | ||
return this.times(0, n); | ||
}; | ||
_.atLeast = function(n) { | ||
return seqMap(this.times(n), this.many(), function(init, rest) { | ||
return init.concat(rest); | ||
}); | ||
}; | ||
_.atLeast = function(n) { | ||
return seqMap(this.times(n), this.many(), function(init, rest) { | ||
return init.concat(rest); | ||
}); | ||
}; | ||
_.map = function(fn) { | ||
assertFunction(fn); | ||
var self = this; | ||
return Parsimmon(function(input, i) { | ||
var result = self._(input, i); | ||
if (!result.status) { | ||
return result; | ||
} | ||
return mergeReplies(makeSuccess(result.index, fn(result.value)), result); | ||
}); | ||
}; | ||
_['fantasy-land/map'] = _.map; | ||
_.map = function(fn) { | ||
assertFunction(fn); | ||
var self = this; | ||
return Parsimmon(function(input, i) { | ||
var result = self._(input, i); | ||
if (!result.status) { | ||
return result; | ||
} | ||
return mergeReplies(makeSuccess(result.index, fn(result.value)), result); | ||
}); | ||
}; | ||
_.skip = function(next) { | ||
return seq(this, next).map(function(results) { return results[0]; }); | ||
}; | ||
_.skip = function(next) { | ||
return seq(this, next).map(function(results) { return results[0]; }); | ||
}; | ||
_.mark = function() { | ||
return seqMap(index, this, index, function(start, value, end) { | ||
return { | ||
start: start, | ||
value: value, | ||
end: end | ||
}; | ||
}); | ||
}; | ||
_.mark = function() { | ||
return seqMap(index, this, index, function(start, value, end) { | ||
return { | ||
start: start, | ||
value: value, | ||
end: end | ||
}; | ||
}); | ||
}; | ||
_.node = function(name) { | ||
return seqMap(index, this, index, function(start, value, end) { | ||
return { | ||
name: name, | ||
value: value, | ||
start: start, | ||
end: end | ||
}; | ||
}); | ||
}; | ||
_.node = function(name) { | ||
return seqMap(index, this, index, function(start, value, end) { | ||
return { | ||
name: name, | ||
value: value, | ||
start: start, | ||
end: end | ||
}; | ||
}); | ||
}; | ||
_.sepBy = function(separator) { | ||
return sepBy(this, separator); | ||
}; | ||
_.sepBy = function(separator) { | ||
return sepBy(this, separator); | ||
}; | ||
_.sepBy1 = function(separator) { | ||
return sepBy1(this, separator); | ||
}; | ||
_.sepBy1 = function(separator) { | ||
return sepBy1(this, separator); | ||
}; | ||
_.lookahead = function(x) { | ||
return this.skip(lookahead(x)); | ||
}; | ||
_.lookahead = function(x) { | ||
return this.skip(lookahead(x)); | ||
}; | ||
_.notFollowedBy = function(x) { | ||
return this.skip(notFollowedBy(x)); | ||
}; | ||
_.notFollowedBy = function(x) { | ||
return this.skip(notFollowedBy(x)); | ||
}; | ||
_.desc = function(expected) { | ||
var self = this; | ||
return Parsimmon(function(input, i) { | ||
var reply = self._(input, i); | ||
if (!reply.status) { | ||
reply.expected = [expected]; | ||
} | ||
return reply; | ||
}); | ||
}; | ||
_.desc = function(expected) { | ||
var self = this; | ||
return Parsimmon(function(input, i) { | ||
var reply = self._(input, i); | ||
if (!reply.status) { | ||
reply.expected = [expected]; | ||
} | ||
return reply; | ||
}); | ||
}; | ||
_.fallback = function(result) { | ||
return this.or(succeed(result)); | ||
}; | ||
_.fallback = function(result) { | ||
return this.or(succeed(result)); | ||
}; | ||
// -*- primitive parsers -*- // | ||
function string(str) { | ||
assertString(str); | ||
var expected = '\'' + str + '\''; | ||
return Parsimmon(function(input, i) { | ||
var j = i + str.length; | ||
var head = input.slice(i, j); | ||
if (head === str) { | ||
return makeSuccess(j, head); | ||
} else { | ||
return makeFailure(i, expected); | ||
} | ||
}); | ||
} | ||
_.ap = function(other) { | ||
return seqMap(other, this, function(f, x) { | ||
return f(x); | ||
}); | ||
}; | ||
function flags(re) { | ||
var s = '' + re; | ||
return s.slice(s.lastIndexOf('/') + 1); | ||
} | ||
_.chain = function(f) { | ||
var self = this; | ||
return Parsimmon(function(input, i) { | ||
var result = self._(input, i); | ||
if (!result.status) { | ||
return result; | ||
} | ||
var nextParser = f(result.value); | ||
return mergeReplies(nextParser._(input, result.index), result); | ||
}); | ||
}; | ||
function anchoredRegexp(re) { | ||
return RegExp('^(?:' + re.source + ')', flags(re)); | ||
} | ||
// -*- Constructors -*- | ||
function regexp(re, group) { | ||
assertRegexp(re); | ||
if (arguments.length >= 2) { | ||
assertNumber(group); | ||
function string(str) { | ||
assertString(str); | ||
var expected = '\'' + str + '\''; | ||
return Parsimmon(function(input, i) { | ||
var j = i + str.length; | ||
var head = input.slice(i, j); | ||
if (head === str) { | ||
return makeSuccess(j, head); | ||
} else { | ||
group = 0; | ||
} | ||
var anchored = anchoredRegexp(re); | ||
var expected = '' + re; | ||
return Parsimmon(function(input, i) { | ||
var match = anchored.exec(input.slice(i)); | ||
if (match) { | ||
var fullMatch = match[0]; | ||
var groupMatch = match[group]; | ||
if (groupMatch != null) { | ||
return makeSuccess(i + fullMatch.length, groupMatch); | ||
} | ||
} | ||
return makeFailure(i, expected); | ||
}); | ||
} | ||
function succeed(value) { | ||
return Parsimmon(function(input, i) { | ||
return makeSuccess(i, value); | ||
}); | ||
} | ||
function fail(expected) { | ||
return Parsimmon(function(input, i) { | ||
return makeFailure(i, expected); | ||
}); | ||
} | ||
function lookahead(x) { | ||
if (isParser(x)) { | ||
return Parsimmon(function(input, i) { | ||
var result = x._(input, i); | ||
result.index = i; | ||
result.value = ''; | ||
return result; | ||
}); | ||
} else if (typeof x === 'string') { | ||
return lookahead(string(x)); | ||
} else if (x instanceof RegExp) { | ||
return lookahead(regexp(x)); | ||
} | ||
throw new Error('not a string, regexp, or parser: ' + x); | ||
} | ||
}); | ||
} | ||
function notFollowedBy(parser) { | ||
assertParser(parser); | ||
return Parsimmon(function(input, i) { | ||
var result = parser._(input, i); | ||
var text = input.slice(i, result.index); | ||
return result.status | ||
? makeFailure(i, 'not "' + text + '"') | ||
: makeSuccess(i, null); | ||
}); | ||
function regexp(re, group) { | ||
assertRegexp(re); | ||
if (arguments.length >= 2) { | ||
assertNumber(group); | ||
} else { | ||
group = 0; | ||
} | ||
var any = Parsimmon(function(input, i) { | ||
if (i >= input.length) { | ||
return makeFailure(i, 'any character'); | ||
var anchored = anchoredRegexp(re); | ||
var expected = '' + re; | ||
return Parsimmon(function(input, i) { | ||
var match = anchored.exec(input.slice(i)); | ||
if (match) { | ||
var fullMatch = match[0]; | ||
var groupMatch = match[group]; | ||
if (groupMatch !== null) { | ||
return makeSuccess(i + fullMatch.length, groupMatch); | ||
} | ||
} | ||
return makeSuccess(i+1, input.charAt(i)); | ||
return makeFailure(i, expected); | ||
}); | ||
} | ||
var all = Parsimmon(function(input, i) { | ||
return makeSuccess(input.length, input.slice(i)); | ||
function succeed(value) { | ||
return Parsimmon(function(input, i) { | ||
return makeSuccess(i, value); | ||
}); | ||
} | ||
var eof = Parsimmon(function(input, i) { | ||
if (i < input.length) { | ||
return makeFailure(i, 'EOF'); | ||
} | ||
return makeSuccess(i, null); | ||
function fail(expected) { | ||
return Parsimmon(function(input, i) { | ||
return makeFailure(i, expected); | ||
}); | ||
} | ||
function test(predicate) { | ||
assertFunction(predicate); | ||
function lookahead(x) { | ||
if (isParser(x)) { | ||
return Parsimmon(function(input, i) { | ||
var char = input.charAt(i); | ||
if (i < input.length && predicate(char)) { | ||
return makeSuccess(i + 1, char); | ||
} else { | ||
return makeFailure(i, 'a character matching ' + predicate); | ||
} | ||
var result = x._(input, i); | ||
result.index = i; | ||
result.value = ''; | ||
return result; | ||
}); | ||
} else if (typeof x === 'string') { | ||
return lookahead(string(x)); | ||
} else if (x instanceof RegExp) { | ||
return lookahead(regexp(x)); | ||
} | ||
throw new Error('not a string, regexp, or parser: ' + x); | ||
} | ||
function oneOf(str) { | ||
return test(function(ch) { | ||
return str.indexOf(ch) >= 0; | ||
}); | ||
} | ||
function notFollowedBy(parser) { | ||
assertParser(parser); | ||
return Parsimmon(function(input, i) { | ||
var result = parser._(input, i); | ||
var text = input.slice(i, result.index); | ||
return result.status | ||
? makeFailure(i, 'not "' + text + '"') | ||
: makeSuccess(i, null); | ||
}); | ||
} | ||
function noneOf(str) { | ||
return test(function(ch) { | ||
return str.indexOf(ch) < 0; | ||
}); | ||
} | ||
function test(predicate) { | ||
assertFunction(predicate); | ||
return Parsimmon(function(input, i) { | ||
var char = input.charAt(i); | ||
if (i < input.length && predicate(char)) { | ||
return makeSuccess(i + 1, char); | ||
} else { | ||
return makeFailure(i, 'a character matching ' + predicate); | ||
} | ||
}); | ||
} | ||
// TODO: Improve error message using JSON.stringify eventually. | ||
function range(begin, end) { | ||
return test(function(ch) { | ||
return begin <= ch && ch <= end; | ||
}).desc(begin + '-' + end); | ||
} | ||
function oneOf(str) { | ||
return test(function(ch) { | ||
return str.indexOf(ch) >= 0; | ||
}); | ||
} | ||
function takeWhile(predicate) { | ||
assertFunction(predicate); | ||
function noneOf(str) { | ||
return test(function(ch) { | ||
return str.indexOf(ch) < 0; | ||
}); | ||
} | ||
return Parsimmon(function(input, i) { | ||
var j = i; | ||
while (j < input.length && predicate(input.charAt(j))) { | ||
j++; | ||
} | ||
return makeSuccess(j, input.slice(i, j)); | ||
}); | ||
} | ||
function custom(parsingFunction) { | ||
return Parsimmon(parsingFunction(makeSuccess, makeFailure)); | ||
} | ||
function lazy(desc, f) { | ||
if (arguments.length < 2) { | ||
f = desc; | ||
desc = undefined; | ||
} | ||
// TODO[ES5]: Improve error message using JSON.stringify eventually. | ||
function range(begin, end) { | ||
return test(function(ch) { | ||
return begin <= ch && ch <= end; | ||
}).desc(begin + '-' + end); | ||
} | ||
var parser = Parsimmon(function(input, i) { | ||
parser._ = f()._; | ||
return parser._(input, i); | ||
}); | ||
function takeWhile(predicate) { | ||
assertFunction(predicate); | ||
if (desc) { | ||
return parser.desc(desc); | ||
} else { | ||
return parser; | ||
return Parsimmon(function(input, i) { | ||
var j = i; | ||
while (j < input.length && predicate(input.charAt(j))) { | ||
j++; | ||
} | ||
} | ||
return makeSuccess(j, input.slice(i, j)); | ||
}); | ||
} | ||
function makeLineColumnIndex(input, i) { | ||
var lines = input.slice(0, i).split('\n'); | ||
// Note that unlike the character offset, the line and column offsets are | ||
// 1-based. | ||
var lineWeAreUpTo = lines.length; | ||
var columnWeAreUpTo = lines[lines.length - 1].length + 1; | ||
return { | ||
offset: i, | ||
line: lineWeAreUpTo, | ||
column: columnWeAreUpTo | ||
}; | ||
function lazy(desc, f) { | ||
if (arguments.length < 2) { | ||
f = desc; | ||
desc = undefined; | ||
} | ||
var index = Parsimmon(function(input, i) { | ||
return makeSuccess(i, makeLineColumnIndex(input, i)); | ||
var parser = Parsimmon(function(input, i) { | ||
parser._ = f()._; | ||
return parser._(input, i); | ||
}); | ||
function empty() { | ||
return fail('fantasy-land/empty'); | ||
if (desc) { | ||
return parser.desc(desc); | ||
} else { | ||
return parser; | ||
} | ||
} | ||
// Fantasy Land Semigroup support | ||
_.concat = _.or; | ||
_['fantasy-land/concat'] = _.concat; | ||
// -*- Fantasy Land Extras -*- | ||
// Fantasy Land Semigroup and Monoid support | ||
_.empty = empty; | ||
_['fantasy-land/empty'] = _.empty; | ||
function empty() { | ||
return fail('fantasy-land/empty'); | ||
} | ||
// Fantasy Land Applicative support | ||
_.of = succeed; | ||
_['fantasy-land/of'] = _.of; | ||
_.concat = _.or; | ||
_.empty = empty; | ||
_.of = succeed; | ||
_['fantasy-land/ap'] = _.ap; | ||
_['fantasy-land/chain'] = _.chain; | ||
_['fantasy-land/concat'] = _.concat; | ||
_['fantasy-land/empty'] = _.empty; | ||
_['fantasy-land/of'] = _.of; | ||
_['fantasy-land/map'] = _.map; | ||
// Fantasy Land Applicative support | ||
_.ap = function(other) { | ||
return seqMap(other, this, function(f, x) { | ||
return f(x); | ||
}); | ||
}; | ||
_['fantasy-land/ap'] = _.ap; | ||
// -*- Base Parsers -*- | ||
// Fantasy Land Monad support | ||
_.chain = function(f) { | ||
var self = this; | ||
return Parsimmon(function(input, i) { | ||
var result = self._(input, i); | ||
if (!result.status) { | ||
return result; | ||
} | ||
var nextParser = f(result.value); | ||
return mergeReplies(nextParser._(input, result.index), result); | ||
}); | ||
}; | ||
_['fantasy-land/chain'] = _.chain; | ||
var index = Parsimmon(function(input, i) { | ||
return makeSuccess(i, makeLineColumnIndex(input, i)); | ||
}); | ||
var digit = regexp(/[0-9]/).desc('a digit'); | ||
var digits = regexp(/[0-9]*/).desc('optional digits'); | ||
var letter = regexp(/[a-z]/i).desc('a letter'); | ||
var letters = regexp(/[a-z]*/i).desc('optional letters'); | ||
var optWhitespace = regexp(/\s*/).desc('optional whitespace'); | ||
var whitespace = regexp(/\s+/).desc('whitespace'); | ||
var any = Parsimmon(function(input, i) { | ||
if (i >= input.length) { | ||
return makeFailure(i, 'any character'); | ||
} | ||
return makeSuccess(i + 1, input.charAt(i)); | ||
}); | ||
Parsimmon.createLanguage = createLanguage; | ||
Parsimmon.all = all; | ||
Parsimmon.alt = alt; | ||
Parsimmon.any = any; | ||
Parsimmon.custom = custom; | ||
Parsimmon.digit = digit; | ||
Parsimmon.digits = digits; | ||
Parsimmon.eof = eof; | ||
Parsimmon.fail = fail; | ||
Parsimmon.formatError = formatError; | ||
Parsimmon.index = index; | ||
Parsimmon.isParser = isParser; | ||
Parsimmon.lazy = lazy; | ||
Parsimmon.letter = letter; | ||
Parsimmon.letters = letters; | ||
Parsimmon.lookahead = lookahead; | ||
Parsimmon.notFollowedBy = notFollowedBy; | ||
Parsimmon.makeFailure = makeFailure; | ||
Parsimmon.makeSuccess = makeSuccess; | ||
Parsimmon.noneOf = noneOf; | ||
Parsimmon.oneOf = oneOf; | ||
Parsimmon.range = range; | ||
Parsimmon.optWhitespace = optWhitespace; | ||
Parsimmon.Parser = Parsimmon; | ||
Parsimmon.regex = regexp; | ||
Parsimmon.regexp = regexp; | ||
Parsimmon.sepBy = sepBy; | ||
Parsimmon.sepBy1 = sepBy1; | ||
Parsimmon.seq = seq; | ||
Parsimmon.seqMap = seqMap; | ||
Parsimmon.string = string; | ||
Parsimmon.succeed = succeed; | ||
Parsimmon.takeWhile = takeWhile; | ||
Parsimmon.test = test; | ||
Parsimmon.whitespace = whitespace; | ||
var all = Parsimmon(function(input, i) { | ||
return makeSuccess(input.length, input.slice(i)); | ||
}); | ||
// Fantasy Land Semigroup support | ||
Parsimmon.empty = empty; | ||
Parsimmon['fantasy-land/empty'] = empty; | ||
var eof = Parsimmon(function(input, i) { | ||
if (i < input.length) { | ||
return makeFailure(i, 'EOF'); | ||
} | ||
return makeSuccess(i, null); | ||
}); | ||
// Fantasy Land Applicative support | ||
Parsimmon.of = succeed; | ||
Parsimmon['fantasy-land/of'] = succeed; | ||
var digit = regexp(/[0-9]/).desc('a digit'); | ||
var digits = regexp(/[0-9]*/).desc('optional digits'); | ||
var letter = regexp(/[a-z]/i).desc('a letter'); | ||
var letters = regexp(/[a-z]*/i).desc('optional letters'); | ||
var optWhitespace = regexp(/\s*/).desc('optional whitespace'); | ||
var whitespace = regexp(/\s+/).desc('whitespace'); | ||
return Parsimmon; | ||
})); | ||
Parsimmon.all = all; | ||
Parsimmon.alt = alt; | ||
Parsimmon.any = any; | ||
Parsimmon.createLanguage = createLanguage; | ||
Parsimmon.custom = custom; | ||
Parsimmon.digit = digit; | ||
Parsimmon.digits = digits; | ||
Parsimmon.empty = empty; | ||
Parsimmon.eof = eof; | ||
Parsimmon.fail = fail; | ||
Parsimmon.formatError = formatError; | ||
Parsimmon.index = index; | ||
Parsimmon.isParser = isParser; | ||
Parsimmon.lazy = lazy; | ||
Parsimmon.letter = letter; | ||
Parsimmon.letters = letters; | ||
Parsimmon.lookahead = lookahead; | ||
Parsimmon.makeFailure = makeFailure; | ||
Parsimmon.makeSuccess = makeSuccess; | ||
Parsimmon.noneOf = noneOf; | ||
Parsimmon.notFollowedBy = notFollowedBy; | ||
Parsimmon.of = succeed; | ||
Parsimmon.oneOf = oneOf; | ||
Parsimmon.optWhitespace = optWhitespace; | ||
Parsimmon.Parser = Parsimmon; | ||
Parsimmon.range = range; | ||
Parsimmon.regex = regexp; | ||
Parsimmon.regexp = regexp; | ||
Parsimmon.sepBy = sepBy; | ||
Parsimmon.sepBy1 = sepBy1; | ||
Parsimmon.seq = seq; | ||
Parsimmon.seqMap = seqMap; | ||
Parsimmon.seqObj = seqObj; | ||
Parsimmon.string = string; | ||
Parsimmon.succeed = succeed; | ||
Parsimmon.takeWhile = takeWhile; | ||
Parsimmon.test = test; | ||
Parsimmon.whitespace = whitespace; | ||
Parsimmon['fantasy-land/empty'] = empty; | ||
Parsimmon['fantasy-land/of'] = succeed; | ||
module.exports = Parsimmon; |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
6
123
39377
6
709
1