From c87ed21fdf6e393e6f7601bd867f61e529cc058d Mon Sep 17 00:00:00 2001 From: ConorDavenport Date: Thu, 27 Feb 2020 11:41:05 +0000 Subject: [PATCH 01/62] assert: port common.mustCall() to assert Fixes: https://github.com/nodejs/node/issues/31392 PR-URL: https://github.com/nodejs/node/pull/31982 Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Zeyu Yang Reviewed-By: Colin Ihrig Reviewed-By: Denys Otrishko --- doc/api/assert.md | 135 ++++++++++++++++++ doc/api/errors.md | 7 + lib/assert.js | 3 + lib/internal/assert/assertion_error.js | 20 ++- lib/internal/assert/calltracker.js | 93 ++++++++++++ lib/internal/errors.js | 2 + node.gyp | 1 + .../parallel/test-assert-calltracker-calls.js | 66 +++++++++ .../test-assert-calltracker-report.js | 32 +++++ .../test-assert-calltracker-verify.js | 32 +++++ 10 files changed, 388 insertions(+), 3 deletions(-) create mode 100644 lib/internal/assert/calltracker.js create mode 100644 test/parallel/test-assert-calltracker-calls.js create mode 100644 test/parallel/test-assert-calltracker-report.js create mode 100644 test/parallel/test-assert-calltracker-verify.js diff --git a/doc/api/assert.md b/doc/api/assert.md index 9731ddaa13f315..f8178ed6ec1249 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -149,6 +149,137 @@ try { } ``` +## Class: `assert.CallTracker` + +### `new assert.CallTracker()` + + +Creates a new [`CallTracker`][] object which can be used to track if functions +were called a specific number of times. The `tracker.verify()` must be called +for the verification to take place. The usual pattern would be to call it in a +[`process.on('exit')`][] handler. + +```js +const assert = require('assert'); + +const tracker = new assert.CallTracker(); + +function func() {} + +// callsfunc() must be called exactly 1 time before tracker.verify(). +const callsfunc = tracker.calls(func, 1); + +callsfunc(); + +// Calls tracker.verify() and verifies if all tracker.calls() functions have +// been called exact times. +process.on('exit', () => { + tracker.verify(); +}); +``` + +### `tracker.calls([fn][, exact])` + + +* `fn` {Function} **Default** A no-op function. +* `exact` {number} **Default** `1`. +* Returns: {Function} that wraps `fn`. + +The wrapper function is expected to be called exactly `exact` times. If the +function has not been called exactly `exact` times when +[`tracker.verify()`][] is called, then [`tracker.verify()`][] will throw an +error. + +```js +const assert = require('assert'); + +// Creates call tracker. +const tracker = new assert.CallTracker(); + +function func() {} + +// Returns a function that wraps func() that must be called exact times +// before tracker.verify(). +const callsfunc = tracker.calls(func); +``` + +### `tracker.report()` + + +* Returns: {Array} of objects containing information about the wrapper functions +returned by [`tracker.calls()`][]. +* Object {Object} + * `message` {string} + * `actual` {number} The actual number of times the function was called. + * `expected` {number} The number of times the function was expected to be + called. + * `operator` {string} The name of the function that is wrapped. + * `stack` {Object} A stack trace of the function. + +The arrays contains information about the expected and actual number of calls of +the functions that have not been called the expected number of times. + +```js +const assert = require('assert'); + +// Creates call tracker. +const tracker = new assert.CallTracker(); + +function func() {} + +function foo() {} + +// Returns a function that wraps func() that must be called exact times +// before tracker.verify(). +const callsfunc = tracker.calls(func, 2); + +// Returns an array containing information on callsfunc() +tracker.report(); +// [ +// { +// message: 'Expected the func function to be executed 2 time(s) but was +// executed 0 time(s).', +// actual: 0, +// expected: 2, +// operator: 'func', +// stack: stack trace +// } +// ] +``` + +### `tracker.verify()` + + +Iterates through the list of functions passed to +[`tracker.calls()`][] and will throw an error for functions that +have not been called the expected number of times. + +```js +const assert = require('assert'); + +// Creates call tracker. +const tracker = new assert.CallTracker(); + +function func() {} + +// Returns a function that wraps func() that must be called exact times +// before tracker.verify(). +const callsfunc = tracker.calls(func, 2); + +callsfunc(); + +// Will throw an error since callsfunc() was only called once. +tracker.verify(); +``` + ## `assert(value[, message])` * `options` {Object} @@ -107,6 +110,8 @@ changes: **Default:** `'auto'`. * `inspectOptions` {Object} Specifies options that are passed along to [`util.inspect()`][]. + * `groupIndentation` {number} Set group indentation. + **Default:** `2`. Creates a new `Console` with one or two writable stream instances. `stdout` is a writable stream to print log or info output. `stderr` is used for warning or @@ -306,7 +311,8 @@ added: v8.5.0 * `...label` {any} -Increases indentation of subsequent lines by two spaces. +Increases indentation of subsequent lines by spaces for `groupIndentation` +length. If one or more `label`s are provided, those are printed first without the additional indentation. @@ -323,7 +329,8 @@ An alias for [`console.group()`][]. added: v8.5.0 --> -Decreases indentation of subsequent lines by two spaces. +Decreases indentation of subsequent lines by spaces for `groupIndentation` +length. ### `console.info([data][, ...args])` `). +// All rules are in their own packages and presets. +function lint$1() { + this.use(lintMessageControl$1); +} + +function lintMessageControl$1() { + return remarkMessageControl$1({name: 'lint', source: 'remark-lint'}) +} + /** * An Array.prototype.slice.call(arguments) alternative * @@ -41822,9 +42655,9 @@ function promise(value) { return value && 'function' == typeof value.then; } -var unifiedLintRule = factory$7; +var unifiedLintRule = factory$9; -function factory$7(id, rule) { +function factory$9(id, rule) { var parts = id.split(':'); var source = parts[0]; var ruleId = parts[1]; @@ -41862,7 +42695,7 @@ function factory$7(id, rule) { if (err && messages.indexOf(err) === -1) { try { file.fail(err); - } catch (error) {} + } catch (_) {} } while (index < messages.length) { @@ -41921,7 +42754,7 @@ function coerce(name, value) { if (level < 0 || level > 2) { throw new Error( - 'Invalid severity `' + + 'Incorrect severity `' + level + '` for `' + name + @@ -41946,490 +42779,700 @@ function finalNewline(tree, file) { } } -const addendum = "addenda"; -const aircraft = "aircraft"; -const alga = "algae"; -const alumna = "alumnae"; -const alumnus = "alumni"; -const amoeba = "amoebae"; -const analysis = "analyses"; -const antenna = "antennae"; -const antithesis = "antitheses"; -const apex = "apices"; -const appendix = "appendices"; -const automaton = "automata"; -const axis = "axes"; -const bacillus = "bacilli"; -const bacterium = "bacteria"; -const barracks = "barracks"; -const basis = "bases"; -const beau = "beaux"; -const bison = "bison"; -const buffalo = "buffalo"; -const bureau = "bureaus"; -const cactus = "cacti"; -const calf = "calves"; -const carp = "carp"; -const census = "censuses"; -const chassis = "chassis"; -const cherub = "cherubim"; -const child = "children"; -const cod = "cod"; -const codex = "codices"; -const concerto = "concerti"; -const corpus = "corpora"; -const crisis = "crises"; -const criterion = "criteria"; -const curriculum = "curricula"; -const datum = "data"; -const deer = "deer"; -const diagnosis = "diagnoses"; -const die$1 = "dice"; -const dwarf = "dwarfs"; -const echo = "echoes"; -const elf = "elves"; -const elk = "elk"; -const ellipsis = "ellipses"; -const embargo = "embargoes"; -const emphasis$3 = "emphases"; -const erratum = "errata"; -const fez = "fezes"; -const firmware = "firmware"; -const fish = "fish"; -const focus = "foci"; -const foot = "feet"; -const formula = "formulae"; -const fungus = "fungi"; -const gallows = "gallows"; -const genus = "genera"; -const goose = "geese"; -const graffito = "graffiti"; -const grouse = "grouse"; -const half$1 = "halves"; -const hero = "heroes"; -const hoof = "hooves"; -const hovercraft = "hovercraft"; -const hypothesis = "hypotheses"; -const index$5 = "indices"; -const kakapo = "kakapo"; -const knife = "knives"; -const larva = "larvae"; -const leaf = "leaves"; -const libretto = "libretti"; -const life = "lives"; -const loaf = "loaves"; -const locus = "loci"; -const louse = "lice"; -const man = "men"; -const matrix = "matrices"; -const means = "means"; -const medium = "media"; -const memorandum = "memoranda"; -const millennium = "millennia"; -const minutia = "minutiae"; -const moose = "moose"; -const mouse = "mice"; -const nebula = "nebulae"; -const nemesis = "nemeses"; -const neurosis = "neuroses"; -const news = "news"; -const nucleus = "nuclei"; -const oasis = "oases"; -const offspring = "offspring"; -const opus = "opera"; -const ovum = "ova"; -const ox = "oxen"; -const paralysis = "paralyses"; -const parenthesis = "parentheses"; -const person = "people"; -const phenomenon = "phenomena"; -const phylum = "phyla"; -const pike = "pike"; -const polyhedron = "polyhedra"; -const potato = "potatoes"; -const prognosis = "prognoses"; -const quiz = "quizzes"; -const radius = "radii"; -const referendum = "referenda"; -const salmon = "salmon"; -const scarf = "scarves"; -const self = "selves"; -const series = "series"; -const sheep = "sheep"; -const shelf = "shelves"; -const shrimp = "shrimp"; -const spacecraft = "spacecraft"; -const species = "species"; -const spectrum = "spectra"; -const squid = "squid"; -const stimulus = "stimuli"; -const stratum = "strata"; -const swine = "swine"; -const syllabus = "syllabi"; -const symposium = "symposia"; -const synopsis = "synopses"; -const synthesis = "syntheses"; -const tableau = "tableaus"; -const that = "those"; -const thesis = "theses"; -const thief = "thieves"; -const tomato = "tomatoes"; -const tooth = "teeth"; -const trout = "trout"; -const tuna = "tuna"; -const vertebra = "vertebrae"; -const vertex = "vertices"; -const veto = "vetoes"; -const vita = "vitae"; -const vortex = "vortices"; -const watercraft = "watercraft"; -const wharf = "wharves"; -const wife = "wives"; -const wolf = "wolves"; -const woman = "women"; -var irregularPlurals = { - addendum: addendum, - aircraft: aircraft, - alga: alga, - alumna: alumna, - alumnus: alumnus, - amoeba: amoeba, - analysis: analysis, - antenna: antenna, - antithesis: antithesis, - apex: apex, - appendix: appendix, - automaton: automaton, - axis: axis, - bacillus: bacillus, - bacterium: bacterium, - barracks: barracks, - basis: basis, - beau: beau, - bison: bison, - buffalo: buffalo, - bureau: bureau, - cactus: cactus, - calf: calf, - carp: carp, - census: census, - chassis: chassis, - cherub: cherub, - child: child, - "château": "châteaus", - cod: cod, - codex: codex, - concerto: concerto, - corpus: corpus, - crisis: crisis, - criterion: criterion, - curriculum: curriculum, - datum: datum, - deer: deer, - diagnosis: diagnosis, - die: die$1, - dwarf: dwarf, - echo: echo, - elf: elf, - elk: elk, - ellipsis: ellipsis, - embargo: embargo, - emphasis: emphasis$3, - erratum: erratum, - "faux pas": "faux pas", - fez: fez, - firmware: firmware, - fish: fish, - focus: focus, - foot: foot, - formula: formula, - fungus: fungus, - gallows: gallows, - genus: genus, - goose: goose, - graffito: graffito, - grouse: grouse, - half: half$1, - hero: hero, - hoof: hoof, - hovercraft: hovercraft, - hypothesis: hypothesis, - index: index$5, - kakapo: kakapo, - knife: knife, - larva: larva, - leaf: leaf, - libretto: libretto, - life: life, - loaf: loaf, - locus: locus, - louse: louse, - man: man, - matrix: matrix, - means: means, - medium: medium, - memorandum: memorandum, - millennium: millennium, - minutia: minutia, - moose: moose, - mouse: mouse, - nebula: nebula, - nemesis: nemesis, - neurosis: neurosis, - news: news, - nucleus: nucleus, - oasis: oasis, - offspring: offspring, - opus: opus, - ovum: ovum, - ox: ox, - paralysis: paralysis, - parenthesis: parenthesis, - person: person, - phenomenon: phenomenon, - phylum: phylum, - pike: pike, - polyhedron: polyhedron, - potato: potato, - prognosis: prognosis, - quiz: quiz, - radius: radius, - referendum: referendum, - salmon: salmon, - scarf: scarf, - self: self, - series: series, - sheep: sheep, - shelf: shelf, - shrimp: shrimp, - spacecraft: spacecraft, - species: species, - spectrum: spectrum, - squid: squid, - stimulus: stimulus, - stratum: stratum, - swine: swine, - syllabus: syllabus, - symposium: symposium, - synopsis: synopsis, - synthesis: synthesis, - tableau: tableau, - that: that, - thesis: thesis, - thief: thief, - "this": "these", - tomato: tomato, - tooth: tooth, - trout: trout, - tuna: tuna, - vertebra: vertebra, - vertex: vertex, - veto: veto, - vita: vita, - vortex: vortex, - watercraft: watercraft, - wharf: wharf, - wife: wife, - wolf: wolf, - woman: woman -}; - -var irregularPlurals$1 = /*#__PURE__*/Object.freeze({ - __proto__: null, - addendum: addendum, - aircraft: aircraft, - alga: alga, - alumna: alumna, - alumnus: alumnus, - amoeba: amoeba, - analysis: analysis, - antenna: antenna, - antithesis: antithesis, - apex: apex, - appendix: appendix, - automaton: automaton, - axis: axis, - bacillus: bacillus, - bacterium: bacterium, - barracks: barracks, - basis: basis, - beau: beau, - bison: bison, - buffalo: buffalo, - bureau: bureau, - cactus: cactus, - calf: calf, - carp: carp, - census: census, - chassis: chassis, - cherub: cherub, - child: child, - cod: cod, - codex: codex, - concerto: concerto, - corpus: corpus, - crisis: crisis, - criterion: criterion, - curriculum: curriculum, - datum: datum, - deer: deer, - diagnosis: diagnosis, - die: die$1, - dwarf: dwarf, - echo: echo, - elf: elf, - elk: elk, - ellipsis: ellipsis, - embargo: embargo, - emphasis: emphasis$3, - erratum: erratum, - fez: fez, - firmware: firmware, - fish: fish, - focus: focus, - foot: foot, - formula: formula, - fungus: fungus, - gallows: gallows, - genus: genus, - goose: goose, - graffito: graffito, - grouse: grouse, - half: half$1, - hero: hero, - hoof: hoof, - hovercraft: hovercraft, - hypothesis: hypothesis, - index: index$5, - kakapo: kakapo, - knife: knife, - larva: larva, - leaf: leaf, - libretto: libretto, - life: life, - loaf: loaf, - locus: locus, - louse: louse, - man: man, - matrix: matrix, - means: means, - medium: medium, - memorandum: memorandum, - millennium: millennium, - minutia: minutia, - moose: moose, - mouse: mouse, - nebula: nebula, - nemesis: nemesis, - neurosis: neurosis, - news: news, - nucleus: nucleus, - oasis: oasis, - offspring: offspring, - opus: opus, - ovum: ovum, - ox: ox, - paralysis: paralysis, - parenthesis: parenthesis, - person: person, - phenomenon: phenomenon, - phylum: phylum, - pike: pike, - polyhedron: polyhedron, - potato: potato, - prognosis: prognosis, - quiz: quiz, - radius: radius, - referendum: referendum, - salmon: salmon, - scarf: scarf, - self: self, - series: series, - sheep: sheep, - shelf: shelf, - shrimp: shrimp, - spacecraft: spacecraft, - species: species, - spectrum: spectrum, - squid: squid, - stimulus: stimulus, - stratum: stratum, - swine: swine, - syllabus: syllabus, - symposium: symposium, - synopsis: synopsis, - synthesis: synthesis, - tableau: tableau, - that: that, - thesis: thesis, - thief: thief, - tomato: tomato, - tooth: tooth, - trout: trout, - tuna: tuna, - vertebra: vertebra, - vertex: vertex, - veto: veto, - vita: vita, - vortex: vortex, - watercraft: watercraft, - wharf: wharf, - wife: wife, - wolf: wolf, - woman: woman, - 'default': irregularPlurals -}); +var pluralize = createCommonjsModule(function (module, exports) { +/* global define */ -var irregularPlurals$2 = getCjsExportFromNamespace(irregularPlurals$1); +(function (root, pluralize) { + /* istanbul ignore else */ + if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { + // Node. + module.exports = pluralize(); + } else { + // Browser global. + root.pluralize = pluralize(); + } +})(commonjsGlobal, function () { + // Rule storage - pluralize and singularize need to be run sequentially, + // while other rules can be optimized using an object for instant lookups. + var pluralRules = []; + var singularRules = []; + var uncountables = {}; + var irregularPlurals = {}; + var irregularSingles = {}; -var irregularPlurals_1 = createCommonjsModule(function (module) { + /** + * Sanitize a pluralization rule to a usable regular expression. + * + * @param {(RegExp|string)} rule + * @return {RegExp} + */ + function sanitizeRule (rule) { + if (typeof rule === 'string') { + return new RegExp('^' + rule + '$', 'i'); + } + return rule; + } -const map = new Map(); -// TODO: Use Object.entries when targeting Node.js 8 -for (const key of Object.keys(irregularPlurals$2)) { - map.set(key, irregularPlurals$2[key]); -} + /** + * Pass in a word token to produce a function that can replicate the case on + * another word. + * + * @param {string} word + * @param {string} token + * @return {Function} + */ + function restoreCase (word, token) { + // Tokens are an exact match. + if (word === token) return token; -// Ensure nobody can modify each others Map -Object.defineProperty(module, 'exports', { - get() { - return map; - } -}); -}); + // Lower cased words. E.g. "hello". + if (word === word.toLowerCase()) return token.toLowerCase(); -var plur = (word, plural, count) => { - if (typeof plural === 'number') { - count = plural; - } + // Upper cased words. E.g. "WHISKY". + if (word === word.toUpperCase()) return token.toUpperCase(); - if (irregularPlurals_1.has(word.toLowerCase())) { - plural = irregularPlurals_1.get(word.toLowerCase()); + // Title cased words. E.g. "Title". + if (word[0] === word[0].toUpperCase()) { + return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); + } - const firstLetter = word.charAt(0); - const isFirstLetterUpperCase = firstLetter === firstLetter.toUpperCase(); - if (isFirstLetterUpperCase) { - plural = firstLetter.toUpperCase() + plural.slice(1); - } + // Lower cased words. E.g. "test". + return token.toLowerCase(); + } - const isWholeWordUpperCase = word === word.toUpperCase(); - if (isWholeWordUpperCase) { - plural = plural.toUpperCase(); - } - } else if (typeof plural !== 'string') { - plural = (word.replace(/(?:s|x|z|ch|sh)$/i, '$&e').replace(/([^aeiou])y$/i, '$1ie') + 's') - .replace(/i?e?s$/i, match => { - const isTailLowerCase = word.slice(-1) === word.slice(-1).toLowerCase(); - return isTailLowerCase ? match.toLowerCase() : match.toUpperCase(); - }); - } + /** + * Interpolate a regexp string. + * + * @param {string} str + * @param {Array} args + * @return {string} + */ + function interpolate (str, args) { + return str.replace(/\$(\d{1,2})/g, function (match, index) { + return args[index] || ''; + }); + } - return Math.abs(count) === 1 ? word : plural; -}; + /** + * Replace a word using a rule. + * + * @param {string} word + * @param {Array} rule + * @return {string} + */ + function replace (word, rule) { + return word.replace(rule[0], function (match, index) { + var result = interpolate(rule[1], arguments); + + if (match === '') { + return restoreCase(word[index - 1], result); + } + + return restoreCase(match, result); + }); + } + + /** + * Sanitize a word by passing in the word and sanitization rules. + * + * @param {string} token + * @param {string} word + * @param {Array} rules + * @return {string} + */ + function sanitizeWord (token, word, rules) { + // Empty string or doesn't need fixing. + if (!token.length || uncountables.hasOwnProperty(token)) { + return word; + } + + var len = rules.length; + + // Iterate over the sanitization rules and use the first one to match. + while (len--) { + var rule = rules[len]; + + if (rule[0].test(word)) return replace(word, rule); + } + + return word; + } + + /** + * Replace a word with the updated word. + * + * @param {Object} replaceMap + * @param {Object} keepMap + * @param {Array} rules + * @return {Function} + */ + function replaceWord (replaceMap, keepMap, rules) { + return function (word) { + // Get the correct token and case restoration functions. + var token = word.toLowerCase(); + + // Check against the keep object map. + if (keepMap.hasOwnProperty(token)) { + return restoreCase(word, token); + } + + // Check against the replacement map for a direct word replacement. + if (replaceMap.hasOwnProperty(token)) { + return restoreCase(word, replaceMap[token]); + } + + // Run all the rules against the word. + return sanitizeWord(token, word, rules); + }; + } + + /** + * Check if a word is part of the map. + */ + function checkWord (replaceMap, keepMap, rules, bool) { + return function (word) { + var token = word.toLowerCase(); + + if (keepMap.hasOwnProperty(token)) return true; + if (replaceMap.hasOwnProperty(token)) return false; + + return sanitizeWord(token, token, rules) === token; + }; + } + + /** + * Pluralize or singularize a word based on the passed in count. + * + * @param {string} word The word to pluralize + * @param {number} count How many of the word exist + * @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks) + * @return {string} + */ + function pluralize (word, count, inclusive) { + var pluralized = count === 1 + ? pluralize.singular(word) : pluralize.plural(word); + + return (inclusive ? count + ' ' : '') + pluralized; + } + + /** + * Pluralize a word. + * + * @type {Function} + */ + pluralize.plural = replaceWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Check if a word is plural. + * + * @type {Function} + */ + pluralize.isPlural = checkWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Singularize a word. + * + * @type {Function} + */ + pluralize.singular = replaceWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Check if a word is singular. + * + * @type {Function} + */ + pluralize.isSingular = checkWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Add a pluralization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addPluralRule = function (rule, replacement) { + pluralRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add a singularization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addSingularRule = function (rule, replacement) { + singularRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add an uncountable word rule. + * + * @param {(string|RegExp)} word + */ + pluralize.addUncountableRule = function (word) { + if (typeof word === 'string') { + uncountables[word.toLowerCase()] = true; + return; + } + + // Set singular and plural references for the word. + pluralize.addPluralRule(word, '$0'); + pluralize.addSingularRule(word, '$0'); + }; + + /** + * Add an irregular word definition. + * + * @param {string} single + * @param {string} plural + */ + pluralize.addIrregularRule = function (single, plural) { + plural = plural.toLowerCase(); + single = single.toLowerCase(); + + irregularSingles[single] = plural; + irregularPlurals[plural] = single; + }; + + /** + * Irregular rules. + */ + [ + // Pronouns. + ['I', 'we'], + ['me', 'us'], + ['he', 'they'], + ['she', 'they'], + ['them', 'them'], + ['myself', 'ourselves'], + ['yourself', 'yourselves'], + ['itself', 'themselves'], + ['herself', 'themselves'], + ['himself', 'themselves'], + ['themself', 'themselves'], + ['is', 'are'], + ['was', 'were'], + ['has', 'have'], + ['this', 'these'], + ['that', 'those'], + // Words ending in with a consonant and `o`. + ['echo', 'echoes'], + ['dingo', 'dingoes'], + ['volcano', 'volcanoes'], + ['tornado', 'tornadoes'], + ['torpedo', 'torpedoes'], + // Ends with `us`. + ['genus', 'genera'], + ['viscus', 'viscera'], + // Ends with `ma`. + ['stigma', 'stigmata'], + ['stoma', 'stomata'], + ['dogma', 'dogmata'], + ['lemma', 'lemmata'], + ['schema', 'schemata'], + ['anathema', 'anathemata'], + // Other irregular rules. + ['ox', 'oxen'], + ['axe', 'axes'], + ['die', 'dice'], + ['yes', 'yeses'], + ['foot', 'feet'], + ['eave', 'eaves'], + ['goose', 'geese'], + ['tooth', 'teeth'], + ['quiz', 'quizzes'], + ['human', 'humans'], + ['proof', 'proofs'], + ['carve', 'carves'], + ['valve', 'valves'], + ['looey', 'looies'], + ['thief', 'thieves'], + ['groove', 'grooves'], + ['pickaxe', 'pickaxes'], + ['passerby', 'passersby'] + ].forEach(function (rule) { + return pluralize.addIrregularRule(rule[0], rule[1]); + }); + + /** + * Pluralization rules. + */ + [ + [/s?$/i, 's'], + [/[^\u0000-\u007F]$/i, '$0'], + [/([^aeiou]ese)$/i, '$1'], + [/(ax|test)is$/i, '$1es'], + [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], + [/(e[mn]u)s?$/i, '$1s'], + [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], + [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], + [/(seraph|cherub)(?:im)?$/i, '$1im'], + [/(her|at|gr)o$/i, '$1oes'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], + [/sis$/i, 'ses'], + [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], + [/([^aeiouy]|qu)y$/i, '$1ies'], + [/([^ch][ieo][ln])ey$/i, '$1ies'], + [/(x|ch|ss|sh|zz)$/i, '$1es'], + [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], + [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], + [/(pe)(?:rson|ople)$/i, '$1ople'], + [/(child)(?:ren)?$/i, '$1ren'], + [/eaux$/i, '$0'], + [/m[ae]n$/i, 'men'], + ['thou', 'you'] + ].forEach(function (rule) { + return pluralize.addPluralRule(rule[0], rule[1]); + }); + + /** + * Singularization rules. + */ + [ + [/s$/i, ''], + [/(ss)$/i, '$1'], + [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], + [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], + [/ies$/i, 'y'], + [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], + [/\b(mon|smil)ies$/i, '$1ey'], + [/\b((?:tit)?m|l)ice$/i, '$1ouse'], + [/(seraph|cherub)im$/i, '$1'], + [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], + [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], + [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], + [/(test)(?:is|es)$/i, '$1is'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], + [/(alumn|alg|vertebr)ae$/i, '$1a'], + [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], + [/(matr|append)ices$/i, '$1ix'], + [/(pe)(rson|ople)$/i, '$1rson'], + [/(child)ren$/i, '$1'], + [/(eau)x?$/i, '$1'], + [/men$/i, 'man'] + ].forEach(function (rule) { + return pluralize.addSingularRule(rule[0], rule[1]); + }); + + /** + * Uncountable rules. + */ + [ + // Singular words with no plurals. + 'adulthood', + 'advice', + 'agenda', + 'aid', + 'aircraft', + 'alcohol', + 'ammo', + 'analytics', + 'anime', + 'athletics', + 'audio', + 'bison', + 'blood', + 'bream', + 'buffalo', + 'butter', + 'carp', + 'cash', + 'chassis', + 'chess', + 'clothing', + 'cod', + 'commerce', + 'cooperation', + 'corps', + 'debris', + 'diabetes', + 'digestion', + 'elk', + 'energy', + 'equipment', + 'excretion', + 'expertise', + 'firmware', + 'flounder', + 'fun', + 'gallows', + 'garbage', + 'graffiti', + 'hardware', + 'headquarters', + 'health', + 'herpes', + 'highjinks', + 'homework', + 'housework', + 'information', + 'jeans', + 'justice', + 'kudos', + 'labour', + 'literature', + 'machinery', + 'mackerel', + 'mail', + 'media', + 'mews', + 'moose', + 'music', + 'mud', + 'manga', + 'news', + 'only', + 'personnel', + 'pike', + 'plankton', + 'pliers', + 'police', + 'pollution', + 'premises', + 'rain', + 'research', + 'rice', + 'salmon', + 'scissors', + 'series', + 'sewage', + 'shambles', + 'shrimp', + 'software', + 'species', + 'staff', + 'swine', + 'tennis', + 'traffic', + 'transportation', + 'trout', + 'tuna', + 'wealth', + 'welfare', + 'whiting', + 'wildebeest', + 'wildlife', + 'you', + /pok[eé]mon$/i, + // Regexes. + /[^aeiou]ese$/i, // "chinese", "japanese" + /deer$/i, // "deer", "reindeer" + /fish$/i, // "fish", "blowfish", "angelfish" + /measles$/i, + /o[iu]s$/i, // "carnivorous" + /pox$/i, // "chickpox", "smallpox" + /sheep$/i + ].forEach(pluralize.addUncountableRule); + + return pluralize; +}); +}); + +var convert_1$3 = convert$4; + +function convert$4(test) { + if (typeof test === 'string') { + return typeFactory$3(test) + } + + if (test === null || test === undefined) { + return ok$4 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$3 : matchesFactory$3)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$3(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$4(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$3(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$3(tests) { + var checks = convertAll$3(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$3(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$4() { + return true +} + +var unistUtilVisitParents$3 = visitParents$3; + + + +var CONTINUE$6 = true; +var SKIP$6 = 'skip'; +var EXIT$6 = false; + +visitParents$3.CONTINUE = CONTINUE$6; +visitParents$3.SKIP = SKIP$6; +visitParents$3.EXIT = EXIT$6; + +function visitParents$3(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$3(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$3(visitor(node, parents)); + + if (result[0] === EXIT$6) { + return result + } + } + + if (node.children && result[0] !== SKIP$6) { + subresult = toResult$3(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$6 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$6) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$3(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$1 = factory$8('start'); -var end = factory$8('end'); + if (typeof value === 'number') { + return [CONTINUE$6, value] + } + + return [value] +} + +var unistUtilVisit$3 = visit$3; + + + +var CONTINUE$7 = unistUtilVisitParents$3.CONTINUE; +var SKIP$7 = unistUtilVisitParents$3.SKIP; +var EXIT$7 = unistUtilVisitParents$3.EXIT; + +visit$3.CONTINUE = CONTINUE$7; +visit$3.SKIP = SKIP$7; +visit$3.EXIT = EXIT$7; + +function visit$3(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$3(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var start$1 = factory$a('start'); +var end = factory$a('end'); var unistUtilPosition = position$1; @@ -42440,7 +43483,7 @@ function position$1(node) { return {start: start$1(node), end: end(node)} } -function factory$8(type) { +function factory$a(type) { point.displayName = type; return point @@ -42480,7 +43523,7 @@ var start$2 = unistUtilPosition.start; function listItemBulletIndent(tree, file) { var contents = String(file); - unistUtilVisit(tree, 'list', visitor); + unistUtilVisit$3(tree, 'list', visitor); function visitor(node) { node.children.forEach(visitItems); @@ -42501,7 +43544,7 @@ function listItemBulletIndent(tree, file) { 'Incorrect indentation before bullet: remove ' + indent + ' ' + - plur('space', indent); + pluralize('space', indent); file.message(reason, { line: final.line, @@ -42512,26 +43555,216 @@ function listItemBulletIndent(tree, file) { } } +var convert_1$4 = convert$5; + +function convert$5(test) { + if (typeof test === 'string') { + return typeFactory$4(test) + } + + if (test === null || test === undefined) { + return ok$5 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$4 : matchesFactory$4)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$4(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$5(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$4(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$4(tests) { + var checks = convertAll$4(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$4(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$5() { + return true +} + +var unistUtilVisitParents$4 = visitParents$4; + + + +var CONTINUE$8 = true; +var SKIP$8 = 'skip'; +var EXIT$8 = false; + +visitParents$4.CONTINUE = CONTINUE$8; +visitParents$4.SKIP = SKIP$8; +visitParents$4.EXIT = EXIT$8; + +function visitParents$4(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$4(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$4(visitor(node, parents)); + + if (result[0] === EXIT$8) { + return result + } + } + + if (node.children && result[0] !== SKIP$8) { + subresult = toResult$4(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$8 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$8) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$4(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$8, value] + } + + return [value] +} + +var unistUtilVisit$4 = visit$4; + + + +var CONTINUE$9 = unistUtilVisitParents$4.CONTINUE; +var SKIP$9 = unistUtilVisitParents$4.SKIP; +var EXIT$9 = unistUtilVisitParents$4.EXIT; + +visit$4.CONTINUE = CONTINUE$9; +visit$4.SKIP = SKIP$9; +visit$4.EXIT = EXIT$9; + +function visit$4(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$4(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + var remarkLintListItemIndent = unifiedLintRule('remark-lint:list-item-indent', listItemIndent); var start$3 = unistUtilPosition.start; var styles = {'tab-size': true, mixed: true, space: true}; -function listItemIndent(tree, file, pref) { +function listItemIndent(tree, file, option) { var contents = String(file); + var preferred = typeof option === 'string' ? option : 'tab-size'; - pref = typeof pref === 'string' ? pref : 'tab-size'; - - if (styles[pref] !== true) { + if (styles[preferred] !== true) { file.fail( - 'Invalid list-item indent style `' + - pref + + 'Incorrect list-item indent style `' + + preferred + "`: use either `'tab-size'`, `'space'`, or `'mixed'`" ); } - unistUtilVisit(tree, 'list', visitor); + unistUtilVisit$4(tree, 'list', visitor); function visitor(node) { var spread = node.spread || node.loose; @@ -42548,28 +43781,30 @@ function listItemIndent(tree, file, pref) { var style; var diff; var reason; + var abs; marker = contents .slice(start$3(item).offset, final.offset) .replace(/\[[x ]?]\s*$/i, ''); - bulletSize = marker.trimRight().length; + bulletSize = marker.replace(/\s+$/, '').length; style = - pref === 'tab-size' || (pref === 'mixed' && spread) + preferred === 'tab-size' || (preferred === 'mixed' && spread) ? Math.ceil(bulletSize / 4) * 4 : bulletSize + 1; if (marker.length !== style) { diff = style - marker.length; + abs = Math.abs(diff); reason = 'Incorrect list-item indent: ' + (diff > 0 ? 'add' : 'remove') + ' ' + - Math.abs(diff) + + abs + ' ' + - plur('space', diff); + pluralize('space', abs); file.message(reason, final); } @@ -42577,1385 +43812,7850 @@ function listItemIndent(tree, file, pref) { } } -var mdastUtilToString = toString$4; +var convert_1$5 = convert$6; -// Get the text content of a node. If the node itself does not expose -// plain-text fields, `toString` will recursivly try its children. -function toString$4(node) { - return ( - valueOf$1(node) || - (node.children && node.children.map(toString$4).join('')) || - '' - ) +function convert$6(test) { + if (typeof test === 'string') { + return typeFactory$5(test) + } + + if (test === null || test === undefined) { + return ok$6 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$5 : matchesFactory$5)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') } -// Get the value of `node`. Checks, `value`, `alt`, and `title`, in that order. -function valueOf$1(node) { - return ( - (node && node.value ? node.value : node.alt ? node.alt : node.title) || '' - ) +function convertAll$5(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$6(tests[index]); + } + + return results } -var remarkLintNoAutoLinkWithoutProtocol = unifiedLintRule( - 'remark-lint:no-auto-link-without-protocol', - noAutoLinkWithoutProtocol -); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$5(test) { + return matches -var start$4 = unistUtilPosition.start; -var end$1 = unistUtilPosition.end; + function matches(node) { + var key; -// Protocol expression. -// See: . -var protocol$2 = /^[a-z][a-z+.-]+:\/?/i; + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } -var reason = 'All automatic links must start with a protocol'; + return true + } +} -function noAutoLinkWithoutProtocol(tree, file) { - unistUtilVisit(tree, 'link', visitor); +function anyFactory$5(tests) { + var checks = convertAll$5(tests); + var length = checks.length; - function visitor(node) { - var children; + return matches - if (!unistUtilGenerated(node)) { - children = node.children; + function matches() { + var index = -1; - if ( - start$4(node).column === start$4(children[0]).column - 1 && - end$1(node).column === end$1(children[children.length - 1]).column + 1 && - !protocol$2.test(mdastUtilToString(node)) - ) { - file.message(reason, node); + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true } } + + return false } } -var remarkLintNoBlockquoteWithoutMarker = unifiedLintRule( - 'remark-lint:no-blockquote-without-marker', - noBlockquoteWithoutMarker -); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$5(test) { + return type -var reason$1 = 'Missing marker in blockquote'; + function type(node) { + return Boolean(node && node.type === test) + } +} -function noBlockquoteWithoutMarker(tree, file) { - var contents = String(file); - var location = vfileLocation(file); - var last = contents.length; +// Utility to return true. +function ok$6() { + return true +} - unistUtilVisit(tree, 'blockquote', visitor); +var unistUtilVisitParents$5 = visitParents$5; - function visitor(node) { - var indent = node.position && node.position.indent; - var start; - var length; - var index; - var line; - var offset; - var character; - var pos; - if (unistUtilGenerated(node) || !indent || indent.length === 0) { - return - } - start = unistUtilPosition.start(node).line; - length = indent.length; - index = -1; +var CONTINUE$a = true; +var SKIP$a = 'skip'; +var EXIT$a = false; - while (++index < length) { - line = start + index + 1; - pos = {line: line, column: indent[index]}; - offset = location.toOffset(pos) - 1; +visitParents$5.CONTINUE = CONTINUE$a; +visitParents$5.SKIP = SKIP$a; +visitParents$5.EXIT = EXIT$a; - while (++offset < last) { +function visitParents$5(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$5(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$5(visitor(node, parents)); + + if (result[0] === EXIT$a) { + return result + } + } + + if (node.children && result[0] !== SKIP$a) { + subresult = toResult$5(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$a ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$a) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$5(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$a, value] + } + + return [value] +} + +var unistUtilVisit$5 = visit$5; + + + +var CONTINUE$b = unistUtilVisitParents$5.CONTINUE; +var SKIP$b = unistUtilVisitParents$5.SKIP; +var EXIT$b = unistUtilVisitParents$5.EXIT; + +visit$5.CONTINUE = CONTINUE$b; +visit$5.SKIP = SKIP$b; +visit$5.EXIT = EXIT$b; + +function visit$5(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$5(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var mdastUtilToString = toString$4; + +// Get the text content of a node. +// Prefer the node’s plain-text fields, otherwise serialize its children, +// and if the given value is an array, serialize the nodes in it. +function toString$4(node) { + return ( + (node && + (node.value || + node.alt || + node.title || + ('children' in node && all$1(node.children)) || + ('length' in node && all$1(node)))) || + '' + ) +} + +function all$1(values) { + var result = []; + var length = values.length; + var index = -1; + + while (++index < length) { + result[index] = toString$4(values[index]); + } + + return result.join('') +} + +var remarkLintNoAutoLinkWithoutProtocol = unifiedLintRule( + 'remark-lint:no-auto-link-without-protocol', + noAutoLinkWithoutProtocol +); + +var start$4 = unistUtilPosition.start; +var end$1 = unistUtilPosition.end; + +// Protocol expression. +// See: . +var protocol$2 = /^[a-z][a-z+.-]+:\/?/i; + +var reason = 'All automatic links must start with a protocol'; + +function noAutoLinkWithoutProtocol(tree, file) { + unistUtilVisit$5(tree, 'link', visitor); + + function visitor(node) { + var children; + + if (!unistUtilGenerated(node)) { + children = node.children; + + if ( + start$4(node).column === start$4(children[0]).column - 1 && + end$1(node).column === end$1(children[children.length - 1]).column + 1 && + !protocol$2.test(mdastUtilToString(node)) + ) { + file.message(reason, node); + } + } + } +} + +var vfileLocation$3 = factory$b; + +function factory$b(file) { + var contents = indices$3(String(file)); + + return { + toPosition: offsetToPositionFactory$3(contents), + toOffset: positionToOffsetFactory$3(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$3(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$3(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$3(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$6 = convert$7; + +function convert$7(test) { + if (typeof test === 'string') { + return typeFactory$6(test) + } + + if (test === null || test === undefined) { + return ok$7 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$6 : matchesFactory$6)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$6(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$7(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$6(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$6(tests) { + var checks = convertAll$6(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$6(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$7() { + return true +} + +var unistUtilVisitParents$6 = visitParents$6; + + + +var CONTINUE$c = true; +var SKIP$c = 'skip'; +var EXIT$c = false; + +visitParents$6.CONTINUE = CONTINUE$c; +visitParents$6.SKIP = SKIP$c; +visitParents$6.EXIT = EXIT$c; + +function visitParents$6(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$6(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$6(visitor(node, parents)); + + if (result[0] === EXIT$c) { + return result + } + } + + if (node.children && result[0] !== SKIP$c) { + subresult = toResult$6(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$c ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$c) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$6(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$c, value] + } + + return [value] +} + +var unistUtilVisit$6 = visit$6; + + + +var CONTINUE$d = unistUtilVisitParents$6.CONTINUE; +var SKIP$d = unistUtilVisitParents$6.SKIP; +var EXIT$d = unistUtilVisitParents$6.EXIT; + +visit$6.CONTINUE = CONTINUE$d; +visit$6.SKIP = SKIP$d; +visit$6.EXIT = EXIT$d; + +function visit$6(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$6(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoBlockquoteWithoutMarker = unifiedLintRule( + 'remark-lint:no-blockquote-without-marker', + noBlockquoteWithoutMarker +); + +var reason$1 = 'Missing marker in block quote'; + +function noBlockquoteWithoutMarker(tree, file) { + var contents = String(file); + var location = vfileLocation$3(file); + var last = contents.length; + + unistUtilVisit$6(tree, 'blockquote', visitor); + + function visitor(node) { + var indent = node.position && node.position.indent; + var start; + var length; + var index; + var line; + var offset; + var character; + var pos; + + if (unistUtilGenerated(node) || !indent || indent.length === 0) { + return + } + + start = unistUtilPosition.start(node).line; + length = indent.length; + index = -1; + + while (++index < length) { + line = start + index + 1; + pos = {line: line, column: indent[index]}; + offset = location.toOffset(pos) - 1; + + while (++offset < last) { character = contents.charAt(offset); - if (character === '>') { - break - } + if (character === '>') { + break + } + + /* istanbul ignore else - just for safety */ + if (character !== ' ' && character !== '\t') { + file.message(reason$1, pos); + break + } + } + } + } +} + +var convert_1$7 = convert$8; + +function convert$8(test) { + if (typeof test === 'string') { + return typeFactory$7(test) + } + + if (test === null || test === undefined) { + return ok$8 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$7 : matchesFactory$7)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$7(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$8(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$7(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$7(tests) { + var checks = convertAll$7(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$7(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$8() { + return true +} + +var unistUtilVisitParents$7 = visitParents$7; + + + +var CONTINUE$e = true; +var SKIP$e = 'skip'; +var EXIT$e = false; + +visitParents$7.CONTINUE = CONTINUE$e; +visitParents$7.SKIP = SKIP$e; +visitParents$7.EXIT = EXIT$e; + +function visitParents$7(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$7(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$7(visitor(node, parents)); + + if (result[0] === EXIT$e) { + return result + } + } + + if (node.children && result[0] !== SKIP$e) { + subresult = toResult$7(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$e ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$e) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$7(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$e, value] + } + + return [value] +} + +var unistUtilVisit$7 = visit$7; + + + +var CONTINUE$f = unistUtilVisitParents$7.CONTINUE; +var SKIP$f = unistUtilVisitParents$7.SKIP; +var EXIT$f = unistUtilVisitParents$7.EXIT; + +visit$7.CONTINUE = CONTINUE$f; +visit$7.SKIP = SKIP$f; +visit$7.EXIT = EXIT$f; + +function visit$7(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$7(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoLiteralUrls = unifiedLintRule('remark-lint:no-literal-urls', noLiteralURLs); + +var start$5 = unistUtilPosition.start; +var end$2 = unistUtilPosition.end; +var mailto$3 = 'mailto:'; +var reason$2 = 'Don’t use literal URLs without angle brackets'; + +function noLiteralURLs(tree, file) { + unistUtilVisit$7(tree, 'link', visitor); + + function visitor(node) { + var children = node.children; + var value = mdastUtilToString(node); + + if ( + !unistUtilGenerated(node) && + start$5(node).column === start$5(children[0]).column && + end$2(node).column === end$2(children[children.length - 1]).column && + (node.url === mailto$3 + value || node.url === value) + ) { + file.message(reason$2, node); + } + } +} + +var convert_1$8 = convert$9; + +function convert$9(test) { + if (typeof test === 'string') { + return typeFactory$8(test) + } + + if (test === null || test === undefined) { + return ok$9 + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$8 : matchesFactory$8)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$8(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$9(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$8(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$8(tests) { + var checks = convertAll$8(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$8(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$9() { + return true +} + +var unistUtilVisitParents$8 = visitParents$8; + + + +var CONTINUE$g = true; +var SKIP$g = 'skip'; +var EXIT$g = false; + +visitParents$8.CONTINUE = CONTINUE$g; +visitParents$8.SKIP = SKIP$g; +visitParents$8.EXIT = EXIT$g; + +function visitParents$8(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$8(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$8(visitor(node, parents)); + + if (result[0] === EXIT$g) { + return result + } + } + + if (node.children && result[0] !== SKIP$g) { + subresult = toResult$8(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$g ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$g) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$8(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$g, value] + } + + return [value] +} + +var unistUtilVisit$8 = visit$8; + + + +var CONTINUE$h = unistUtilVisitParents$8.CONTINUE; +var SKIP$h = unistUtilVisitParents$8.SKIP; +var EXIT$h = unistUtilVisitParents$8.EXIT; + +visit$8.CONTINUE = CONTINUE$h; +visit$8.SKIP = SKIP$h; +visit$8.EXIT = EXIT$h; + +function visit$8(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$8(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintOrderedListMarkerStyle = unifiedLintRule( + 'remark-lint:ordered-list-marker-style', + orderedListMarkerStyle +); + +var start$6 = unistUtilPosition.start; + +var styles$1 = { + ')': true, + '.': true, + null: true +}; + +function orderedListMarkerStyle(tree, file, option) { + var contents = String(file); + var preferred = + typeof option !== 'string' || option === 'consistent' ? null : option; + + if (styles$1[preferred] !== true) { + file.fail( + 'Incorrect ordered list item marker style `' + + preferred + + "`: use either `'.'` or `')'`" + ); + } + + unistUtilVisit$8(tree, 'list', visitor); + + function visitor(node) { + var children = node.children; + var length = node.ordered ? children.length : 0; + var index = -1; + var marker; + var child; + + while (++index < length) { + child = children[index]; + + if (!unistUtilGenerated(child)) { + marker = contents + .slice(start$6(child).offset, start$6(child.children[0]).offset) + .replace(/\s|\d/g, '') + .replace(/\[[x ]?]\s*$/i, ''); + + if (preferred) { + if (marker !== preferred) { + file.message('Marker style should be `' + preferred + '`', child); + } + } else { + preferred = marker; + } + } + } + } +} + +var convert_1$9 = convert$a; + +function convert$a(test) { + if (typeof test === 'string') { + return typeFactory$9(test) + } + + if (test === null || test === undefined) { + return ok$a + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$9 : matchesFactory$9)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$9(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$a(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$9(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$9(tests) { + var checks = convertAll$9(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$9(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$a() { + return true +} + +var unistUtilVisitParents$9 = visitParents$9; + + + +var CONTINUE$i = true; +var SKIP$i = 'skip'; +var EXIT$i = false; + +visitParents$9.CONTINUE = CONTINUE$i; +visitParents$9.SKIP = SKIP$i; +visitParents$9.EXIT = EXIT$i; + +function visitParents$9(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$9(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$9(visitor(node, parents)); + + if (result[0] === EXIT$i) { + return result + } + } + + if (node.children && result[0] !== SKIP$i) { + subresult = toResult$9(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$i ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$i) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$9(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$i, value] + } + + return [value] +} + +var unistUtilVisit$9 = visit$9; + + + +var CONTINUE$j = unistUtilVisitParents$9.CONTINUE; +var SKIP$j = unistUtilVisitParents$9.SKIP; +var EXIT$j = unistUtilVisitParents$9.EXIT; + +visit$9.CONTINUE = CONTINUE$j; +visit$9.SKIP = SKIP$j; +visit$9.EXIT = EXIT$j; + +function visit$9(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$9(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintHardBreakSpaces = unifiedLintRule('remark-lint:hard-break-spaces', hardBreakSpaces); + +var reason$3 = 'Use two spaces for hard line breaks'; + +function hardBreakSpaces(tree, file) { + var contents = String(file); + + unistUtilVisit$9(tree, 'break', visitor); + + function visitor(node) { + var value; + + if (!unistUtilGenerated(node)) { + value = contents + .slice(unistUtilPosition.start(node).offset, unistUtilPosition.end(node).offset) + .split('\n', 1)[0] + .replace(/\r$/, ''); + + if (value.length > 2) { + file.message(reason$3, node); + } + } + } +} + +var convert_1$a = convert$b; + +function convert$b(test) { + if (typeof test === 'string') { + return typeFactory$a(test) + } + + if (test === null || test === undefined) { + return ok$b + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$a : matchesFactory$a)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$a(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$b(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$a(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$a(tests) { + var checks = convertAll$a(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$a(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$b() { + return true +} + +var unistUtilVisitParents$a = visitParents$a; + + + +var CONTINUE$k = true; +var SKIP$k = 'skip'; +var EXIT$k = false; + +visitParents$a.CONTINUE = CONTINUE$k; +visitParents$a.SKIP = SKIP$k; +visitParents$a.EXIT = EXIT$k; + +function visitParents$a(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$a(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$a(visitor(node, parents)); + + if (result[0] === EXIT$k) { + return result + } + } + + if (node.children && result[0] !== SKIP$k) { + subresult = toResult$a(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$k ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$k) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$a(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$k, value] + } + + return [value] +} + +var unistUtilVisit$a = visit$a; + + + +var CONTINUE$l = unistUtilVisitParents$a.CONTINUE; +var SKIP$l = unistUtilVisitParents$a.SKIP; +var EXIT$l = unistUtilVisitParents$a.EXIT; + +visit$a.CONTINUE = CONTINUE$l; +visit$a.SKIP = SKIP$l; +visit$a.EXIT = EXIT$l; + +function visit$a(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$a(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoDuplicateDefinitions = unifiedLintRule( + 'remark-lint:no-duplicate-definitions', + noDuplicateDefinitions +); + +var reason$4 = 'Do not use definitions with the same identifier'; + +function noDuplicateDefinitions(tree, file) { + var map = {}; + + unistUtilVisit$a(tree, ['definition', 'footnoteDefinition'], check); + + function check(node) { + var identifier; + var duplicate; + + if (!unistUtilGenerated(node)) { + identifier = node.identifier; + duplicate = map[identifier]; + + if (duplicate && duplicate.type) { + file.message( + reason$4 + ' (' + unistUtilStringifyPosition(unistUtilPosition.start(duplicate)) + ')', + node + ); + } + + map[identifier] = node; + } + } +} + +var convert_1$b = convert$c; + +function convert$c(test) { + if (typeof test === 'string') { + return typeFactory$b(test) + } + + if (test === null || test === undefined) { + return ok$c + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$b : matchesFactory$b)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$b(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$c(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$b(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$b(tests) { + var checks = convertAll$b(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$b(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$c() { + return true +} + +var unistUtilVisitParents$b = visitParents$b; + + + +var CONTINUE$m = true; +var SKIP$m = 'skip'; +var EXIT$m = false; + +visitParents$b.CONTINUE = CONTINUE$m; +visitParents$b.SKIP = SKIP$m; +visitParents$b.EXIT = EXIT$m; + +function visitParents$b(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$b(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$b(visitor(node, parents)); + + if (result[0] === EXIT$m) { + return result + } + } + + if (node.children && result[0] !== SKIP$m) { + subresult = toResult$b(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$m ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$m) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$b(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$m, value] + } + + return [value] +} + +var unistUtilVisit$b = visit$b; + + + +var CONTINUE$n = unistUtilVisitParents$b.CONTINUE; +var SKIP$n = unistUtilVisitParents$b.SKIP; +var EXIT$n = unistUtilVisitParents$b.EXIT; + +visit$b.CONTINUE = CONTINUE$n; +visit$b.SKIP = SKIP$n; +visit$b.EXIT = EXIT$n; + +function visit$b(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$b(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var mdastUtilHeadingStyle = style; + +function style(node, relative) { + var last = node.children[node.children.length - 1]; + var depth = node.depth; + var pos = node && node.position && node.position.end; + var final = last && last.position && last.position.end; + + if (!pos) { + return null + } + + // This can only occur for `'atx'` and `'atx-closed'` headings. + // This might incorrectly match `'atx'` headings with lots of trailing white + // space as an `'atx-closed'` heading. + if (!last) { + if (pos.column - 1 <= depth * 2) { + return consolidate(depth, relative) + } + + return 'atx-closed' + } + + if (final.line + 1 === pos.line) { + return 'setext' + } + + if (final.column + depth < pos.column) { + return 'atx-closed' + } + + return consolidate(depth, relative) +} + +// Get the probable style of an atx-heading, depending on preferred style. +function consolidate(depth, relative) { + return depth < 3 + ? 'atx' + : relative === 'atx' || relative === 'setext' + ? relative + : null +} + +var remarkLintNoHeadingContentIndent = unifiedLintRule( + 'remark-lint:no-heading-content-indent', + noHeadingContentIndent +); + +var start$7 = unistUtilPosition.start; +var end$3 = unistUtilPosition.end; + +function noHeadingContentIndent(tree, file) { + var contents = String(file); + + unistUtilVisit$b(tree, 'heading', visitor); + + function visitor(node) { + var depth; + var children; + var type; + var head; + var initial; + var final; + var diff; + var index; + var char; + var reason; + var abs; + + if (unistUtilGenerated(node)) { + return + } + + depth = node.depth; + children = node.children; + type = mdastUtilHeadingStyle(node, 'atx'); + + if (type === 'atx' || type === 'atx-closed') { + initial = start$7(node); + index = initial.offset; + char = contents.charAt(index); + + while (char && char !== '#') { + char = contents.charAt(++index); + } + + /* istanbul ignore if - CR/LF bug: remarkjs/remark#195. */ + if (!char) { + return + } + + index = depth + (index - initial.offset); + head = start$7(children[0]).column; + + // Ignore empty headings. + if (!head) { + return + } + + diff = head - initial.column - 1 - index; + + if (diff) { + abs = Math.abs(diff); + + reason = + (diff > 0 ? 'Remove' : 'Add') + + ' ' + + abs + + ' ' + + pluralize('space', abs) + + ' before this heading’s content'; + + file.message(reason, start$7(children[0])); + } + } + + // Closed ATX headings always must have a space between their content and + // the final hashes, thus, there is no `add x spaces`. + if (type === 'atx-closed') { + final = end$3(children[children.length - 1]); + diff = end$3(node).column - final.column - 1 - depth; + + if (diff) { + reason = + 'Remove ' + + diff + + ' ' + + pluralize('space', diff) + + ' after this heading’s content'; + + file.message(reason, final); + } + } + } +} + +var convert_1$c = convert$d; + +function convert$d(test) { + if (typeof test === 'string') { + return typeFactory$c(test) + } + + if (test === null || test === undefined) { + return ok$d + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$c : matchesFactory$c)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$c(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$d(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$c(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$c(tests) { + var checks = convertAll$c(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$c(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$d() { + return true +} + +var unistUtilVisitParents$c = visitParents$c; + + + +var CONTINUE$o = true; +var SKIP$o = 'skip'; +var EXIT$o = false; + +visitParents$c.CONTINUE = CONTINUE$o; +visitParents$c.SKIP = SKIP$o; +visitParents$c.EXIT = EXIT$o; + +function visitParents$c(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$c(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$c(visitor(node, parents)); + + if (result[0] === EXIT$o) { + return result + } + } + + if (node.children && result[0] !== SKIP$o) { + subresult = toResult$c(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$o ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$o) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$c(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$o, value] + } + + return [value] +} + +var unistUtilVisit$c = visit$c; + + + +var CONTINUE$p = unistUtilVisitParents$c.CONTINUE; +var SKIP$p = unistUtilVisitParents$c.SKIP; +var EXIT$p = unistUtilVisitParents$c.EXIT; + +visit$c.CONTINUE = CONTINUE$p; +visit$c.SKIP = SKIP$p; +visit$c.EXIT = EXIT$p; + +function visit$c(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$c(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoInlinePadding = unifiedLintRule('remark-lint:no-inline-padding', noInlinePadding); + +function noInlinePadding(tree, file) { + unistUtilVisit$c(tree, ['emphasis', 'strong', 'delete', 'image', 'link'], visitor); + + function visitor(node) { + var contents; + + if (!unistUtilGenerated(node)) { + contents = mdastUtilToString(node); + + if ( + contents.charAt(0) === ' ' || + contents.charAt(contents.length - 1) === ' ' + ) { + file.message('Don’t pad `' + node.type + '` with inner spaces', node); + } + } + } +} + +var convert_1$d = convert$e; + +function convert$e(test) { + if (typeof test === 'string') { + return typeFactory$d(test) + } + + if (test === null || test === undefined) { + return ok$e + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$d : matchesFactory$d)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$d(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$e(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$d(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$d(tests) { + var checks = convertAll$d(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$d(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$e() { + return true +} + +var unistUtilVisitParents$d = visitParents$d; + + + +var CONTINUE$q = true; +var SKIP$q = 'skip'; +var EXIT$q = false; + +visitParents$d.CONTINUE = CONTINUE$q; +visitParents$d.SKIP = SKIP$q; +visitParents$d.EXIT = EXIT$q; + +function visitParents$d(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$d(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$d(visitor(node, parents)); + + if (result[0] === EXIT$q) { + return result + } + } + + if (node.children && result[0] !== SKIP$q) { + subresult = toResult$d(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$q ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$q) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$d(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$q, value] + } + + return [value] +} + +var unistUtilVisit$d = visit$d; + + + +var CONTINUE$r = unistUtilVisitParents$d.CONTINUE; +var SKIP$r = unistUtilVisitParents$d.SKIP; +var EXIT$r = unistUtilVisitParents$d.EXIT; + +visit$d.CONTINUE = CONTINUE$r; +visit$d.SKIP = SKIP$r; +visit$d.EXIT = EXIT$r; + +function visit$d(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$d(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoShortcutReferenceImage = unifiedLintRule( + 'remark-lint:no-shortcut-reference-image', + noShortcutReferenceImage +); + +var reason$5 = 'Use the trailing [] on reference images'; + +function noShortcutReferenceImage(tree, file) { + unistUtilVisit$d(tree, 'imageReference', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { + file.message(reason$5, node); + } + } +} + +var convert_1$e = convert$f; + +function convert$f(test) { + if (typeof test === 'string') { + return typeFactory$e(test) + } + + if (test === null || test === undefined) { + return ok$f + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$e : matchesFactory$e)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$e(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$f(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$e(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$e(tests) { + var checks = convertAll$e(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$e(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$f() { + return true +} + +var unistUtilVisitParents$e = visitParents$e; + + + +var CONTINUE$s = true; +var SKIP$s = 'skip'; +var EXIT$s = false; + +visitParents$e.CONTINUE = CONTINUE$s; +visitParents$e.SKIP = SKIP$s; +visitParents$e.EXIT = EXIT$s; + +function visitParents$e(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$e(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$e(visitor(node, parents)); + + if (result[0] === EXIT$s) { + return result + } + } + + if (node.children && result[0] !== SKIP$s) { + subresult = toResult$e(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$s ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$s) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$e(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$s, value] + } + + return [value] +} + +var unistUtilVisit$e = visit$e; + + + +var CONTINUE$t = unistUtilVisitParents$e.CONTINUE; +var SKIP$t = unistUtilVisitParents$e.SKIP; +var EXIT$t = unistUtilVisitParents$e.EXIT; + +visit$e.CONTINUE = CONTINUE$t; +visit$e.SKIP = SKIP$t; +visit$e.EXIT = EXIT$t; + +function visit$e(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$e(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoShortcutReferenceLink = unifiedLintRule( + 'remark-lint:no-shortcut-reference-link', + noShortcutReferenceLink +); + +var reason$6 = 'Use the trailing `[]` on reference links'; + +function noShortcutReferenceLink(tree, file) { + unistUtilVisit$e(tree, 'linkReference', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { + file.message(reason$6, node); + } + } +} + +var convert_1$f = convert$g; + +function convert$g(test) { + if (typeof test === 'string') { + return typeFactory$f(test) + } + + if (test === null || test === undefined) { + return ok$g + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$f : matchesFactory$f)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$f(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$g(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$f(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$f(tests) { + var checks = convertAll$f(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$f(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$g() { + return true +} + +var unistUtilVisitParents$f = visitParents$f; + + + +var CONTINUE$u = true; +var SKIP$u = 'skip'; +var EXIT$u = false; + +visitParents$f.CONTINUE = CONTINUE$u; +visitParents$f.SKIP = SKIP$u; +visitParents$f.EXIT = EXIT$u; + +function visitParents$f(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$f(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$f(visitor(node, parents)); + + if (result[0] === EXIT$u) { + return result + } + } + + if (node.children && result[0] !== SKIP$u) { + subresult = toResult$f(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$u ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$u) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$f(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$u, value] + } + + return [value] +} + +var unistUtilVisit$f = visit$f; + + + +var CONTINUE$v = unistUtilVisitParents$f.CONTINUE; +var SKIP$v = unistUtilVisitParents$f.SKIP; +var EXIT$v = unistUtilVisitParents$f.EXIT; + +visit$f.CONTINUE = CONTINUE$v; +visit$f.SKIP = SKIP$v; +visit$f.EXIT = EXIT$v; + +function visit$f(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$f(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoUndefinedReferences = unifiedLintRule( + 'remark-lint:no-undefined-references', + noUndefinedReferences +); + +var reason$7 = 'Found reference to undefined definition'; + +// The identifier is upcased to avoid naming collisions with fields inherited +// from `Object.prototype`. +// If `Object.create(null)` was used in place of `{}`, downcasing would work +// equally well. +function normalize$3(s) { + return collapseWhiteSpace(s.toUpperCase()) +} + +function noUndefinedReferences(tree, file, option) { + var allow = ((option || {}).allow || []).map(normalize$3); + var map = {}; + + unistUtilVisit$f(tree, ['definition', 'footnoteDefinition'], mark); + unistUtilVisit$f(tree, ['imageReference', 'linkReference', 'footnoteReference'], find); + + function mark(node) { + if (!unistUtilGenerated(node)) { + map[normalize$3(node.identifier)] = true; + } + } + + function find(node) { + if ( + !unistUtilGenerated(node) && + !(normalize$3(node.identifier) in map) && + allow.indexOf(normalize$3(node.identifier)) === -1 + ) { + file.message(reason$7, node); + } + } +} + +var convert_1$g = convert$h; + +function convert$h(test) { + if (typeof test === 'string') { + return typeFactory$g(test) + } + + if (test === null || test === undefined) { + return ok$h + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$g : matchesFactory$g)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$g(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$h(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$g(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$g(tests) { + var checks = convertAll$g(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$g(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$h() { + return true +} + +var unistUtilVisitParents$g = visitParents$g; + + + +var CONTINUE$w = true; +var SKIP$w = 'skip'; +var EXIT$w = false; + +visitParents$g.CONTINUE = CONTINUE$w; +visitParents$g.SKIP = SKIP$w; +visitParents$g.EXIT = EXIT$w; + +function visitParents$g(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$g(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$g(visitor(node, parents)); + + if (result[0] === EXIT$w) { + return result + } + } + + if (node.children && result[0] !== SKIP$w) { + subresult = toResult$g(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$w ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$w) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$g(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$w, value] + } + + return [value] +} + +var unistUtilVisit$g = visit$g; + + + +var CONTINUE$x = unistUtilVisitParents$g.CONTINUE; +var SKIP$x = unistUtilVisitParents$g.SKIP; +var EXIT$x = unistUtilVisitParents$g.EXIT; + +visit$g.CONTINUE = CONTINUE$x; +visit$g.SKIP = SKIP$x; +visit$g.EXIT = EXIT$x; + +function visit$g(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$g(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoUnusedDefinitions = unifiedLintRule('remark-lint:no-unused-definitions', noUnusedDefinitions); + +var reason$8 = 'Found unused definition'; + +function noUnusedDefinitions(tree, file) { + var map = {}; + var identifier; + var entry; + + unistUtilVisit$g(tree, ['definition', 'footnoteDefinition'], find); + unistUtilVisit$g(tree, ['imageReference', 'linkReference', 'footnoteReference'], mark); + + for (identifier in map) { + entry = map[identifier]; + + if (!entry.used) { + file.message(reason$8, entry.node); + } + } + + function find(node) { + if (!unistUtilGenerated(node)) { + map[node.identifier.toUpperCase()] = {node: node, used: false}; + } + } + + function mark(node) { + var info = map[node.identifier.toUpperCase()]; + + if (!unistUtilGenerated(node) && info) { + info.used = true; + } + } +} + +var plugins$1 = [ + remarkLint$1, + // Unix compatibility. + remarkLintFinalNewline, + // Rendering across vendors differs greatly if using other styles. + remarkLintListItemBulletIndent, + [remarkLintListItemIndent, 'tab-size'], + // Differs or unsupported across vendors. + remarkLintNoAutoLinkWithoutProtocol, + remarkLintNoBlockquoteWithoutMarker, + remarkLintNoLiteralUrls, + [remarkLintOrderedListMarkerStyle, '.'], + // Mistakes. + remarkLintHardBreakSpaces, + remarkLintNoDuplicateDefinitions, + remarkLintNoHeadingContentIndent, + remarkLintNoInlinePadding, + remarkLintNoShortcutReferenceImage, + remarkLintNoShortcutReferenceLink, + remarkLintNoUndefinedReferences, + remarkLintNoUnusedDefinitions +]; + +var remarkPresetLintRecommended = { + plugins: plugins$1 +}; + +var convert_1$h = convert$i; + +function convert$i(test) { + if (typeof test === 'string') { + return typeFactory$h(test) + } + + if (test === null || test === undefined) { + return ok$i + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$h : matchesFactory$h)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$h(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$i(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$h(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$h(tests) { + var checks = convertAll$h(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$h(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$i() { + return true +} + +var unistUtilVisitParents$h = visitParents$h; + + + +var CONTINUE$y = true; +var SKIP$y = 'skip'; +var EXIT$y = false; + +visitParents$h.CONTINUE = CONTINUE$y; +visitParents$h.SKIP = SKIP$y; +visitParents$h.EXIT = EXIT$y; + +function visitParents$h(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$h(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$h(visitor(node, parents)); + + if (result[0] === EXIT$y) { + return result + } + } + + if (node.children && result[0] !== SKIP$y) { + subresult = toResult$h(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$y ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$y) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$h(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$y, value] + } + + return [value] +} + +var unistUtilVisit$h = visit$h; + + + +var CONTINUE$z = unistUtilVisitParents$h.CONTINUE; +var SKIP$z = unistUtilVisitParents$h.SKIP; +var EXIT$z = unistUtilVisitParents$h.EXIT; + +visit$h.CONTINUE = CONTINUE$z; +visit$h.SKIP = SKIP$z; +visit$h.EXIT = EXIT$z; + +function visit$h(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$h(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintBlockquoteIndentation = unifiedLintRule( + 'remark-lint:blockquote-indentation', + blockquoteIndentation +); + +function blockquoteIndentation(tree, file, option) { + var preferred = typeof option === 'number' && !isNaN(option) ? option : null; + + unistUtilVisit$h(tree, 'blockquote', visitor); + + function visitor(node) { + var abs; + var diff; + var reason; + + if (unistUtilGenerated(node) || node.children.length === 0) { + return + } + + if (preferred) { + diff = preferred - check$3(node); + + if (diff !== 0) { + abs = Math.abs(diff); + reason = + (diff > 0 ? 'Add' : 'Remove') + + ' ' + + abs + + ' ' + + pluralize('space', abs) + + ' between block quote and content'; + + file.message(reason, unistUtilPosition.start(node.children[0])); + } + } else { + preferred = check$3(node); + } + } +} + +function check$3(node) { + var head = node.children[0]; + var indentation = unistUtilPosition.start(head).column - unistUtilPosition.start(node).column; + var padding = mdastUtilToString(head).match(/^ +/); + + if (padding) { + indentation += padding[0].length; + } + + return indentation +} + +var vfileLocation$4 = factory$c; + +function factory$c(file) { + var contents = indices$4(String(file)); + + return { + toPosition: offsetToPositionFactory$4(contents), + toOffset: positionToOffsetFactory$4(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$4(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$4(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$4(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$i = convert$j; + +function convert$j(test) { + if (typeof test === 'string') { + return typeFactory$i(test) + } + + if (test === null || test === undefined) { + return ok$j + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$i : matchesFactory$i)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$i(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$j(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$i(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$i(tests) { + var checks = convertAll$i(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$i(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$j() { + return true +} + +var unistUtilVisitParents$i = visitParents$i; + + + +var CONTINUE$A = true; +var SKIP$A = 'skip'; +var EXIT$A = false; + +visitParents$i.CONTINUE = CONTINUE$A; +visitParents$i.SKIP = SKIP$A; +visitParents$i.EXIT = EXIT$A; + +function visitParents$i(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$i(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$i(visitor(node, parents)); + + if (result[0] === EXIT$A) { + return result + } + } + + if (node.children && result[0] !== SKIP$A) { + subresult = toResult$i(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$A ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$A) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$i(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$A, value] + } + + return [value] +} + +var unistUtilVisit$i = visit$i; + + + +var CONTINUE$B = unistUtilVisitParents$i.CONTINUE; +var SKIP$B = unistUtilVisitParents$i.SKIP; +var EXIT$B = unistUtilVisitParents$i.EXIT; + +visit$i.CONTINUE = CONTINUE$B; +visit$i.SKIP = SKIP$B; +visit$i.EXIT = EXIT$B; + +function visit$i(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$i(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintCheckboxCharacterStyle = unifiedLintRule( + 'remark-lint:checkbox-character-style', + checkboxCharacterStyle +); + +var start$8 = unistUtilPosition.start; +var end$4 = unistUtilPosition.end; + +var checked = {x: true, X: true}; +var unchecked = {' ': true, '\t': true}; +var types$1 = {true: 'checked', false: 'unchecked'}; + +function checkboxCharacterStyle(tree, file, option) { + var contents = String(file); + var location = vfileLocation$4(file); + var preferred = typeof option === 'object' ? option : {}; + + if (preferred.unchecked && unchecked[preferred.unchecked] !== true) { + file.fail( + 'Incorrect unchecked checkbox marker `' + + preferred.unchecked + + "`: use either `'\\t'`, or `' '`" + ); + } + + if (preferred.checked && checked[preferred.checked] !== true) { + file.fail( + 'Incorrect checked checkbox marker `' + + preferred.checked + + "`: use either `'x'`, or `'X'`" + ); + } + + unistUtilVisit$i(tree, 'listItem', visitor); + + function visitor(node) { + var type; + var initial; + var final; + var value; + var style; + var character; + var reason; + + // Exit early for items without checkbox. + if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { + return + } + + type = types$1[node.checked]; + initial = start$8(node).offset; + final = (node.children.length === 0 ? end$4(node) : start$8(node.children[0])) + .offset; + + // For a checkbox to be parsed, it must be followed by a whitespace. + value = contents.slice(initial, final).replace(/\s+$/, '').slice(0, -1); + + // The checkbox character is behind a square bracket. + character = value.charAt(value.length - 1); + style = preferred[type]; + + if (style) { + if (character !== style) { + reason = + type.charAt(0).toUpperCase() + + type.slice(1) + + ' checkboxes should use `' + + style + + '` as a marker'; + + file.message(reason, { + start: location.toPosition(initial + value.length - 1), + end: location.toPosition(initial + value.length) + }); + } + } else { + preferred[type] = character; + } + } +} + +var vfileLocation$5 = factory$d; + +function factory$d(file) { + var contents = indices$5(String(file)); + + return { + toPosition: offsetToPositionFactory$5(contents), + toOffset: positionToOffsetFactory$5(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$5(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$5(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices$5(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var convert_1$j = convert$k; + +function convert$k(test) { + if (typeof test === 'string') { + return typeFactory$j(test) + } + + if (test === null || test === undefined) { + return ok$k + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$j : matchesFactory$j)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$j(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$k(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$j(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$j(tests) { + var checks = convertAll$j(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$j(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$k() { + return true +} + +var unistUtilVisitParents$j = visitParents$j; + + + +var CONTINUE$C = true; +var SKIP$C = 'skip'; +var EXIT$C = false; + +visitParents$j.CONTINUE = CONTINUE$C; +visitParents$j.SKIP = SKIP$C; +visitParents$j.EXIT = EXIT$C; + +function visitParents$j(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$j(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$j(visitor(node, parents)); + + if (result[0] === EXIT$C) { + return result + } + } + + if (node.children && result[0] !== SKIP$C) { + subresult = toResult$j(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$C ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$C) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$j(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$C, value] + } + + return [value] +} + +var unistUtilVisit$j = visit$j; + + + +var CONTINUE$D = unistUtilVisitParents$j.CONTINUE; +var SKIP$D = unistUtilVisitParents$j.SKIP; +var EXIT$D = unistUtilVisitParents$j.EXIT; + +visit$j.CONTINUE = CONTINUE$D; +visit$j.SKIP = SKIP$D; +visit$j.EXIT = EXIT$D; + +function visit$j(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$j(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintCheckboxContentIndent = unifiedLintRule( + 'remark-lint:checkbox-content-indent', + checkboxContentIndent +); + +var start$9 = unistUtilPosition.start; +var end$5 = unistUtilPosition.end; + +var reason$9 = 'Checkboxes should be followed by a single character'; + +function checkboxContentIndent(tree, file) { + var contents = String(file); + var location = vfileLocation$5(file); + + unistUtilVisit$j(tree, 'listItem', visitor); + + function visitor(node) { + var initial; + var final; + var value; + + // Exit early for items without checkbox. + if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { + return + } + + initial = start$9(node).offset; + /* istanbul ignore next - hard to test, couldn’t find a case. */ + final = (node.children.length === 0 ? end$5(node) : start$9(node.children[0])) + .offset; + + while (/[^\S\n]/.test(contents.charAt(final))) { + final++; + } + + // For a checkbox to be parsed, it must be followed by a whitespace. + value = contents.slice(initial, final); + value = value.slice(value.indexOf(']') + 1); + + if (value.length !== 1) { + file.message(reason$9, { + start: location.toPosition(final - value.length + 1), + end: location.toPosition(final) + }); + } + } +} + +var convert_1$k = convert$l; + +function convert$l(test) { + if (typeof test === 'string') { + return typeFactory$k(test) + } + + if (test === null || test === undefined) { + return ok$l + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$k : matchesFactory$k)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$k(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$l(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$k(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$k(tests) { + var checks = convertAll$k(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$k(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$l() { + return true +} + +var unistUtilVisitParents$k = visitParents$k; + + + +var CONTINUE$E = true; +var SKIP$E = 'skip'; +var EXIT$E = false; + +visitParents$k.CONTINUE = CONTINUE$E; +visitParents$k.SKIP = SKIP$E; +visitParents$k.EXIT = EXIT$E; + +function visitParents$k(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$k(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$k(visitor(node, parents)); + + if (result[0] === EXIT$E) { + return result + } + } + + if (node.children && result[0] !== SKIP$E) { + subresult = toResult$k(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$E ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$E) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$k(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$E, value] + } + + return [value] +} + +var unistUtilVisit$k = visit$k; + + + +var CONTINUE$F = unistUtilVisitParents$k.CONTINUE; +var SKIP$F = unistUtilVisitParents$k.SKIP; +var EXIT$F = unistUtilVisitParents$k.EXIT; + +visit$k.CONTINUE = CONTINUE$F; +visit$k.SKIP = SKIP$F; +visit$k.EXIT = EXIT$F; + +function visit$k(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$k(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintCodeBlockStyle = unifiedLintRule('remark-lint:code-block-style', codeBlockStyle); + +var start$a = unistUtilPosition.start; +var end$6 = unistUtilPosition.end; + +var styles$2 = {null: true, fenced: true, indented: true}; + +function codeBlockStyle(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; + + if (styles$2[preferred] !== true) { + file.fail( + 'Incorrect code block style `' + + preferred + + "`: use either `'consistent'`, `'fenced'`, or `'indented'`" + ); + } + + unistUtilVisit$k(tree, 'code', visitor); + + function visitor(node) { + var initial; + var final; + var current; + + if (unistUtilGenerated(node)) { + return null + } + + initial = start$a(node).offset; + final = end$6(node).offset; + + current = + node.lang || /^\s*([~`])\1{2,}/.test(contents.slice(initial, final)) + ? 'fenced' + : 'indented'; + + if (preferred) { + if (preferred !== current) { + file.message('Code blocks should be ' + preferred, node); + } + } else { + preferred = current; + } + } +} + +var convert_1$l = convert$m; + +function convert$m(test) { + if (typeof test === 'string') { + return typeFactory$l(test) + } + + if (test === null || test === undefined) { + return ok$m + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$l : matchesFactory$l)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$l(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$m(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$l(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$l(tests) { + var checks = convertAll$l(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$l(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$m() { + return true +} + +var unistUtilVisitParents$l = visitParents$l; + + + +var CONTINUE$G = true; +var SKIP$G = 'skip'; +var EXIT$G = false; + +visitParents$l.CONTINUE = CONTINUE$G; +visitParents$l.SKIP = SKIP$G; +visitParents$l.EXIT = EXIT$G; + +function visitParents$l(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$l(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$l(visitor(node, parents)); + + if (result[0] === EXIT$G) { + return result + } + } + + if (node.children && result[0] !== SKIP$G) { + subresult = toResult$l(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$G ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$G) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$l(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$G, value] + } + + return [value] +} + +var unistUtilVisit$l = visit$l; + + + +var CONTINUE$H = unistUtilVisitParents$l.CONTINUE; +var SKIP$H = unistUtilVisitParents$l.SKIP; +var EXIT$H = unistUtilVisitParents$l.EXIT; + +visit$l.CONTINUE = CONTINUE$H; +visit$l.SKIP = SKIP$H; +visit$l.EXIT = EXIT$H; + +function visit$l(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$l(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintDefinitionSpacing = unifiedLintRule('remark-lint:definition-spacing', definitionSpacing); + +var label$1 = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; +var reason$a = 'Do not use consecutive whitespace in definition labels'; + +function definitionSpacing(tree, file) { + var contents = String(file); + + unistUtilVisit$l(tree, ['definition', 'footnoteDefinition'], check); + + function check(node) { + var start = unistUtilPosition.start(node).offset; + var end = unistUtilPosition.end(node).offset; + + if ( + !unistUtilGenerated(node) && + /[ \t\n]{2,}/.test(contents.slice(start, end).match(label$1)[1]) + ) { + file.message(reason$a, node); + } + } +} + +var convert_1$m = convert$n; + +function convert$n(test) { + if (typeof test === 'string') { + return typeFactory$m(test) + } + + if (test === null || test === undefined) { + return ok$n + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$m : matchesFactory$m)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$m(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$n(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$m(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$m(tests) { + var checks = convertAll$m(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$m(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$n() { + return true +} + +var unistUtilVisitParents$m = visitParents$m; + + + +var CONTINUE$I = true; +var SKIP$I = 'skip'; +var EXIT$I = false; + +visitParents$m.CONTINUE = CONTINUE$I; +visitParents$m.SKIP = SKIP$I; +visitParents$m.EXIT = EXIT$I; + +function visitParents$m(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$m(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$m(visitor(node, parents)); + + if (result[0] === EXIT$I) { + return result + } + } + + if (node.children && result[0] !== SKIP$I) { + subresult = toResult$m(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$I ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$I) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$m(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$I, value] + } + + return [value] +} + +var unistUtilVisit$m = visit$m; + + + +var CONTINUE$J = unistUtilVisitParents$m.CONTINUE; +var SKIP$J = unistUtilVisitParents$m.SKIP; +var EXIT$J = unistUtilVisitParents$m.EXIT; + +visit$m.CONTINUE = CONTINUE$J; +visit$m.SKIP = SKIP$J; +visit$m.EXIT = EXIT$J; + +function visit$m(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$m(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFencedCodeFlag = unifiedLintRule('remark-lint:fenced-code-flag', fencedCodeFlag); + +var start$b = unistUtilPosition.start; +var end$7 = unistUtilPosition.end; + +var fence$2 = /^ {0,3}([~`])\1{2,}/; +var reasonIncorrect = 'Incorrect code language flag'; +var reasonMissing = 'Missing code language flag'; + +function fencedCodeFlag(tree, file, option) { + var contents = String(file); + var allowEmpty = false; + var allowed = []; + var flags = option; + + if (typeof flags === 'object' && !('length' in flags)) { + allowEmpty = Boolean(flags.allowEmpty); + flags = flags.flags; + } + + if (typeof flags === 'object' && 'length' in flags) { + allowed = String(flags).split(','); + } + + unistUtilVisit$m(tree, 'code', visitor); + + function visitor(node) { + var value; + + if (!unistUtilGenerated(node)) { + if (node.lang) { + if (allowed.length !== 0 && allowed.indexOf(node.lang) === -1) { + file.message(reasonIncorrect, node); + } + } else { + value = contents.slice(start$b(node).offset, end$7(node).offset); + + if (!allowEmpty && fence$2.test(value)) { + file.message(reasonMissing, node); + } + } + } + } +} + +var convert_1$n = convert$o; + +function convert$o(test) { + if (typeof test === 'string') { + return typeFactory$n(test) + } + + if (test === null || test === undefined) { + return ok$o + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$n : matchesFactory$n)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$n(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$o(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$n(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$n(tests) { + var checks = convertAll$n(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$n(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$o() { + return true +} + +var unistUtilVisitParents$n = visitParents$n; + + + +var CONTINUE$K = true; +var SKIP$K = 'skip'; +var EXIT$K = false; + +visitParents$n.CONTINUE = CONTINUE$K; +visitParents$n.SKIP = SKIP$K; +visitParents$n.EXIT = EXIT$K; + +function visitParents$n(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$n(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$n(visitor(node, parents)); + + if (result[0] === EXIT$K) { + return result + } + } + + if (node.children && result[0] !== SKIP$K) { + subresult = toResult$n(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$K ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$K) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$n(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$K, value] + } + + return [value] +} + +var unistUtilVisit$n = visit$n; + + + +var CONTINUE$L = unistUtilVisitParents$n.CONTINUE; +var SKIP$L = unistUtilVisitParents$n.SKIP; +var EXIT$L = unistUtilVisitParents$n.EXIT; + +visit$n.CONTINUE = CONTINUE$L; +visit$n.SKIP = SKIP$L; +visit$n.EXIT = EXIT$L; + +function visit$n(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$n(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFencedCodeMarker = unifiedLintRule('remark-lint:fenced-code-marker', fencedCodeMarker); + +var markers = { + '`': true, + '~': true, + null: true +}; + +function fencedCodeMarker(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; + + if (markers[preferred] !== true) { + file.fail( + 'Incorrect fenced code marker `' + + preferred + + "`: use either `'consistent'`, `` '`' ``, or `'~'`" + ); + } + + unistUtilVisit$n(tree, 'code', visitor); + + function visitor(node) { + var start; + var marker; + var label; + + if (!unistUtilGenerated(node)) { + start = unistUtilPosition.start(node).offset; + marker = contents + .slice(start, start + 4) + .replace(/^\s+/, '') + .charAt(0); + + // Ignore unfenced code blocks. + if (markers[marker] === true) { + if (preferred) { + if (marker !== preferred) { + label = preferred === '~' ? preferred : '` ` `'; + file.message( + 'Fenced code should use `' + label + '` as a marker', + node + ); + } + } else { + preferred = marker; + } + } + } + } +} + +var remarkLintFileExtension = unifiedLintRule('remark-lint:file-extension', fileExtension); + +function fileExtension(tree, file, option) { + var ext = file.extname; + var preferred = typeof option === 'string' ? option : 'md'; + + if (ext && ext.slice(1) !== preferred) { + file.message('Incorrect extension: use `' + preferred + '`'); + } +} + +var convert_1$o = convert$p; + +function convert$p(test) { + if (typeof test === 'string') { + return typeFactory$o(test) + } + + if (test === null || test === undefined) { + return ok$p + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$o : matchesFactory$o)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$o(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$p(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$o(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$o(tests) { + var checks = convertAll$o(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$o(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$p() { + return true +} + +var unistUtilVisitParents$o = visitParents$o; + + + +var CONTINUE$M = true; +var SKIP$M = 'skip'; +var EXIT$M = false; + +visitParents$o.CONTINUE = CONTINUE$M; +visitParents$o.SKIP = SKIP$M; +visitParents$o.EXIT = EXIT$M; + +function visitParents$o(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$o(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$o(visitor(node, parents)); + + if (result[0] === EXIT$M) { + return result + } + } + + if (node.children && result[0] !== SKIP$M) { + subresult = toResult$o(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$M ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$M) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$o(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$M, value] + } + + return [value] +} + +var unistUtilVisit$o = visit$o; + + + +var CONTINUE$N = unistUtilVisitParents$o.CONTINUE; +var SKIP$N = unistUtilVisitParents$o.SKIP; +var EXIT$N = unistUtilVisitParents$o.EXIT; + +visit$o.CONTINUE = CONTINUE$N; +visit$o.SKIP = SKIP$N; +visit$o.EXIT = EXIT$N; + +function visit$o(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$o(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFinalDefinition = unifiedLintRule('remark-lint:final-definition', finalDefinition); + +var start$c = unistUtilPosition.start; + +function finalDefinition(tree, file) { + var last = null; + + unistUtilVisit$o(tree, visitor, true); + + function visitor(node) { + var line = start$c(node).line; + + // Ignore generated nodes. + if (node.type === 'root' || unistUtilGenerated(node)) { + return + } + + if (node.type === 'definition') { + if (last !== null && last > line) { + file.message( + 'Move definitions to the end of the file (after the node at line `' + + last + + '`)', + node + ); + } + } else if (last === null) { + last = line; + } + } +} + +var convert_1$p = convert$q; + +function convert$q(test) { + if (typeof test === 'string') { + return typeFactory$p(test) + } + + if (test === null || test === undefined) { + return ok$q + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$p : matchesFactory$p)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$p(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$q(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$p(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$p(tests) { + var checks = convertAll$p(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$p(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$q() { + return true +} + +var unistUtilVisitParents$p = visitParents$p; + + + +var CONTINUE$O = true; +var SKIP$O = 'skip'; +var EXIT$O = false; + +visitParents$p.CONTINUE = CONTINUE$O; +visitParents$p.SKIP = SKIP$O; +visitParents$p.EXIT = EXIT$O; + +function visitParents$p(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$p(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$p(visitor(node, parents)); + + if (result[0] === EXIT$O) { + return result + } + } + + if (node.children && result[0] !== SKIP$O) { + subresult = toResult$p(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$O ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$O) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$p(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$O, value] + } + + return [value] +} + +var unistUtilVisit$p = visit$p; + + + +var CONTINUE$P = unistUtilVisitParents$p.CONTINUE; +var SKIP$P = unistUtilVisitParents$p.SKIP; +var EXIT$P = unistUtilVisitParents$p.EXIT; + +visit$p.CONTINUE = CONTINUE$P; +visit$p.SKIP = SKIP$P; +visit$p.EXIT = EXIT$P; + +function visit$p(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$p(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintFirstHeadingLevel = unifiedLintRule('remark-lint:first-heading-level', firstHeadingLevel); + +var re$3 = / min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$Q) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$q(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$Q, value] + } + + return [value] +} + +var unistUtilVisit$q = visit$q; + + + +var CONTINUE$R = unistUtilVisitParents$q.CONTINUE; +var SKIP$R = unistUtilVisitParents$q.SKIP; +var EXIT$R = unistUtilVisitParents$q.EXIT; + +visit$q.CONTINUE = CONTINUE$R; +visit$q.SKIP = SKIP$R; +visit$q.EXIT = EXIT$R; + +function visit$q(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$q(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintHeadingStyle = unifiedLintRule('remark-lint:heading-style', headingStyle); + +var types$2 = ['atx', 'atx-closed', 'setext']; + +function headingStyle(tree, file, option) { + var preferred = types$2.indexOf(option) === -1 ? null : option; + + unistUtilVisit$q(tree, 'heading', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node)) { + if (preferred) { + if (mdastUtilHeadingStyle(node, preferred) !== preferred) { + file.message('Headings should use ' + preferred, node); + } + } else { + preferred = mdastUtilHeadingStyle(node, preferred); + } + } + } +} + +var convert_1$r = convert$s; + +function convert$s(test) { + if (typeof test === 'string') { + return typeFactory$r(test) + } + + if (test === null || test === undefined) { + return ok$s + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$r : matchesFactory$r)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$r(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$s(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$r(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$r(tests) { + var checks = convertAll$r(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$r(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$s() { + return true +} + +var unistUtilVisitParents$r = visitParents$r; + + + +var CONTINUE$S = true; +var SKIP$S = 'skip'; +var EXIT$S = false; + +visitParents$r.CONTINUE = CONTINUE$S; +visitParents$r.SKIP = SKIP$S; +visitParents$r.EXIT = EXIT$S; + +function visitParents$r(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$r(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$r(visitor(node, parents)); + + if (result[0] === EXIT$S) { + return result + } + } + + if (node.children && result[0] !== SKIP$S) { + subresult = toResult$r(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$S ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$S) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$r(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$S, value] + } + + return [value] +} + +var unistUtilVisit$r = visit$r; + + + +var CONTINUE$T = unistUtilVisitParents$r.CONTINUE; +var SKIP$T = unistUtilVisitParents$r.SKIP; +var EXIT$T = unistUtilVisitParents$r.EXIT; + +visit$r.CONTINUE = CONTINUE$T; +visit$r.SKIP = SKIP$T; +visit$r.EXIT = EXIT$T; + +function visit$r(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$r(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintMaximumLineLength = unifiedLintRule('remark-lint:maximum-line-length', maximumLineLength); + +var start$d = unistUtilPosition.start; +var end$8 = unistUtilPosition.end; + +function maximumLineLength(tree, file, option) { + var preferred = typeof option === 'number' && !isNaN(option) ? option : 80; + var content = String(file); + var lines = content.split(/\r?\n/); + var length = lines.length; + var index = -1; + var lineLength; + + // Note: JSX is from MDX: . + unistUtilVisit$r(tree, ['heading', 'table', 'code', 'definition', 'html', 'jsx'], ignore); + unistUtilVisit$r(tree, ['link', 'image', 'inlineCode'], inline); + + // Iterate over every line, and warn for violating lines. + while (++index < length) { + lineLength = lines[index].length; + + if (lineLength > preferred) { + file.message('Line must be at most ' + preferred + ' characters', { + line: index + 1, + column: lineLength + 1 + }); + } + } + + // Finally, whitelist some inline spans, but only if they occur at or after + // the wrap. + // However, when they do, and there’s whitespace after it, they are not + // whitelisted. + function inline(node, pos, parent) { + var next = parent.children[pos + 1]; + var initial; + var final; + + /* istanbul ignore if - Nothing to whitelist when generated. */ + if (unistUtilGenerated(node)) { + return + } + + initial = start$d(node); + final = end$8(node); + + // No whitelisting when starting after the border, or ending before it. + if (initial.column > preferred || final.column < preferred) { + return + } + + // No whitelisting when there’s whitespace after the link. + if ( + next && + start$d(next).line === initial.line && + (!next.value || /^(.+?[ \t].+?)/.test(next.value)) + ) { + return + } + + whitelist(initial.line - 1, final.line); + } + + function ignore(node) { + /* istanbul ignore else - Hard to test, as we only run this case on `position: true` */ + if (!unistUtilGenerated(node)) { + whitelist(start$d(node).line - 1, end$8(node).line); + } + } + + // Whitelist from `initial` to `final`, zero-based. + function whitelist(initial, final) { + while (initial < final) { + lines[initial++] = ''; + } + } +} + +var convert_1$s = convert$t; + +function convert$t(test) { + if (typeof test === 'string') { + return typeFactory$s(test) + } + + if (test === null || test === undefined) { + return ok$t + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$s : matchesFactory$s)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$s(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$t(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$s(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$s(tests) { + var checks = convertAll$s(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$s(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$t() { + return true +} + +var unistUtilVisitParents$s = visitParents$s; + + + +var CONTINUE$U = true; +var SKIP$U = 'skip'; +var EXIT$U = false; + +visitParents$s.CONTINUE = CONTINUE$U; +visitParents$s.SKIP = SKIP$U; +visitParents$s.EXIT = EXIT$U; + +function visitParents$s(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$s(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$s(visitor(node, parents)); + + if (result[0] === EXIT$U) { + return result + } + } + + if (node.children && result[0] !== SKIP$U) { + subresult = toResult$s(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$U ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$U) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$s(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$U, value] + } + + return [value] +} + +var unistUtilVisit$s = visit$s; + + + +var CONTINUE$V = unistUtilVisitParents$s.CONTINUE; +var SKIP$V = unistUtilVisitParents$s.SKIP; +var EXIT$V = unistUtilVisitParents$s.EXIT; + +visit$s.CONTINUE = CONTINUE$V; +visit$s.SKIP = SKIP$V; +visit$s.EXIT = EXIT$V; + +function visit$s(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$s(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoConsecutiveBlankLines = unifiedLintRule( + 'remark-lint:no-consecutive-blank-lines', + noConsecutiveBlankLines +); + +function noConsecutiveBlankLines(tree, file) { + unistUtilVisit$s(tree, visitor); + + function visitor(node) { + var children = node.children; + var head; + var tail; + + if (!unistUtilGenerated(node) && children) { + head = children[0]; + + if (head && !unistUtilGenerated(head)) { + // Compare parent and first child. + compare(unistUtilPosition.start(node), unistUtilPosition.start(head), 0); + + // Compare between each child. + children.forEach(visitChild); + + tail = children[children.length - 1]; + + // Compare parent and last child. + if (tail !== head && !unistUtilGenerated(tail)) { + compare(unistUtilPosition.end(node), unistUtilPosition.end(tail), 1); + } + } + } + } + + // Compare the difference between `start` and `end`, and warn when that + // difference exceeds `max`. + function compare(start, end, max) { + var diff = end.line - start.line; + var lines = Math.abs(diff) - max; + var reason; + + if (lines > 0) { + reason = + 'Remove ' + + lines + + ' ' + + pluralize('line', Math.abs(lines)) + + ' ' + + (diff > 0 ? 'before' : 'after') + + ' node'; + + file.message(reason, end); + } + } + + function visitChild(child, index, all) { + var previous = all[index - 1]; + var max = 2; + + if (previous && !unistUtilGenerated(previous) && !unistUtilGenerated(child)) { + if ( + (previous.type === 'list' && child.type === 'list') || + (child.type === 'code' && previous.type === 'list' && !child.lang) + ) { + max++; + } + + compare(unistUtilPosition.end(previous), unistUtilPosition.start(child), max); + } + } +} + +var remarkLintNoFileNameArticles = unifiedLintRule('remark-lint:no-file-name-articles', noFileNameArticles); + +function noFileNameArticles(tree, file) { + var match = file.stem && file.stem.match(/^(the|teh|an?)\b/i); + + if (match) { + file.message('Do not start file names with `' + match[0] + '`'); + } +} + +var remarkLintNoFileNameConsecutiveDashes = unifiedLintRule( + 'remark-lint:no-file-name-consecutive-dashes', + noFileNameConsecutiveDashes +); + +var reason$b = 'Do not use consecutive dashes in a file name'; + +function noFileNameConsecutiveDashes(tree, file) { + if (file.stem && /-{2,}/.test(file.stem)) { + file.message(reason$b); + } +} + +var remarkLintNoFileNameOuterDashes = unifiedLintRule( + 'remark-lint:no-file-name-outer-dashes', + noFileNameOuterDashes +); + +var reason$c = 'Do not use initial or final dashes in a file name'; + +function noFileNameOuterDashes(tree, file) { + if (file.stem && /^-|-$/.test(file.stem)) { + file.message(reason$c); + } +} + +var convert_1$t = convert$u; + +function convert$u(test) { + if (typeof test === 'string') { + return typeFactory$t(test) + } + + if (test === null || test === undefined) { + return ok$u + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$t : matchesFactory$t)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$t(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$u(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$t(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$t(tests) { + var checks = convertAll$t(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$t(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$u() { + return true +} + +var unistUtilVisitParents$t = visitParents$t; + + + +var CONTINUE$W = true; +var SKIP$W = 'skip'; +var EXIT$W = false; + +visitParents$t.CONTINUE = CONTINUE$W; +visitParents$t.SKIP = SKIP$W; +visitParents$t.EXIT = EXIT$W; + +function visitParents$t(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$t(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$t(visitor(node, parents)); + + if (result[0] === EXIT$W) { + return result + } + } + + if (node.children && result[0] !== SKIP$W) { + subresult = toResult$t(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$W ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$W) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$t(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$W, value] + } + + return [value] +} + +var unistUtilVisit$t = visit$t; + + + +var CONTINUE$X = unistUtilVisitParents$t.CONTINUE; +var SKIP$X = unistUtilVisitParents$t.SKIP; +var EXIT$X = unistUtilVisitParents$t.EXIT; + +visit$t.CONTINUE = CONTINUE$X; +visit$t.SKIP = SKIP$X; +visit$t.EXIT = EXIT$X; + +function visit$t(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$t(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoHeadingIndent = unifiedLintRule('remark-lint:no-heading-indent', noHeadingIndent); + +var start$e = unistUtilPosition.start; + +function noHeadingIndent(tree, file) { + var contents = String(file); + var length = contents.length; + + unistUtilVisit$t(tree, 'heading', visitor); + + function visitor(node) { + var initial; + var begin; + var index; + var character; + var diff; + + if (unistUtilGenerated(node)) { + return + } + + initial = start$e(node); + begin = initial.offset; + index = begin - 1; + + while (++index < length) { + character = contents.charAt(index); + + if (character !== ' ' && character !== '\t') { + break + } + } + + diff = index - begin; + + if (diff) { + file.message( + 'Remove ' + diff + ' ' + pluralize('space', diff) + ' before this heading', + { + line: initial.line, + column: initial.column + diff + } + ); + } + } +} + +var convert_1$u = convert$v; + +function convert$v(test) { + if (typeof test === 'string') { + return typeFactory$u(test) + } + + if (test === null || test === undefined) { + return ok$v + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$u : matchesFactory$u)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$u(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$v(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$u(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$u(tests) { + var checks = convertAll$u(tests); + var length = checks.length; - /* istanbul ignore else - just for safety */ - if (character !== ' ' && character !== '\t') { - file.message(reason$1, pos); - break - } + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true } } + + return false } } -var remarkLintNoLiteralUrls = unifiedLintRule('remark-lint:no-literal-urls', noLiteralURLs); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$u(test) { + return type -var start$5 = unistUtilPosition.start; -var end$2 = unistUtilPosition.end; -var mailto$3 = 'mailto:'; -var reason$2 = 'Don’t use literal URLs without angle brackets'; + function type(node) { + return Boolean(node && node.type === test) + } +} -function noLiteralURLs(tree, file) { - unistUtilVisit(tree, 'link', visitor); +// Utility to return true. +function ok$v() { + return true +} - function visitor(node) { - var children = node.children; - var value = mdastUtilToString(node); +var unistUtilVisitParents$u = visitParents$u; - if ( - !unistUtilGenerated(node) && - start$5(node).column === start$5(children[0]).column && - end$2(node).column === end$2(children[children.length - 1]).column && - (node.url === mailto$3 + value || node.url === value) - ) { - file.message(reason$2, node); + + +var CONTINUE$Y = true; +var SKIP$Y = 'skip'; +var EXIT$Y = false; + +visitParents$u.CONTINUE = CONTINUE$Y; +visitParents$u.SKIP = SKIP$Y; +visitParents$u.EXIT = EXIT$Y; + +function visitParents$u(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$u(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$u(visitor(node, parents)); + + if (result[0] === EXIT$Y) { + return result + } + } + + if (node.children && result[0] !== SKIP$Y) { + subresult = toResult$u(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$Y ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$Y) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintOrderedListMarkerStyle = unifiedLintRule( - 'remark-lint:ordered-list-marker-style', - orderedListMarkerStyle -); +function toResult$u(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$6 = unistUtilPosition.start; + if (typeof value === 'number') { + return [CONTINUE$Y, value] + } -var styles$1 = { - ')': true, - '.': true, - null: true -}; + return [value] +} -function orderedListMarkerStyle(tree, file, pref) { - var contents = String(file); +var unistUtilVisit$u = visit$u; - pref = typeof pref !== 'string' || pref === 'consistent' ? null : pref; - if (styles$1[pref] !== true) { - file.fail( - 'Invalid ordered list-item marker style `' + - pref + - "`: use either `'.'` or `')'`" - ); + +var CONTINUE$Z = unistUtilVisitParents$u.CONTINUE; +var SKIP$Z = unistUtilVisitParents$u.SKIP; +var EXIT$Z = unistUtilVisitParents$u.EXIT; + +visit$u.CONTINUE = CONTINUE$Z; +visit$u.SKIP = SKIP$Z; +visit$u.EXIT = EXIT$Z; + +function visit$u(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$u(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } +} + +var start$f = unistUtilPosition.start; - unistUtilVisit(tree, 'list', visitor); + + +var remarkLintNoMultipleToplevelHeadings = unifiedLintRule( + 'remark-lint:no-multiple-toplevel-headings', + noMultipleToplevelHeadings +); + +function noMultipleToplevelHeadings(tree, file, option) { + var preferred = option || 1; + var duplicate; + + unistUtilVisit$u(tree, 'heading', visitor); function visitor(node) { - var children = node.children; - var length = node.ordered ? children.length : 0; - var index = -1; - var marker; - var child; + if (!unistUtilGenerated(node) && node.depth === preferred) { + if (duplicate) { + file.message( + 'Don’t use multiple top level headings (' + duplicate + ')', + node + ); + } else { + duplicate = unistUtilStringifyPosition(start$f(node)); + } + } + } +} - while (++index < length) { - child = children[index]; +var convert_1$v = convert$w; - if (!unistUtilGenerated(child)) { - marker = contents - .slice(start$6(child).offset, start$6(child.children[0]).offset) - .replace(/\s|\d/g, '') - .replace(/\[[x ]?]\s*$/i, ''); +function convert$w(test) { + if (typeof test === 'string') { + return typeFactory$v(test) + } - if (pref) { - if (marker !== pref) { - file.message('Marker style should be `' + pref + '`', child); - } - } else { - pref = marker; - } + if (test === null || test === undefined) { + return ok$w + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$v : matchesFactory$v)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$v(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$w(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$v(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false } } + + return true } } -var remarkLintHardBreakSpaces = unifiedLintRule('remark-lint:hard-break-spaces', hardBreakSpaces); +function anyFactory$v(tests) { + var checks = convertAll$v(tests); + var length = checks.length; -var reason$3 = 'Use two spaces for hard line breaks'; + return matches -function hardBreakSpaces(tree, file) { - var contents = String(file); + function matches() { + var index = -1; - unistUtilVisit(tree, 'break', visitor); + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } - function visitor(node) { - var value; + return false + } +} - if (!unistUtilGenerated(node)) { - value = contents - .slice(unistUtilPosition.start(node).offset, unistUtilPosition.end(node).offset) - .split('\n', 1)[0] - .replace(/\r$/, ''); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$v(test) { + return type - if (value.length > 2) { - file.message(reason$3, node); + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$w() { + return true +} + +var unistUtilVisitParents$v = visitParents$v; + + + +var CONTINUE$_ = true; +var SKIP$_ = 'skip'; +var EXIT$_ = false; + +visitParents$v.CONTINUE = CONTINUE$_; +visitParents$v.SKIP = SKIP$_; +visitParents$v.EXIT = EXIT$_; + +function visitParents$v(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$v(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$v(visitor(node, parents)); + + if (result[0] === EXIT$_) { + return result + } + } + + if (node.children && result[0] !== SKIP$_) { + subresult = toResult$v(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$_ ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$_) { + return result } + + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintNoDuplicateDefinitions = unifiedLintRule( - 'remark-lint:no-duplicate-definitions', - noDuplicateDefinitions -); +function toResult$v(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var reason$4 = 'Do not use definitions with the same identifier'; + if (typeof value === 'number') { + return [CONTINUE$_, value] + } -function noDuplicateDefinitions(tree, file) { - var map = {}; + return [value] +} - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], validate); +var unistUtilVisit$v = visit$v; - function validate(node) { - var identifier; - var duplicate; - if (!unistUtilGenerated(node)) { - identifier = node.identifier; - duplicate = map[identifier]; - if (duplicate && duplicate.type) { - file.message( - reason$4 + ' (' + unistUtilStringifyPosition(unistUtilPosition.start(duplicate)) + ')', - node - ); +var CONTINUE$$ = unistUtilVisitParents$v.CONTINUE; +var SKIP$$ = unistUtilVisitParents$v.SKIP; +var EXIT$$ = unistUtilVisitParents$v.EXIT; + +visit$v.CONTINUE = CONTINUE$$; +visit$v.SKIP = SKIP$$; +visit$v.EXIT = EXIT$$; + +function visit$v(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$v(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var remarkLintNoShellDollars = unifiedLintRule('remark-lint:no-shell-dollars', noShellDollars); + +var reason$d = 'Do not use dollar signs before shell commands'; + +// List of shell script file extensions (also used as code flags for syntax +// highlighting on GitHub): +// See: +var flags = [ + 'sh', + 'bash', + 'bats', + 'cgi', + 'command', + 'fcgi', + 'ksh', + 'tmux', + 'tool', + 'zsh' +]; + +function noShellDollars(tree, file) { + unistUtilVisit$v(tree, 'code', visitor); + + function visitor(node) { + var lines; + var line; + var length; + var index; + + // Check both known shell code and unknown code. + if (!unistUtilGenerated(node) && node.lang && flags.indexOf(node.lang) !== -1) { + lines = node.value.split('\n'); + length = lines.length; + index = -1; + + if (length <= 1) { + return } - map[identifier] = node; + while (++index < length) { + line = lines[index]; + + if (line.trim() && !line.match(/^\s*\$\s*/)) { + return + } + } + + file.message(reason$d, node); } } } -var mdastUtilHeadingStyle = style; +var convert_1$w = convert$x; -function style(node, relative) { - var last = node.children[node.children.length - 1]; - var depth = node.depth; - var pos = node && node.position && node.position.end; - var final = last && last.position && last.position.end; +function convert$x(test) { + if (typeof test === 'string') { + return typeFactory$w(test) + } - if (!pos) { - return null + if (test === null || test === undefined) { + return ok$x } - // This can only occur for `'atx'` and `'atx-closed'` headings. - // This might incorrectly match `'atx'` headings with lots of trailing white - // space as an `'atx-closed'` heading. - if (!last) { - if (pos.column - 1 <= depth * 2) { - return consolidate(depth, relative) + if (typeof test === 'object') { + return ('length' in test ? anyFactory$w : matchesFactory$w)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$w(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$x(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$w(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } } - return 'atx-closed' + return true } +} - if (final.line + 1 === pos.line) { - return 'setext' +function anyFactory$w(tests) { + var checks = convertAll$w(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false } +} - if (final.column + depth < pos.column) { - return 'atx-closed' +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$w(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) } +} - return consolidate(depth, relative) +// Utility to return true. +function ok$x() { + return true } -// Get the probable style of an atx-heading, depending on preferred style. -function consolidate(depth, relative) { - return depth < 3 - ? 'atx' - : relative === 'atx' || relative === 'setext' - ? relative - : null +var unistUtilVisitParents$w = visitParents$w; + + + +var CONTINUE$10 = true; +var SKIP$10 = 'skip'; +var EXIT$10 = false; + +visitParents$w.CONTINUE = CONTINUE$10; +visitParents$w.SKIP = SKIP$10; +visitParents$w.EXIT = EXIT$10; + +function visitParents$w(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$w(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$w(visitor(node, parents)); + + if (result[0] === EXIT$10) { + return result + } + } + + if (node.children && result[0] !== SKIP$10) { + subresult = toResult$w(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$10 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$10) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } } -var remarkLintNoHeadingContentIndent = unifiedLintRule( - 'remark-lint:no-heading-content-indent', - noHeadingContentIndent -); +function toResult$w(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$7 = unistUtilPosition.start; -var end$3 = unistUtilPosition.end; + if (typeof value === 'number') { + return [CONTINUE$10, value] + } -function noHeadingContentIndent(tree, file) { - var contents = String(file); + return [value] +} - unistUtilVisit(tree, 'heading', visitor); +var unistUtilVisit$w = visit$w; - function visitor(node) { - var depth; - var children; - var type; - var head; - var initial; - var final; - var diff; - var index; - var char; - var reason; - if (unistUtilGenerated(node)) { - return - } - depth = node.depth; - children = node.children; - type = mdastUtilHeadingStyle(node, 'atx'); +var CONTINUE$11 = unistUtilVisitParents$w.CONTINUE; +var SKIP$11 = unistUtilVisitParents$w.SKIP; +var EXIT$11 = unistUtilVisitParents$w.EXIT; - if (type === 'atx' || type === 'atx-closed') { - initial = start$7(node); - index = initial.offset; - char = contents.charAt(index); +visit$w.CONTINUE = CONTINUE$11; +visit$w.SKIP = SKIP$11; +visit$w.EXIT = EXIT$11; - while (char && char !== '#') { - char = contents.charAt(++index); - } +function visit$w(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - /* istanbul ignore if - CR/LF bug: remarkjs/remark#195. */ - if (!char) { - return - } + unistUtilVisitParents$w(tree, test, overload, reverse); - index = depth + (index - initial.offset); - head = start$7(children[0]).column; + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} - // Ignore empty headings. - if (!head) { - return - } +var remarkLintNoTableIndentation = unifiedLintRule('remark-lint:no-table-indentation', noTableIndentation); - diff = head - initial.column - 1 - index; +var reason$e = 'Do not indent table rows'; - if (diff) { - reason = - (diff > 0 ? 'Remove' : 'Add') + - ' ' + - Math.abs(diff) + - ' ' + - plur('space', diff) + - ' before this heading’s content'; +function noTableIndentation(tree, file) { + var contents = String(file); - file.message(reason, start$7(children[0])); - } + unistUtilVisit$w(tree, 'table', visitor); + + function visitor(node) { + if (!unistUtilGenerated(node)) { + node.children.forEach(each); } - // Closed ATX-heading always must have a space between their content and the - // final hashes, thus, there is no `add x spaces`. - if (type === 'atx-closed') { - final = end$3(children[children.length - 1]); - diff = end$3(node).column - final.column - 1 - depth; + return unistUtilVisit$w.SKIP + } - if (diff) { - reason = - 'Remove ' + - diff + - ' ' + - plur('space', diff) + - ' after this heading’s content'; + function each(row) { + var fence = contents.slice( + unistUtilPosition.start(row).offset, + unistUtilPosition.start(row.children[0]).offset + ); - file.message(reason, final); - } + if (fence.indexOf('|') > 1) { + file.message(reason$e, row); } } } -var remarkLintNoInlinePadding = unifiedLintRule('remark-lint:no-inline-padding', noInlinePadding); - -function noInlinePadding(tree, file) { - unistUtilVisit(tree, ['emphasis', 'strong', 'delete', 'image', 'link'], visitor); - - function visitor(node) { - var contents; +var vfileLocation$6 = factory$e; - if (!unistUtilGenerated(node)) { - contents = mdastUtilToString(node); +function factory$e(file) { + var contents = indices$6(String(file)); - if ( - contents.charAt(0) === ' ' || - contents.charAt(contents.length - 1) === ' ' - ) { - file.message('Don’t pad `' + node.type + '` with inner spaces', node); - } - } + return { + toPosition: offsetToPositionFactory$6(contents), + toOffset: positionToOffsetFactory$6(contents) } } -var remarkLintNoShortcutReferenceImage = unifiedLintRule( - 'remark-lint:no-shortcut-reference-image', - noShortcutReferenceImage -); +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$6(indices) { + return offsetToPosition -var reason$5 = 'Use the trailing [] on reference images'; + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; -function noShortcutReferenceImage(tree, file) { - unistUtilVisit(tree, 'imageReference', visitor); + if (offset < 0) { + return {} + } - function visitor(node) { - if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { - file.message(reason$5, node); + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } } + + return {} } } -var remarkLintNoShortcutReferenceLink = unifiedLintRule( - 'remark-lint:no-shortcut-reference-link', - noShortcutReferenceLink -); - -var reason$6 = 'Use the trailing [] on reference links'; +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$6(indices) { + return positionToOffset -function noShortcutReferenceLink(tree, file) { - unistUtilVisit(tree, 'linkReference', visitor); + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; - function visitor(node) { - if (!unistUtilGenerated(node) && node.referenceType === 'shortcut') { - file.message(reason$6, node); + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 } + + return -1 } } -var remarkLintNoUndefinedReferences = unifiedLintRule( - 'remark-lint:no-undefined-references', - noUndefinedReferences -); +// Get indices of line-breaks in `value`. +function indices$6(value) { + var result = []; + var index = value.indexOf('\n'); -var reason$7 = 'Found reference to undefined definition'; + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } -// The identifier is upcased to avoid naming collisions with properties -// inherited from `Object.prototype`. Were `Object.create(null)` to be -// used in place of `{}`, downcasing would work equally well. -function normalize$3(s) { - return collapseWhiteSpace(s.toUpperCase()) + result.push(value.length + 1); + + return result } -function noUndefinedReferences(tree, file, pref) { - var allow = - pref != null && Array.isArray(pref.allow) ? pref.allow.map(normalize$3) : []; +var remarkLintNoTabs = unifiedLintRule('remark-lint:no-tabs', noTabs); - var map = {}; +var reason$f = 'Use spaces instead of tabs'; - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], mark); - unistUtilVisit(tree, ['imageReference', 'linkReference', 'footnoteReference'], find); +function noTabs(tree, file) { + var content = String(file); + var position = vfileLocation$6(file).toPosition; + var index = content.indexOf('\t'); - function mark(node) { - if (!unistUtilGenerated(node)) { - map[normalize$3(node.identifier)] = true; - } + while (index !== -1) { + file.message(reason$f, position(index)); + index = content.indexOf('\t', index + 1); } +} - function find(node) { - if ( - !( - unistUtilGenerated(node) || - allow.includes(normalize$3(node.identifier)) || - normalize$3(node.identifier) in map - ) - ) { - file.message(reason$7, node); +var remarkLintNoTrailingSpaces = unifiedLintRule('remark-lint:no-trailing-spaces', noTrailingSpaces); + +/** + * Lines that are just space characters are not present in + * the AST, which is why we loop through lines manually. + */ + +function noTrailingSpaces(ast, file) { + var lines = file.toString().split(/\r?\n/); + for (var i = 0; i < lines.length; i++) { + var currentLine = lines[i]; + var lineIndex = i + 1; + if (/\s$/.test(currentLine)) { + file.message('Remove trailing whitespace', { + position: { + start: { line: lineIndex, column: currentLine.length + 1 }, + end: { line: lineIndex } + } + }); } } } -var remarkLintNoUnusedDefinitions = unifiedLintRule('remark-lint:no-unused-definitions', noUnusedDefinitions); - -var reason$8 = 'Found unused definition'; - -function noUnusedDefinitions(tree, file) { - var map = {}; - var identifier; - var entry; +var escapeStringRegexp$1 = string => { + if (typeof string !== 'string') { + throw new TypeError('Expected a string'); + } - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], find); - unistUtilVisit(tree, ['imageReference', 'linkReference', 'footnoteReference'], mark); + // Escape characters with special meaning either inside or outside character sets. + // Use a simple backslash escape when it’s always valid, and a \unnnn escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. + return string + .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') + .replace(/-/g, '\\x2d'); +}; - for (identifier in map) { - entry = map[identifier]; +var convert_1$x = convert$y; - if (!entry.used) { - file.message(reason$8, entry.node); - } +function convert$y(test) { + if (typeof test === 'string') { + return typeFactory$x(test) } - function find(node) { - if (!unistUtilGenerated(node)) { - map[node.identifier.toUpperCase()] = {node: node, used: false}; - } + if (test === null || test === undefined) { + return ok$y } - function mark(node) { - var info = map[node.identifier.toUpperCase()]; + if (typeof test === 'object') { + return ('length' in test ? anyFactory$x : matchesFactory$x)(test) + } - if (!unistUtilGenerated(node) && info) { - info.used = true; - } + if (typeof test === 'function') { + return test } -} -var plugins$1 = [ - remarkLint, - // Unix compatibility. - remarkLintFinalNewline, - // Rendering across vendors differs greatly if using other styles. - remarkLintListItemBulletIndent, - [remarkLintListItemIndent, 'tab-size'], - // Differs or unsupported across vendors. - remarkLintNoAutoLinkWithoutProtocol, - remarkLintNoBlockquoteWithoutMarker, - remarkLintNoLiteralUrls, - [remarkLintOrderedListMarkerStyle, '.'], - // Mistakes. - remarkLintHardBreakSpaces, - remarkLintNoDuplicateDefinitions, - remarkLintNoHeadingContentIndent, - remarkLintNoInlinePadding, - remarkLintNoShortcutReferenceImage, - remarkLintNoShortcutReferenceLink, - remarkLintNoUndefinedReferences, - remarkLintNoUnusedDefinitions -]; + throw new Error('Expected function, string, or object as test') +} -var remarkPresetLintRecommended = { - plugins: plugins$1 -}; +function convertAll$x(tests) { + var results = []; + var length = tests.length; + var index = -1; -var remarkLintBlockquoteIndentation = unifiedLintRule( - 'remark-lint:blockquote-indentation', - blockquoteIndentation -); + while (++index < length) { + results[index] = convert$y(tests[index]); + } -function blockquoteIndentation(tree, file, pref) { - pref = typeof pref === 'number' && !isNaN(pref) ? pref : null; + return results +} - unistUtilVisit(tree, 'blockquote', visitor); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$x(test) { + return matches - function visitor(node) { - var diff; - var reason; + function matches(node) { + var key; - if (unistUtilGenerated(node) || node.children.length === 0) { - return + for (key in test) { + if (node[key] !== test[key]) { + return false + } } - if (pref) { - diff = pref - check$3(node); + return true + } +} - if (diff !== 0) { - reason = - (diff > 0 ? 'Add' : 'Remove') + - ' ' + - Math.abs(diff) + - ' ' + - plur('space', diff) + - ' between blockquote and content'; +function anyFactory$x(tests) { + var checks = convertAll$x(tests); + var length = checks.length; - file.message(reason, unistUtilPosition.start(node.children[0])); + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true } - } else { - pref = check$3(node); } + + return false } } -function check$3(node) { - var head = node.children[0]; - var indentation = unistUtilPosition.start(head).column - unistUtilPosition.start(node).column; - var padding = mdastUtilToString(head).match(/^ +/); +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$x(test) { + return type - if (padding) { - indentation += padding[0].length; + function type(node) { + return Boolean(node && node.type === test) } +} - return indentation +// Utility to return true. +function ok$y() { + return true } -var remarkLintCheckboxCharacterStyle = unifiedLintRule( - 'remark-lint:checkbox-character-style', - checkboxCharacterStyle -); +var unistUtilVisitParents$x = visitParents$x; -var start$8 = unistUtilPosition.start; -var end$4 = unistUtilPosition.end; -var checked = {x: true, X: true}; -var unchecked = {' ': true, '\t': true}; -var types$1 = {true: 'checked', false: 'unchecked'}; -function checkboxCharacterStyle(tree, file, pref) { - var contents = String(file); - var location = vfileLocation(file); +var CONTINUE$12 = true; +var SKIP$12 = 'skip'; +var EXIT$12 = false; - pref = typeof pref === 'object' ? pref : {}; +visitParents$x.CONTINUE = CONTINUE$12; +visitParents$x.SKIP = SKIP$12; +visitParents$x.EXIT = EXIT$12; - if (pref.unchecked && unchecked[pref.unchecked] !== true) { - file.fail( - 'Invalid unchecked checkbox marker `' + - pref.unchecked + - "`: use either `'\\t'`, or `' '`" - ); - } +function visitParents$x(tree, test, visitor, reverse) { + var is; - if (pref.checked && checked[pref.checked] !== true) { - file.fail( - 'Invalid checked checkbox marker `' + - pref.checked + - "`: use either `'x'`, or `'X'`" - ); + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } - unistUtilVisit(tree, 'listItem', visitor); + is = convert_1$x(test); - function visitor(node) { - var type; - var initial; - var final; - var value; - var style; - var character; - var reason; + one(tree, null, []); - // Exit early for items without checkbox. - if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { - return + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$x(visitor(node, parents)); + + if (result[0] === EXIT$12) { + return result + } } - type = types$1[node.checked]; - initial = start$8(node).offset; - final = (node.children.length === 0 ? end$4(node) : start$8(node.children[0])) - .offset; + if (node.children && result[0] !== SKIP$12) { + subresult = toResult$x(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$12 ? subresult : result + } - // For a checkbox to be parsed, it must be followed by a whitespace. - value = contents - .slice(initial, final) - .trimRight() - .slice(0, -1); + return result + } - // The checkbox character is behind a square bracket. - character = value.charAt(value.length - 1); - style = pref[type]; + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; - if (style) { - if (character !== style) { - reason = - type.charAt(0).toUpperCase() + - type.slice(1) + - ' checkboxes should use `' + - style + - '` as a marker'; + while (index > min && index < children.length) { + result = one(children[index], index, parents); - file.message(reason, { - start: location.toPosition(initial + value.length - 1), - end: location.toPosition(initial + value.length) - }); + if (result[0] === EXIT$12) { + return result } - } else { - pref[type] = character; + + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintCheckboxContentIndent = unifiedLintRule( - 'remark-lint:checkbox-content-indent', - checkboxContentIndent -); +function toResult$x(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var start$9 = unistUtilPosition.start; -var end$5 = unistUtilPosition.end; + if (typeof value === 'number') { + return [CONTINUE$12, value] + } -var reason$9 = 'Checkboxes should be followed by a single character'; + return [value] +} -function checkboxContentIndent(tree, file) { - var contents = String(file); - var location = vfileLocation(file); +var unistUtilVisit$x = visit$x; - unistUtilVisit(tree, 'listItem', visitor); - function visitor(node) { - var initial; - var final; - var value; - // Exit early for items without checkbox. - if (typeof node.checked !== 'boolean' || unistUtilGenerated(node)) { - return - } +var CONTINUE$13 = unistUtilVisitParents$x.CONTINUE; +var SKIP$13 = unistUtilVisitParents$x.SKIP; +var EXIT$13 = unistUtilVisitParents$x.EXIT; - initial = start$9(node).offset; - /* istanbul ignore next - hard to test, couldn’t find a case. */ - final = (node.children.length === 0 ? end$5(node) : start$9(node.children[0])) - .offset; +visit$x.CONTINUE = CONTINUE$13; +visit$x.SKIP = SKIP$13; +visit$x.EXIT = EXIT$13; - while (/[^\S\n]/.test(contents.charAt(final))) { - final++; - } +function visit$x(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } - // For a checkbox to be parsed, it must be followed by a whitespace. - value = contents.slice(initial, final); - value = value.slice(value.indexOf(']') + 1); + unistUtilVisitParents$x(tree, test, overload, reverse); - if (value.length !== 1) { - file.message(reason$9, { - start: location.toPosition(final - value.length + 1), - end: location.toPosition(final) - }); - } + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } } -var remarkLintCodeBlockStyle = unifiedLintRule('remark-lint:code-block-style', codeBlockStyle); - -var start$a = unistUtilPosition.start; -var end$6 = unistUtilPosition.end; - -var styles$2 = {null: true, fenced: true, indented: true}; - -function codeBlockStyle(tree, file, pref) { - var contents = String(file); +var vfileLocation$7 = factory$f; - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; +function factory$f(file) { + var contents = indices$7(String(file)); - if (styles$2[pref] !== true) { - file.fail( - 'Invalid code block style `' + - pref + - "`: use either `'consistent'`, `'fenced'`, or `'indented'`" - ); + return { + toPosition: offsetToPositionFactory$7(contents), + toOffset: positionToOffsetFactory$7(contents) } +} - unistUtilVisit(tree, 'code', visitor); +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory$7(indices) { + return offsetToPosition - function visitor(node) { - var current = check(node); + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; - if (current) { - if (!pref) { - pref = current; - } else if (pref !== current) { - file.message('Code blocks should be ' + pref, node); + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } } } + + return {} } +} - // Get the style of `node`. - function check(node) { - var initial = start$a(node).offset; - var final = end$6(node).offset; +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory$7(indices) { + return positionToOffset - if (unistUtilGenerated(node)) { - return null + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 } - return node.lang || /^\s*([~`])\1{2,}/.test(contents.slice(initial, final)) - ? 'fenced' - : 'indented' + return -1 } } -var remarkLintDefinitionSpacing = unifiedLintRule('remark-lint:definition-spacing', definitionSpacing); +// Get indices of line-breaks in `value`. +function indices$7(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); -var label$1 = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; -var reason$a = 'Do not use consecutive white-space in definition labels'; + return result +} -function definitionSpacing(tree, file) { - var contents = String(file); +const start$g = unistUtilPosition.start; - unistUtilVisit(tree, ['definition', 'footnoteDefinition'], validate); +var remarkLintProhibitedStrings = unifiedLintRule('remark-lint:prohibited-strings', prohibitedStrings); - function validate(node) { - var start = unistUtilPosition.start(node).offset; - var end = unistUtilPosition.end(node).offset; +function testProhibited (val, content) { + let regexpFlags = 'g'; - if ( - !unistUtilGenerated(node) && - /[ \t\n]{2,}/.test(contents.slice(start, end).match(label$1)[1]) - ) { - file.message(reason$a, node); - } + if (!val.no) { + val.no = escapeStringRegexp$1(val.yes); + regexpFlags += 'i'; } -} -var remarkLintFencedCodeFlag = unifiedLintRule('remark-lint:fenced-code-flag', fencedCodeFlag); + let regexpString = '(? { + const results = testProhibited(val, content); + if (results.length) { + results.forEach(({ result, index }) => { + const message = val.yes ? `Use "${val.yes}" instead of "${result}"` : `Do not use "${result}"`; + file.message(message, { + start: location.toPosition(initial + index), + end: location.toPosition(initial + index + [...result].length) + }); + }); } - } + }); } } -var remarkLintFencedCodeMarker = unifiedLintRule('remark-lint:fenced-code-marker', fencedCodeMarker); - -var markers = { - '`': true, - '~': true, - null: true -}; +var convert_1$y = convert$z; -function fencedCodeMarker(tree, file, pref) { - var contents = String(file); +function convert$z(test) { + if (typeof test === 'string') { + return typeFactory$y(test) + } - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; + if (test === null || test === undefined) { + return ok$z + } - if (markers[pref] !== true) { - file.fail( - 'Invalid fenced code marker `' + - pref + - "`: use either `'consistent'`, `` '`' ``, or `'~'`" - ); + if (typeof test === 'object') { + return ('length' in test ? anyFactory$y : matchesFactory$y)(test) } - unistUtilVisit(tree, 'code', visitor); + if (typeof test === 'function') { + return test + } - function visitor(node) { - var marker; + throw new Error('Expected function, string, or object as test') +} - if (!unistUtilGenerated(node)) { - marker = contents - .substr(unistUtilPosition.start(node).offset, 4) - .trimLeft() - .charAt(0); +function convertAll$y(tests) { + var results = []; + var length = tests.length; + var index = -1; - // Ignore unfenced code blocks. - if (markers[marker] === true) { - if (pref) { - if (marker !== pref) { - file.message( - 'Fenced code should use ' + pref + ' as a marker', - node - ); - } - } else { - pref = marker; - } - } - } + while (++index < length) { + results[index] = convert$z(tests[index]); } + + return results } -var remarkLintFileExtension = unifiedLintRule('remark-lint:file-extension', fileExtension); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$y(test) { + return matches -function fileExtension(tree, file, pref) { - var ext = file.extname; + function matches(node) { + var key; - pref = typeof pref === 'string' ? pref : 'md'; + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } - if (ext && ext.slice(1) !== pref) { - file.message('Invalid extension: use `' + pref + '`'); + return true } } -var remarkLintFinalDefinition = unifiedLintRule('remark-lint:final-definition', finalDefinition); +function anyFactory$y(tests) { + var checks = convertAll$y(tests); + var length = checks.length; -var start$c = unistUtilPosition.start; + return matches -function finalDefinition(tree, file) { - var last = null; + function matches() { + var index = -1; - unistUtilVisit(tree, visitor, true); + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } - function visitor(node) { - var line = start$c(node).line; + return false + } +} - // Ignore generated nodes. - if (node.type === 'root' || unistUtilGenerated(node)) { - return - } +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$y(test) { + return type - if (node.type === 'definition') { - if (last !== null && last > line) { - file.message( - 'Move definitions to the end of the file (after the node at line `' + - last + - '`)', - node - ); - } - } else if (last === null) { - last = line; - } + function type(node) { + return Boolean(node && node.type === test) } } -var remarkLintFirstHeadingLevel = unifiedLintRule('remark-lint:first-heading-level', firstHeadingLevel); +// Utility to return true. +function ok$z() { + return true +} -var re$3 = /. - unistUtilVisit(tree, ['heading', 'table', 'code', 'definition', 'html', 'jsx'], ignore); - unistUtilVisit(tree, ['link', 'image', 'inlineCode'], inline); + while (index > min && index < children.length) { + result = one(children[index], index, parents); - // Iterate over every line, and warn for violating lines. - while (++index < length) { - lineLength = lines[index].length; + if (result[0] === EXIT$14) { + return result + } - if (lineLength > style) { - file.message('Line must be at most ' + style + ' characters', { - line: index + 1, - column: lineLength + 1 - }); + index = typeof result[1] === 'number' ? result[1] : index + step; } } +} - // Finally, whitelist some inline spans, but only if they occur at or after - // the wrap. - // However, when they do, and there’s whitespace after it, they are not - // whitelisted. - function inline(node, pos, parent) { - var next = parent.children[pos + 1]; - var initial; - var final; +function toResult$y(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } - /* istanbul ignore if - Nothing to whitelist when generated. */ - if (unistUtilGenerated(node)) { - return - } + if (typeof value === 'number') { + return [CONTINUE$14, value] + } - initial = start$d(node); - final = end$8(node); + return [value] +} - // No whitelisting when starting after the border, or ending before it. - if (initial.column > style || final.column < style) { - return - } +var unistUtilVisit$y = visit$y; - // No whitelisting when there’s whitespace after the link. - if ( - next && - start$d(next).line === initial.line && - (!next.value || /^(.+?[ \t].+?)/.test(next.value)) - ) { - return - } - whitelist(initial.line - 1, final.line); - } - function ignore(node) { - /* istanbul ignore else - Hard to test, as we only run this case on `position: true` */ - if (!unistUtilGenerated(node)) { - whitelist(start$d(node).line - 1, end$8(node).line); - } +var CONTINUE$15 = unistUtilVisitParents$y.CONTINUE; +var SKIP$15 = unistUtilVisitParents$y.SKIP; +var EXIT$15 = unistUtilVisitParents$y.EXIT; + +visit$y.CONTINUE = CONTINUE$15; +visit$y.SKIP = SKIP$15; +visit$y.EXIT = EXIT$15; + +function visit$y(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } - // Whitelist from `initial` to `final`, zero-based. - function whitelist(initial, final) { - while (initial < final) { - lines[initial++] = ''; - } + unistUtilVisitParents$y(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } } -var remarkLintNoConsecutiveBlankLines = unifiedLintRule( - 'remark-lint:no-consecutive-blank-lines', - noConsecutiveBlankLines -); +var rule = unifiedLintRule; -function noConsecutiveBlankLines(tree, file) { - unistUtilVisit(tree, visitor); - function visitor(node) { - var children = node.children; - var head; - var tail; - if (!unistUtilGenerated(node) && children) { - head = children[0]; - if (head && !unistUtilGenerated(head)) { - // Compare parent and first child. - compare(unistUtilPosition.start(node), unistUtilPosition.start(head), 0); +var remarkLintRuleStyle = rule('remark-lint:rule-style', ruleStyle); - // Compare between each child. - children.forEach(visitChild); +var start$h = unistUtilPosition.start; +var end$9 = unistUtilPosition.end; - tail = children[children.length - 1]; +function ruleStyle(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - // Compare parent and last child. - if (tail !== head && !unistUtilGenerated(tail)) { - compare(unistUtilPosition.end(node), unistUtilPosition.end(tail), 1); - } - } - } + if (preferred !== null && /[^-_* ]/.test(preferred)) { + file.fail( + "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" + ); } - // Compare the difference between `start` and `end`, and warn when that - // difference exceeds `max`. - function compare(start, end, max) { - var diff = end.line - start.line; - var lines = Math.abs(diff) - max; - var reason; - - if (lines > 0) { - reason = - 'Remove ' + - lines + - ' ' + - plur('line', lines) + - ' ' + - (diff > 0 ? 'before' : 'after') + - ' node'; + unistUtilVisit$y(tree, 'thematicBreak', visitor); - file.message(reason, end); - } - } + function visitor(node) { + var initial = start$h(node).offset; + var final = end$9(node).offset; + var rule; - function visitChild(child, index, all) { - var prev = all[index - 1]; - var max = 2; + if (!unistUtilGenerated(node)) { + rule = contents.slice(initial, final); - if (prev && !unistUtilGenerated(prev) && !unistUtilGenerated(child)) { - if ( - (prev.type === 'list' && child.type === 'list') || - (child.type === 'code' && prev.type === 'list' && !child.lang) - ) { - max++; + if (preferred) { + if (rule !== preferred) { + file.message('Rules should use `' + preferred + '`', node); + } + } else { + preferred = rule; } - - compare(unistUtilPosition.end(prev), unistUtilPosition.start(child), max); } } } -var remarkLintNoFileNameArticles = unifiedLintRule('remark-lint:no-file-name-articles', noFileNameArticles); - -function noFileNameArticles(tree, file) { - var match = file.stem && file.stem.match(/^(the|teh|an?)\b/i); +var convert_1$z = convert$A; - if (match) { - file.message('Do not start file names with `' + match[0] + '`'); +function convert$A(test) { + if (typeof test === 'string') { + return typeFactory$z(test) } -} -var remarkLintNoFileNameConsecutiveDashes = unifiedLintRule( - 'remark-lint:no-file-name-consecutive-dashes', - noFileNameConsecutiveDashes -); + if (test === null || test === undefined) { + return ok$A + } -var reason$b = 'Do not use consecutive dashes in a file name'; + if (typeof test === 'object') { + return ('length' in test ? anyFactory$z : matchesFactory$z)(test) + } -function noFileNameConsecutiveDashes(tree, file) { - if (file.stem && /-{2,}/.test(file.stem)) { - file.message(reason$b); + if (typeof test === 'function') { + return test } -} -var remarkLintNoFileNameOuterDashes = unifiedLintRule( - 'remark-lint:no-file-name-outer-dashes', - noFileNameOuterDashes -); + throw new Error('Expected function, string, or object as test') +} -var reason$c = 'Do not use initial or final dashes in a file name'; +function convertAll$z(tests) { + var results = []; + var length = tests.length; + var index = -1; -function noFileNameOuterDashes(tree, file) { - if (file.stem && /^-|-$/.test(file.stem)) { - file.message(reason$c); + while (++index < length) { + results[index] = convert$A(tests[index]); } + + return results } -var remarkLintNoHeadingIndent = unifiedLintRule('remark-lint:no-heading-indent', noHeadingIndent); +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$z(test) { + return matches -var start$e = unistUtilPosition.start; + function matches(node) { + var key; -function noHeadingIndent(tree, file) { - var contents = String(file); - var length = contents.length; + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } - unistUtilVisit(tree, 'heading', visitor); + return true + } +} - function visitor(node) { - var initial; - var begin; - var index; - var character; - var diff; +function anyFactory$z(tests) { + var checks = convertAll$z(tests); + var length = checks.length; - if (unistUtilGenerated(node)) { - return - } + return matches - initial = start$e(node); - begin = initial.offset; - index = begin - 1; + function matches() { + var index = -1; while (++index < length) { - character = contents.charAt(index); - - if (character !== ' ' && character !== '\t') { - break + if (checks[index].apply(this, arguments)) { + return true } } - diff = index - begin; + return false + } +} - if (diff) { - file.message( - 'Remove ' + diff + ' ' + plur('space', diff) + ' before this heading', - { - line: initial.line, - column: initial.column + diff - } - ); - } +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$z(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) } } -var start$f = unistUtilPosition.start; +// Utility to return true. +function ok$A() { + return true +} +var unistUtilVisitParents$z = visitParents$z; -var remarkLintNoMultipleToplevelHeadings = unifiedLintRule( - 'remark-lint:no-multiple-toplevel-headings', - noMultipleToplevelHeadings -); -function noMultipleToplevelHeadings(tree, file, pref) { - var style = pref ? pref : 1; - var duplicate; +var CONTINUE$16 = true; +var SKIP$16 = 'skip'; +var EXIT$16 = false; - unistUtilVisit(tree, 'heading', visitor); +visitParents$z.CONTINUE = CONTINUE$16; +visitParents$z.SKIP = SKIP$16; +visitParents$z.EXIT = EXIT$16; - function visitor(node) { - if (!unistUtilGenerated(node) && node.depth === style) { - if (duplicate) { - file.message( - 'Don’t use multiple top level headings (' + duplicate + ')', - node - ); - } else { - duplicate = unistUtilStringifyPosition(start$f(node)); - } - } +function visitParents$z(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } -} -var remarkLintNoShellDollars = unifiedLintRule('remark-lint:no-shell-dollars', noShellDollars); + is = convert_1$z(test); -var reason$d = 'Do not use dollar signs before shell-commands'; + one(tree, null, []); -// List of shell script file extensions (also used as code flags for syntax -// highlighting on GitHub): -// See: -var flags = [ - 'sh', - 'bash', - 'bats', - 'cgi', - 'command', - 'fcgi', - 'ksh', - 'tmux', - 'tool', - 'zsh' -]; + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; -function noShellDollars(tree, file) { - unistUtilVisit(tree, 'code', visitor); + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$z(visitor(node, parents)); - function visitor(node) { - var lines; - var line; - var length; - var index; + if (result[0] === EXIT$16) { + return result + } + } - // Check both known shell code and unknown code. - if (!unistUtilGenerated(node) && node.lang && flags.indexOf(node.lang) !== -1) { - lines = node.value.split('\n'); - length = lines.length; - index = -1; + if (node.children && result[0] !== SKIP$16) { + subresult = toResult$z(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$16 ? subresult : result + } - if (length <= 1) { - return - } + return result + } - while (++index < length) { - line = lines[index]; + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; - if (line.trim() && !line.match(/^\s*\$\s*/)) { - return - } + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$16) { + return result } - file.message(reason$d, node); + index = typeof result[1] === 'number' ? result[1] : index + step; } } } -var remarkLintNoTableIndentation = unifiedLintRule('remark-lint:no-table-indentation', noTableIndentation); +function toResult$z(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } -var reason$e = 'Do not indent table rows'; + if (typeof value === 'number') { + return [CONTINUE$16, value] + } -function noTableIndentation(tree, file) { - var contents = String(file); + return [value] +} - unistUtilVisit(tree, 'table', visitor); +var unistUtilVisit$z = visit$z; - function visitor(node) { - if (!unistUtilGenerated(node)) { - node.children.forEach(each); - } - return unistUtilVisit.SKIP + +var CONTINUE$17 = unistUtilVisitParents$z.CONTINUE; +var SKIP$17 = unistUtilVisitParents$z.SKIP; +var EXIT$17 = unistUtilVisitParents$z.EXIT; + +visit$z.CONTINUE = CONTINUE$17; +visit$z.SKIP = SKIP$17; +visit$z.EXIT = EXIT$17; + +function visit$z(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; } - function each(row) { - var fence = contents.slice( - unistUtilPosition.start(row).offset, - unistUtilPosition.start(row.children[0]).offset - ); + unistUtilVisitParents$z(tree, test, overload, reverse); - if (fence.indexOf('|') > 1) { - file.message(reason$e, row); - } + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) } } -var remarkLintNoTabs = unifiedLintRule('remark-lint:no-tabs', noTabs); +var remarkLintStrongMarker = unifiedLintRule('remark-lint:strong-marker', strongMarker); -var reason$f = 'Use spaces instead of hard-tabs'; +var markers$1 = {'*': true, _: true, null: true}; -function noTabs(tree, file) { - var content = String(file); - var position = vfileLocation(file).toPosition; - var index = content.indexOf('\t'); +function strongMarker(tree, file, option) { + var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - while (index !== -1) { - file.message(reason$f, position(index)); - index = content.indexOf('\t', index + 1); + if (markers$1[preferred] !== true) { + file.fail( + 'Incorrect strong marker `' + + preferred + + "`: use either `'consistent'`, `'*'`, or `'_'`" + ); } -} -var remarkLintNoTrailingSpaces = unifiedLintRule('remark-lint:no-trailing-spaces', noTrailingSpaces); + unistUtilVisit$z(tree, 'strong', visitor); -/** - * Lines that are just space characters are not present in - * the AST, which is why we loop through lines manually. - */ + function visitor(node) { + var marker = contents.charAt(unistUtilPosition.start(node).offset); -function noTrailingSpaces(ast, file) { - var lines = file.toString().split(/\r?\n/); - for (var i = 0; i < lines.length; i++) { - var currentLine = lines[i]; - var lineIndex = i + 1; - if (/\s$/.test(currentLine)) { - file.message('Remove trailing whitespace', { - position: { - start: { line: lineIndex, column: currentLine.length + 1 }, - end: { line: lineIndex } + if (!unistUtilGenerated(node)) { + if (preferred) { + if (marker !== preferred) { + file.message( + 'Strong should use `' + preferred + '` as a marker', + node + ); } - }); + } else { + preferred = marker; + } } } } -var convert_1$1 = convert$2; +var convert_1$A = convert$B; -function convert$2(test) { +function convert$B(test) { if (typeof test === 'string') { - return typeFactory$1(test) + return typeFactory$A(test) } if (test === null || test === undefined) { - return ok$2 + return ok$B } if (typeof test === 'object') { - return ('length' in test ? anyFactory$1 : matchesFactory$1)(test) + return ('length' in test ? anyFactory$A : matchesFactory$A)(test) } if (typeof test === 'function') { @@ -43965,13 +51665,13 @@ function convert$2(test) { throw new Error('Expected function, string, or object as test') } -function convertAll$1(tests) { +function convertAll$A(tests) { var results = []; var length = tests.length; var index = -1; while (++index < length) { - results[index] = convert$2(tests[index]); + results[index] = convert$B(tests[index]); } return results @@ -43979,7 +51679,7 @@ function convertAll$1(tests) { // Utility assert each property in `test` is represented in `node`, and each // values are strictly equal. -function matchesFactory$1(test) { +function matchesFactory$A(test) { return matches function matches(node) { @@ -43995,8 +51695,8 @@ function matchesFactory$1(test) { } } -function anyFactory$1(tests) { - var checks = convertAll$1(tests); +function anyFactory$A(tests) { + var checks = convertAll$A(tests); var length = checks.length; return matches @@ -44016,7 +51716,7 @@ function anyFactory$1(tests) { // Utility to convert a string into a function which checks a given node’s type // for said string. -function typeFactory$1(test) { +function typeFactory$A(test) { return type function type(node) { @@ -44025,23 +51725,23 @@ function typeFactory$1(test) { } // Utility to return true. -function ok$2() { +function ok$B() { return true } -var unistUtilVisitParents$1 = visitParents$1; +var unistUtilVisitParents$A = visitParents$A; -var CONTINUE$2 = true; -var SKIP$2 = 'skip'; -var EXIT$2 = false; +var CONTINUE$18 = true; +var SKIP$18 = 'skip'; +var EXIT$18 = false; -visitParents$1.CONTINUE = CONTINUE$2; -visitParents$1.SKIP = SKIP$2; -visitParents$1.EXIT = EXIT$2; +visitParents$A.CONTINUE = CONTINUE$18; +visitParents$A.SKIP = SKIP$18; +visitParents$A.EXIT = EXIT$18; -function visitParents$1(tree, test, visitor, reverse) { +function visitParents$A(tree, test, visitor, reverse) { var is; if (typeof test === 'function' && typeof visitor !== 'function') { @@ -44050,7 +51750,7 @@ function visitParents$1(tree, test, visitor, reverse) { test = null; } - is = convert_1$1(test); + is = convert_1$A(test); one(tree, null, []); @@ -44060,16 +51760,16 @@ function visitParents$1(tree, test, visitor, reverse) { var subresult; if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult$1(visitor(node, parents)); + result = toResult$A(visitor(node, parents)); - if (result[0] === EXIT$2) { + if (result[0] === EXIT$18) { return result } } - if (node.children && result[0] !== SKIP$2) { - subresult = toResult$1(all(node.children, parents.concat(node))); - return subresult[0] === EXIT$2 ? subresult : result + if (node.children && result[0] !== SKIP$18) { + subresult = toResult$A(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$18 ? subresult : result } return result @@ -44085,7 +51785,7 @@ function visitParents$1(tree, test, visitor, reverse) { while (index > min && index < children.length) { result = one(children[index], index, parents); - if (result[0] === EXIT$2) { + if (result[0] === EXIT$18) { return result } @@ -44094,38 +51794,38 @@ function visitParents$1(tree, test, visitor, reverse) { } } -function toResult$1(value) { +function toResult$A(value) { if (value !== null && typeof value === 'object' && 'length' in value) { return value } if (typeof value === 'number') { - return [CONTINUE$2, value] + return [CONTINUE$18, value] } return [value] } -var unistUtilVisit$1 = visit$1; +var unistUtilVisit$A = visit$A; -var CONTINUE$3 = unistUtilVisitParents$1.CONTINUE; -var SKIP$3 = unistUtilVisitParents$1.SKIP; -var EXIT$3 = unistUtilVisitParents$1.EXIT; +var CONTINUE$19 = unistUtilVisitParents$A.CONTINUE; +var SKIP$19 = unistUtilVisitParents$A.SKIP; +var EXIT$19 = unistUtilVisitParents$A.EXIT; -visit$1.CONTINUE = CONTINUE$3; -visit$1.SKIP = SKIP$3; -visit$1.EXIT = EXIT$3; +visit$A.CONTINUE = CONTINUE$19; +visit$A.SKIP = SKIP$19; +visit$A.EXIT = EXIT$19; -function visit$1(tree, test, visitor, reverse) { +function visit$A(tree, test, visitor, reverse) { if (typeof test === 'function' && typeof visitor !== 'function') { reverse = visitor; visitor = test; test = null; } - unistUtilVisitParents$1(tree, test, overload, reverse); + unistUtilVisitParents$A(tree, test, overload, reverse); function overload(node, parents) { var parent = parents[parents.length - 1]; @@ -44134,142 +51834,27 @@ function visit$1(tree, test, visitor, reverse) { } } -var remarkLintProhibitedStrings = unifiedLintRule('remark-lint:prohibited-strings', prohibitedStrings); - -function testProhibited(val, content) { - let regexpString = '(\\.|@[a-z0-9/-]*)?'; - - // If it starts with a letter, make sure it is a word break. - if (/^\b/.test(val.no)) { - regexpString += '\\b'; - } - regexpString += `(${val.no})`; - - // If it ends with a letter, make sure it is a word break. - if (/\b$/.test(val.no)) { - regexpString += '\\b'; - } - regexpString += '(\\.\\w)?'; - const re = new RegExp(regexpString, 'g'); - - let result = null; - while (result = re.exec(content)) { - if (!result[1] && !result[3]) { - return result[2]; - } - } - - return false; -} - -function prohibitedStrings(ast, file, strings) { - unistUtilVisit$1(ast, 'text', checkText); - - function checkText(node) { - const content = node.value; - - strings.forEach((val) => { - const result = testProhibited(val, content); - if (result) { - file.message(`Use "${val.yes}" instead of "${result}"`, node); - } - }); - } -} - -var rule = unifiedLintRule; - - - - -var remarkLintRuleStyle = rule('remark-lint:rule-style', ruleStyle); - -var start$g = unistUtilPosition.start; -var end$9 = unistUtilPosition.end; - -function ruleStyle(tree, file, pref) { - var contents = String(file); - - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (pref !== null && /[^-_* ]/.test(pref)) { - file.fail( - "Invalid preferred rule-style: provide a valid markdown rule, or `'consistent'`" - ); - } - - unistUtilVisit(tree, 'thematicBreak', visitor); - - function visitor(node) { - var initial = start$g(node).offset; - var final = end$9(node).offset; - var rule; - - if (!unistUtilGenerated(node)) { - rule = contents.slice(initial, final); - - if (pref) { - if (rule !== pref) { - file.message('Rules should use `' + pref + '`', node); - } - } else { - pref = rule; - } - } - } -} - -var remarkLintStrongMarker = unifiedLintRule('remark-lint:strong-marker', strongMarker); - -var markers$1 = {'*': true, _: true, null: true}; - -function strongMarker(tree, file, pref) { - var contents = String(file); - - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (markers$1[pref] !== true) { - file.fail( - 'Invalid strong marker `' + - pref + - "`: use either `'consistent'`, `'*'`, or `'_'`" - ); - } - - unistUtilVisit(tree, 'strong', visitor); - - function visitor(node) { - var marker = contents.charAt(unistUtilPosition.start(node).offset); - - if (!unistUtilGenerated(node)) { - if (pref) { - if (marker !== pref) { - file.message('Strong should use `' + pref + '` as a marker', node); - } - } else { - pref = marker; - } - } - } -} - var remarkLintTableCellPadding = unifiedLintRule('remark-lint:table-cell-padding', tableCellPadding); -var start$h = unistUtilPosition.start; +var start$i = unistUtilPosition.start; var end$a = unistUtilPosition.end; var styles$3 = {null: true, padded: true, compact: true}; -function tableCellPadding(tree, file, pref) { +function tableCellPadding(tree, file, option) { var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (styles$3[pref] !== true) { - file.fail('Invalid table-cell-padding style `' + pref + '`'); + if (styles$3[preferred] !== true) { + file.fail( + 'Incorrect table cell padding style `' + + preferred + + "`, expected `'padded'`, `'compact'`, or `'consistent'`" + ); } - unistUtilVisit(tree, 'table', visitor); + unistUtilVisit$A(tree, 'table', visitor); function visitor(node) { var rows = node.children; @@ -44304,8 +51889,8 @@ function tableCellPadding(tree, file, pref) { next = cells[column + 1]; fence = contents.slice( - cell ? end$a(cell).offset : start$h(row).offset, - next ? start$h(next).offset : end$a(row).offset + cell ? end$a(cell).offset : start$i(row).offset, + next ? start$i(next).offset : end$a(row).offset ); pos = fence.indexOf('|'); @@ -44327,8 +51912,8 @@ function tableCellPadding(tree, file, pref) { } } - if (pref) { - style = pref === 'padded' ? 1 : 0; + if (preferred) { + style = preferred === 'padded' ? 1 : 0; } else { style = entries[0] && (!entries[0].start || !entries[0].end) ? 0 : 1; } @@ -44342,7 +51927,7 @@ function tableCellPadding(tree, file, pref) { checkSide('end', entry, style, sizes); } - return unistUtilVisit.SKIP + return unistUtilVisit$A.SKIP } function checkSide(side, entry, style, sizes) { @@ -44382,12 +51967,203 @@ function tableCellPadding(tree, file, pref) { } function size(node) { - return end$a(node).offset - start$h(node).offset + return end$a(node).offset - start$i(node).offset +} + +var convert_1$B = convert$C; + +function convert$C(test) { + if (typeof test === 'string') { + return typeFactory$B(test) + } + + if (test === null || test === undefined) { + return ok$C + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$B : matchesFactory$B)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$B(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$C(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$B(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$B(tests) { + var checks = convertAll$B(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$B(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$C() { + return true +} + +var unistUtilVisitParents$B = visitParents$B; + + + +var CONTINUE$1a = true; +var SKIP$1a = 'skip'; +var EXIT$1a = false; + +visitParents$B.CONTINUE = CONTINUE$1a; +visitParents$B.SKIP = SKIP$1a; +visitParents$B.EXIT = EXIT$1a; + +function visitParents$B(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$B(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$B(visitor(node, parents)); + + if (result[0] === EXIT$1a) { + return result + } + } + + if (node.children && result[0] !== SKIP$1a) { + subresult = toResult$B(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$1a ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$1a) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$B(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1a, value] + } + + return [value] +} + +var unistUtilVisit$B = visit$B; + + + +var CONTINUE$1b = unistUtilVisitParents$B.CONTINUE; +var SKIP$1b = unistUtilVisitParents$B.SKIP; +var EXIT$1b = unistUtilVisitParents$B.EXIT; + +visit$B.CONTINUE = CONTINUE$1b; +visit$B.SKIP = SKIP$1b; +visit$B.EXIT = EXIT$1b; + +function visit$B(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$B(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } } var remarkLintTablePipes = unifiedLintRule('remark-lint:table-pipes', tablePipes); -var start$i = unistUtilPosition.start; +var start$j = unistUtilPosition.start; var end$b = unistUtilPosition.end; var reasonStart = 'Missing initial pipe in table fence'; @@ -44396,7 +52172,7 @@ var reasonEnd = 'Missing final pipe in table fence'; function tablePipes(tree, file) { var contents = String(file); - unistUtilVisit(tree, 'table', visitor); + unistUtilVisit$B(tree, 'table', visitor); function visitor(node) { var rows = node.children; @@ -44416,11 +52192,11 @@ function tablePipes(tree, file) { cells = row.children; head = cells[0]; tail = cells[cells.length - 1]; - initial = contents.slice(start$i(row).offset, start$i(head).offset); + initial = contents.slice(start$j(row).offset, start$j(head).offset); final = contents.slice(end$b(tail).offset, end$b(row).offset); if (initial.indexOf('|') === -1) { - file.message(reasonStart, start$i(row)); + file.message(reasonStart, start$j(row)); } if (final.indexOf('|') === -1) { @@ -44431,12 +52207,203 @@ function tablePipes(tree, file) { } } +var convert_1$C = convert$D; + +function convert$D(test) { + if (typeof test === 'string') { + return typeFactory$C(test) + } + + if (test === null || test === undefined) { + return ok$D + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory$C : matchesFactory$C)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll$C(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert$D(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory$C(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory$C(tests) { + var checks = convertAll$C(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory$C(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok$D() { + return true +} + +var unistUtilVisitParents$C = visitParents$C; + + + +var CONTINUE$1c = true; +var SKIP$1c = 'skip'; +var EXIT$1c = false; + +visitParents$C.CONTINUE = CONTINUE$1c; +visitParents$C.SKIP = SKIP$1c; +visitParents$C.EXIT = EXIT$1c; + +function visitParents$C(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1$C(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$C(visitor(node, parents)); + + if (result[0] === EXIT$1c) { + return result + } + } + + if (node.children && result[0] !== SKIP$1c) { + subresult = toResult$C(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$1c ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$1c) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult$C(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1c, value] + } + + return [value] +} + +var unistUtilVisit$C = visit$C; + + + +var CONTINUE$1d = unistUtilVisitParents$C.CONTINUE; +var SKIP$1d = unistUtilVisitParents$C.SKIP; +var EXIT$1d = unistUtilVisitParents$C.EXIT; + +visit$C.CONTINUE = CONTINUE$1d; +visit$C.SKIP = SKIP$1d; +visit$C.EXIT = EXIT$1d; + +function visit$C(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents$C(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + var remarkLintUnorderedListMarkerStyle = unifiedLintRule( 'remark-lint:unordered-list-marker-style', unorderedListMarkerStyle ); -var start$j = unistUtilPosition.start; +var start$k = unistUtilPosition.start; var styles$4 = { '-': true, @@ -44445,20 +52412,20 @@ var styles$4 = { null: true }; -function unorderedListMarkerStyle(tree, file, pref) { +function unorderedListMarkerStyle(tree, file, option) { var contents = String(file); + var preferred = + typeof option === 'string' && option !== 'consistent' ? option : null; - pref = typeof pref === 'string' && pref !== 'consistent' ? pref : null; - - if (styles$4[pref] !== true) { + if (styles$4[preferred] !== true) { file.fail( - 'Invalid unordered list-item marker style `' + - pref + + 'Incorrect unordered list item marker style `' + + preferred + "`: use either `'-'`, `'*'`, or `'+'`" ); } - unistUtilVisit(tree, 'list', visitor); + unistUtilVisit$C(tree, 'list', visitor); function visitor(node) { var children = node.children; @@ -44472,16 +52439,16 @@ function unorderedListMarkerStyle(tree, file, pref) { if (!unistUtilGenerated(child)) { marker = contents - .slice(start$j(child).offset, start$j(child.children[0]).offset) + .slice(start$k(child).offset, start$k(child.children[0]).offset) .replace(/\[[x ]?]\s*$/i, '') .replace(/\s/g, ''); - if (pref) { - if (marker !== pref) { - file.message('Marker style should be `' + pref + '`', child); + if (preferred) { + if (marker !== preferred) { + file.message('Marker style should be `' + preferred + '`', child); } } else { - pref = marker; + preferred = marker; } } } @@ -44498,8 +52465,8 @@ var plugins$2 = [ remarkLintCheckboxCharacterStyle, { checked: "x", - unchecked: " " - } + unchecked: " ", + }, ], remarkLintCheckboxContentIndent, [remarkLintCodeBlockStyle, "fenced"], @@ -44517,7 +52484,6 @@ var plugins$2 = [ remarkLintNoFileNameConsecutiveDashes, remarkLintNoFileNameOuterDashes, remarkLintNoHeadingIndent, - [remarkLintNoLiteralUrls, false], remarkLintNoMultipleToplevelHeadings, remarkLintNoShellDollars, remarkLintNoTableIndentation, @@ -44526,29 +52492,25 @@ var plugins$2 = [ [ remarkLintProhibitedStrings, [ - { no: "End-Of-Life", yes: "End-of-Life" }, - { no: "End-of-life", yes: "End-of-Life" }, - { no: "Github", yes: "GitHub" }, + { yes: "End-of-Life" }, + { yes: "GitHub" }, { no: "hostname", yes: "host name" }, - { no: "[Jj]avascript", yes: "JavaScript" }, + { yes: "JavaScript" }, { no: "Node", yes: "Node.js" }, - { no: "Node\\.JS", yes: "Node.js" }, - { no: "node\\.js", yes: "Node.js" }, + { yes: "Node.js" }, { no: "Node\\.js's?", yes: "the Node.js" }, { no: "[Nn]ote that", yes: "" }, - { no: "Rfc", yes: "RFC" }, + { yes: "RFC" }, { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, - { no: "rfc", yes: "RFC" }, - { no: "UNIX", yes: "Unix" }, - { no: "unix", yes: "Unix" }, - { no: "v8", yes: "V8" } - ] + { yes: "Unix" }, + { yes: "V8" }, + ], ], remarkLintRuleStyle, [remarkLintStrongMarker, "*"], [remarkLintTableCellPadding, "padded"], remarkLintTablePipes, - [remarkLintUnorderedListMarkerStyle, "*"] + [remarkLintUnorderedListMarkerStyle, "*"], ]; var remarkPresetLintNode = { diff --git a/tools/node-lint-md-cli-rollup/package-lock.json b/tools/node-lint-md-cli-rollup/package-lock.json index e6597cfdd506fe..bc92428a113cf7 100644 --- a/tools/node-lint-md-cli-rollup/package-lock.json +++ b/tools/node-lint-md-cli-rollup/package-lock.json @@ -401,11 +401,6 @@ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, - "irregular-plurals": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", - "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==" - }, "is-alphabetical": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", @@ -595,14 +590,14 @@ } }, "mdast-util-heading-style": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.5.tgz", - "integrity": "sha512-8zQkb3IUwiwOdUw6jIhnwM6DPyib+mgzQuHAe7j2Hy1rIarU4VUxe472bp9oktqULW3xqZE+Kz6OD4Gi7IA3vw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/mdast-util-heading-style/-/mdast-util-heading-style-1.0.6.tgz", + "integrity": "sha512-8ZuuegRqS0KESgjAGW8zTx4tJ3VNIiIaGFNEzFpRSAQBavVc7AvOo9I4g3crcZBfYisHs4seYh0rAVimO6HyOw==" }, "mdast-util-to-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.7.tgz", - "integrity": "sha512-P+gdtssCoHOX+eJUrrC30Sixqao86ZPlVjR5NEAoy0U79Pfxb1Y0Gntei0+GrnQD4T04X9xA8tcugp90cSmNow==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", + "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==" }, "minimatch": { "version": "3.0.4", @@ -688,13 +683,10 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" }, - "plur": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", - "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", - "requires": { - "irregular-plurals": "^2.0.0" - } + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" }, "rc": { "version": "1.2.8", @@ -753,360 +745,1084 @@ } }, "remark-lint-blockquote-indentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-1.0.3.tgz", - "integrity": "sha512-qK4C1l2VmeOVWEAkDYP0CaDtSFoaEBEo5l4oyz1kTkY7YB0Jh7llW2KjuhJz5IzMLmloKJzIyGwlu/odcwaHpg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-2.0.0.tgz", + "integrity": "sha512-Ma/lk+egYzvzV9+RLxR7iaNcFqwsF02guxY2nFF7gaVFXWDhbRy+hbiRZiTQe3y8AK+smc2yE79I+JRUVL15LQ==", "requires": { "mdast-util-to-string": "^1.0.2", - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-checkbox-character-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-1.0.3.tgz", - "integrity": "sha512-bQGrGHLlguTxOzuywHtYxNcg58TYhNgeEAMCTvdAggt5bYZIwmh/otx51JsQ0a96qxd/6/G0Ri2xzgyxf9wB8w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-2.0.0.tgz", + "integrity": "sha512-V+eTXFHrHCpFFG2RWaQM6lSetLLvpYC8WEZ9dMYSAUbeS/h0PhA7cB7j5kGH86RUwGCihawfzNAKbRmgGxL+DQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-checkbox-content-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-1.0.3.tgz", - "integrity": "sha512-YaM1yy8RdnM0DUaP0r2X8kF+inUTmjkCpj5Xjn7QTOV1T5jqJMJnRRilirAWgOGa1QBZBUew7uj0L1Je9SJIZw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-2.0.0.tgz", + "integrity": "sha512-02Xytexe8nso1ofPC6wN3FE48302nmteSIwydeIDFhJq7mG14SxF4xgay+Kjbhs/O5NoRIF2ju9qcPNJ5gFsXA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-code-block-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-1.0.3.tgz", - "integrity": "sha512-DL+rudnd9ILP5YXm74tLpMzfWZLqziX7NwIwUhqRefaOyWwxgPPy7hbT59FJqcFc6E/zvDz+Oq4nR1BSV5kEdw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-2.0.0.tgz", + "integrity": "sha512-bXT1b9MvYDxKdLfzWTW3eSXWy7v57LXtU5ySLzlD1g3DWoSA6rSWjJT5l/2mA+iOuswg18ssY3SSjwExmTyWUA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-definition-spacing": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-1.0.4.tgz", - "integrity": "sha512-UderghITmru72OXB5ErCFhVsY7up2wK/m1bUD3E2dm/TFn73/7WpykENt5UirCDT/aeyoHYl8QXUVL20rAc3XQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-2.0.0.tgz", + "integrity": "sha512-kE+ffEGsyxgUDlcKSVrnhqyHjQfH0RtUVN/OdA/iSzKfTy/Yc9VMMaNu6xT14xhwjTnSVPrd38rUOnDt1LZhAw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-fenced-code-flag": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-1.0.3.tgz", - "integrity": "sha512-X8Oi6dhfqV9NI3cVg29myvT/NATDHVgRGCpnNz76w7VXwzhBvQtJr1MxZzuPxfWLox+ARCXF2rY9n9hbYFHYTg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-2.0.0.tgz", + "integrity": "sha512-SyQ31cdQlbsS+eBw2DUxkuzNwGIGlWnnCLyHLz3D1nxtZBVUaUOnIAturSA3PsguIrnxH4qD2JYCTp5aPbZhzQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-fenced-code-marker": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-1.0.3.tgz", - "integrity": "sha512-JKnojSQ8JkwpIpbNm6wtKEfx8iiv8QIwNHFM06iTCHExMhXa4pJ3wb5M5f0wsWNHtoND3lrw6AcVPoZxEPnflg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-2.0.0.tgz", + "integrity": "sha512-ZkJ4/o0A34nQefhsu6AU2cftQjCwzXClbZ5TrwgtkQQHG9BSu9/vo3PSLxGGw7XBX63oKcrx5HWGrWXaeLTN2g==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-file-extension": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.3.tgz", - "integrity": "sha512-P5gzsxKmuAVPN7Kq1W0f8Ss0cFKfu+OlezYJWXf+5qOa+9Y5GqHEUOobPnsmNFZrVMiM7JoqJN2C9ZjrUx3N6Q==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-1.0.4.tgz", + "integrity": "sha512-Zfp1mXNwpg7STjTWynZjL+/JtvIOCrmOAZzL3uK+tYpT0ZDPdQ1EQEl5D92+Eiu5OcYlenzG42jiLcyJjv+Q2g==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-final-definition": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-1.0.3.tgz", - "integrity": "sha512-QhbBYy99enfQDeUTElioCHrhgg+SgjMNRlru7/JlOguOufP6wn7AXgn2EVTrLZRoByY0VsNS2jCayXxUTzQ8KA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-2.0.0.tgz", + "integrity": "sha512-oGObGXt/CdQfvnoQHWrFPtpTQK7oHiw5kBGzG5GbPSj3rrv30ohD5K+11ljEle9e3wO048EiWDROO5eKzIeeGw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-final-newline": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.3.tgz", - "integrity": "sha512-ETAadktv75EwUS3XDhyZUVstXKxfPAEn7SmfN9kZ4+Jb4qo4hHE9gtTOzhE6HxLUxxl9BBhpC5mMO3JcL8UZ5A==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-1.0.4.tgz", + "integrity": "sha512-pUwqX8TVTTfqX5arMnu9Dr2ufg6wZ6Pk1VeqlnWfK92PBXLG8Zc3yrLpYXOJy1fHdWpqUECRRowG0H/OkZIEbw==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-first-heading-level": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-1.1.4.tgz", - "integrity": "sha512-iU5G4ZmGx8/2p/U2rPc6qhjyQ/BCcOuj07KzI7XxapYfJqZF6Xxz2rC2b/5xsDJAz2vXG74U4iG3c9vmbyH9WQ==", - "requires": { - "unified-lint-rule": "^1.0.0", - "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" - } - }, - "remark-lint-hard-break-spaces": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-1.0.4.tgz", - "integrity": "sha512-YM82UpgliZCZhGNmFxEe7ArfhqR5CplFf2bc0k0+8w3rKWKx7EJcGMar2NK410tIi40gGeWtH/pIEypPJFCCiA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-2.0.0.tgz", + "integrity": "sha512-LFjKO6nQAPo0oarhLZqHaGUqCpLvjeVuJTr58yo3jpC4v0Gmb1iG8X53hrLtxPz+MP4J5WVz/83eAXCH+Vh3vA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" - } + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } + } + }, + "remark-lint-hard-break-spaces": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-2.0.0.tgz", + "integrity": "sha512-dmB8GucOSDtEctwa+Y8JlSAWF4q8HcquvLr+OpFOSE1QCrpFoZdb2mcSY+rZuTtfeg4S60orhhzArd2aiHvUPQ==", + "requires": { + "unified-lint-rule": "^1.0.0", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } + } }, "remark-lint-heading-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-1.0.3.tgz", - "integrity": "sha512-ZUhMav0HHUxo5gzLqxQsOf2ZpP/I3m6EEK8q25/kqpCYnwm1uRJ5CQ40PDQx46pmKtVibIMzDmraYovxNG3ovw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-2.0.0.tgz", + "integrity": "sha512-LZvnAq5zWh9i/oRAEocth8yajEEH4kRgCrL4dE547Nkv6zaR2SKcym+uXMZ+GF6WEWcjXMiwSxIL7MHaT6XexA==", "requires": { "mdast-util-heading-style": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-list-item-bullet-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-1.0.3.tgz", - "integrity": "sha512-iVxQbrgzLpMHG3C6o6wRta/+Bc96etOiBYJnh2zm/aWz6DJ7cGLDykngblP/C4he7LYSeWOD/8Y57HbXZwM2Og==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-2.0.0.tgz", + "integrity": "sha512-8iK+ht771UBf/Iuj4YBgdLnFFOyEgfXY62jBoywtMuiOLVWXDfPe+jUY7pCrnFjsnxXGEnMaxHJqENgrHd0J/w==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-list-item-indent": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-1.0.4.tgz", - "integrity": "sha512-Sv0gVH6qP1/nFpbJuyyguB9sAD2o42StD2WbEZeUcEexXwRO4u/YaX0Pm5pMtCiEHyN+qyL6ShKBQMtgol9BeA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-2.0.0.tgz", + "integrity": "sha512-qnKsq2UQpCC8gnI1O23dgoKsd+5RAJrAJuvHXrlkRgzsab7BOMluptxRlyLVXn0P71l4Wo/bfo84Ual7qpOyWw==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-maximum-line-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-1.2.1.tgz", - "integrity": "sha512-CSxX1qc+rAqixk8eBrI+yBsUmD8YGfOezFeJWjJRuUaoOvs67oqCIU+I2HbwcUYY8/KnDxF1MCp+uCM0RkjKKw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-2.0.0.tgz", + "integrity": "sha512-Qhe1QwDGisMP/UraUexWIPNBXJO8VQ7LIelz4NdftBQl/FxDVoXn3477Fm+8bGtcTXkMPF+QfllE4L1U7kJQgQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-auto-link-without-protocol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-1.0.3.tgz", - "integrity": "sha512-k+hg2mXnO4Q9WV+UShPLen5oThvFxcRVWkx2hviVd/nu3eiszBKH3o38csBwjeJoMG3l2ZhdUW8dlOBhq8670Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-2.0.0.tgz", + "integrity": "sha512-pIntUa+zNiyRxIt2Wvp1soktDbVnk1SEiJXsjcLYYn9GapgXqOQG5ZfFwR6zxTkGV5mZKo9927EvHQkvIV6cLQ==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-blockquote-without-marker": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-2.0.3.tgz", - "integrity": "sha512-faDzKrA6aKidsRXG6gcIlCO8TexLxIxe+n9B3mdnl8mhZGgE0FfWTkIWVMj0IYps/xVsVMf45KxhXgc1wU9kwg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-3.0.0.tgz", + "integrity": "sha512-auyAxMVDuhvGw29VilqUfUIUnBT7qmByG/kBPqV/GwM1a5rn4fIUJ7p9Je9BlWMRCBMTNQUMsm3ce0dawouVew==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1", - "vfile-location": "^2.0.1" + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-no-consecutive-blank-lines": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-1.0.3.tgz", - "integrity": "sha512-2Ef7fPxrfLditA7sTo2Qfqd+xwh/luWl8GzILE5vcWIxLDqKk3dTLJkB5nP+7Cr4kqWJAwXnRkEDd77ehrRV3A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-2.0.0.tgz", + "integrity": "sha512-qIXHW0atHaOmHlu7V+4Krs5IAdIZhcXoeRdOMgqkGNW8CtfL12pP8KnzigAB9D5/X/qxPxZ95Js/KaESFS+3hA==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-duplicate-definitions": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-1.0.5.tgz", - "integrity": "sha512-zKXmfNUODXhJsGQdqfguMG9Nl9v1sLaDsQgMjUtmOSoQRnNud9ThQAZl62eX5jBn5HKcpOifG80tgkyBvU5eEw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-2.0.0.tgz", + "integrity": "sha512-Z5DkYKbmS+r4D0ZhaXgK6L72EWzhiklpXNF/TS+KCsffAFgfy5aJfSA3A8GpVNj1wYMP35STXBGBCLW5TckvGw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-file-name-articles": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.3.tgz", - "integrity": "sha512-YZDJDKUWZEmhrO6tHB0u0K0K2qJKxyg/kryr14OaRMvWLS62RgMn97sXPZ38XOSN7mOcCnl0k7/bClghJXx0sg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-1.0.4.tgz", + "integrity": "sha512-Ieqg/2WjYs5M+IoZsFrQUG0niN8zRC6IAYWOVaHi3UK/1P0IdmXKZE6pCFSJrhletawAaPw9Xtl42/45tcccCA==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-no-file-name-consecutive-dashes": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.3.tgz", - "integrity": "sha512-7f4vyXn/ca5lAguWWC3eu5hi8oZ7etX7aQlnTSgQZeslnJCbVJm6V6prFJKAzrqbBzMicUXr5pZLBDoXyTvHHw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-1.0.4.tgz", + "integrity": "sha512-Fyc8mL+Fyt2b/BVkCc2Y+GjJ4SwafDKQEUaizeuZQDBTiqRK3S4L9YpvLHTAPgTNntZkXLUsHzFDlGyKzW2gBQ==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-no-file-name-outer-dashes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.4.tgz", - "integrity": "sha512-+bZvvme2Bm3Vp5L2iKuvGHYVmHKrTkkRt8JqJPGepuhvBvT4Q7+CgfKyMtC/hIjyl+IcuJQ2H0qPRzdicjy1wQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-1.0.5.tgz", + "integrity": "sha512-5CMrCqyJj4ydM2QMhMAc60o08fJDxBgmO62r+RqVs+aIdIK6TtsF+T8oX+aTEtc3y/euKJ681tqEsSeJZh/h0A==", "requires": { "unified-lint-rule": "^1.0.0" } }, "remark-lint-no-heading-content-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-1.0.3.tgz", - "integrity": "sha512-7xM6X5E/dt8OXOHdejH+sfYb139a3kMr8ZSSkcp90Ab1y+ZQBNaWsR3mYh8FRKkYPTN5eyd+KjhNpLWyqqCbgg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-2.0.0.tgz", + "integrity": "sha512-Zqg0WXG60Nan8j7HZtnBXidMxXhlhc7Q5JrB54I3n7H3vSPCyaqhZJ2/obYVLalEVGND8NOJGvfA1rtchaZyYg==", "requires": { "mdast-util-heading-style": "^1.0.2", - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-heading-indent": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-1.0.3.tgz", - "integrity": "sha512-RTvsFfiXjHZOxU+t7DtNPk9M9EqGe82MZbo+VOJEUBkQKf17qp4EZkJEvl4h9pn+hJmoKHLb7Vfge8Bxe42gcQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-2.0.0.tgz", + "integrity": "sha512-dBjSP2QdQVypFpwQdjZ6h/VsyY3CBY+IXY2edSWiITOofZrt7knmwrLFUoxPtvc9k4PIBA7XXpiwPPYBQzuLFg==", "requires": { - "plur": "^3.0.0", + "pluralize": "^8.0.0", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-inline-padding": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-1.0.4.tgz", - "integrity": "sha512-u5rgbDkcfVv645YxxOwoGBBJbsHEwWm/XqnO8EhfKTxkfKOF4ZItG7Ajhj89EDaeXMkvCcB/avBl4bj50eJH3g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-2.0.0.tgz", + "integrity": "sha512-0YueQ3SBA8zFQYCN0/afRc6ZuSbM4Azx4sPVeVpAfMT0MrYgmi6msswyhUDXaeN2RwVO6bx/ZW6di8dVqRr7UA==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-literal-urls": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-1.0.3.tgz", - "integrity": "sha512-H5quyMzl2kaewK+jYD1FI0G1SIinIsIp4DEyOUwIR+vYUoKwo0B4vvW0cmPpD1dgqqxHYx0B2B0JQQKFVWzGiw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-2.0.0.tgz", + "integrity": "sha512-bZAxr65ftz9joszDkSs2LBeJB2cRE8GydUtxYdA1WRHYmVW1AfM5ilcqLnWhiOmu+XMPH7J0eRvUzbtvu+xerw==", "requires": { "mdast-util-to-string": "^1.0.2", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-multiple-toplevel-headings": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-1.0.4.tgz", - "integrity": "sha512-0wDddx6htN5sL9/rofesiQF0oEgwN5224UmueiDx0ZUlYrn6VS0/SS0X3WWxtXmyeqlExfWF3D/g89tNs7dcjw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-2.0.0.tgz", + "integrity": "sha512-vpbdnrqUykyqpjaREg4W07J3gHgR0eTapDkz9RjVwyGNmBry7xUnyvaiPavAKqsA+qO/nnpIH8Qyw/2u5hDsJQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", "unist-util-stringify-position": "^2.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-shell-dollars": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-1.0.3.tgz", - "integrity": "sha512-fT3lQMTjEkPryL+63qDP1NfrohP3tG5i3SkNWSSR4VLU6OSsSSXlHGQGjo0ag//+EPKHB5/9frB/YQ0gDEPRGQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-2.0.0.tgz", + "integrity": "sha512-1uEM0kSGlV6UY7w3PdIeIf/USFFvVuU1352myQdaiw/Wof7+uVXznFFCPnhJDTVlPN4vrgwFnLb32UwXrjkrQw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-shortcut-reference-image": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-1.0.3.tgz", - "integrity": "sha512-CGm27X54kXp/5ehXejDTsZjqzK4uIhLGcrFzN3k/KjdwunQouEY92AARGrLSEuJ1hQx0bJsmnvr/hvQyWAfNJg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-2.0.0.tgz", + "integrity": "sha512-kgGCQBHibJ0IFVhWjnfjbqkKC0VeL5+cvyjjwfMJlgZrHEXNOYb2FJE2nvF/l6PSXQ17goRZpznTBfP4mQieUA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-shortcut-reference-link": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-1.0.4.tgz", - "integrity": "sha512-FXdMJYqspZBhPlxYqfVgVluVXjxStg0RHJzqrk8G9wS8fCS62AE3reoaoiCahwoH1tfKcA+poktbKqDAmZo7Jg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-2.0.0.tgz", + "integrity": "sha512-rSdGLWpEsHa4b2doUch+B7QtUHH9XuC8Hndb4rAYf8U0d48KfGAIoiicxUho8qZJ4VA3RIaDo4kA/iQ15Al+Vg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-table-indentation": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-1.0.4.tgz", - "integrity": "sha512-H4VGHcg1k8sTIbwazFYLNbDqpPR+M0aHHKDf+93b/xyd27Dp0ODQrMnQbls1Cls5qOAQnwAQbx+75wcpFxP3OQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-2.0.0.tgz", + "integrity": "sha512-5akpqHl+5r3Xe2WFiZB1I9eAwn6zTYqXNd0CVsiTF3DJo0KyvvgyrFRV1sCf/l/kzyNaFvpWpFDTMoWc8EI0RQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-tabs": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-1.0.3.tgz", - "integrity": "sha512-GxmG1LLxYoVjKnQ39On4mFEiVwpLfR3BPTXyaC9UCBUj9fnDQ7ANXceeCsPAyxamr0UM4r2tk/hB9mNT4rLskQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-2.0.0.tgz", + "integrity": "sha512-aXbqkgjI0611IN651eXK8NxLQLEjReviU6AjtluMVnvGx1B8Y8mEn5pxznrorXaAjOP4mvX0JYeu8kdhcAaHsw==", "requires": { "unified-lint-rule": "^1.0.0", - "vfile-location": "^2.0.1" + "vfile-location": "^3.0.0" + }, + "dependencies": { + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-lint-no-trailing-spaces": { @@ -1118,46 +1834,132 @@ } }, "remark-lint-no-undefined-references": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-1.1.1.tgz", - "integrity": "sha512-b1eIjWFaCu6m16Ax2uG33o1v+eRYqDTQRUqU6UeQ76JXmDmVtVO75ZuyRpqqE7VTZRW8YLVurXfJPDXfIa5Wng==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-2.0.0.tgz", + "integrity": "sha512-K4k05pmlMRqEMUDYewitRUx8zM+ntJWbG61dILmL7to7uy0JoSbzuDtz1cxC+kKBKzkulPnyE3WOgRZG8RX2Jg==", "requires": { "collapse-white-space": "^1.0.4", "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-no-unused-definitions": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-1.0.5.tgz", - "integrity": "sha512-Bo22e0RNzc1QMW317KTuStGFDG7uTDUQhm/TrW6Qzud0WXnNnqUyvts+e7wTYoj8VnwhhjyjyoA9lKA3uXMdAQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-2.0.0.tgz", + "integrity": "sha512-Y8zrulwaf7z6WR1ICfEGjW92iq2SPEN7Zhrs0nloNITHOg22tIPf28TurUz9HSQ3sEd52d9bZCfW9RkdfMq1xw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-ordered-list-marker-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-1.0.3.tgz", - "integrity": "sha512-24TmW1eUa/2JlwprZg9jJ8LKLxNGKnlKiI5YOhN4taUp2yv8daqlV9vR54yfn/ZZQh6EQvbIX0jeVY9NYgQUtw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-2.0.0.tgz", + "integrity": "sha512-zYMZA8tQD/slJYKqsstZv0/Q34Hkdlf4DjC8SOr92PSA60R/xr7JdVd/AHHisbMsFvdnHZrxaB8oIOtbAUJCSw==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-prohibited-strings": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-1.2.1.tgz", - "integrity": "sha512-i3LatoJn/eHkgawdi3eoynikQa5zIEDX+GYcvu4ns5LsOvIrT8WcuvgYQ2kbEFbV0KTy7yBAGLJ9040xs1ssXA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-1.5.1.tgz", + "integrity": "sha512-YZoRWbzIGRIQkngAowwAKG39kUAGSalYvrxqTzUU4LYj1dS37q7i5WDr4m/mnCcc5KwRin08D62Dphs6g9Btnw==", "requires": { + "escape-string-regexp": "^4.0.0", "unified-lint-rule": "^1.0.2", - "unist-util-visit": "^2.0.0" + "unist-util-position": "^3.1.0", + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.1" }, "dependencies": { + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, "unist-util-is": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", @@ -1181,62 +1983,197 @@ "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" } } }, "remark-lint-rule-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-1.0.3.tgz", - "integrity": "sha512-SJe7IFORYRdo8JUhMSdcTktVAUVNVp36YYl1ZD9CfHqQHWlFD+3vWYzJXOZfog/i+CyWf7Yi0WVYmQes+167dA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-2.0.0.tgz", + "integrity": "sha512-fdRfLUE5AJiFEn9rWTQrHwOUG3UcYtIxbWnR7YFvuPlFmzcMRwRHP5ZOcrj4KIpwCdVtlPI3h08m0kfO7a1KlQ==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-strong-marker": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-1.0.3.tgz", - "integrity": "sha512-PFkH282dCwfRsVEw9IxbYbaZBY4UcTuT2SN+lA3R0cBeocWnOySVw8YEm4sv9JfV8BLcQA5gc4tj66/U3KCScw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-2.0.0.tgz", + "integrity": "sha512-1gl6vZF5BvV4kvS4xxhl8cw90La5Cio9ZFDQuspZMRA2KjzpwoU5RlTUbeHv8OqlKJJ2p7s0MDs8bLZNTzzjHA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-table-cell-padding": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-1.0.4.tgz", - "integrity": "sha512-AQWWtV1yca1PN27QaFRJbBK6Ro/bopv1XnVKxj/iMebhOU2D2FBJ8rXmMZXVMC3G9OB2WSzGgqH3nP6QY12LoA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-2.0.0.tgz", + "integrity": "sha512-UstIXIaRVRJPKZPv1AXX/p3qCt//RYNsRHIq8KvL5YQPKaKWRkj2cNermCgm0XoUXy0EmRPNiBtUcuAQaP+jXg==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.4.0" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-table-pipes": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-1.0.3.tgz", - "integrity": "sha512-K9NnGZp6i0m/CaOH7ZT4Ymt2seyiRPcBIlNMMGXBm6gpy34KJDDxYqsNUrh+j7dR+Zg4rYAQLnr3BiSHvj+rbQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-2.0.0.tgz", + "integrity": "sha512-qGIttPFNT+19BEDz2JJWQtJIClFNIpg+XVw6ruX9LSR7xdo5QG9uARG4XS2EGUQQ7fiLIxQYb8g2dHwuXGbfmA==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-lint-unordered-list-marker-style": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-1.0.3.tgz", - "integrity": "sha512-0nn/Yscy5ImO4fqByrk/Ua02UwGx8LRu+0kdCbkVz4IxPO5qxTEfyccUQZR71zTdMJp1d2OeqyD9XtMaO4X7Ww==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-2.0.0.tgz", + "integrity": "sha512-s+ZiBgBDbIiScPPxWG/r2E/4YY+xP6EFLsLXPV/uPx7JqegIP/4+MAPi7Nz2zLmnQ2eekssZrEXma3uDb/dE1Q==", "requires": { "unified-lint-rule": "^1.0.0", "unist-util-generated": "^1.1.0", "unist-util-position": "^3.0.0", - "unist-util-visit": "^1.1.1" + "unist-util-visit": "^2.0.0" + }, + "dependencies": { + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + } } }, "remark-message-control": { @@ -1272,65 +2209,178 @@ } }, "remark-preset-lint-node": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-1.13.0.tgz", - "integrity": "sha512-UNAoY4wl672d0qE+LM5rA0ILOTJN+siNGj3/qa5Zvl7nMIUwqMcz0G266Ck6OL6GOrpys/e4EOrkXiitEdEqNA==", - "requires": { - "remark-lint": "^6.0.5", - "remark-lint-blockquote-indentation": "^1.0.3", - "remark-lint-checkbox-character-style": "^1.0.3", - "remark-lint-checkbox-content-indent": "^1.0.3", - "remark-lint-code-block-style": "^1.0.3", - "remark-lint-definition-spacing": "^1.0.4", - "remark-lint-fenced-code-flag": "^1.0.3", - "remark-lint-fenced-code-marker": "^1.0.3", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-1.14.0.tgz", + "integrity": "sha512-1RJkFNrTA+9S43rfZE2uvzKWe233x4byRZ3gpv3+J28ZnhJ37p1m2df23JkBZbV/pji9+LpUtNCLNEPhLBd6KA==", + "requires": { + "remark-lint": "^7.0.0", + "remark-lint-blockquote-indentation": "^2.0.0", + "remark-lint-checkbox-character-style": "^2.0.0", + "remark-lint-checkbox-content-indent": "^2.0.0", + "remark-lint-code-block-style": "^2.0.0", + "remark-lint-definition-spacing": "^2.0.0", + "remark-lint-fenced-code-flag": "^2.0.0", + "remark-lint-fenced-code-marker": "^2.0.0", "remark-lint-file-extension": "^1.0.3", - "remark-lint-final-definition": "^1.0.3", - "remark-lint-first-heading-level": "^1.1.4", - "remark-lint-heading-style": "^1.0.3", - "remark-lint-list-item-indent": "^1.0.4", - "remark-lint-maximum-line-length": "^1.2.1", - "remark-lint-no-consecutive-blank-lines": "^1.0.3", - "remark-lint-no-file-name-articles": "^1.0.3", - "remark-lint-no-file-name-consecutive-dashes": "^1.0.3", - "remark-lint-no-file-name-outer-dashes": "^1.0.4", - "remark-lint-no-heading-indent": "^1.0.3", - "remark-lint-no-literal-urls": "^1.0.3", - "remark-lint-no-multiple-toplevel-headings": "^1.0.4", - "remark-lint-no-shell-dollars": "^1.0.3", - "remark-lint-no-table-indentation": "^1.0.4", - "remark-lint-no-tabs": "^1.0.3", + "remark-lint-final-definition": "^2.0.0", + "remark-lint-first-heading-level": "^2.0.0", + "remark-lint-heading-style": "^2.0.0", + "remark-lint-list-item-indent": "^2.0.0", + "remark-lint-maximum-line-length": "^2.0.0", + "remark-lint-no-consecutive-blank-lines": "^2.0.0", + "remark-lint-no-file-name-articles": "^1.0.4", + "remark-lint-no-file-name-consecutive-dashes": "^1.0.4", + "remark-lint-no-file-name-outer-dashes": "^1.0.5", + "remark-lint-no-heading-indent": "^2.0.0", + "remark-lint-no-multiple-toplevel-headings": "^2.0.0", + "remark-lint-no-shell-dollars": "^2.0.0", + "remark-lint-no-table-indentation": "^2.0.0", + "remark-lint-no-tabs": "^2.0.0", "remark-lint-no-trailing-spaces": "^2.0.1", - "remark-lint-prohibited-strings": "^1.2.1", - "remark-lint-rule-style": "^1.0.3", - "remark-lint-strong-marker": "^1.0.3", - "remark-lint-table-cell-padding": "^1.0.4", - "remark-lint-table-pipes": "^1.0.3", - "remark-lint-unordered-list-marker-style": "^1.0.3", - "remark-preset-lint-recommended": "^3.0.3" + "remark-lint-prohibited-strings": "^1.5.1", + "remark-lint-rule-style": "^2.0.0", + "remark-lint-strong-marker": "^2.0.0", + "remark-lint-table-cell-padding": "^2.0.0", + "remark-lint-table-pipes": "^2.0.0", + "remark-lint-unordered-list-marker-style": "^2.0.0", + "remark-preset-lint-recommended": "^4.0.0" + }, + "dependencies": { + "remark-lint": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-7.0.0.tgz", + "integrity": "sha512-OLrWPYy0MUcGLa/2rjuy1kQILTRRK+JiRtyUzqe4XRoHboGuvFDcy/W2e7sq5hu/0xmD+Eh7cEa1Coiqp7LeaA==", + "requires": { + "remark-message-control": "^6.0.0" + } + }, + "remark-message-control": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", + "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "requires": { + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^3.0.0" + } + }, + "unified-message-control": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.1.tgz", + "integrity": "sha512-K2Kvvp1DBzeuxYLLsumZh/gDWUTl4e2z/P3VReFirC78cfHKtQifbhnfRrSBtKtd1Uc6cvYTW0/SZIUaMAEcTg==", + "requires": { + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + } + }, + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-preset-lint-recommended": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-3.0.3.tgz", - "integrity": "sha512-5sQ34j1Irlsj6Tt4WWRylZ7UU+1jD5es/LfDZBZp/LXDwC4ldGqKpMmCCR6Z00x1jYM1phmS4M+eGqTdah0qkQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-4.0.0.tgz", + "integrity": "sha512-Nroe+4Itvk+AHxkMCMu6iRUptE/5pXWgLoEOGdVO/2JIiMk/+15HEogMZ05vMhPct9+Wp4uVt2zqfuvzNzdcww==", "requires": { - "remark-lint": "^6.0.0", + "remark-lint": "^7.0.0", "remark-lint-final-newline": "^1.0.0", - "remark-lint-hard-break-spaces": "^1.0.0", - "remark-lint-list-item-bullet-indent": "^1.0.0", - "remark-lint-list-item-indent": "^1.0.0", - "remark-lint-no-auto-link-without-protocol": "^1.0.0", - "remark-lint-no-blockquote-without-marker": "^2.0.0", - "remark-lint-no-duplicate-definitions": "^1.0.0", - "remark-lint-no-heading-content-indent": "^1.0.0", - "remark-lint-no-inline-padding": "^1.0.0", - "remark-lint-no-literal-urls": "^1.0.0", - "remark-lint-no-shortcut-reference-image": "^1.0.0", - "remark-lint-no-shortcut-reference-link": "^1.0.0", - "remark-lint-no-undefined-references": "^1.0.0", - "remark-lint-no-unused-definitions": "^1.0.0", - "remark-lint-ordered-list-marker-style": "^1.0.0" + "remark-lint-hard-break-spaces": "^2.0.0", + "remark-lint-list-item-bullet-indent": "^2.0.0", + "remark-lint-list-item-indent": "^2.0.0", + "remark-lint-no-auto-link-without-protocol": "^2.0.0", + "remark-lint-no-blockquote-without-marker": "^3.0.0", + "remark-lint-no-duplicate-definitions": "^2.0.0", + "remark-lint-no-heading-content-indent": "^2.0.0", + "remark-lint-no-inline-padding": "^2.0.0", + "remark-lint-no-literal-urls": "^2.0.0", + "remark-lint-no-shortcut-reference-image": "^2.0.0", + "remark-lint-no-shortcut-reference-link": "^2.0.0", + "remark-lint-no-undefined-references": "^2.0.0", + "remark-lint-no-unused-definitions": "^2.0.0", + "remark-lint-ordered-list-marker-style": "^2.0.0" + }, + "dependencies": { + "remark-lint": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-7.0.0.tgz", + "integrity": "sha512-OLrWPYy0MUcGLa/2rjuy1kQILTRRK+JiRtyUzqe4XRoHboGuvFDcy/W2e7sq5hu/0xmD+Eh7cEa1Coiqp7LeaA==", + "requires": { + "remark-message-control": "^6.0.0" + } + }, + "remark-message-control": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-6.0.0.tgz", + "integrity": "sha512-k9bt7BYc3G7YBdmeAhvd3VavrPa/XlKWR3CyHjr4sLO9xJyly8WHHT3Sp+8HPR8lEUv+/sZaffL7IjMLV0f6BA==", + "requires": { + "mdast-comment-marker": "^1.0.0", + "unified-message-control": "^3.0.0" + } + }, + "unified-message-control": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-3.0.1.tgz", + "integrity": "sha512-K2Kvvp1DBzeuxYLLsumZh/gDWUTl4e2z/P3VReFirC78cfHKtQifbhnfRrSBtKtd1Uc6cvYTW0/SZIUaMAEcTg==", + "requires": { + "unist-util-visit": "^2.0.0", + "vfile-location": "^3.0.0" + } + }, + "unist-util-is": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==" + }, + "unist-util-visit": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + } + }, + "unist-util-visit-parents": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + } + }, + "vfile-location": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==" + } } }, "remark-stringify": { @@ -1608,9 +2658,9 @@ } }, "unified-lint-rule": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.4.tgz", - "integrity": "sha512-q9wY6S+d38xRAuWQVOMjBQYi7zGyKkY23ciNafB8JFVmDroyKjtytXHCg94JnhBCXrNqpfojo3+8D+gmF4zxJQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-1.0.5.tgz", + "integrity": "sha512-jOPr/fx8lTzqszEfh46p99jUMqgPlIZ8rNKllEepumISvgfj9lUq1c7BSpVihr0L1df3lkjVHAThRPS7dIyjYg==", "requires": { "wrapped": "^1.0.1" } diff --git a/tools/node-lint-md-cli-rollup/package.json b/tools/node-lint-md-cli-rollup/package.json index be155b49e95fce..e444d983b615d6 100644 --- a/tools/node-lint-md-cli-rollup/package.json +++ b/tools/node-lint-md-cli-rollup/package.json @@ -13,7 +13,7 @@ "markdown-extensions": "^1.1.1", "remark": "^11.0.2", "remark-lint": "^6.0.5", - "remark-preset-lint-node": "^1.13.0", + "remark-preset-lint-node": "^1.14.0", "unified-args": "^7.1.0" }, "main": "dist/index.js", From c5a2f9a02ae195b358e321ad05cefe84cf111280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Arboleda?= Date: Sat, 25 Apr 2020 17:30:37 -0500 Subject: [PATCH 20/62] doc: fix markdown parsing on doc/api/os.md PR-URL: https://github.com/nodejs/node/pull/33067 Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott --- doc/api/os.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/os.md b/doc/api/os.md index e2cce1f8a5580f..d70bd2d260b3ac 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -389,7 +389,7 @@ operating system response. Throws a [`SystemError`][] if a user has no `username` or `homedir`. -## `os.version()` +## `os.version()` From 466213d726409a3376b3f183578383e442e4b3fb Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 22 Apr 2020 10:50:08 +0200 Subject: [PATCH 21/62] n-api: simplify uv_idle wrangling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit uv_idle_init(), uv_idle_start() and uv_idle_stop() always succeed. Remove the superfluous error handling. Refs: https://github.com/libuv/libuv/pull/2803 PR-URL: https://github.com/nodejs/node/pull/32997 Reviewed-By: Colin Ihrig Reviewed-By: David Carlier Reviewed-By: Gus Caplan Reviewed-By: Juan José Arboleda Reviewed-By: James M Snell --- src/node_api.cc | 46 +++++++++++++--------------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/src/node_api.cc b/src/node_api.cc index cb8bd4b482365e..098c5e03219396 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -250,8 +250,8 @@ class ThreadSafeFunction : public node::AsyncResource { if (max_queue_size > 0) { cond = std::make_unique(); } - if ((max_queue_size == 0 || cond) && - uv_idle_init(loop, &idle) == 0) { + if (max_queue_size == 0 || cond) { + CHECK_EQ(0, uv_idle_init(loop, &idle)); return napi_ok; } @@ -291,7 +291,6 @@ class ThreadSafeFunction : public node::AsyncResource { void DispatchOne() { void* data = nullptr; bool popped_value = false; - bool idle_stop_failed = false; { node::Mutex::ScopedLock lock(this->mutex); @@ -317,43 +316,24 @@ class ThreadSafeFunction : public node::AsyncResource { } CloseHandlesAndMaybeDelete(); } else { - if (uv_idle_stop(&idle) != 0) { - idle_stop_failed = true; - } + CHECK_EQ(0, uv_idle_stop(&idle)); } } } } - if (popped_value || idle_stop_failed) { + if (popped_value) { v8::HandleScope scope(env->isolate); CallbackScope cb_scope(this); - - if (idle_stop_failed) { - CHECK(napi_throw_error(env, - "ERR_NAPI_TSFN_STOP_IDLE_LOOP", - "Failed to stop the idle loop") == napi_ok); - } else { - napi_value js_callback = nullptr; - if (!ref.IsEmpty()) { - v8::Local js_cb = - v8::Local::New(env->isolate, ref); - js_callback = v8impl::JsValueFromV8LocalValue(js_cb); - } - env->CallIntoModuleThrow([&](napi_env env) { - call_js_cb(env, js_callback, context, data); - }); + napi_value js_callback = nullptr; + if (!ref.IsEmpty()) { + v8::Local js_cb = + v8::Local::New(env->isolate, ref); + js_callback = v8impl::JsValueFromV8LocalValue(js_cb); } - } - } - - void MaybeStartIdle() { - if (uv_idle_start(&idle, IdleCb) != 0) { - v8::HandleScope scope(env->isolate); - CallbackScope cb_scope(this); - CHECK(napi_throw_error(env, - "ERR_NAPI_TSFN_START_IDLE_LOOP", - "Failed to start the idle loop") == napi_ok); + env->CallIntoModuleThrow([&](napi_env env) { + call_js_cb(env, js_callback, context, data); + }); } } @@ -435,7 +415,7 @@ class ThreadSafeFunction : public node::AsyncResource { static void AsyncCb(uv_async_t* async) { ThreadSafeFunction* ts_fn = node::ContainerOf(&ThreadSafeFunction::async, async); - ts_fn->MaybeStartIdle(); + CHECK_EQ(0, uv_idle_start(&ts_fn->idle, IdleCb)); } static void Cleanup(void* data) { From 82e459d9afe3db68198f8c6b8cfc1b819692dd01 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 22 Apr 2020 10:48:22 +0200 Subject: [PATCH 22/62] doc: don't check links in tmp dirs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/32996 Reviewed-By: Gerhard Stöbich Reviewed-By: Yongsheng Zhang Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Anna Henningsen --- tools/doc/checkLinks.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/doc/checkLinks.js b/tools/doc/checkLinks.js index 60a3f65e5ea9f1..00697cc01cf01a 100644 --- a/tools/doc/checkLinks.js +++ b/tools/doc/checkLinks.js @@ -27,6 +27,7 @@ function findMarkdownFilesRecursively(dirPath) { if ( entry.isDirectory() && entry.name !== 'api' && + entry.name !== 'tmp' && entry.name !== 'fixtures' && entry.name !== 'changelogs' && entry.name !== 'deps' && From 92c7e0620f83f0db76a5b8264d6e4b380176f869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Arboleda?= Date: Mon, 20 Apr 2020 18:34:23 -0500 Subject: [PATCH 23/62] test: check args on SourceTextModule cachedData PR-URL: https://github.com/nodejs/node/pull/32956 Reviewed-By: Anna Henningsen Reviewed-By: Gus Caplan --- test/parallel/test-vm-module-errors.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/parallel/test-vm-module-errors.js b/test/parallel/test-vm-module-errors.js index 5f36f9339fe41a..d14296b1e9ebde 100644 --- a/test/parallel/test-vm-module-errors.js +++ b/test/parallel/test-vm-module-errors.js @@ -209,6 +209,22 @@ async function checkInvalidOptionForEvaluate() { }); } +function checkInvalidCachedData() { + [true, false, 'foo', {}, Array, function() {}].forEach((invalidArg) => { + const message = 'The "options.cachedData" property must be an ' + + 'instance of Buffer, TypedArray, or DataView.' + + common.invalidArgTypeHelper(invalidArg); + assert.throws( + () => new SourceTextModule('import "foo";', { cachedData: invalidArg }), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message, + } + ); + }); +} + const finished = common.mustCall(); (async function main() { @@ -217,5 +233,6 @@ const finished = common.mustCall(); await checkLinking(); await checkExecution(); await checkInvalidOptionForEvaluate(); + checkInvalidCachedData(); finished(); })(); From b183d0a18a9c5391a7cfd253d713ebf0ca497bca Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sun, 26 Apr 2020 19:38:43 +0200 Subject: [PATCH 24/62] stream: let Duplex re-use Writable properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of reimplementing Writable properties, fetch them from the Writable prototype. PR-URL: https://github.com/nodejs/node/pull/33079 Reviewed-By: Juan José Arboleda Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Anna Henningsen --- lib/_stream_duplex.js | 51 ++++++++++++------------------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js index 07a16175ffcd73..ced361c8d60898 100644 --- a/lib/_stream_duplex.js +++ b/lib/_stream_duplex.js @@ -71,7 +71,20 @@ function Duplex(options) { } ObjectDefineProperties(Duplex.prototype, { - writable: ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writable'), + writable: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writable'), + writableHighWaterMark: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableHighWaterMark'), + writableBuffer: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableBuffer'), + writableLength: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableLength'), + writableFinished: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableFinished'), + writableCorked: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableCorked'), + writableEnded: + ObjectGetOwnPropertyDescriptor(Writable.prototype, 'writableEnded'), destroyed: { get() { @@ -89,41 +102,5 @@ ObjectDefineProperties(Duplex.prototype, { this._writableState.destroyed = value; } } - }, - - writableHighWaterMark: { - get() { - return this._writableState && this._writableState.highWaterMark; - } - }, - - writableBuffer: { - get() { - return this._writableState && this._writableState.getBuffer(); - } - }, - - writableLength: { - get() { - return this._writableState && this._writableState.length; - } - }, - - writableFinished: { - get() { - return this._writableState ? this._writableState.finished : false; - } - }, - - writableCorked: { - get() { - return this._writableState ? this._writableState.corked : 0; - } - }, - - writableEnded: { - get() { - return this._writableState ? this._writableState.ending : false; - } } }); From 289a5c8dfbe3c50c8c16e6a532fc690472f603b2 Mon Sep 17 00:00:00 2001 From: Chris Holland Date: Sun, 26 Apr 2020 16:03:12 -0700 Subject: [PATCH 25/62] doc: some grammar fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/33081 Reviewed-By: Juan José Arboleda Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott --- doc/guides/backporting-to-release-lines.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/guides/backporting-to-release-lines.md b/doc/guides/backporting-to-release-lines.md index 55fbcb7e5bc344..6fcbdc43f72396 100644 --- a/doc/guides/backporting-to-release-lines.md +++ b/doc/guides/backporting-to-release-lines.md @@ -31,9 +31,9 @@ release line. All commands will use the `v10.x-staging` branch as the target branch. In order to submit a backport pull request to another branch, simply replace that with the staging branch for the targeted release line. -1. Checkout the staging branch for the targeted release line -2. Make sure that the local staging branch is up to date with the remote -3. Create a new branch off of the staging branch +1. Checkout the staging branch for the targeted release line. +2. Make sure that the local staging branch is up to date with the remote. +3. Create a new branch off of the staging branch, as shown below. ```shell # Assuming your fork of Node.js is checked out in $NODE_DIR, @@ -68,17 +68,17 @@ replace that with the staging branch for the targeted release line. using `git add`, and then commit the changes. That can be done with `git cherry-pick --continue`. 6. Leave the commit message as is. If you think it should be modified, comment - in the Pull Request. The `Backport-PR-URL` metadata does need to be added to + in the pull request. The `Backport-PR-URL` metadata does need to be added to the commit, but this will be done later. 7. Make sure `make -j4 test` passes. -8. Push the changes to your fork +8. Push the changes to your fork. 9. Open a pull request: 1. Be sure to target the `v10.x-staging` branch in the pull request. 1. Include the backport target in the pull request title in the following format: `[v10.x backport] `. Example: `[v10.x backport] process: improve performance of nextTick` 1. Check the checkbox labeled "Allow edits from maintainers". - 1. In the description add a reference to the original PR. + 1. In the description add a reference to the original pull request. 1. Amend the commit message and include a `Backport-PR-URL:` metadata and re-push the change to your fork. 1. Run a [`node-test-pull-request`][] CI job (with `REBASE_ONTO` set to the @@ -86,8 +86,8 @@ replace that with the staging branch for the targeted release line. 10. If during the review process conflicts arise, use the following to rebase: `git pull --rebase upstream v10.x-staging` -After the PR lands replace the `backport-requested-v10.x` label on the original -PR with `backported-to-v10.x`. +After the pull request lands, replace the `backport-requested-v10.x` label +on the original pull request with `backported-to-v10.x`. [Release Schedule]: https://github.com/nodejs/Release#release-schedule1 [Release Plan]: https://github.com/nodejs/Release#release-plan From de15edcfc003a674c2558e26622d928ab6113921 Mon Sep 17 00:00:00 2001 From: Ranjan Purbey Date: Mon, 27 Apr 2020 04:13:57 +0530 Subject: [PATCH 26/62] doc: improve worker pool example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the worker pool example, the 'kWorkerFreedEvent' should be emitted in case of error as well. After adding new worker in the error handler, the pending tasks should be notified of an available worker. PR-URL: https://github.com/nodejs/node/pull/33082 Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Trivikram Kamat Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Juan José Arboleda --- doc/api/async_hooks.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md index 5463c39bdc6c93..0b1b22c82996f4 100644 --- a/doc/api/async_hooks.md +++ b/doc/api/async_hooks.md @@ -820,6 +820,7 @@ class WorkerPool extends EventEmitter { }); this.workers.push(worker); this.freeWorkers.push(worker); + this.emit(kWorkerFreedEvent); } runTask(task, callback) { From 3c2f608a8dffcf71be6a5d682b7676e43b89b7a3 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 26 Apr 2020 22:16:14 -0400 Subject: [PATCH 27/62] test: correct typo in test name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the 'uncaugth' typo in the test name. PR-URL: https://github.com/nodejs/node/pull/33083 Reviewed-By: Richard Lau Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Juan José Arboleda --- ...end-cb-uncaugth.js => test-stream-writable-end-cb-uncaught.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/parallel/{test-stream-writable-end-cb-uncaugth.js => test-stream-writable-end-cb-uncaught.js} (100%) diff --git a/test/parallel/test-stream-writable-end-cb-uncaugth.js b/test/parallel/test-stream-writable-end-cb-uncaught.js similarity index 100% rename from test/parallel/test-stream-writable-end-cb-uncaugth.js rename to test/parallel/test-stream-writable-end-cb-uncaught.js From c6d632a72aa6f980a1dec78ac869a64828e4f312 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 27 Apr 2020 03:36:23 +0200 Subject: [PATCH 28/62] worker: unify custom error creation Mostly, this introduces a pattern that makes sure that if a custom error is reported, `stopped_` will be set to `true` correctly in every cast, which was previously missing for the `NewContext().IsEmpty()` case (which led to a hard crash from the `Worker` destructor). This also leaves TODO comments for a few cases in which `ERR_WORKER_OUT_OF_MEMORY` was not used in accordance with the documentation for that error code (or according to its intention). Fixing that is semver-major. PR-URL: https://github.com/nodejs/node/pull/33084 Reviewed-By: Gireesh Punathil Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node_worker.cc | 30 +++++++++++++++++------------- src/node_worker.h | 7 +++++-- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/node_worker.cc b/src/node_worker.cc index 913b5e3a8bd306..2043d84490b6aa 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -131,9 +131,7 @@ class WorkerThreadData { if (ret != 0) { char err_buf[128]; uv_err_name_r(ret, err_buf, sizeof(err_buf)); - w->custom_error_ = "ERR_WORKER_INIT_FAILED"; - w->custom_error_str_ = err_buf; - w->stopped_ = true; + w->Exit(1, "ERR_WORKER_INIT_FAILED", err_buf); return; } loop_init_failed_ = false; @@ -148,9 +146,9 @@ class WorkerThreadData { Isolate* isolate = Isolate::Allocate(); if (isolate == nullptr) { - w->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; - w->custom_error_str_ = "Failed to create new Isolate"; - w->stopped_ = true; + // TODO(addaleax): This should be ERR_WORKER_INIT_FAILED, + // ERR_WORKER_OUT_OF_MEMORY is for reaching the per-Worker heap limit. + w->Exit(1, "ERR_WORKER_OUT_OF_MEMORY", "Failed to create new Isolate"); return; } @@ -233,9 +231,7 @@ class WorkerThreadData { size_t Worker::NearHeapLimit(void* data, size_t current_heap_limit, size_t initial_heap_limit) { Worker* worker = static_cast(data); - worker->custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; - worker->custom_error_str_ = "JS heap out of memory"; - worker->Exit(1); + worker->Exit(1, "ERR_WORKER_OUT_OF_MEMORY", "JS heap out of memory"); // Give the current GC some extra leeway to let it finish rather than // crash hard. We are not going to perform further allocations anyway. constexpr size_t kExtraHeapAllowance = 16 * 1024 * 1024; @@ -292,8 +288,9 @@ void Worker::Run() { TryCatch try_catch(isolate_); context = NewContext(isolate_); if (context.IsEmpty()) { - custom_error_ = "ERR_WORKER_OUT_OF_MEMORY"; - custom_error_str_ = "Failed to create new Context"; + // TODO(addaleax): This should be ERR_WORKER_INIT_FAILED, + // ERR_WORKER_OUT_OF_MEMORY is for reaching the per-Worker heap limit. + Exit(1, "ERR_WORKER_OUT_OF_MEMORY", "Failed to create new Context"); return; } } @@ -682,9 +679,16 @@ Local Worker::GetResourceLimits(Isolate* isolate) const { return Float64Array::New(ab, 0, kTotalResourceLimitCount); } -void Worker::Exit(int code) { +void Worker::Exit(int code, const char* error_code, const char* error_message) { Mutex::ScopedLock lock(mutex_); - Debug(this, "Worker %llu called Exit(%d)", thread_id_.id, code); + Debug(this, "Worker %llu called Exit(%d, %s, %s)", + thread_id_.id, code, error_code, error_message); + + if (error_code != nullptr) { + custom_error_ = error_code; + custom_error_str_ = error_message; + } + if (env_ != nullptr) { exit_code_ = code; Stop(env_); diff --git a/src/node_worker.h b/src/node_worker.h index b962e5757a6f75..f9deaa59b4a8cc 100644 --- a/src/node_worker.h +++ b/src/node_worker.h @@ -34,8 +34,11 @@ class Worker : public AsyncWrap { void Run(); // Forcibly exit the thread with a specified exit code. This may be called - // from any thread. - void Exit(int code); + // from any thread. `error_code` and `error_message` can be used to create + // a custom `'error'` event before emitting `'exit'`. + void Exit(int code, + const char* error_code = nullptr, + const char* error_message = nullptr); // Wait for the worker thread to stop (in a blocking manner). void JoinThread(); From bc9e413dae9968a7ac0d969a5e7e369fba66243c Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 27 Apr 2020 03:41:56 +0200 Subject: [PATCH 29/62] worker: add stack size resource limit option Add `stackSizeMb` to the `resourceLimit` option group. Refs: https://github.com/nodejs/node/pull/31593#issuecomment-619633820 PR-URL: https://github.com/nodejs/node/pull/33085 Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- doc/api/worker_threads.md | 4 ++ lib/internal/worker.js | 6 ++- src/node_worker.cc | 20 ++++++-- src/node_worker.h | 3 +- test/parallel/test-worker-resource-limits.js | 1 + .../test-worker-stack-overflow-stack-size.js | 47 +++++++++++++------ 6 files changed, 61 insertions(+), 20 deletions(-) diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 2d6c3c23940cf2..d70b63bd98558c 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -174,6 +174,7 @@ added: * `maxYoungGenerationSizeMb` {number} * `maxOldGenerationSizeMb` {number} * `codeRangeSizeMb` {number} + * `stackSizeMb` {number} Provides the set of JS engine resource constraints inside this Worker thread. If the `resourceLimits` option was passed to the [`Worker`][] constructor, @@ -584,6 +585,8 @@ changes: recently created objects. * `codeRangeSizeMb` {number} The size of a pre-allocated memory range used for generated code. + * `stackSizeMb` {number} The default maximum stack size for the thread. + Small values may lead to unusable Worker instances. **Default:** `4`. ### Event: `'error'` * `iterable` {Iterable} Object implementing the `Symbol.asyncIterator` or - `Symbol.iterator` iterable protocol. + `Symbol.iterator` iterable protocol. Emits an 'error' event if a null + value is passed. * `options` {Object} Options provided to `new stream.Readable([options])`. By default, `Readable.from()` will set `options.objectMode` to `true`, unless this is explicitly opted out by setting `options.objectMode` to `false`. diff --git a/lib/internal/streams/from.js b/lib/internal/streams/from.js index ca567914bbf0fe..6752679ae3bc2b 100644 --- a/lib/internal/streams/from.js +++ b/lib/internal/streams/from.js @@ -7,7 +7,8 @@ const { const { Buffer } = require('buffer'); const { - ERR_INVALID_ARG_TYPE + ERR_INVALID_ARG_TYPE, + ERR_STREAM_NULL_VALUES } = require('internal/errors').codes; function from(Readable, iterable, opts) { @@ -73,15 +74,20 @@ function from(Readable, iterable, opts) { needToClose = false; const { value, done } = await iterator.next(); needToClose = !done; - const resolved = await value; if (done) { readable.push(null); } else if (readable.destroyed) { await close(); - } else if (readable.push(resolved)) { - next(); } else { - reading = false; + const res = await value; + if (res === null) { + reading = false; + throw new ERR_STREAM_NULL_VALUES(); + } else if (readable.push(res)) { + next(); + } else { + reading = false; + } } } catch (err) { readable.destroy(err); diff --git a/test/parallel/test-readable-from-iterator-closing.js b/test/parallel/test-readable-from-iterator-closing.js index 0254ccfc163093..02252ffe56854c 100644 --- a/test/parallel/test-readable-from-iterator-closing.js +++ b/test/parallel/test-readable-from-iterator-closing.js @@ -168,18 +168,17 @@ async function closeAfterNullYielded() { const finallyMustCall = mustCall(); const dataMustCall = mustCall(3); - function* infiniteGenerate() { + function* generate() { try { yield 'a'; yield 'a'; yield 'a'; - while (true) yield null; } finally { finallyMustCall(); } } - const stream = Readable.from(infiniteGenerate()); + const stream = Readable.from(generate()); stream.on('data', (chunk) => { dataMustCall(); diff --git a/test/parallel/test-stream-readable-next-no-null.js b/test/parallel/test-stream-readable-next-no-null.js new file mode 100644 index 00000000000000..64ca40be11ed03 --- /dev/null +++ b/test/parallel/test-stream-readable-next-no-null.js @@ -0,0 +1,19 @@ +'use strict'; +const { mustNotCall, expectsError } = require('../common'); +const { Readable } = require('stream'); + +async function* generate() { + yield null; +} + +const stream = Readable.from(generate()); + +stream.on('error', expectsError({ + code: 'ERR_STREAM_NULL_VALUES', + name: 'TypeError', + message: 'May not write null values to stream' +})); + +stream.on('data', mustNotCall((chunk) => {})); + +stream.on('end', mustNotCall()); From 23962191c134cd389bab7beefe93735c60ccc3e3 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 27 Apr 2020 02:17:28 -0400 Subject: [PATCH 31/62] doc: correct Nodejs to Node.js spelling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/33088 Reviewed-By: Trivikram Kamat Reviewed-By: Myles Borins Reviewed-By: Zeyu Yang Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: Juan José Arboleda Reviewed-By: James M Snell Reviewed-By: Rich Trott --- doc/guides/diagnostic-tooling-support-tiers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guides/diagnostic-tooling-support-tiers.md b/doc/guides/diagnostic-tooling-support-tiers.md index 254f90ecadd5fd..5d935a29369a88 100644 --- a/doc/guides/diagnostic-tooling-support-tiers.md +++ b/doc/guides/diagnostic-tooling-support-tiers.md @@ -25,7 +25,7 @@ the following tiers. * The tool must have a guide or other documentation in the Node.js GitHub organization or website; * The tool must be working on all supported platforms; - * The tool must only be using APIs exposed by Nodejs as opposed to + * The tool must only be using APIs exposed by Node.js as opposed to its dependencies; and * The tool must be open source. From 541ea035bf1cd62ad107c58f817c2145ce82243d Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Apr 2020 13:09:56 -0700 Subject: [PATCH 32/62] src: separate out NgLibMemoryManagerBase Extracted from the [QUIC PR](https://github.com/nodejs/node/pull/32379) So far, this is only used by the QUIC PR directly but the change itself is independent of QUIC, even if not used directly by anything else yet. Separated out per request. Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/33104 Reviewed-By: Anna Henningsen Reviewed-By: Sam Roberts --- src/node_mem.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/node_mem.h b/src/node_mem.h index 0d3388ad4766bb..f8cdc20848f82e 100644 --- a/src/node_mem.h +++ b/src/node_mem.h @@ -13,8 +13,12 @@ namespace mem { // use different struct names. To allow for code re-use, // the NgLibMemoryManager template class can be used for both. +struct NgLibMemoryManagerBase { + virtual void StopTrackingMemory(void* ptr) = 0; +}; + template -class NgLibMemoryManager { +class NgLibMemoryManager : public NgLibMemoryManagerBase { public: // Class needs to provide these methods: // void CheckAllocatedSize(size_t previous_size) const; @@ -24,7 +28,7 @@ class NgLibMemoryManager { AllocatorStructName MakeAllocator(); - void StopTrackingMemory(void* ptr); + void StopTrackingMemory(void* ptr) override; private: static void* ReallocImpl(void* ptr, size_t size, void* user_data); From eab4be1b93de7946cd2819c7a4c47b0438fdb2e3 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Apr 2020 13:20:52 -0700 Subject: [PATCH 33/62] lib: cosmetic change to builtinLibs list for maintainability This is a largely cosmetic change suggested for easier maintainability of the builtinLibs list. While the QUIC PR no longer modifies this list, the original version of the PR did and the fact that all of the entries were bundled up into the same lines meant that adding one forced a larger change to all. With this PR, when we want to add a new built-in, it won't impact any of the others. PR-URL: https://github.com/nodejs/node/pull/33106 Reviewed-By: Gus Caplan Reviewed-By: Anna Henningsen --- lib/internal/modules/cjs/helpers.js | 38 +++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js index 2d73219a77772c..2f62c8623e27be 100644 --- a/lib/internal/modules/cjs/helpers.js +++ b/lib/internal/modules/cjs/helpers.js @@ -110,11 +110,39 @@ function stripBOM(content) { } const builtinLibs = [ - 'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'crypto', - 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'http2', 'https', 'net', - 'os', 'path', 'perf_hooks', 'punycode', 'querystring', 'readline', 'repl', - 'stream', 'string_decoder', 'tls', 'trace_events', 'tty', 'url', 'util', - 'v8', 'vm', 'worker_threads', 'zlib' + 'assert', + 'async_hooks', + 'buffer', + 'child_process', + 'cluster', + 'crypto', + 'dgram', + 'dns', + 'domain', + 'events', + 'fs', + 'http', + 'http2', + 'https', + 'net', + 'os', + 'path', + 'perf_hooks', + 'punycode', + 'querystring', + 'readline', + 'repl', + 'stream', + 'string_decoder', + 'tls', + 'trace_events', + 'tty', + 'url', + 'util', + 'v8', + 'vm', + 'worker_threads', + 'zlib', ]; if (internalBinding('config').experimentalWasi) { From f4e5ab14dab70ee35d08727d7ff4825fa33befd0 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Apr 2020 13:40:30 -0700 Subject: [PATCH 34/62] src: crypto::UseSNIContext to use BaseObjectPtr Extracted from the QUIC PR. Not specific to QUIC. Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/33107 Reviewed-By: Anna Henningsen Reviewed-By: Sam Roberts --- src/node_crypto.cc | 2 +- src/node_crypto_common.cc | 3 ++- src/node_crypto_common.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 34b19407c93150..afdb2e3c270348 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2486,7 +2486,7 @@ void SSLWrap::CertCbDone(const FunctionCallbackInfo& args) { // Store the SNI context for later use. w->sni_context_ = BaseObjectPtr(sc); - if (UseSNIContext(w->ssl_, sc) && !w->SetCACerts(sc)) { + if (UseSNIContext(w->ssl_, w->sni_context_) && !w->SetCACerts(sc)) { // Not clear why sometimes we throw error, and sometimes we call // onerror(). Both cause .destroy(), but onerror does a bit more. unsigned long err = ERR_get_error(); // NOLINT(runtime/int) diff --git a/src/node_crypto_common.cc b/src/node_crypto_common.cc index 197bc5cd5913a4..9358edb66b3cb9 100644 --- a/src/node_crypto_common.cc +++ b/src/node_crypto_common.cc @@ -1,3 +1,4 @@ +#include "base_object-inl.h" #include "env-inl.h" #include "node_buffer.h" #include "node_crypto.h" @@ -223,7 +224,7 @@ long VerifyPeerCertificate( // NOLINT(runtime/int) return err; } -int UseSNIContext(const SSLPointer& ssl, SecureContext* context) { +int UseSNIContext(const SSLPointer& ssl, BaseObjectPtr context) { SSL_CTX* ctx = context->ctx_.get(); X509* x509 = SSL_CTX_get0_certificate(ctx); EVP_PKEY* pkey = SSL_CTX_get0_privatekey(ctx); diff --git a/src/node_crypto_common.h b/src/node_crypto_common.h index 8d40052bcca2f9..c373a97e4763a4 100644 --- a/src/node_crypto_common.h +++ b/src/node_crypto_common.h @@ -71,7 +71,7 @@ long VerifyPeerCertificate( // NOLINT(runtime/int) const SSLPointer& ssl, long def = X509_V_ERR_UNSPECIFIED); // NOLINT(runtime/int) -int UseSNIContext(const SSLPointer& ssl, SecureContext* context); +int UseSNIContext(const SSLPointer& ssl, BaseObjectPtr context); const char* GetClientHelloALPN(const SSLPointer& ssl); From f61928ba35422892a1c7225664b660998202fc08 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Apr 2020 13:43:50 -0700 Subject: [PATCH 35/62] src: return undefined when validation err == 0 Extracted from the QUIC PR. Not specific to QUIC even if the behavior is currently only used there. Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/33107 Reviewed-By: Anna Henningsen Reviewed-By: Sam Roberts --- src/node_crypto_common.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/node_crypto_common.cc b/src/node_crypto_common.cc index 9358edb66b3cb9..3b35ee1ff7ba8a 100644 --- a/src/node_crypto_common.cc +++ b/src/node_crypto_common.cc @@ -34,6 +34,7 @@ using v8::NewStringType; using v8::Null; using v8::Object; using v8::String; +using v8::Undefined; using v8::Value; namespace crypto { @@ -330,11 +331,15 @@ const char* X509ErrorCode(long err) { // NOLINT(runtime/int) } MaybeLocal GetValidationErrorReason(Environment* env, int err) { + if (err == 0) + return Undefined(env->isolate()); const char* reason = X509_verify_cert_error_string(err); return OneByteString(env->isolate(), reason); } MaybeLocal GetValidationErrorCode(Environment* env, int err) { + if (err == 0) + return Undefined(env->isolate()); return OneByteString(env->isolate(), X509ErrorCode(err)); } From 3866dc1311a6135d63b74337eee0d341438c30ee Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Apr 2020 02:26:39 +0200 Subject: [PATCH 36/62] wasi: use free() to release preopen array As this is allocated with `Calloc()`, we cannot use `delete[]` here. PR-URL: https://github.com/nodejs/node/pull/33110 Reviewed-By: Colin Ihrig Reviewed-By: Richard Lau Reviewed-By: Gus Caplan Reviewed-By: James M Snell --- src/node_wasi.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node_wasi.cc b/src/node_wasi.cc index f4670ea36f6525..0330656b29e926 100644 --- a/src/node_wasi.cc +++ b/src/node_wasi.cc @@ -236,7 +236,7 @@ void WASI::New(const FunctionCallbackInfo& args) { free(options.preopens[i].real_path); } - delete[] options.preopens; + free(options.preopens); } } From de643bc325cd61b35a8864ccdc985fbb6b201471 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Apr 2020 04:06:09 +0200 Subject: [PATCH 37/62] src: use unique_ptr for CachedData in ContextifyScript::New This closes a memory leak. PR-URL: https://github.com/nodejs/node/pull/33113 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Gus Caplan --- src/node_contextify.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 7926965302161c..34dbdf08420329 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -764,8 +764,8 @@ void ContextifyScript::New(const FunctionCallbackInfo& args) { env->cached_data_rejected_string(), Boolean::New(isolate, source.GetCachedData()->rejected)).Check(); } else if (produce_cached_data) { - const ScriptCompiler::CachedData* cached_data = - ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked()); + std::unique_ptr cached_data { + ScriptCompiler::CreateCodeCache(v8_script.ToLocalChecked()) }; bool cached_data_produced = cached_data != nullptr; if (cached_data_produced) { MaybeLocal buf = Buffer::Copy( From 9ccb6b2e8c1fd78e97bed360b45dfc62448a1962 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Apr 2020 04:49:39 +0200 Subject: [PATCH 38/62] test: add missing calls to napi_async_destroy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/33114 Reviewed-By: Chengzhong Wu Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Gerhard Stöbich --- test/node-api/test_callback_scope/binding.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/node-api/test_callback_scope/binding.cc b/test/node-api/test_callback_scope/binding.cc index 153428a65bd6e4..a8a755a016a7ee 100644 --- a/test/node-api/test_callback_scope/binding.cc +++ b/test/node-api/test_callback_scope/binding.cc @@ -47,6 +47,7 @@ napi_value RunInCallbackScope(napi_env env, napi_callback_info info) { } NAPI_CALL(env, napi_close_callback_scope(env, scope)); + NAPI_CALL(env, napi_async_destroy(env, context)); return result; } @@ -85,6 +86,7 @@ static void Callback(uv_work_t* req, int ignored) { NAPI_CALL_RETURN_VOID(env, napi_close_callback_scope(env, scope)); NAPI_CALL_RETURN_VOID(env, napi_close_handle_scope(env, handle_scope)); + NAPI_CALL_RETURN_VOID(env, napi_async_destroy(env, context)); delete req; } From af7da46d9bae0e3b69f6a7c53317c661cc61c327 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Apr 2020 04:53:52 +0200 Subject: [PATCH 39/62] test: fix out-of-bound reads from invalid sizeof usage `sizeof(data)` does not return the correct result here, as it measures the size of the `data` variable, not what it points to. PR-URL: https://github.com/nodejs/node/pull/33115 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/addons/worker-buffer-callback/binding.cc | 2 +- .../test_worker_buffer_callback/test_worker_buffer_callback.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/addons/worker-buffer-callback/binding.cc b/test/addons/worker-buffer-callback/binding.cc index f600f410c1ed18..ac4c0cb498b7c7 100644 --- a/test/addons/worker-buffer-callback/binding.cc +++ b/test/addons/worker-buffer-callback/binding.cc @@ -30,7 +30,7 @@ void Initialize(Local exports, node::Buffer::New( isolate, data, - sizeof(data), + sizeof(char), [](char* data, void* hint) { delete data; free_call_count++; diff --git a/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c b/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c index 3275551aee526a..b4f2e288ece31b 100644 --- a/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c +++ b/test/node-api/test_worker_buffer_callback/test_worker_buffer_callback.c @@ -35,7 +35,7 @@ NAPI_MODULE_INIT() { NAPI_CALL(env, napi_create_external_arraybuffer( env, data, - sizeof(data), + sizeof(char), finalize_cb, NULL, &buffer)); From f62d92b900eac7d8603817ea65e95e08678ff840 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 6 Apr 2020 14:17:57 +0200 Subject: [PATCH 40/62] build: add --error-on-warn configure flag This commit adds a configuration time flag named error-on-warn: $ ./configure --help | grep -A1 error-on-warn --error-on-warn Turn compiler warnings into errors for node core sources. The motivation for this is that CI jobs can use this flag to turn warnings into errors. PR-URL: https://github.com/nodejs/node/pull/32685 Reviewed-By: Richard Lau Reviewed-By: Anna Henningsen Reviewed-By: Matheus Marchini --- common.gypi | 10 +++++++++- configure.py | 6 ++++++ node.gyp | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/common.gypi b/common.gypi index fec140bbae983b..2ebabf8f80b38b 100644 --- a/common.gypi +++ b/common.gypi @@ -26,6 +26,7 @@ 'uv_library%': 'static_library', 'clang%': 0, + 'error_on_warn%': 'false', 'openssl_fips%': '', 'openssl_no_asm%': 0, @@ -218,7 +219,14 @@ # Forcibly disable -Werror. We support a wide range of compilers, it's # simply not feasible to squelch all warnings, never mind that the # libraries in deps/ are not under our control. - 'cflags!': ['-Werror'], + 'conditions': [ + [ 'error_on_warn=="false"', { + 'cflags!': ['-Werror'], + }, '(_target_name!="<(node_lib_target_name)" or ' + '_target_name!="<(node_core_target_name)")', { + 'cflags!': ['-Werror'], + }], + ], 'msvs_settings': { 'VCCLCompilerTool': { 'BufferSecurityCheck': 'true', diff --git a/configure.py b/configure.py index 2e7deb5a15ef11..ac26f62916cd06 100755 --- a/configure.py +++ b/configure.py @@ -117,6 +117,11 @@ choices=valid_os, help='operating system to build for ({0})'.format(', '.join(valid_os))) +parser.add_option('--error-on-warn', + action='store_true', + dest='error_on_warn', + help='Turn compiler warnings into errors for node core sources.') + parser.add_option('--gdb', action='store_true', dest='gdb', @@ -1018,6 +1023,7 @@ def configure_node(o): o['variables']['node_install_npm'] = b(not options.without_npm) o['variables']['debug_node'] = b(options.debug_node) o['default_configuration'] = 'Debug' if options.debug else 'Release' + o['variables']['error_on_warn'] = b(options.error_on_warn) host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc() target_arch = options.dest_cpu or host_arch diff --git a/node.gyp b/node.gyp index 2f0f0f152ba8b3..3dadad15c9e193 100644 --- a/node.gyp +++ b/node.gyp @@ -376,6 +376,9 @@ 'msvs_disabled_warnings!': [4244], 'conditions': [ + [ 'error_on_warn=="true"', { + 'cflags': ['-Werror'], + }], [ 'node_intermediate_lib_type=="static_library" and ' 'node_shared=="true" and OS=="aix"', { # For AIX, shared lib is linked by static lib and .exp. In the @@ -750,6 +753,9 @@ 'msvs_disabled_warnings!': [4244], 'conditions': [ + [ 'error_on_warn=="true"', { + 'cflags': ['-Werror'], + }], [ 'node_builtin_modules_path!=""', { 'defines': [ 'NODE_BUILTIN_MODULES_PATH="<(node_builtin_modules_path)"' ] }], From a87d3710148c0d1128e5372a1a8b90edd174a65d Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 6 Apr 2020 14:21:08 +0200 Subject: [PATCH 41/62] tools: fix redundant-move warning in inspector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the following warning is generated from the inspector protocol: /out/Release/obj/gen/src/node/inspector/protocol/Protocol.cpp: In member function ‘virtual std::unique_ptr node::inspector::protocol::ListValue::clone() const’: /out/Release/obj/gen/src/node/inspector/protocol/Protocol.cpp:739:21: error: redundant move in return statement [-Werror=redundant-move] 739 | return std::move(result); | ~~~~~~~~~^~~~~~~~ This commit removes the move for DictionaryValue and ListValue. PR-URL: https://github.com/nodejs/node/pull/32685 Reviewed-By: Richard Lau Reviewed-By: Anna Henningsen Reviewed-By: Matheus Marchini --- tools/inspector_protocol/lib/Values_cpp.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/inspector_protocol/lib/Values_cpp.template b/tools/inspector_protocol/lib/Values_cpp.template index 764b4d37d9a7d5..be3149d50356f2 100644 --- a/tools/inspector_protocol/lib/Values_cpp.template +++ b/tools/inspector_protocol/lib/Values_cpp.template @@ -606,7 +606,7 @@ std::unique_ptr DictionaryValue::clone() const DCHECK(value != m_data.cend() && value->second); result->setValue(key, value->second->clone()); } - return std::move(result); + return result; } DictionaryValue::DictionaryValue() @@ -647,7 +647,7 @@ std::unique_ptr ListValue::clone() const std::unique_ptr result = ListValue::create(); for (const std::unique_ptr& value : m_data) result->pushValue(value->clone()); - return std::move(result); + return result; } ListValue::ListValue() From 5eccf1e9adb60da962d43daacc4cd9311bb64aeb Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 26 Apr 2020 21:40:01 -0700 Subject: [PATCH 42/62] module: no type module resolver side effects PR-URL: https://github.com/nodejs/node/pull/33086 Reviewed-By: Jan Krems Reviewed-By: Geoffrey Booth --- doc/api/esm.md | 7 ------- lib/internal/modules/esm/resolve.js | 9 +-------- test/es-module/test-esm-type-main.mjs | 9 +++++++++ test/fixtures/node_modules/type-main/index.js | 1 + test/fixtures/node_modules/type-main/package.json | 4 ++++ 5 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 test/es-module/test-esm-type-main.mjs create mode 100644 test/fixtures/node_modules/type-main/index.js create mode 100644 test/fixtures/node_modules/type-main/package.json diff --git a/doc/api/esm.md b/doc/api/esm.md index 49c467effbc3cd..5047600f988f66 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1601,13 +1601,6 @@ The resolver can throw the following errors: > 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, > _mainExport_, _""_). > 1. Throw a _Package Path Not Exported_ error. -> 1. If _pjson.main_ is a String, then -> 1. Let _resolvedMain_ be the URL resolution of _packageURL_, "/", and -> _pjson.main_. -> 1. If the file at _resolvedMain_ exists, then -> 1. Return _resolvedMain_. -> 1. If _pjson.type_ is equal to _"module"_, then -> 1. Throw a _Module Not Found_ error. > 1. Let _legacyMainURL_ be the result applying the legacy > **LOAD_AS_DIRECTORY** CommonJS resolver to _packageURL_, throwing a > _Module Not Found_ error for no resolution. diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index 5bb2f37e53eeb5..8b8582544494a5 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -439,11 +439,6 @@ function packageMainResolve(packageJSONUrl, packageConfig, base, conditions) { throw new ERR_PACKAGE_PATH_NOT_EXPORTED(packageJSONUrl, '.'); } - if (packageConfig.main !== undefined) { - const resolved = new URL(packageConfig.main, packageJSONUrl); - const path = fileURLToPath(resolved); - if (tryStatSync(path).isFile()) return resolved; - } if (getOptionValue('--experimental-specifier-resolution') === 'node') { if (packageConfig.main !== undefined) { return finalizeResolution( @@ -453,9 +448,7 @@ function packageMainResolve(packageJSONUrl, packageConfig, base, conditions) { new URL('index', packageJSONUrl), base); } } - if (packageConfig.type !== 'module') { - return legacyMainResolve(packageJSONUrl, packageConfig); - } + return legacyMainResolve(packageJSONUrl, packageConfig); } throw new ERR_MODULE_NOT_FOUND( diff --git a/test/es-module/test-esm-type-main.mjs b/test/es-module/test-esm-type-main.mjs new file mode 100644 index 00000000000000..012cf4f35fc959 --- /dev/null +++ b/test/es-module/test-esm-type-main.mjs @@ -0,0 +1,9 @@ +import { mustNotCall } from '../common/index.mjs'; +import assert from 'assert'; +import { importFixture } from '../fixtures/pkgexports.mjs'; + +(async () => { + const m = await importFixture('type-main'); + assert.strictEqual(m.default, 'asdf'); +})() +.catch(mustNotCall); diff --git a/test/fixtures/node_modules/type-main/index.js b/test/fixtures/node_modules/type-main/index.js new file mode 100644 index 00000000000000..a4cb53964349f5 --- /dev/null +++ b/test/fixtures/node_modules/type-main/index.js @@ -0,0 +1 @@ +export default 'asdf'; diff --git a/test/fixtures/node_modules/type-main/package.json b/test/fixtures/node_modules/type-main/package.json new file mode 100644 index 00000000000000..7665d7a8037428 --- /dev/null +++ b/test/fixtures/node_modules/type-main/package.json @@ -0,0 +1,4 @@ +{ + "main": "index", + "type": "module" +} From 4cfa7e07161da1d1f164fcff9f288e1d653a872a Mon Sep 17 00:00:00 2001 From: himself65 Date: Fri, 17 Apr 2020 15:04:38 +0800 Subject: [PATCH 43/62] stream: simplify Readable push/unshift logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/32899 Reviewed-By: Robert Nagy Reviewed-By: Luigi Pinca Reviewed-By: Ruben Bridgewater Reviewed-By: Juan José Arboleda Reviewed-By: James M Snell --- lib/_stream_readable.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index ec9f86d7eacf4a..f39c49867805d3 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -230,13 +230,15 @@ function readableAddChunk(stream, chunk, encoding, addToFront) { if (!state.objectMode) { if (typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; - if (addToFront && state.encoding && state.encoding !== encoding) { - // When unshifting, if state.encoding is set, we have to save - // the string in the BufferList with the state encoding. - chunk = Buffer.from(chunk, encoding).toString(state.encoding); - } else if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; + if (state.encoding !== encoding) { + if (addToFront && state.encoding) { + // When unshifting, if state.encoding is set, we have to save + // the string in the BufferList with the state encoding. + chunk = Buffer.from(chunk, encoding).toString(state.encoding); + } else { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } } } else if (chunk instanceof Buffer) { encoding = ''; From d39254ada6dd7fc5b5099f5601b1e4522cb9014f Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Wed, 22 Apr 2020 10:28:20 +0800 Subject: [PATCH 44/62] vm: fix vm.measureMemory() and introduce execution option https://github.com/nodejs/node-v8/pull/147 broke the `vm.measureMemory()` API. It only created a `MeasureMemoryDelegate` and without actually calling `v8::Isolate::MeasureMemory()` so the returned promise will never resolve. This was not caught by the tests because the promise resolvers were not wrapped with `common.mustCall()`. This patch migrates the API properly and also introduce the newly added execution option to the API. It also removes support for specifying contexts to measure - instead we'll just return the measurements for all contexts in the detailed mode, which is what the `performance.measureMemory()` prototype in V8 currently does. We can consider implementing our own `v8::MeasureMemoryDelegate` to select the target context in `ShouldMeasure()` in the future, but then we'll also need to implement `MeasurementComplete()` to assemble the result. For now it's probably too early to do that. Since this API is still experimental (and guarded with a warning), such breakage should be acceptable. Refs: https://github.com/nodejs/node-v8/pull/147 PR-URL: https://github.com/nodejs/node/pull/32988 Reviewed-By: Ben Noordhuis Reviewed-By: Jiawen Geng Reviewed-By: James M Snell --- doc/api/vm.md | 62 ++++++++++++------ lib/vm.js | 17 +++-- src/node_contextify.cc | 58 +++++++++-------- test/common/measure-memory.js | 57 +++++++++++++++++ test/parallel/test-vm-measure-memory-lazy.js | 37 +++++++++++ .../test-vm-measure-memory-multi-context.js | 28 ++++++++ test/parallel/test-vm-measure-memory.js | 64 +++++-------------- 7 files changed, 226 insertions(+), 97 deletions(-) create mode 100644 test/common/measure-memory.js create mode 100644 test/parallel/test-vm-measure-memory-lazy.js create mode 100644 test/parallel/test-vm-measure-memory-multi-context.js diff --git a/doc/api/vm.md b/doc/api/vm.md index f45b5373683029..6411419e549760 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -303,15 +303,21 @@ added: v13.10.0 > Stability: 1 - Experimental -Measure the memory known to V8 and used by the current execution context -or a specified context. +Measure the memory known to V8 and used by all contexts known to the +current V8 isolate, or the main context. * `options` {Object} Optional. - * `mode` {string} Either `'summary'` or `'detailed'`. + * `mode` {string} Either `'summary'` or `'detailed'`. In summary mode, + only the memory measured for the main context will be returned. In + detailed mode, the measure measured for all contexts known to the + current V8 isolate will be returned. **Default:** `'summary'` - * `context` {Object} Optional. A [contextified][] object returned - by `vm.createContext()`. If not specified, measure the memory - usage of the current context where `vm.measureMemory()` is invoked. + * `execution` {string} Either `'default'` or `'eager'`. With default + execution, the promise will not resolve until after the next scheduled + garbage collection starts, which may take a while (or never if the program + exits before the next GC). With eager execution, the GC will be started + right away to measure the memory. + **Default:** `'default'` * Returns: {Promise} If the memory is successfully measured the promise will resolve with an object containing information about the memory usage. @@ -319,28 +325,48 @@ The format of the object that the returned Promise may resolve with is specific to the V8 engine and may change from one version of V8 to the next. The returned result is different from the statistics returned by -`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measures -the memory reachable by V8 from a specific context, while -`v8.getHeapSpaceStatistics()` measures the memory used by an instance -of V8 engine, which can switch among multiple contexts that reference -objects in the heap of one engine. +`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the +memory reachable by each V8 specific contexts in the current instance of +the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure +the memory occupied by each heap space in the current V8 instance. ```js const vm = require('vm'); -// Measure the memory used by the current context and return the result -// in summary. +// Measure the memory used by the main context. vm.measureMemory({ mode: 'summary' }) - // Is the same as vm.measureMemory() + // This is the same as vm.measureMemory() .then((result) => { // The current format is: - // { total: { jsMemoryEstimate: 2211728, jsMemoryRange: [ 0, 2211728 ] } } + // { + // total: { + // jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ] + // } + // } console.log(result); }); -const context = vm.createContext({}); -vm.measureMemory({ mode: 'detailed' }, context) +const context = vm.createContext({ a: 1 }); +vm.measureMemory({ mode: 'detailed', execution: 'eager' }) .then((result) => { - // At the moment the detailed format is the same as the summary one. + // Reference the context here so that it won't be GC'ed + // until the measurement is complete. + console.log(context.a); + // { + // total: { + // jsMemoryEstimate: 2574732, + // jsMemoryRange: [ 2574732, 2904372 ] + // }, + // current: { + // jsMemoryEstimate: 2438996, + // jsMemoryRange: [ 2438996, 2768636 ] + // }, + // other: [ + // { + // jsMemoryEstimate: 135736, + // jsMemoryRange: [ 135736, 465376 ] + // } + // ] + // } console.log(result); }); ``` diff --git a/lib/vm.js b/lib/vm.js index cffca355720dae..fd81e9da8b0515 100644 --- a/lib/vm.js +++ b/lib/vm.js @@ -385,20 +385,27 @@ const measureMemoryModes = { detailed: constants.measureMemory.mode.DETAILED, }; +const measureMemoryExecutions = { + default: constants.measureMemory.execution.DEFAULT, + eager: constants.measureMemory.execution.EAGER, +}; + function measureMemory(options = {}) { emitExperimentalWarning('vm.measureMemory'); validateObject(options, 'options'); - const { mode = 'summary', context } = options; + const { mode = 'summary', execution = 'default' } = options; if (mode !== 'summary' && mode !== 'detailed') { throw new ERR_INVALID_ARG_VALUE( 'options.mode', options.mode, 'must be either \'summary\' or \'detailed\''); } - if (context !== undefined && - (typeof context !== 'object' || context === null || !_isContext(context))) { - throw new ERR_INVALID_ARG_TYPE('options.context', 'vm.Context', context); + if (execution !== 'default' && execution !== 'eager') { + throw new ERR_INVALID_ARG_VALUE( + 'options.execution', options.execution, + 'must be either \'default\' or \'eager\''); } - const result = _measureMemory(measureMemoryModes[mode], context); + const result = _measureMemory(measureMemoryModes[mode], + measureMemoryExecutions[execution]); if (result === undefined) { return PromiseReject(new ERR_CONTEXT_NOT_INITIALIZED()); } diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 34dbdf08420329..99adccbcef9d64 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -53,6 +53,7 @@ using v8::Isolate; using v8::Local; using v8::Maybe; using v8::MaybeLocal; +using v8::MeasureMemoryExecution; using v8::MeasureMemoryMode; using v8::Name; using v8::NamedPropertyHandlerConfiguration; @@ -1211,29 +1212,22 @@ static void WatchdogHasPendingSigint(const FunctionCallbackInfo& args) { static void MeasureMemory(const FunctionCallbackInfo& args) { CHECK(args[0]->IsInt32()); + CHECK(args[1]->IsInt32()); int32_t mode = args[0].As()->Value(); + int32_t execution = args[1].As()->Value(); Isolate* isolate = args.GetIsolate(); - Environment* env = Environment::GetCurrent(args); - Local context; - if (args[1]->IsUndefined()) { - context = isolate->GetCurrentContext(); - } else { - CHECK(args[1]->IsObject()); - ContextifyContext* sandbox = - ContextifyContext::ContextFromContextifiedSandbox(env, - args[1].As()); - CHECK_NOT_NULL(sandbox); - context = sandbox->context(); - if (context.IsEmpty()) { // Not yet fully initialized - return; - } - } + + Local current_context = isolate->GetCurrentContext(); Local resolver; - if (!Promise::Resolver::New(context).ToLocal(&resolver)) return; - std::unique_ptr i = + if (!Promise::Resolver::New(current_context).ToLocal(&resolver)) return; + std::unique_ptr delegate = v8::MeasureMemoryDelegate::Default( - isolate, context, resolver, static_cast(mode)); - CHECK_NOT_NULL(i); + isolate, + current_context, + resolver, + static_cast(mode)); + isolate->MeasureMemory(std::move(delegate), + static_cast(execution)); v8::Local promise = resolver->GetPromise(); args.GetReturnValue().Set(promise); @@ -1265,13 +1259,27 @@ void Initialize(Local target, Local constants = Object::New(env->isolate()); Local measure_memory = Object::New(env->isolate()); - Local memory_mode = Object::New(env->isolate()); - MeasureMemoryMode SUMMARY = MeasureMemoryMode::kSummary; - MeasureMemoryMode DETAILED = MeasureMemoryMode::kDetailed; - NODE_DEFINE_CONSTANT(memory_mode, SUMMARY); - NODE_DEFINE_CONSTANT(memory_mode, DETAILED); - READONLY_PROPERTY(measure_memory, "mode", memory_mode); + Local memory_execution = Object::New(env->isolate()); + + { + Local memory_mode = Object::New(env->isolate()); + MeasureMemoryMode SUMMARY = MeasureMemoryMode::kSummary; + MeasureMemoryMode DETAILED = MeasureMemoryMode::kDetailed; + NODE_DEFINE_CONSTANT(memory_mode, SUMMARY); + NODE_DEFINE_CONSTANT(memory_mode, DETAILED); + READONLY_PROPERTY(measure_memory, "mode", memory_mode); + } + + { + MeasureMemoryExecution DEFAULT = MeasureMemoryExecution::kDefault; + MeasureMemoryExecution EAGER = MeasureMemoryExecution::kEager; + NODE_DEFINE_CONSTANT(memory_execution, DEFAULT); + NODE_DEFINE_CONSTANT(memory_execution, EAGER); + READONLY_PROPERTY(measure_memory, "execution", memory_execution); + } + READONLY_PROPERTY(constants, "measureMemory", measure_memory); + target->Set(context, env->constants_string(), constants).Check(); env->SetMethod(target, "measureMemory", MeasureMemory); diff --git a/test/common/measure-memory.js b/test/common/measure-memory.js new file mode 100644 index 00000000000000..67c8fb3b9d2d67 --- /dev/null +++ b/test/common/measure-memory.js @@ -0,0 +1,57 @@ +/* eslint-disable node-core/require-common-first, node-core/required-modules */ +'use strict'; + +const assert = require('assert'); +const common = require('./'); + +// The formats could change when V8 is updated, then the tests should be +// updated accordingly. +function assertResultShape(result) { + assert.strictEqual(typeof result.jsMemoryEstimate, 'number'); + assert.strictEqual(typeof result.jsMemoryRange[0], 'number'); + assert.strictEqual(typeof result.jsMemoryRange[1], 'number'); +} + +function assertSummaryShape(result) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.total, 'object'); + assertResultShape(result.total); +} + +function assertDetailedShape(result, contexts = 0) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.total, 'object'); + assert.strictEqual(typeof result.current, 'object'); + assertResultShape(result.total); + assertResultShape(result.current); + if (contexts === 0) { + assert.deepStrictEqual(result.other, []); + } else { + assert.strictEqual(result.other.length, contexts); + for (const item of result.other) { + assertResultShape(item); + } + } +} + +function assertSingleDetailedShape(result) { + assert.strictEqual(typeof result, 'object'); + assert.strictEqual(typeof result.total, 'object'); + assert.strictEqual(typeof result.current, 'object'); + assert.deepStrictEqual(result.other, []); + assertResultShape(result.total); + assertResultShape(result.current); +} + +function expectExperimentalWarning() { + common.expectWarning('ExperimentalWarning', + 'vm.measureMemory is an experimental feature. ' + + 'This feature could change at any time'); +} + +module.exports = { + assertSummaryShape, + assertDetailedShape, + assertSingleDetailedShape, + expectExperimentalWarning +}; diff --git a/test/parallel/test-vm-measure-memory-lazy.js b/test/parallel/test-vm-measure-memory-lazy.js new file mode 100644 index 00000000000000..513cfbc3672451 --- /dev/null +++ b/test/parallel/test-vm-measure-memory-lazy.js @@ -0,0 +1,37 @@ +// Flags: --expose-gc + +'use strict'; +const common = require('../common'); +const { + assertSummaryShape, + expectExperimentalWarning +} = require('../common/measure-memory'); +const vm = require('vm'); + +expectExperimentalWarning(); + +// Test lazy memory measurement - we will need to global.gc() +// or otherwise these may not resolve. +{ + vm.measureMemory() + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} + +{ + vm.measureMemory({}) + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} + +{ + vm.measureMemory({ mode: 'summary' }) + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} + +{ + vm.measureMemory({ mode: 'detailed' }) + .then(common.mustCall(assertSummaryShape)); + global.gc(); +} diff --git a/test/parallel/test-vm-measure-memory-multi-context.js b/test/parallel/test-vm-measure-memory-multi-context.js new file mode 100644 index 00000000000000..3a3065a8edb631 --- /dev/null +++ b/test/parallel/test-vm-measure-memory-multi-context.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +const { + assertDetailedShape, + expectExperimentalWarning +} = require('../common/measure-memory'); +const vm = require('vm'); +const assert = require('assert'); + +expectExperimentalWarning(); +{ + const arr = []; + const count = 10; + for (let i = 0; i < count; ++i) { + const context = vm.createContext({ + test: new Array(100).fill('foo') + }); + arr.push(context); + } + // Check that one more context shows up in the result + vm.measureMemory({ mode: 'detailed', execution: 'eager' }) + .then(common.mustCall((result) => { + // We must hold on to the contexts here so that they + // don't get GC'ed until the measurement is complete + assert.strictEqual(arr.length, count); + assertDetailedShape(result, count); + })); +} diff --git a/test/parallel/test-vm-measure-memory.js b/test/parallel/test-vm-measure-memory.js index 7e620304e0a276..6b18db9be7a714 100644 --- a/test/parallel/test-vm-measure-memory.js +++ b/test/parallel/test-vm-measure-memory.js @@ -1,42 +1,25 @@ 'use strict'; const common = require('../common'); +const { + assertSummaryShape, + assertSingleDetailedShape, + expectExperimentalWarning +} = require('../common/measure-memory'); const assert = require('assert'); const vm = require('vm'); -common.expectWarning('ExperimentalWarning', - 'vm.measureMemory is an experimental feature. ' + - 'This feature could change at any time'); +expectExperimentalWarning(); -// The formats could change when V8 is updated, then the tests should be -// updated accordingly. -function assertSummaryShape(result) { - assert.strictEqual(typeof result, 'object'); - assert.strictEqual(typeof result.total, 'object'); - assert.strictEqual(typeof result.total.jsMemoryEstimate, 'number'); - assert(Array.isArray(result.total.jsMemoryRange)); - assert.strictEqual(typeof result.total.jsMemoryRange[0], 'number'); - assert.strictEqual(typeof result.total.jsMemoryRange[1], 'number'); -} - -function assertDetailedShape(result) { - // For now, the detailed shape is the same as the summary shape. This - // should change in future versions of V8. - return assertSummaryShape(result); -} - -// Test measuring memory of the current context +// Test eager memory measurement { - vm.measureMemory() - .then(assertSummaryShape); + vm.measureMemory({ execution: 'eager' }) + .then(common.mustCall(assertSummaryShape)); - vm.measureMemory({}) - .then(assertSummaryShape); + vm.measureMemory({ mode: 'detailed', execution: 'eager' }) + .then(common.mustCall(assertSingleDetailedShape)); - vm.measureMemory({ mode: 'summary' }) - .then(assertSummaryShape); - - vm.measureMemory({ mode: 'detailed' }) - .then(assertDetailedShape); + vm.measureMemory({ mode: 'summary', execution: 'eager' }) + .then(common.mustCall(assertSummaryShape)); assert.throws(() => vm.measureMemory(null), { code: 'ERR_INVALID_ARG_TYPE' @@ -47,24 +30,7 @@ function assertDetailedShape(result) { assert.throws(() => vm.measureMemory({ mode: 'random' }), { code: 'ERR_INVALID_ARG_VALUE' }); -} - -// Test measuring memory of the sandbox -{ - const context = vm.createContext(); - vm.measureMemory({ context }) - .then(assertSummaryShape); - - vm.measureMemory({ mode: 'summary', context },) - .then(assertSummaryShape); - - vm.measureMemory({ mode: 'detailed', context }) - .then(assertDetailedShape); - - assert.throws(() => vm.measureMemory({ mode: 'summary', context: null }), { - code: 'ERR_INVALID_ARG_TYPE' - }); - assert.throws(() => vm.measureMemory({ mode: 'summary', context: {} }), { - code: 'ERR_INVALID_ARG_TYPE' + assert.throws(() => vm.measureMemory({ execution: 'random' }), { + code: 'ERR_INVALID_ARG_VALUE' }); } From 45032a39e8b713e55e4eb91774b33b1c4f950fbe Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Tue, 28 Apr 2020 19:36:23 +0200 Subject: [PATCH 45/62] stream: fix stream.finished on Duplex finished would incorrectly believe that a Duplex is already closed if either the readable or writable side has completed. Fixes: https://github.com/nodejs/node/issues/33130 PR-URL: https://github.com/nodejs/node/pull/33133 Reviewed-By: Anna Henningsen Reviewed-By: Matteo Collina --- lib/internal/streams/end-of-stream.js | 16 +++-- test/parallel/test-stream-finished.js | 86 ++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/lib/internal/streams/end-of-stream.js b/lib/internal/streams/end-of-stream.js index 7d5689ddadb7fc..bc2d0ccfcaf142 100644 --- a/lib/internal/streams/end-of-stream.js +++ b/lib/internal/streams/end-of-stream.js @@ -147,10 +147,17 @@ function eos(stream, opts, callback) { if (opts.error !== false) stream.on('error', onerror); stream.on('close', onclose); - const closed = (wState && wState.closed) || (rState && rState.closed) || - (wState && wState.errorEmitted) || (rState && rState.errorEmitted) || - (wState && wState.finished) || (rState && rState.endEmitted) || - (rState && stream.req && stream.aborted); + const closed = ( + (wState && wState.closed) || + (rState && rState.closed) || + (wState && wState.errorEmitted) || + (rState && rState.errorEmitted) || + (rState && stream.req && stream.aborted) || + ( + (!writable || (wState && wState.finished)) && + (!readable || (rState && rState.endEmitted)) + ) + ); if (closed) { // TODO(ronag): Re-throw error if errorEmitted? @@ -158,6 +165,7 @@ function eos(stream, opts, callback) { // before being closed? i.e. if closed but not errored, ended or finished. // TODO(ronag): Throw some kind of error? Does it make sense // to call finished() on a "finished" stream? + // TODO(ronag): willEmitClose? process.nextTick(() => { callback(); }); diff --git a/test/parallel/test-stream-finished.js b/test/parallel/test-stream-finished.js index d4336e84db35d6..4622d2c695e1fa 100644 --- a/test/parallel/test-stream-finished.js +++ b/test/parallel/test-stream-finished.js @@ -1,7 +1,14 @@ 'use strict'; const common = require('../common'); -const { Writable, Readable, Transform, finished, Duplex } = require('stream'); +const { + Writable, + Readable, + Transform, + finished, + Duplex, + PassThrough +} = require('stream'); const assert = require('assert'); const EE = require('events'); const fs = require('fs'); @@ -396,3 +403,80 @@ testClosed((opts) => new Writable({ write() {}, ...opts })); r.destroyed = true; r.push(null); } + +{ + // Regression https://github.com/nodejs/node/issues/33130 + const response = new PassThrough(); + + class HelloWorld extends Duplex { + constructor(response) { + super({ + autoDestroy: false + }); + + this.response = response; + this.readMore = false; + + response.once('end', () => { + this.push(null); + }); + + response.on('readable', () => { + if (this.readMore) { + this._read(); + } + }); + } + + _read() { + const { response } = this; + + this.readMore = true; + + if (response.readableLength) { + this.readMore = false; + } + + let data; + while ((data = response.read()) !== null) { + this.push(data); + } + } + } + + const instance = new HelloWorld(response); + instance.setEncoding('utf8'); + instance.end(); + + (async () => { + await EE.once(instance, 'finish'); + + setImmediate(() => { + response.write('chunk 1'); + response.write('chunk 2'); + response.write('chunk 3'); + response.end(); + }); + + let res = ''; + for await (const data of instance) { + res += data; + } + + assert.strictEqual(res, 'chunk 1chunk 2chunk 3'); + })().then(common.mustCall()); +} + +{ + const p = new PassThrough(); + p.end(); + finished(p, common.mustNotCall()); +} + +{ + const p = new PassThrough(); + p.end(); + p.on('finish', common.mustCall(() => { + finished(p, common.mustNotCall()); + })); +} From 89ed7a5862d9c34182c1dd4ad8d4f1ee2ec54e86 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Wed, 29 Apr 2020 23:42:30 +0200 Subject: [PATCH 46/62] test: move test-process-title to sequential This test can fail when run in parallel with test-process-title-cli, which also sets the process title, which is global state on Windows. Example failure (note that `foo` does not appear in test-process-title but in test-process-title-cli): not ok 1727 parallel/test-process-title --- duration_ms: 0.156 severity: fail exitcode: 1 stack: |- assert.js:103 throw new AssertionError(obj); ^ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: + actual - expected + 'foo' - 'd:\\a\\node\\node\\out\\Release\\node.exe' at Object. (d:\a\node\node\test\parallel\test-process-title.js:22:1) at Module._compile (internal/modules/cjs/loader.js:1176:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1196:10) at Module.load (internal/modules/cjs/loader.js:1040:32) at Function.Module._load (internal/modules/cjs/loader.js:929:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12) at internal/main/run_main_module.js:17:47 { generatedMessage: true, code: 'ERR_ASSERTION', actual: 'foo', expected: 'd:\\a\\node\\node\\out\\Release\\node.exe', operator: 'strictEqual' } ... (from https://github.com/nodejs/node/runs/628144750?check_suite_focus=true) PR-URL: https://github.com/nodejs/node/pull/33150 Reviewed-By: James M Snell Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Andrey Pechkurov --- test/{parallel => sequential}/test-process-title.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{parallel => sequential}/test-process-title.js (100%) diff --git a/test/parallel/test-process-title.js b/test/sequential/test-process-title.js similarity index 100% rename from test/parallel/test-process-title.js rename to test/sequential/test-process-title.js From c5a4534d5cbec234264c66b506e9661e270a7f5c Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Apr 2020 15:29:48 +0200 Subject: [PATCH 47/62] deps: V8: backport e29c62b74854 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original commit message: [arraybuffer] Clean up BackingStore even if it pointer to nullptr For a zero-length BackingStore allocation, it is valid for the underlying memory to be a null pointer. However, some cleanup is still necessary, since the BackingStore may hold a reference to the allocator itself, which needs to be released when destroying the `BackingStore` instance. Change-Id: I1f168079d39e4592d2fde31fbe5f705586690e85 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2169646 Reviewed-by: Ulan Degenbaev Commit-Queue: Ulan Degenbaev Cr-Commit-Position: refs/heads/master@{#67420} Refs: https://github.com/v8/v8/commit/e29c62b7485462c1ce8f4129b26e7f7a4d4b193c PR-URL: https://github.com/nodejs/node/pull/33125 Reviewed-By: Colin Ihrig Reviewed-By: Michaël Zasso Reviewed-By: Juan José Arboleda --- common.gypi | 2 +- deps/v8/src/objects/backing-store.cc | 5 ++- deps/v8/test/cctest/test-api-array-buffer.cc | 40 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/common.gypi b/common.gypi index 2ebabf8f80b38b..5e4f9b6dba1dce 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.32', + 'v8_embedder_string': '-node.33', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/objects/backing-store.cc b/deps/v8/src/objects/backing-store.cc index 8d604ba35d8d06..c9a5c2e4c8ec20 100644 --- a/deps/v8/src/objects/backing-store.cc +++ b/deps/v8/src/objects/backing-store.cc @@ -164,7 +164,10 @@ void BackingStore::Clear() { BackingStore::~BackingStore() { GlobalBackingStoreRegistry::Unregister(this); - if (buffer_start_ == nullptr) return; // nothing to deallocate + if (buffer_start_ == nullptr) { + Clear(); + return; + } if (is_wasm_memory_) { DCHECK(free_on_destruct_); diff --git a/deps/v8/test/cctest/test-api-array-buffer.cc b/deps/v8/test/cctest/test-api-array-buffer.cc index e8e026f156053d..eeddbcca1003be 100644 --- a/deps/v8/test/cctest/test-api-array-buffer.cc +++ b/deps/v8/test/cctest/test-api-array-buffer.cc @@ -729,6 +729,46 @@ TEST(BackingStore_HoldAllocatorAlive_UntilIsolateShutdown) { CHECK(allocator_weak.expired()); } +class NullptrAllocator final : public v8::ArrayBuffer::Allocator { + public: + void* Allocate(size_t length) override { + CHECK_EQ(length, 0); + return nullptr; + } + void* AllocateUninitialized(size_t length) override { + CHECK_EQ(length, 0); + return nullptr; + } + void Free(void* data, size_t length) override { CHECK_EQ(data, nullptr); } +}; + +TEST(BackingStore_ReleaseAllocator_NullptrBackingStore) { + std::shared_ptr allocator = + std::make_shared(); + std::weak_ptr allocator_weak(allocator); + + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator_shared = allocator; + v8::Isolate* isolate = v8::Isolate::New(create_params); + isolate->Enter(); + + allocator.reset(); + create_params.array_buffer_allocator_shared.reset(); + CHECK(!allocator_weak.expired()); + + { + std::shared_ptr backing_store = + v8::ArrayBuffer::NewBackingStore(isolate, 0); + // This should release a reference to the allocator, even though the + // buffer is empty/nullptr. + backing_store.reset(); + } + + isolate->Exit(); + isolate->Dispose(); + CHECK(allocator_weak.expired()); +} + TEST(BackingStore_HoldAllocatorAlive_AfterIsolateShutdown) { std::shared_ptr allocator = std::make_shared(); From e276524fcca0040495ece7131521f9bdf00dc99d Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Apr 2020 18:12:43 +0200 Subject: [PATCH 48/62] test: skip memory usage tests when ASAN is enabled Running tests with an ASAN build leads to increased memory usage, rendering the memory usage assumptions in the test invalid. Refs: https://github.com/nodejs/node/pull/32776#issuecomment-620407014 PR-URL: https://github.com/nodejs/node/pull/33129 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Jiawen Geng Reviewed-By: Benjamin Gruenbaum Reviewed-By: Matheus Marchini Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca --- test/parallel/test-crypto-dh-leak.js | 2 ++ test/sequential/test-net-bytes-per-incoming-chunk-overhead.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/test/parallel/test-crypto-dh-leak.js b/test/parallel/test-crypto-dh-leak.js index 9ba8d29e155dc6..65486dbd80cb64 100644 --- a/test/parallel/test-crypto-dh-leak.js +++ b/test/parallel/test-crypto-dh-leak.js @@ -4,6 +4,8 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); +if (process.config.variables.asan) + common.skip('ASAN messes with memory measurements'); const assert = require('assert'); const crypto = require('crypto'); diff --git a/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js b/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js index 46c1f6d1a5885c..c905c22d8afa78 100644 --- a/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js +++ b/test/sequential/test-net-bytes-per-incoming-chunk-overhead.js @@ -2,6 +2,9 @@ 'use strict'; const common = require('../common'); +if (process.config.variables.asan) + common.skip('ASAN messes with memory measurements'); + const assert = require('assert'); const net = require('net'); From 451993ea9433c964bb1de325e17e58eaccfd5787 Mon Sep 17 00:00:00 2001 From: Owen Smith Date: Tue, 28 Apr 2020 11:42:34 -0400 Subject: [PATCH 49/62] http: set default timeout in agent keepSocketAlive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous location of setting the timeout would override behaviour of custom HttpAgents' keepSocketAlive. Moving it into the default keepSocketAlive allows it to interoperate with custom agents. Fixes: https://github.com/nodejs/node/issues/33111 PR-URL: https://github.com/nodejs/node/pull/33127 Reviewed-By: Anna Henningsen Reviewed-By: Robert Nagy Reviewed-By: Luigi Pinca Reviewed-By: Juan José Arboleda Reviewed-By: Andrey Pechkurov --- lib/_http_agent.js | 10 +++--- test/parallel/test-http-agent-timeout.js | 40 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 2618c6c3cb8223..3db42174d73004 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -138,11 +138,6 @@ function Agent(options) { socket._httpMessage = null; this.removeSocket(socket, options); - const agentTimeout = this.options.timeout || 0; - if (socket.timeout !== agentTimeout) { - socket.setTimeout(agentTimeout); - } - socket.once('error', freeSocketErrorListener); freeSockets.push(socket); }); @@ -402,6 +397,11 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) { socket.setKeepAlive(true, this.keepAliveMsecs); socket.unref(); + const agentTimeout = this.options.timeout || 0; + if (socket.timeout !== agentTimeout) { + socket.setTimeout(agentTimeout); + } + return true; }; diff --git a/test/parallel/test-http-agent-timeout.js b/test/parallel/test-http-agent-timeout.js index d8d34414d991a1..07c189e9745330 100644 --- a/test/parallel/test-http-agent-timeout.js +++ b/test/parallel/test-http-agent-timeout.js @@ -92,3 +92,43 @@ const http = require('http'); })); })); } + +{ + // Ensure custom keepSocketAlive timeout is respected + + const CUSTOM_TIMEOUT = 60; + const AGENT_TIMEOUT = 50; + + class CustomAgent extends http.Agent { + keepSocketAlive(socket) { + if (!super.keepSocketAlive(socket)) { + return false; + } + + socket.setTimeout(CUSTOM_TIMEOUT); + return true; + } + } + + const agent = new CustomAgent({ keepAlive: true, timeout: AGENT_TIMEOUT }); + + const server = http.createServer((req, res) => { + res.end(); + }); + + server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port, agent }) + .on('response', common.mustCall((res) => { + const socket = res.socket; + assert(socket); + res.resume(); + socket.on('free', common.mustCall(() => { + socket.on('timeout', common.mustCall(() => { + assert.strictEqual(socket.timeout, CUSTOM_TIMEOUT); + agent.destroy(); + server.close(); + })); + })); + })); + })); +} From a99013718cc4708162e7b20540b6235bd4bb6e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E4=B8=80=E6=A2=93?= Date: Sat, 1 Feb 2020 21:36:36 +0800 Subject: [PATCH 50/62] doc: fix the spelling error in stream.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change `64kb` to `64KB` in `stream.md` PR-URL: https://github.com/nodejs/node/pull/31561 Reviewed-By: Robert Nagy Reviewed-By: Andrey Pechkurov Reviewed-By: Juan José Arboleda --- doc/api/stream.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index 134687530eb95f..6229704eb91bc4 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1442,7 +1442,7 @@ If the loop terminates with a `break` or a `throw`, the stream will be destroyed. In other terms, iterating over a stream will consume the stream fully. The stream will be read in chunks of size equal to the `highWaterMark` option. In the code example above, data will be in a single chunk if the file -has less then 64kb of data because no `highWaterMark` option is provided to +has less then 64KB of data because no `highWaterMark` option is provided to [`fs.createReadStream()`][]. ### Duplex and Transform Streams @@ -1830,7 +1830,7 @@ changes: * `options` {Object} * `highWaterMark` {number} Buffer level when [`stream.write()`][stream-write] starts returning `false`. **Default:** - `16384` (16kb), or `16` for `objectMode` streams. + `16384` (16KB), or `16` for `objectMode` streams. * `decodeStrings` {boolean} Whether to encode `string`s passed to [`stream.write()`][stream-write] to `Buffer`s (with the encoding specified in the [`stream.write()`][stream-write] call) before passing @@ -2112,7 +2112,7 @@ changes: * `options` {Object} * `highWaterMark` {number} The maximum [number of bytes][hwm-gotcha] to store in the internal buffer before ceasing to read from the underlying resource. - **Default:** `16384` (16kb), or `16` for `objectMode` streams. + **Default:** `16384` (16KB), or `16` for `objectMode` streams. * `encoding` {string} If specified, then buffers will be decoded to strings using the specified encoding. **Default:** `null`. * `objectMode` {boolean} Whether this stream should behave From 36d50027af7f3b8f5af6cefbc995d64b96416639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Arboleda?= Date: Mon, 27 Apr 2020 14:37:10 -0500 Subject: [PATCH 51/62] doc: clarify when not to run CI on docs Collaborators won't need to run CI on documentation-only changes. PR-URL: https://github.com/nodejs/node/pull/33101 Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Andrey Pechkurov --- doc/guides/collaborator-guide.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/guides/collaborator-guide.md b/doc/guides/collaborator-guide.md index c08834ea4a1352..128f06857b8f0a 100644 --- a/doc/guides/collaborator-guide.md +++ b/doc/guides/collaborator-guide.md @@ -177,8 +177,10 @@ All pull requests must pass continuous integration tests. Code changes must pass on [project CI server](https://ci.nodejs.org/). Pull requests that only change documentation and comments can use GitHub Actions results. -Do not land any pull requests without passing (green or yellow) CI runs. If -there are CI failures unrelated to the change in the pull request, try "Resume +Do not land any pull requests without a passing (green or yellow) CI run. +For documentation-only changes, GitHub Actions CI is sufficient. +For all other code changes, Jenkins CI must pass as well. If there are +Jenkins CI failures unrelated to the change in the pull request, try "Resume Build". It is in the left navigation of the relevant `node-test-pull-request` job. It will preserve all the green results from the current job but re-run everything else. Start a fresh CI if more than seven days have elapsed since From d02ced8af65f8255be96cb31c61db6f8b643f16f Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Mon, 27 Apr 2020 07:09:03 -0600 Subject: [PATCH 52/62] doc: add util.types.isArrayBufferView() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function was added by nodejs/node#15663, but was never documented. This commit documents it. PR-URL: https://github.com/nodejs/node/pull/33092 Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Gireesh Punathil Reviewed-By: Masashi Hirano Reviewed-By: Juan José Arboleda Reviewed-By: Andrey Pechkurov --- doc/api/util.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/api/util.md b/doc/api/util.md index 757c6a48f6ece9..567ac5f7523260 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1259,6 +1259,25 @@ util.types.isAnyArrayBuffer(new ArrayBuffer()); // Returns true util.types.isAnyArrayBuffer(new SharedArrayBuffer()); // Returns true ``` +### `util.types.isArrayBufferView(value)` + + +* `value` {any} +* Returns: {boolean} + +Returns `true` if the value is an instance of one of the [`ArrayBuffer`][] +views, such as typed array objects or [`DataView`][]. Equivalent to +[`ArrayBuffer.isView()`][]. + +```js +util.types.isArrayBufferView(new Int8Array()); // true +util.types.isArrayBufferView(Buffer.from('hello world')); // true +util.types.isArrayBufferView(new DataView(new ArrayBuffer(16))); // true +util.types.isArrayBufferView(new ArrayBuffer()); // false +``` + ### `util.types.isArgumentsObject(value)` +> Stability: 0 - Deprecated: Use [`request.destroy()`][] instead. + Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed. From 60ebbc4386a9edeb919bd41890b3b3222ad0f93d Mon Sep 17 00:00:00 2001 From: bcoe Date: Wed, 29 Apr 2020 17:00:06 -0700 Subject: [PATCH 59/62] test: update c8 ignore comment PR-URL: https://github.com/nodejs/node/pull/33151 Reviewed-By: Rich Trott Reviewed-By: Ruben Bridgewater --- lib/internal/util/comparisons.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/util/comparisons.js b/lib/internal/util/comparisons.js index 3cc593ae27f403..9d4cdf9f183f16 100644 --- a/lib/internal/util/comparisons.js +++ b/lib/internal/util/comparisons.js @@ -147,7 +147,7 @@ function isIdenticalTypedArrayType(a, b) { return check(b); } } - /* c8 ignore next */ + /* c8 ignore next 4 */ assert.fail( `Unknown TypedArray type checking ${a[SymbolToStringTag]} ${a}\n` + `and ${b[SymbolToStringTag]} ${b}` From 74b0e8c3a82f678c5b6bf5cca63b9d27c4d5963e Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Thu, 30 Apr 2020 23:36:19 +0200 Subject: [PATCH 60/62] http: ensure client request emits close If socket creation failed then an error would be emitted on the client request object, but not 'close' nor would destroyed be set to true. PR-URL: https://github.com/nodejs/node/pull/33178 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/_http_agent.js | 32 ++++++++++---------------- lib/_http_client.js | 15 ++++++++---- test/parallel/test-http-agent-close.js | 21 +++++++++++++++++ 3 files changed, 43 insertions(+), 25 deletions(-) create mode 100644 test/parallel/test-http-agent-close.js diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 3db42174d73004..b9d2c0c2c04a7c 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -242,7 +242,12 @@ Agent.prototype.addRequest = function addRequest(req, options, port/* legacy */, } else if (sockLen < this.maxSockets) { debug('call onSocket', sockLen, freeLen); // If we are under maxSockets create a new one. - this.createSocket(req, options, handleSocketCreation(this, req, true)); + this.createSocket(req, options, (err, socket) => { + if (err) + req.onSocket(socket, err); + else + setRequestSocket(this, req, socket); + }); } else { debug('wait for socket'); // We are over limit so we'll add it to the queue. @@ -388,8 +393,12 @@ Agent.prototype.removeSocket = function removeSocket(s, options) { debug('removeSocket, have a request, make a socket'); const req = this.requests[name][0]; // If we have pending requests and a socket gets closed make a new one - const socketCreationHandler = handleSocketCreation(this, req, false); - this.createSocket(req, options, socketCreationHandler); + this.createSocket(req, options, (err, socket) => { + if (err) + req.onSocket(socket, err); + else + socket.emit('free'); + }); } }; @@ -422,19 +431,6 @@ Agent.prototype.destroy = function destroy() { } }; -function handleSocketCreation(agent, request, informRequest) { - return function handleSocketCreation_Inner(err, socket) { - if (err) { - process.nextTick(emitErrorNT, request, err); - return; - } - if (informRequest) - setRequestSocket(agent, request, socket); - else - socket.emit('free'); - }; -} - function setRequestSocket(agent, req, socket) { req.onSocket(socket); const agentTimeout = agent.options.timeout || 0; @@ -444,10 +440,6 @@ function setRequestSocket(agent, req, socket) { socket.setTimeout(req.timeout); } -function emitErrorNT(emitter, err) { - emitter.emit('error', err); -} - module.exports = { Agent, globalAgent: new Agent() diff --git a/lib/_http_client.js b/lib/_http_client.js index 73a6409c411cc1..c78289138e756a 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -371,10 +371,12 @@ function _destroy(req, socket, err) { // TODO (ronag): Check if socket was used at all (e.g. headersSent) and // re-use it in that case. `req.socket` just checks whether the socket was // assigned to the request and *might* have been used. - if (!req.agent || req.socket) { + if (socket && (!req.agent || req.socket)) { socket.destroy(err); } else { - socket.emit('free'); + if (socket) { + socket.emit('free'); + } if (!req.aborted && !err) { err = connResetException('socket hang up'); } @@ -776,15 +778,18 @@ function listenSocketTimeout(req) { } } -ClientRequest.prototype.onSocket = function onSocket(socket) { +ClientRequest.prototype.onSocket = function onSocket(socket, err) { // TODO(ronag): Between here and onSocketNT the socket // has no 'error' handler. - process.nextTick(onSocketNT, this, socket); + process.nextTick(onSocketNT, this, socket, err); }; -function onSocketNT(req, socket) { +function onSocketNT(req, socket, err) { if (req.destroyed) { _destroy(req, socket, req[kError]); + } else if (err) { + req.destroyed = true; + _destroy(req, null, err); } else { tickOnSocket(req, socket); } diff --git a/test/parallel/test-http-agent-close.js b/test/parallel/test-http-agent-close.js new file mode 100644 index 00000000000000..84ed5e57c5fb86 --- /dev/null +++ b/test/parallel/test-http-agent-close.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const agent = new http.Agent(); +const _err = new Error('kaboom'); +agent.createSocket = function(req, options, cb) { + cb(_err); +}; + +const req = http + .request({ + agent + }) + .on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })) + .on('close', common.mustCall(() => { + assert.strictEqual(req.destroyed, true); + })); From 6925b358f98fa62d4126213578f9e1294616fd2c Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 28 Apr 2020 15:19:14 +0200 Subject: [PATCH 61/62] doc: mark assert.CallTracker experimental MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some details might still change and it would be good to get feedback from users before we mark this as stable. Signed-off-by: Ruben Bridgewater PR-URL: https://github.com/nodejs/node/pull/33124 Reviewed-By: Zeyu Yang Reviewed-By: Juan José Arboleda Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso --- doc/api/assert.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/api/assert.md b/doc/api/assert.md index f8178ed6ec1249..ac7edf36dd2107 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -150,6 +150,13 @@ try { ``` ## Class: `assert.CallTracker` + + +> Stability: 1 - Experimental + +This feature is currently experimental and behavior might still change. ### `new assert.CallTracker()` > Stability: 1 - Experimental @@ -160,7 +160,7 @@ This feature is currently experimental and behavior might still change. ### `new assert.CallTracker()` Creates a new [`CallTracker`][] object which can be used to track if functions @@ -189,7 +189,7 @@ process.on('exit', () => { ### `tracker.calls([fn][, exact])` * `fn` {Function} **Default** A no-op function. @@ -216,7 +216,7 @@ const callsfunc = tracker.calls(func); ### `tracker.report()` * Returns: {Array} of objects containing information about the wrapper functions @@ -262,7 +262,7 @@ tracker.report(); ### `tracker.verify()` Iterates through the list of functions passed to diff --git a/doc/api/console.md b/doc/api/console.md index 9122b85efaa77b..2f4a8e64ed5bfa 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -81,7 +81,7 @@ const { Console } = console; ### `new Console(options)` +```js +const assert = require('assert'); + +const tracker = new assert.CallTracker(); + +function func() {} +const callsfunc = tracker.calls(func); + +console.log(tracker.report()); +/* +[ + { + message: 'Expected the func function to be executed 1 time(s) but was executed 0 time(s).', + actual: 0, + expected: 1, + operator: 'func', + stack: Error + ... + } +] +*/ +``` + +Contributed by ConorDavenport - [#31982](https://github.com/nodejs/node/pull/31982). + +#### Console `groupIndentation` option + +The Console constructor (`require('console').Console`) now supports different group indentations. + +This is useful in case you want different grouping width than 2 spaces. + +```js +const { Console } = require('console'); +const customConsole = new Console({ + stdout: process.stdout, + stderr: process.stderr, + groupIndentation: 10 +}); + +customConsole.log('foo'); +// 'foo' +customConsole.group(); +customConsole.log('foo'); +// 'foo' +``` + +Contributed by rickyes - [#32964](https://github.com/nodejs/node/pull/32964). + +### Commits + +#### Semver-minor commits + +* [[`c87ed21fdf`](https://github.com/nodejs/node/commit/c87ed21fdf)] - **(SEMVER-MINOR)** **assert**: port common.mustCall() to assert (ConorDavenport) [#31982](https://github.com/nodejs/node/pull/31982) +* [[`c49e3ea20c`](https://github.com/nodejs/node/commit/c49e3ea20c)] - **(SEMVER-MINOR)** **console**: support console constructor groupIndentation option (rickyes) [#32964](https://github.com/nodejs/node/pull/32964) +* [[`bc9e413dae`](https://github.com/nodejs/node/commit/bc9e413dae)] - **(SEMVER-MINOR)** **worker**: add stack size resource limit option (Anna Henningsen) [#33085](https://github.com/nodejs/node/pull/33085) + +#### Semver-patch commits + +* [[`f62d92b900`](https://github.com/nodejs/node/commit/f62d92b900)] - **build**: add --error-on-warn configure flag (Daniel Bevenius) [#32685](https://github.com/nodejs/node/pull/32685) +* [[`db293c47dd`](https://github.com/nodejs/node/commit/db293c47dd)] - **cluster**: fix error on worker disconnect/destroy (Santiago Gimeno) [#32793](https://github.com/nodejs/node/pull/32793) +* [[`83e165bf88`](https://github.com/nodejs/node/commit/83e165bf88)] - **crypto**: check DiffieHellman p and g params (Ben Noordhuis) [#32739](https://github.com/nodejs/node/pull/32739) +* [[`e07cca6af6`](https://github.com/nodejs/node/commit/e07cca6af6)] - **crypto**: generator must be int32 in DiffieHellman() (Ben Noordhuis) [#32739](https://github.com/nodejs/node/pull/32739) +* [[`637442fec9`](https://github.com/nodejs/node/commit/637442fec9)] - **crypto**: key size must be int32 in DiffieHellman() (Ben Noordhuis) [#32739](https://github.com/nodejs/node/pull/32739) +* [[`c5a4534d5c`](https://github.com/nodejs/node/commit/c5a4534d5c)] - **deps**: V8: backport e29c62b74854 (Anna Henningsen) [#33125](https://github.com/nodejs/node/pull/33125) +* [[`8325c29e92`](https://github.com/nodejs/node/commit/8325c29e92)] - **deps**: update to uvwasi 0.0.8 (Colin Ihrig) [#33078](https://github.com/nodejs/node/pull/33078) +* [[`2174159598`](https://github.com/nodejs/node/commit/2174159598)] - **esm**: improve commonjs hint on module not found (Daniele Belardi) [#31906](https://github.com/nodejs/node/pull/31906) +* [[`74b0e8c3a8`](https://github.com/nodejs/node/commit/74b0e8c3a8)] - **http**: ensure client request emits close (Robert Nagy) [#33178](https://github.com/nodejs/node/pull/33178) +* [[`a4ec01c55b`](https://github.com/nodejs/node/commit/a4ec01c55b)] - **http**: simplify sending header (Robert Nagy) [#33200](https://github.com/nodejs/node/pull/33200) +* [[`451993ea94`](https://github.com/nodejs/node/commit/451993ea94)] - **http**: set default timeout in agent keepSocketAlive (Owen Smith) [#33127](https://github.com/nodejs/node/pull/33127) +* [[`3cb1713a59`](https://github.com/nodejs/node/commit/3cb1713a59)] - **http2,doc**: minor fixes (Alba Mendez) [#28044](https://github.com/nodejs/node/pull/28044) +* [[`eab4be1b93`](https://github.com/nodejs/node/commit/eab4be1b93)] - **lib**: cosmetic change to builtinLibs list for maintainability (James M Snell) [#33106](https://github.com/nodejs/node/pull/33106) +* [[`542da430ff`](https://github.com/nodejs/node/commit/542da430ff)] - **lib**: fix validateport error message when allowZero is false (rickyes) [#32861](https://github.com/nodejs/node/pull/32861) +* [[`5eccf1e9ad`](https://github.com/nodejs/node/commit/5eccf1e9ad)] - **module**: no type module resolver side effects (Guy Bedford) [#33086](https://github.com/nodejs/node/pull/33086) +* [[`466213d726`](https://github.com/nodejs/node/commit/466213d726)] - **n-api**: simplify uv\_idle wrangling (Ben Noordhuis) [#32997](https://github.com/nodejs/node/pull/32997) +* [[`ed45b51642`](https://github.com/nodejs/node/commit/ed45b51642)] - **path**: fix comment grammar (thecodrr) [#32942](https://github.com/nodejs/node/pull/32942) +* [[`bb2d2f6e0e`](https://github.com/nodejs/node/commit/bb2d2f6e0e)] - **src**: remove unused v8 Message namespace (Adrian Estrada) [#33180](https://github.com/nodejs/node/pull/33180) +* [[`de643bc325`](https://github.com/nodejs/node/commit/de643bc325)] - **src**: use unique\_ptr for CachedData in ContextifyScript::New (Anna Henningsen) [#33113](https://github.com/nodejs/node/pull/33113) +* [[`f61928ba35`](https://github.com/nodejs/node/commit/f61928ba35)] - **src**: return undefined when validation err == 0 (James M Snell) [#33107](https://github.com/nodejs/node/pull/33107) +* [[`f4e5ab14da`](https://github.com/nodejs/node/commit/f4e5ab14da)] - **src**: crypto::UseSNIContext to use BaseObjectPtr (James M Snell) [#33107](https://github.com/nodejs/node/pull/33107) +* [[`541ea035bf`](https://github.com/nodejs/node/commit/541ea035bf)] - **src**: separate out NgLibMemoryManagerBase (James M Snell) [#33104](https://github.com/nodejs/node/pull/33104) +* [[`10a87c81cf`](https://github.com/nodejs/node/commit/10a87c81cf)] - **src**: remove unnecessary fully qualified names (rickyes) [#33077](https://github.com/nodejs/node/pull/33077) +* [[`45032a39e8`](https://github.com/nodejs/node/commit/45032a39e8)] - **stream**: fix stream.finished on Duplex (Robert Nagy) [#33133](https://github.com/nodejs/node/pull/33133) +* [[`4cfa7e0716`](https://github.com/nodejs/node/commit/4cfa7e0716)] - **stream**: simplify Readable push/unshift logic (himself65) [#32899](https://github.com/nodejs/node/pull/32899) +* [[`bc40ed31b3`](https://github.com/nodejs/node/commit/bc40ed31b3)] - **stream**: add null check in Readable.from (Pranshu Srivastava) [#32873](https://github.com/nodejs/node/pull/32873) +* [[`b183d0a18a`](https://github.com/nodejs/node/commit/b183d0a18a)] - **stream**: let Duplex re-use Writable properties (Robert Nagy) [#33079](https://github.com/nodejs/node/pull/33079) +* [[`ec24577406`](https://github.com/nodejs/node/commit/ec24577406)] - **v8**: use AliasedBuffers for passing heap statistics around (Joyee Cheung) [#32929](https://github.com/nodejs/node/pull/32929) +* [[`d39254ada6`](https://github.com/nodejs/node/commit/d39254ada6)] - **vm**: fix vm.measureMemory() and introduce execution option (Joyee Cheung) [#32988](https://github.com/nodejs/node/pull/32988) +* [[`4423304ac4`](https://github.com/nodejs/node/commit/4423304ac4)] - **vm**: throw error when duplicated exportNames in SyntheticModule (himself65) [#32810](https://github.com/nodejs/node/pull/32810) +* [[`3866dc1311`](https://github.com/nodejs/node/commit/3866dc1311)] - **wasi**: use free() to release preopen array (Anna Henningsen) [#33110](https://github.com/nodejs/node/pull/33110) +* [[`d7d9960d38`](https://github.com/nodejs/node/commit/d7d9960d38)] - **wasi**: update start() behavior to match spec (Colin Ihrig) [#33073](https://github.com/nodejs/node/pull/33073) +* [[`8d5ac1bbf0`](https://github.com/nodejs/node/commit/8d5ac1bbf0)] - **wasi**: rename \_\_wasi\_unstable\_reactor\_start() (Colin Ihrig) [#33073](https://github.com/nodejs/node/pull/33073) +* [[`c6d632a72a`](https://github.com/nodejs/node/commit/c6d632a72a)] - **worker**: unify custom error creation (Anna Henningsen) [#33084](https://github.com/nodejs/node/pull/33084) + +#### Documentation commits + +* [[`6925b358f9`](https://github.com/nodejs/node/commit/6925b358f9)] - **doc**: mark assert.CallTracker experimental (Ruben Bridgewater) [#33124](https://github.com/nodejs/node/pull/33124) +* [[`413f5d3581`](https://github.com/nodejs/node/commit/413f5d3581)] - **doc**: add missing deprecation not (Robert Nagy) [#33203](https://github.com/nodejs/node/pull/33203) +* [[`7893bde07e`](https://github.com/nodejs/node/commit/7893bde07e)] - **doc**: fix a typo in crypto.generateKeyPairSync() (himself65) [#33187](https://github.com/nodejs/node/pull/33187) +* [[`d02ced8af6`](https://github.com/nodejs/node/commit/d02ced8af6)] - **doc**: add util.types.isArrayBufferView() (Kevin Locke) [#33092](https://github.com/nodejs/node/pull/33092) +* [[`36d50027af`](https://github.com/nodejs/node/commit/36d50027af)] - **doc**: clarify when not to run CI on docs (Juan José Arboleda) [#33101](https://github.com/nodejs/node/pull/33101) +* [[`a99013718c`](https://github.com/nodejs/node/commit/a99013718c)] - **doc**: fix the spelling error in stream.md (白一梓) [#31561](https://github.com/nodejs/node/pull/31561) +* [[`23962191c1`](https://github.com/nodejs/node/commit/23962191c1)] - **doc**: correct Nodejs to Node.js spelling (Nick Schonning) [#33088](https://github.com/nodejs/node/pull/33088) +* [[`de15edcfc0`](https://github.com/nodejs/node/commit/de15edcfc0)] - **doc**: improve worker pool example (Ranjan Purbey) [#33082](https://github.com/nodejs/node/pull/33082) +* [[`289a5c8dfb`](https://github.com/nodejs/node/commit/289a5c8dfb)] - **doc**: some grammar fixes (Chris Holland) [#33081](https://github.com/nodejs/node/pull/33081) +* [[`82e459d9af`](https://github.com/nodejs/node/commit/82e459d9af)] - **doc**: don't check links in tmp dirs (Ben Noordhuis) [#32996](https://github.com/nodejs/node/pull/32996) +* [[`c5a2f9a02a`](https://github.com/nodejs/node/commit/c5a2f9a02a)] - **doc**: fix markdown parsing on doc/api/os.md (Juan José Arboleda) [#33067](https://github.com/nodejs/node/pull/33067) + +#### Other commits + +* [[`60ebbc4386`](https://github.com/nodejs/node/commit/60ebbc4386)] - **test**: update c8 ignore comment (Benjamin Coe) [#33151](https://github.com/nodejs/node/pull/33151) +* [[`e276524fcc`](https://github.com/nodejs/node/commit/e276524fcc)] - **test**: skip memory usage tests when ASAN is enabled (Anna Henningsen) [#33129](https://github.com/nodejs/node/pull/33129) +* [[`89ed7a5862`](https://github.com/nodejs/node/commit/89ed7a5862)] - **test**: move test-process-title to sequential (Anna Henningsen) [#33150](https://github.com/nodejs/node/pull/33150) +* [[`af7da46d9b`](https://github.com/nodejs/node/commit/af7da46d9b)] - **test**: fix out-of-bound reads from invalid sizeof usage (Anna Henningsen) [#33115](https://github.com/nodejs/node/pull/33115) +* [[`9ccb6b2e8c`](https://github.com/nodejs/node/commit/9ccb6b2e8c)] - **test**: add missing calls to napi\_async\_destroy (Anna Henningsen) [#33114](https://github.com/nodejs/node/pull/33114) +* [[`3c2f608a8d`](https://github.com/nodejs/node/commit/3c2f608a8d)] - **test**: correct typo in test name (Colin Ihrig) [#33083](https://github.com/nodejs/node/pull/33083) +* [[`92c7e0620f`](https://github.com/nodejs/node/commit/92c7e0620f)] - **test**: check args on SourceTextModule cachedData (Juan José Arboleda) [#32956](https://github.com/nodejs/node/pull/32956) +* [[`f79ef96fea`](https://github.com/nodejs/node/commit/f79ef96fea)] - **test**: mark test flaky on freebsd (Sam Roberts) [#32849](https://github.com/nodejs/node/pull/32849) +* [[`aced1f5d70`](https://github.com/nodejs/node/commit/aced1f5d70)] - **test**: flaky test-stdout-close-catch on freebsd (Sam Roberts) [#32849](https://github.com/nodejs/node/pull/32849) +* [[`6734cc43df`](https://github.com/nodejs/node/commit/6734cc43df)] - **tools**: bump remark-preset-lint-node to 1.15.0 (Rich Trott) [#33157](https://github.com/nodejs/node/pull/33157) +* [[`a87d371014`](https://github.com/nodejs/node/commit/a87d371014)] - **tools**: fix redundant-move warning in inspector (Daniel Bevenius) [#32685](https://github.com/nodejs/node/pull/32685) +* [[`12426f59f5`](https://github.com/nodejs/node/commit/12426f59f5)] - **tools**: update remark-preset-lint-node@1.14.0 (Rich Trott) [#33072](https://github.com/nodejs/node/pull/33072) +* [[`8c40ffc329`](https://github.com/nodejs/node/commit/8c40ffc329)] - **tools**: update broken types in type parser (Colin Ihrig) [#33068](https://github.com/nodejs/node/pull/33068) + ## 2020-04-29, Version 14.1.0 (Current), @BethGriggs diff --git a/src/node_version.h b/src/node_version.h index 78d1640de6834a..8c4a897ea2dcda 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,13 +23,13 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 14 -#define NODE_MINOR_VERSION 1 -#define NODE_PATCH_VERSION 1 +#define NODE_MINOR_VERSION 2 +#define NODE_PATCH_VERSION 0 #define NODE_VERSION_IS_LTS 0 #define NODE_VERSION_LTS_CODENAME "" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)