master
Sven Slootweg 1 year ago
parent d34156d043
commit 22a8505797

@ -0,0 +1,3 @@
{
"extends": "@joepie91/eslint-config"
}

@ -7,8 +7,13 @@
"license": "MIT",
"dependencies": {
"as-expression": "^1.0.0",
"es6-promise-try": "^1.0.2",
"is-generator-function": "^1.0.10",
"is-regex": "^1.1.4",
"match-value": "^1.1.0"
},
"devDependencies": {
"@joepie91/eslint-config": "^1.1.1",
"eslint": "^8.27.0"
}
}

@ -0,0 +1,21 @@
"use strict";
const { NotEnoughInput, NoMatch } = require("../symbols");
module.exports = function* characterRange(instruction, state) {
let { start, end } = instruction;
// FIXME: Unicode only! Need to check if we can assume that strings are always unicode, even when the source data was interpreted as another string encoding
let codepoint = state.currentInput.codePointAt(state.currentIndex);
// FIXME: Find a way to do this generically without breaking the EndOfInput operation
if (state.currentIndex === state.currentInput.length) {
return NotEnoughInput;
} else if (codepoint >= start && codepoint <= end) {
// TODO: Should we return the codepoint in string form here? That will be unnecessary work in most cases where `wholeMatch` will be used
state.currentIndex += 1;
return;
} else {
return NoMatch;
}
};

@ -0,0 +1,24 @@
"use strict";
const { NoMatch } = require("../symbols");
module.exports = function* either(instruction, state, context) {
let { options } = instruction;
for (let option of options) {
let result = yield option;
if (result === NoMatch) {
// Restore index and try again with the next option
state.currentIndex = context.startIndex;
continue;
} else {
// Don't restore index; the match has been consumed
// FIXME: This includes NotEnoughInput! As it warrants an immediate abort. Handling of NotEnoughInput markers should be moved to a centralized place instead. Also, we should figure out exactly how to retain the current parsing position when one is encountered, and whether eg. individual core operations need to manage cursor resets for this purpose, or whether the core can centrally handle that as well, eg. by retaining the parsing stack.
return result;
}
}
// None of the options matched
return NoMatch;
};

@ -0,0 +1,18 @@
"use strict";
const { NotEnoughInput, NoMatch } = require("../symbols");
// FIXME: This is likely *completely* broken right now
module.exports = function* endOfInput(_instruction, state) {
// FIXME: Make this not order-sensitive in an `either`! Currently the NotEnoughInput marker *might* cause issues if this (zero-width) rule comes after nonzero-width rules? Need to investigate.
if (state.currentIndex === state.currentInput.length) {
if (state.isFullyLoaded) {
return true;
} else {
return NotEnoughInput;
}
} else {
return NoMatch;
}
};

@ -0,0 +1,16 @@
"use strict";
const { NoMatch, NotEnoughInput } = require("../symbols");
module.exports = function* literal(instruction, state) {
let { string } = instruction;
if (state.currentIndex + string.length > state.currentInput.length) {
return NotEnoughInput;
} else if (state.currentInput.slice(state.currentIndex, state.currentIndex + string.length) === string) {
state.currentIndex += string.length;
return string;
} else {
return NoMatch;
}
};

@ -0,0 +1,16 @@
"use strict";
const yieldcore = require("../yieldcore");
const { NoMatch } = require("../symbols");
const zeroOrMore = require("./zero-or-more");
module.exports = function* oneOrMore(instruction, state, context) {
let matches = yield yieldcore.Internal(zeroOrMore(instruction, state, context));
// FIXME: NotEnoughInput propagation necessary here?
if (matches.length > 0) {
return matches;
} else {
return NoMatch;
}
};

@ -0,0 +1,14 @@
"use strict";
const { NoMatch } = require("../symbols");
module.exports = function* optional(instruction, state, context) {
let result = yield instruction.rule;
// FIXME: NotEnoughInput handling?
if (result === NoMatch) {
return undefined; // TODO: Or return `null` instead?
} else {
return result;
}
};

@ -0,0 +1,10 @@
"use strict";
module.exports = function* peek(instruction, state, context) {
let result = yield instruction.rule;
// Reset the index, to "undo" consuming the input
state.currentIndex = context.startIndex;
return result;
};

@ -0,0 +1,15 @@
"use strict";
const yieldcore = require("../yieldcore");
const { NoMatch } = require("../symbols");
const peek = require("./peek");
module.exports = function* test(instruction, state, context) {
let result = yield* yieldcore.Internal(peek(instruction, state, context)); // FIXME: Test that this actually works
if (result === NoMatch) {
return false;
} else {
return true;
}
};

@ -0,0 +1,28 @@
"use strict";
const { NoMatch, NotEnoughInput } = require("../symbols");
module.exports = function* until(instruction, state, context) {
while (state.currentIndex < state.currentInput.length) {
let attemptIndex = state.currentIndex;
let result = yield instruction.rule;
if (result === NoMatch) {
state.currentIndex += 1;
continue;
} else {
// Un-consume the terminator we've matched, and continue parsing other rules
state.currentIndex = attemptIndex;
if (state.currentIndex > context.startIndex) {
return state.currentInput.slice(context.startIndex, state.currentIndex);
} else {
// Zero-width match; that's a fail
return NoMatch;
}
}
}
// Reached the end of the currently available input, and we still haven't encountered our terminator
return NotEnoughInput;
};

@ -0,0 +1,11 @@
"use strict";
const ifMatch = require("../if-match");
module.exports = function* wholeMatch(instruction, state, context) {
let result = yield instruction.rule;
return ifMatch(result, () => {
return state.currentInput.slice(context.startIndex, state.currentIndex);
});
};

@ -0,0 +1,23 @@
"use strict";
const { NotEnoughInput, NoMatch } = require("../symbols");
module.exports = function* zeroOrMore(instruction, state) {
let matches = [];
while (true) {
let result = yield instruction.rule;
// FIXME: is NotEnoughInput handling actually necessary here? Wouldn't that be handled by the runtime hook?
if (result === NotEnoughInput) {
// Propagate, reparse later
return NotEnoughInput;
} else if (result === NoMatch) {
break;
} else {
matches.push(result);
}
}
return matches;
};

@ -1,48 +1,84 @@
"use strict";
const { either, oneOrMore, EndOfInput } = require("./operations");
const Newline = require("./simple/lines/newline").LF;
const RestOfLine = require("./simple/lines/rest-of-line").LF;
const matchValue = require("match-value");
const { either, oneOrMore, EndOfInput, zeroOrMore, optional } = require("./operations");
const Newline = require("./simple/lines/newline").looseCRLF;
const RestOfLine = require("./simple/lines/rest-of-line").looseCRLF;
const Integer = require("./simple/numeric/integer");
const Decimal = require("./simple/numeric/decimal");
const spacedLine = require("./simple/template/spaced-line").looseCRLF;
const format = require("./simple/template/format");
function lastItem(array) {
return array[array.length - 1];
}
function line(strings, ... parsers) {
return function* () {
let parserResults = [];
for (let i = 0; i < strings.length - 1; i++) {
yield strings[i];
parserResults.push(yield parsers[i]);
}
yield lastItem(strings);
yield Newline;
return parserResults;
}
function* MaybeEmptyLines() {
yield zeroOrMore(Newline);
}
function* Playlist() {
return yield either([ MediaPlaylist ]);
}
function* FormatHeader() {
yield spacedLine`#EXTM3U`;
}
function MetaField(namePrefix, valueParser) {
// NOTE: prefix must include `:` if required, as this varies between fields
return function* CommentField() {
yield format`#${namePrefix}`;
return yield valueParser;
};
}
function* MetaLine() {
let line = yield either([
MetaField("EXTINF:", function* MetaExtraInfo() {
// TODO: Support additional property fields in EXTINF, figure out what the correct parsing rules actually are for this
let [ duration, trackTitle ] = yield spacedLine`${Decimal},${optional(RestOfLine)}`;
return { type: "track", duration, trackTitle };
}),
MetaField("PLAYLIST:", function* MetaPlaylistTitle() {
return { type: "playlist", playlistTitle: yield RestOfLine };
}),
MetaField("EXTGRP:", function* MetaGroup() {
return { type: "groupStart", name: yield RestOfLine };
})
]);
return line;
}
function* MediaPlaylist() {
yield line`#EXTM3U`;
let [ targetDuration] = yield line`#EXT-X-TARGETDURATION:${Integer}`;
yield Newline;
let playlistMeta = {};
yield FormatHeader;
let [ targetDuration ] = yield spacedLine`#EXT-X-TARGETDURATION:${Integer}`;
let items = yield oneOrMore(function* () {
let [ duration ] = yield line`#EXTINF:${Decimal},`;
let trackMeta = {};
let metaComments = yield zeroOrMore(MetaLine);
let url = yield RestOfLine;
yield MaybeEmptyLines;
for (let { type, ... properties } of metaComments) {
matchValue(type, {
track: () => {
Object.assign(trackMeta, properties);
},
playlist: () => {
Object.assign(playlistMeta, properties);
},
groupStart: () => {
// Ignore for now
}
});
}
return { url, duration };
return { url, ... trackMeta };
});
return { targetDuration, items };
return { targetDuration, items, ... playlistMeta };
}
module.exports = { Playlist };

@ -0,0 +1,13 @@
"use strict";
const { NoMatch, NotEnoughInput } = require("./symbols");
// This is a utility function for propagating NoMatches through the stack, without resorting to `throw`/`catch` (which can be slow)
// FIXME: Use a Result type instead?
module.exports = function ifMatch(testResult, produceResult) {
if (testResult === NoMatch || testResult === NotEnoughInput) {
return testResult;
} else {
return produceResult(testResult);
}
};

@ -60,19 +60,10 @@ const isRegex = require("is-regex");
const asExpression = require("as-expression");
const matchValue = require("match-value");
const util = require("util");
const yieldcore = require("./yieldcore");
const assert = require("assert");
const NoMatch = Symbol("protocolkit:NoMatch");
const NotEnoughInput = Symbol("protocolkit:NotEnoughInput");
// This is a utility function for propagating NoMatches through the stack, without resorting to `throw`/`catch` (which can be slow)
// FIXME: Use a Result type instead?
function assertMatch(testResult, produceResult) {
if (testResult === NoMatch || testResult === NotEnoughInput) {
return testResult;
} else {
return produceResult(testResult);
}
}
const { NoMatch, NotEnoughInput } = require("./symbols");
/* TO DO:
- amount of characters
@ -85,322 +76,128 @@ FEATURES:
- grammar-defined streams for large payloads
*/
function isInternalFrame(frame) {
if (process.env.DEBUG_PARSER_INTERNAL) {
return false;
} else {
return (frame.instruction === "internal");
}
}
function getStackSize(stack) {
return stack.filter((frame) => !isInternalFrame(frame)).length;
}
module.exports = {
NoMatch: NoMatch,
parse: function parse(input, rootParser) {
let currentInput = input; // TODO: Cut this down, switch to chunked API instead
let currentIndex = 0;
let inputLength = input.length;
let parserStack = [];
let inputIsEnded = true; // FIXME: Make this dynamic in streaming mode
function printIndex() {
return String(currentIndex).padStart(Math.ceil(Math.log10(input.length)));
// NOTE: `state` is mutable from within core ops, `context` is not, but both may be updated externally (eg. for input shifting)
let state = {
currentInput: input,
currentIndex: 0,
isFullyLoaded: true // FIXME: Only set to true once the input stream has been fully consumed
};
function shiftInput(bytes) {
// This function is called to remove a certain amount of bytes from the start of the currentInput; this can be done to reduce memory usage whenever the parser is at a point where backtracking is no longer possible.
// FIXME: Also debuglog input shifts.
assert(state.currentInput.length >= bytes); // FIXME: Better check
state.currentInput = state.currentInput.slice(bytes);
state.currentIndex -= bytes;
}
function applyRule(rule) {
let currentFrame = {
startPosition: currentIndex,
rule: rule
};
parserStack.push(currentFrame);
if (process.env.DEBUG_PARSER) {
// console.log(parserStack);
console.log(`>> (${printIndex()})` + " ".repeat(parserStack.length) + util.inspect(rule, { colors: true, compact: true, breakLength: Infinity }));
}
// HACK
function formatIndex() {
// This formats the current parsing index for display in debug messages, padded to the maximum possible width of any index, so that debug log entries remain visually aligned.
return String(state.currentIndex).padStart(Math.ceil(Math.log10(state.currentInput.length)));
}
function* applyRule(rule, frame, stack) {
// HACK: This converts yielded string literals into string literal matching rules.
if (typeof rule === "string") {
rule = { __protocolKitInstruction: true, type: "literal", string: rule };
} else if (isRegex(rule)) {
rule = { __protocolKitInstruction: true, type: "regex", regex: rule };
}
assert(typeof rule === "object" && rule.__protocolKitInstruction === true); // FIXME: Better error
// console.log({rule});
let result = asExpression(() => {
if (isGeneratorFunction(rule)) {
let returnValue; // FIXME: Is this correct?
let lastValue;
let done = false;
let generator = rule();
while (done === false) {
let subRule = generator.next(lastValue);
// console.log({subRule});
if (subRule.done === true) {
returnValue = subRule.value;
done = true;
} else {
lastValue = applyRule(subRule.value);
if (lastValue === NoMatch || lastValue === NotEnoughInput) {
// Don't bother parsing any further
return lastValue;
}
}
}
return returnValue;
} else if (typeof rule === "object" && rule.__protocolKitInstruction === true) {
return matchValue(rule.type, {
literal: () => {
let { string } = rule;
if (currentIndex + string.length > inputLength) {
return NotEnoughInput;
// throw new Error(`End of input reached`); // FIXME: Error type
} else if (input.slice(currentIndex, currentIndex + string.length) === string) {
currentIndex += string.length;
return string;
} else {
return NoMatch;
}
},
characterRange: () => {
// FIXME: Unicode only! Need to check if we can assume that strings are always unicode, even when the source data was interpreted as another string encoding
let codepoint = input.codePointAt(currentIndex)
// FIXME: Find a way to do this generically without breaking the EndOfInput operation
if (currentIndex === input.length) {
return NotEnoughInput;
} else if (codepoint >= rule.start && codepoint <= rule.end) {
// TODO: Should we return the codepoint in string form here? That will be unnecessary work in most cases where `wholeMatch` will be used
currentIndex += 1;
return;
} else {
return NoMatch;
}
},
// NOTE: Regex literals deprecated due to incompatibility with streaming/mixed-mode parsing
// regex: () => {
// let { regex } = rule;
// // HACK: This is very much an imperfect approach. We're doing a (potentially large) string copy, and are letting it match at *any* position in the input, potentially wasting resurces if it turns out the match wasn't at index 0. This is unfortunate, but likely still the best option - the internal regex implementation is highly optimized (meaning a written-in-JS implementation is unlikely to beat it in performance), and the built-in implementation doesn't allow anchoring a match separately from the regex definition itself. We *could* transform the regex to have a start anchor, but then this would defeat optimization of repeatedly used regexes - this transformation step would be applied *every time the parsing rule is used*, instead of only once at JS parsing time. Should investigate whether there's any performant way of cacheing this work internally!
// // FIXME: Disallow global-flagged regexes? As the internal starting index can throw off our logic
// // FIXME: The approach we've chosen here is probably *really* unperformant when combining a regex literal with an `until` combinator!
// let match = regex.exec(input.slice(currentIndex));
// if (match?.index === 0) {
// // Valid match, because it starts at the currentIndex
// currentIndex += match[0].length;
// // NOTE: We only return the groups, and not the full match, for consistency with the rest of the API - wholeMatch should be used for that (and the performance cost of that additional call should be negligible)
// return {
// $positional: match.slice(1),
// ... match.groups
// };
// } else {
// return NoMatch;
// }
// },
endOfInput: () => {
// FIXME: Make this not order-sensitive in an `either`! Currently the NotEnoughInput marker *might* cause issues if this (zero-width) rule comes after nonzero-width rules? Need to investigate.
if (currentIndex === input.length) {
// FIXME: Make this NotEnoughInput-aware; there is probably a similar "exception from the core handling" problem here as in `until`
currentIndex += 1; // We have consumed the 'virtual' end-of-input marker at the end of the input
// FIXME: Verify that this doesn't break anything elsewhere
return true;
} else {
return NoMatch;
}
},
wholeMatch: () => {
let result = applyRule(rule.rule);
return assertMatch(result, () => {
return input.slice(currentFrame.startPosition, currentIndex);
});
},
either: () => {
let encounteredNotEnoughInput = false;
for (let option of rule.options) {
// FIXME: currentFrame.startPosition
let startPosition = currentIndex;
let result = applyRule(option);
if (result === NoMatch) {
// Restore index and try again with the next option
encounteredNotEnoughInput = encounteredNotEnoughInput || (result === NotEnoughInput);
currentIndex = startPosition;
continue;
} else {
// Don't restore index; the match has been consumed
// FIXME: This includes NotEnoughInput! As it warrants an immediate abort. Handling of NotEnoughInput markers should be moved to a centralized place instead. Also, we should figure out exactly how to retain the current parsing position when one is encountered, and whether eg. individual core operations need to manage cursor resets for this purpose, or whether the core can centrally handle that as well, eg. by retaining the parsing stack.
return result;
}
}
// None of the options matched
if (encounteredNotEnoughInput) {
// This means that at least one of the options returned a NotEnoughInput; which means that we couldn't actually determine whether that option *would* have matched or not, so the entire Either will be considered to need more input
return NotEnoughInput;
} else {
return NoMatch;
}
},
peek: () => {
let result = applyRule(rule.rule);
currentIndex = currentFrame.startPosition;
return result;
},
test: () => {
// FIXME: Test
// TODO: Share implementation with `peek`, maybe compose?
let result = applyRule(rule.rule);
currentIndex = currentFrame.startPosition;
if (result === NotEnoughInput) {
// Propagate this marker directly, as we will need to re-parse after receiving more input, and we cannot yet decide whether there is a match or not.
return NotEnoughInput;
} else if (result === NoMatch) {
return false;
} else {
return true;
}
},
zeroOrMore: () => {
let matches = [];
while (true) {
let result = applyRule(rule.rule);
if (result === NotEnoughInput) {
// Propagate, reparse later
return NotEnoughInput;
} else if (result === NoMatch) {
break;
} else {
matches.push(result);
}
}
return matches;
},
oneOrMore: () => {
// FIXME: Compose on zeroOrMore, but add a length assertion
let matches = applyRule({ __protocolKitInstruction: true, type: "zeroOrMore", rule: rule.rule });
if (matches === NotEnoughInput || matches.length > 0) {
return matches;
} else {
return NoMatch;
}
},
optional: () => {
let result = applyRule(rule.rule);
if (result === NotEnoughInput) {
return NotEnoughInput;
} else if (result === NoMatch) {
return undefined; // TODO: Or return `null` instead?
} else {
return result;
}
},
until: () => {
// FIXME: We're probably never actually triggering NotEnoughInput right now, due to how the loop logic works here?
// TODO: Build this on `peek` instead? Is there any actual benefit to that?
// TODO: *Should* end of input be handled specially here, or should it be up to the parser itself to determine whether to stop there? Could be surprising behaviour for it to fail a match just because the input ended with only desired values, but it could also be surprising to expect it to match a delimiter without that delimiter actually being there (but wouldn't that be handled anyway by a subsequent rule for that delimiter?)
for (; currentIndex <= input.length; currentIndex++) {
console.log({currentIndex, length: input.length});
let result = applyRule(rule.rule);
// FIXME: Fix the structure here, and figure out a way to deal with allowEnd without needing to special-case NotEnoughInput handling against inputIsEnded, because that should be a core concern only
if (result === NotEnoughInput) {
if (inputIsEnded && rule.allowEnd) {
// Fall through
break;
} else {
return NotEnoughInput;
}
} else if (result === NoMatch) {
continue;
} else {
// Fall through
break;
}
}
// We've consumed everything *up to* the match, but not the match itself
currentIndex -= 1;
return input.slice(currentFrame.startPosition, currentIndex);
}
// zeroOrMore: () => {
// },
// oneOrMore: () => {
// },
// either: () => {
// contextStack.push({
// index: currentIndex
// });
// // try each rule, try next on error, until success or final failure
// },
// optional: () => {
// // Also generates a context
// },
// peek: () => {
// // TODO: semantic difference between peek and either is that the either context should be thrown away after it fully completes (including nested rules)?
// // TODO: emit items (or not) option
// contextStack.push({
// index: currentIndex
// });
// // run parser as normal, but reset index afterwards -- return boolean true/false or an actual parsed item? maybe a separate test instruction for boolean result?
// },
// test: () => {
// },
// wholeMatch: () => {
// },
// trackPosition: () => {
// }
});
} else {
// FIXME: Do we need to implement anything else, or is this just a bug in the grammar?
throw new Error(`Unimplemented`);
}
let context = { startIndex: state.currentIndex };
let handler = matchValue.literal(rule.type, {
literal: require("./core-ops/literal"),
characterRange: require("./core-ops/character-range"),
endOfInput: require("./core-ops/end-of-input"),
either: require("./core-ops/either"),
peek: require("./core-ops/peek"),
test: require("./core-ops/test"),
zeroOrMore: require("./core-ops/zero-or-more"),
oneOrMore: require("./core-ops/one-or-more"),
optional: require("./core-ops/optional"),
until: require("./core-ops/until"),
wholeMatch: require("./core-ops/whole-match"),
// FIXME: Implement trackPosition
});
if (process.env.DEBUG_PARSER) {
console.log(`!! (${printIndex()})` + " ".repeat(parserStack.length) + util.inspect(result, { colors: true, compact: true, breakLength: Infinity }));
}
let result = yield* handler(rule, state, context);
parserStack.pop();
// HACK: Make this nicer, maybe visually represent this in the parse debug tree as well
if (inputIsEnded && result === NotEnoughInput) {
result = NoMatch;
}
// FIXME: Restore index when retrying a match after NotEnoughInput
return result;
}
let rootResult = applyRule(rootParser);
// FIXME: Detect when rules run out but end of input has not yet been reached, as this is an error (unless specified otherwise - need to figure out how to let grammar authors configure this maybe, for formats that allow trailing data, but that still need to be embeddable? or maybe that doesn't matter because when it's embedded, by definition the sub-parser will never be the root parser, and therefore there are always more higher-level rules left? maybe it's sufficient to just let the top-level parse call determine whether this is valid or not)
if (currentIndex < input.length) {
console.log("incomplete result:", rootResult);
throw new Error("Ran out of parsing rules before end of input");
}
let core = yieldcore.create(rootParser, {
onYieldInstruction: function* (instruction, frame, stack) {
// Parser yielded
let result = yield* applyRule(instruction, frame, stack);
if (result === NotEnoughInput) {
throw new Error(`Ran out of input`);
} else if (result === NoMatch) {
throw new Error(`No match`);
} else {
return result;
}
},
onReturn: function* (value) {
// FIXME: Value produced, emit this at some point?, noop for now
return value; // Return the produced value unchanged
},
onBeforeStackDecrease: function (stack, returnValue) {
let frame = stack.at(-1);
if (process.env.DEBUG_PARSER && !isInternalFrame(frame)) {
console.log(`!! (${formatIndex()})` + " ".repeat(getStackSize(stack)) + util.inspect(returnValue, { colors: true, compact: true, breakLength: Infinity }));
}
},
onAfterStackIncrease: function (stack) {
let frame = stack.at(-1);
if (rootResult === NoMatch) {
throw new Error(`No match`);
} else if (rootResult === NotEnoughInput) {
throw new Error("Not enough input");
} else {
return rootResult;
}
if (process.env.DEBUG_PARSER && !isInternalFrame(frame)) {
console.log(`>> (${formatIndex()})` + " ".repeat(getStackSize(stack)) + util.inspect(frame.instruction, { colors: true, compact: true, breakLength: Infinity }));
}
}
});
return core.resume();
// let rootResult = applyRule(rootParser);
// // FIXME: Detect when rules run out but end of input has not yet been reached, as this is an error (unless specified otherwise - need to figure out how to let grammar authors configure this maybe, for formats that allow trailing data, but that still need to be embeddable? or maybe that doesn't matter because when it's embedded, by definition the sub-parser will never be the root parser, and therefore there are always more higher-level rules left? maybe it's sufficient to just let the top-level parse call determine whether this is valid or not)
// if (currentIndex < input.length) {
// console.log("incomplete result:", rootResult);
// throw new Error("Ran out of parsing rules before end of input");
// }
// if (rootResult === NoMatch) {
// throw new Error(`No match`);
// } else if (rootResult === NotEnoughInput) {
// throw new Error("Not enough input");
// } else {
// return rootResult;
// }
}
};

@ -0,0 +1,18 @@
"use strict";
const isGenerator = require("is-generator-function");
const yieldcore = require("../yieldcore");
module.exports = {
create: function createParserCore(rootRule) {
let core = yieldCore(rootRule, {
onYield: (rule) => {
if (isGenerator(rule)) {
// Ignore?
} else {
}
}
});
}
};

@ -0,0 +1,15 @@
"use strict";
module.exports = function stringOperation({ textMode, characterIndex, input, operation }) {
let { string } = operation;
if (!textMode) {
throw new Error(`Cannot use string literal rules in binary parsing mode`);
} else if (currentIndex + string.length > input.length) {
return NotEnoughInput;
} else if (input.slice(characterIndex, characterIndex + string.length) === operation.string) {
return { value: string, consumedCharacters: string.length };
} else {
return NoMatch;
}
};

@ -4,6 +4,7 @@
#EXTINF:9.009,
http://media.example.com/first.ts
#EXTINF:9.009,
#EXTGRP:Sample group
http://media.example.com/second.ts
#EXTINF:3.003,
http://media.example.com/third.ts
http://media.example.com/third.ts

@ -0,0 +1,16 @@
"use strict";
const Newline = require("./newline");
module.exports = function makeNewlineVariants(callback) {
let variants = {};
for (let type of [ "CR", "LF", "CRLF", "looseCRLF" ]) {
variants[type] = callback(Newline[type], type);
}
// FIXME: Doesn't currently compose correctly through spacedLine -> line
// variants.custom = callback;
return variants;
};

@ -0,0 +1,9 @@
"use strict";
const makeNewlineVariants = require("./_make-newline-variants");
module.exports = makeNewlineVariants((Newline) => {
return function* MaybeEmptyLines() {
yield zeroOrMore(Newline);
};
});

@ -1,5 +1,6 @@
"use strict";
const { optional } = require("../../operations");
const LineFeed = require("./line-feed");
const CarriageReturn = require("./carriage-return");
@ -7,7 +8,11 @@ module.exports = {
LF: LineFeed,
CR: CarriageReturn,
CRLF: function* () {
yield LineFeed;
yield CarriageReturn;
yield LineFeed;
},
looseCRLF: function* () {
yield optional(CarriageReturn);
yield LineFeed;
}
};

@ -0,0 +1,8 @@
"use strict";
const { oneOrMore } = require("../../operations");
const makeNewlineVariants = require("./_make-newline-variants");
module.exports = makeNewlineVariants((Newline) => {
return oneOrMore(Newline);
});

@ -1,17 +1,11 @@
"use strict";
const { either, EndOfInput } = require("../../operations");
const Newline = require("./newline");
const untilDelimiter = require("../../combinator/until-delimiter");
const makeNewlineVariants = require("./_make-newline-variants");
function createRestOfLine(newlineRule) {
module.exports = makeNewlineVariants((Newline) => {
return function* RestOfLine() {
return yield untilDelimiter(either([ newlineRule, EndOfInput ]));
}
}
module.exports = {
LF: createRestOfLine(Newline.LF),
CR: createRestOfLine(Newline.CR),
CRLF: createRestOfLine(Newline.CRLF),
};
return yield untilDelimiter(either([ Newline, EndOfInput ]));
}
});

@ -0,0 +1,18 @@
"use strict";
const lastItem = require("../../util/last-item");
module.exports = function format(strings, ... parsers) {
return function* FormatTemplate() {
let parserResults = [];
for (let i = 0; i < strings.length - 1; i++) {
yield strings[i];
parserResults.push(yield parsers[i]);
}
yield lastItem(strings);
return parserResults;
}
};

@ -0,0 +1,16 @@
"use strict";
const _makeNewlineVariants = require("../lines/_make-newline-variants");
const format = require("./format");
module.exports = _makeNewlineVariants((Newline) => {
return function line(strings, ... params) {
return function* LineTemplate() {
let results = yield format(strings, ... params);
yield Newline;
return results;
}
};
});

@ -0,0 +1,16 @@
"use strict";
const { zeroOrMore } = require("../../operations");
const makeNewlineVariants = require("../lines/_make-newline-variants");
const line = require("./line");
module.exports = makeNewlineVariants((Newline, type) => {
return function spacedLine(strings, ... parsers) {
return function* SpacedLineTemplate() {
// NOTE: This does *not* allow leading newlines, because a line template may start parsing in the middle of an existing line, and allowing leading newlines would break the intended behaviour of only parsing that same line
let result = yield line[type](strings, ... parsers);
yield zeroOrMore(Newline);
return result;
}
};
});

@ -0,0 +1,6 @@
"use strict";
module.exports = {
NoMatch: Symbol("protocolkit:NoMatch"),
NotEnoughInput: Symbol("protocolkit:NotEnoughInput")
};

@ -4,20 +4,20 @@ const { parse } = require("./index");
const { wholeMatch, either, peek } = require("./operations");
function* A() {
yield "hello";
return yield "hello";
}
function* Whitespace() {
yield " "; // FIXME
return yield " "; // FIXME
}
function* B1() {
yield peek("world");
yield "world";
return yield "world";
}
function* B2() {
yield "earth";
return yield "earth";
}
function* B3() {
@ -27,11 +27,13 @@ function* B3() {
}
module.exports = function* TestParser() {
return yield wholeMatch(function*() {
return yield wholeMatch(function* innerWholeMatch () {
yield A;
yield Whitespace;
yield either([ B1, B2, B3 ]);
return yield either([ B1, B2, B3 ]);
});
};
console.log(parse(process.argv[2], module.exports));
parse(process.argv[2], module.exports).then((result) => {
console.log(result);
});

@ -0,0 +1,5 @@
"use strict";
module.exports = function lastItem(array) {
return array[array.length - 1];
};

@ -0,0 +1,170 @@
"use strict";
const PromiseTry = require("es6-promise-try");
const isGenerator = require("is-generator-function");
const lastItem = require("../util/last-item");
const Pause = Symbol("Pause");
const isPromise = require("./is-promise");
async function asyncGeneratorContext(generatorFunction, customHook) {
let generator = generatorFunction();
let lastResult = { done: false };
let nextValue;
while (lastResult.done === false) {
lastResult = generator.next(nextValue);
if (typeof lastResult.value?.then === "function") {
nextValue = await lastResult.value;
} else {
nextValue = customHook(lastResult.value);
}
}
return nextValue;
}
module.exports = {
Pause: Pause,
Instruction: (instruction) => {
// FIXME: Unused?
return {
__yieldcoreInstruction: true,
instruction: instruction
};
},
Internal: (generator) => {
return {
__yieldcoreInternal: true,
generator: generator
};
// FIXME: propagate NotEnoughInput, handle in custom handler as a retry
},
create: function createYieldCore(rootGenerator, { onYieldInstruction, onReturn, onBeforeStackDecrease, onAfterStackIncrease }) {
let running = false;
let finished = false;
let stack = [];
let currentFrame;
let lastValue; // FIXME: Clear on every stack change
function decreaseStack(returnValue) {
if (onBeforeStackDecrease != null) {
onBeforeStackDecrease(stack, returnValue);
}
stack.pop();
currentFrame = lastItem(stack);
// console.log("popping stack, new frame:", currentFrame);
}
function increaseStack(frame) {
stack.push(frame);
currentFrame = lastItem(stack);
// console.log("increasing stack, new frame:", currentFrame);
if (onAfterStackIncrease != null) {
onAfterStackIncrease(stack);
}
}
function insertInstruction(instruction) {
increaseStack({
instruction: instruction,
generator: instruction(),
done: false,
value: undefined
});
}
function insertInternalInstruction(generator) {
increaseStack({
instruction: "internal",
generator: generator,
done: false,
value: undefined
});
}
async function startLoop() {
while (finished === false && running === true) {
if (currentFrame.done === true) {
// This is a previously completed frame; it doesn't need any further processing
// console.log(`deferred-decreasing stack for ${currentFrame.instruction} with`, currentFrame.value);
decreaseStack(currentFrame.value);
} else {
// FIXME: Catch
let result = currentFrame.generator.next(lastValue);
let action;
if (result.done === true) {
// value == return value
currentFrame.done = true;
currentFrame.value = result.value;
let lastFrame = currentFrame;
// console.log(`decreasing stack for ${currentFrame.instruction} with`, result.value);
decreaseStack(result.value);
if (onReturn != null && lastFrame.instruction !== "internal") {
insertInternalInstruction(onReturn(result.value, lastFrame, stack));
} else {
// console.log(`setting action (no-onReturn) to ${result.value}`);
action = result.value;
}
} else if (isGenerator(result.value)) {
// TODO: Figure out better semantics for onYieldGenerator?
// NOTE: Currently this hook *cannot* be a generator!
// if (onYieldGenerator != null) {
// onYieldGenerator(result.value, currentFrame, stack);
// }
insertInstruction(result.value);
continue; // Proceed with the next cycle immediately
} else if (isPromise(result.value)) {
// console.log(`setting action (promise) to ${result.value}`);
action = await result.value;
} else if (result.value === Pause) {
running = false;
} else if (result.value?.__yieldcoreInternal === true) {
insertInternalInstruction(result.value);
continue; // FIXME: Is this correct?
} else {
if (onYieldInstruction != null && currentFrame.instruction !== "internal") {
insertInternalInstruction(onYieldInstruction(result.value, currentFrame, stack));
} else {
// TODO: Is there ever a good reason not to have an onYieldInstruction handler? Should we just disallow that case?
// console.log(`setting action (no-onYield) to ${result.value}`);
action = result.value;
}
}
lastValue = action;
if (stack.length === 0) {
finished = true;
}
}
}
return lastValue;
}
// Initial frame
insertInstruction(rootGenerator);
return {
resume: function () {
if (running) {
throw new Error(`Already running`);
} else if (finished) {
throw new Error(`Program has finished already!`);
} else {
running = true;
return startLoop();
}
}
};
}
};

@ -0,0 +1,6 @@
"use strict";
module.exports = function isPromise(value) {
// NOTE: This is basically a test for Promises/A+, not ES6 Promises specifically
return (typeof value?.then === "function");
};

@ -0,0 +1,34 @@
"use strict";
module.exports = async function generatorLoopAsync(generator, callback = (value) => value) {
let lastResult = { done: false };
let lastValue;
while (lastResult.done === false) {
lastResult = generator.next(lastValue);
let evaluatedValue = (typeof lastResult.value?.then === "function")
? await lastResult.value
: lastResult.value;
lastValue = (lastResult.done === false)
? callback(evaluatedValue)
: evaluatedValue;
}
return lastValue;
};
function* testGen() {
let array = [];
array.push(yield Promise.resolve(1));
array.push(yield Promise.resolve(2));
array.push(yield Promise.resolve(3));
return array;
}
module.exports(testGen(), (number) => number * 2).then((result) => {
console.log(result);
});

@ -0,0 +1,29 @@
"use strict";
module.exports = function generatorLoopSync(generator, callback = (value) => value) {
let lastResult = { done: false };
let lastValue;
while (lastResult.done === false) {
lastResult = generator.next(lastValue);
lastValue = (lastResult.done === false)
? callback(lastResult.value)
: lastResult.value;
}
return lastValue;
};
function* testGen() {
let array = [];
array.push(yield 1);
array.push(yield 2);
array.push(yield 3);
return array;
}
let result = module.exports(testGen(), (number) => number * 2);
console.log(result);

@ -0,0 +1,51 @@
"use strict";
const isGenerator = require("is-generator-function");
const yieldcore = require("./index");
function* A() {
yield 1;
yield 2;
yield B;
yield 3;
return 9;
}
function* B() {
yield 10;
yield 11;
yield C;
yield D;
return 19;
}
function* C() {
yield 28;
return 29;
}
function* D() {
yield 37;
yield 38;
return 39;
}
let core = yieldcore.create(A, {
onYieldInstruction: function* (value) {
console.log(value);
},
onYieldGenerator: function* (value) {
// Waiting 2 seconds...
console.log("Waiting...");
// setTimeout(() => core.resume(), 2000);
// yield yieldcore.Pause;
yield new Promise((resolve) => setTimeout(resolve, 2000));
},
onReturn: function* (value) {
console.log(`r ${value}`);
}
});
core.resume();
// expected: 1, 2, 10, 11, 28, r 29, 37, 38, r 39, r 19, 3, r 9

@ -2,11 +2,121 @@
# yarn lockfile v1
"@eslint/eslintrc@^1.3.3":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95"
integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.4.0"
globals "^13.15.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@humanwhocodes/config-array@^0.11.6":
version "0.11.7"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f"
integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==
dependencies:
"@humanwhocodes/object-schema" "^1.2.1"
debug "^4.1.1"
minimatch "^3.0.5"
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/object-schema@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@joepie91/eslint-config@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@joepie91/eslint-config/-/eslint-config-1.1.1.tgz#cb276dec6dd25b5777daefbef561850c9717180d"
integrity sha512-q8l83tdpL0YGC24ftlpeHgmQIIRmcpiVhwwEUFPcJ1YXWaee/JjoUs6e5tLKMTNNk+fvDKtq2YPSXkmLQU7h5Q==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@2.0.5":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
"@nodelib/fs.walk@^1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^8.8.0:
version "8.8.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
ajv@^6.10.0, ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
as-expression@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/as-expression/-/as-expression-1.0.0.tgz#7bc620ca4cb2fe0ee90d86729bd6add33b8fd831"
integrity sha512-Iqh4GxNUfxbJdGn6b7/XMzc8m1Dz2ZHouBQ9DDTzyMRO3VPPIAXeoY/sucRxxxXKbUtzwzWZSN6jPR3zfpYHHA==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
call-bind@^1.0.2:
version "1.0.2"
resolved "http://localhost:4873/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
@ -15,6 +125,232 @@ call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
debug@^4.1.1, debug@^4.3.2:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
dependencies:
esutils "^2.0.2"
es6-promise-try@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/es6-promise-try/-/es6-promise-try-1.0.2.tgz#91f718b8140c3e5d6b187715a2d8707db96c4803"
integrity sha512-t7xE0FUYBa84ma0rpcvPGV7PaNS8ljeMYdG49zRFBkkJYi6ZhVH2PHo4/PIdZc9H4G1lrx0vMqoZzsPAd7arPw==
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-scope@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-utils@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
dependencies:
eslint-visitor-keys "^2.0.0"
eslint-visitor-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint-visitor-keys@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
eslint@^8.27.0:
version "8.27.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.27.0.tgz#d547e2f7239994ad1faa4bb5d84e5d809db7cf64"
integrity sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ==
dependencies:
"@eslint/eslintrc" "^1.3.3"
"@humanwhocodes/config-array" "^0.11.6"
"@humanwhocodes/module-importer" "^1.0.1"
"@nodelib/fs.walk" "^1.2.8"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
debug "^4.3.2"
doctrine "^3.0.0"
escape-string-regexp "^4.0.0"
eslint-scope "^7.1.1"
eslint-utils "^3.0.0"
eslint-visitor-keys "^3.3.0"
espree "^9.4.0"
esquery "^1.4.0"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
file-entry-cache "^6.0.1"
find-up "^5.0.0"
glob-parent "^6.0.2"
globals "^13.15.0"
grapheme-splitter "^1.0.4"
ignore "^5.2.0"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
is-glob "^4.0.0"
is-path-inside "^3.0.3"
js-sdsl "^4.1.4"
js-yaml "^4.1.0"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1"
lodash.merge "^4.6.2"
minimatch "^3.1.2"
natural-compare "^1.4.0"
optionator "^0.9.1"
regexpp "^3.2.0"
strip-ansi "^6.0.1"
strip-json-comments "^3.1.0"
text-table "^0.2.0"
espree@^9.4.0:
version "9.4.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd"
integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==
dependencies:
acorn "^8.8.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.3.0"
esquery@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
dependencies:
estraverse "^5.1.0"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^5.1.0, estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
fast-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fastq@^1.6.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
dependencies:
reusify "^1.0.4"
file-entry-cache@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
dependencies:
flat-cache "^3.0.4"
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
dependencies:
locate-path "^6.0.0"
path-exists "^4.0.0"
flat-cache@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
dependencies:
flatted "^3.1.0"
rimraf "^3.0.2"
flatted@^3.1.0:
version "3.2.7"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
function-bind@^1.1.1:
version "1.1.1"
resolved "http://localhost:4873/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@ -29,6 +365,42 @@ get-intrinsic@^1.0.2:
has "^1.0.3"
has-symbols "^1.0.3"
glob-parent@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies:
is-glob "^4.0.3"
glob@^7.1.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^13.15.0:
version "13.17.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4"
integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==
dependencies:
type-fest "^0.20.2"
grapheme-splitter@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-symbols@^1.0.2, has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
@ -48,6 +420,42 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-generator-function@^1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
@ -55,6 +463,18 @@ is-generator-function@^1.0.10:
dependencies:
has-tostringtag "^1.0.0"
is-glob@^4.0.0, is-glob@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-path-inside@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
is-regex@^1.1.4:
version "1.1.4"
resolved "http://localhost:4873/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@ -63,7 +483,247 @@ is-regex@^1.1.4:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
js-sdsl@^4.1.4:
version "4.1.5"
resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a"
integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
dependencies:
prelude-ls "^1.2.1"
type-check "~0.4.0"
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
dependencies:
p-locate "^5.0.0"
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
match-value@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/match-value/-/match-value-1.1.0.tgz#ad311ef8bbe2d344a53ec3104e28fe221984b98e"
integrity sha512-NOvpobcmkX+l9Eb6r2s3BkR1g1ZwzExDFdXA9d6p1r1O1olLbo88KuzMiBmg43xSpodfm7I6Hqlx2OoySquEgg==
minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
optionator@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
dependencies:
deep-is "^0.1.3"
fast-levenshtein "^2.0.6"
levn "^0.4.1"
prelude-ls "^1.2.1"
type-check "^0.4.0"
word-wrap "^1.2.3"
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
dependencies:
yocto-queue "^0.1.0"
p-locate@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
dependencies:
p-limit "^3.0.2"
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
dependencies:
callsites "^3.0.0"
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
punycode@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
regexpp@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
dependencies:
queue-microtask "^1.2.2"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
dependencies:
prelude-ls "^1.2.1"
type-fest@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
which@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
word-wrap@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==

Loading…
Cancel
Save