{"version":3,"sources":["jsdelivr-header.js","/npm/standardmark@0.1.0/lib/markdownlint.js"],"names":[],"mappings":"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","file":"/npm/standardmark@0.1.0/lib/markdownlint.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/standardmark@0.1.0/lib/markdownlint.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","// @ts-check\n\n'use strict'\n\nconst fs = require('fs')\nconst path = require('path')\nconst { URL } = require('url')\nconst markdownIt = require('markdown-it')\nconst rules = require('./rules')\nconst helpers = require('../helpers')\nconst cache = require('./cache')\n\nconst deprecatedRuleNames = ['MD002', 'MD006']\n\n/**\n * Validate the list of rules for structure and reuse.\n *\n * @param {Rule[]} ruleList List of rules.\n * @returns {string} Error message if validation fails.\n */\nfunction validateRuleList (ruleList) {\n  let result = null\n  if (ruleList.length === rules.length) {\n    // No need to validate if only using built-in rules\n    return result\n  }\n  const allIds = {}\n  ruleList.forEach(function forRule (rule, index) {\n    const customIndex = index - rules.length\n    function newError (property) {\n      return new Error(\n        \"Property '\" + property + \"' of custom rule at index \" +\n        customIndex + ' is incorrect.')\n    }\n    ['names', 'tags'].forEach(function forProperty (property) {\n      const value = rule[property]\n      if (!result &&\n        (!value || !Array.isArray(value) || (value.length === 0) ||\n         !value.every(helpers.isString) || value.some(helpers.isEmptyString))) {\n        result = newError(property)\n      }\n    });\n    [\n      ['description', 'string'],\n      ['function', 'function']\n    ].forEach(function forProperty (propertyInfo) {\n      const property = propertyInfo[0]\n      const value = rule[property]\n      if (!result && (!value || (typeof value !== propertyInfo[1]))) {\n        result = newError(property)\n      }\n    })\n    if (!result && rule.information) {\n      if (Object.getPrototypeOf(rule.information) !== URL.prototype) {\n        result = newError('information')\n      }\n    }\n    if (!result) {\n      rule.names.forEach(function forName (name) {\n        const nameUpper = name.toUpperCase()\n        if (!result && (allIds[nameUpper] !== undefined)) {\n          result = new Error(\"Name '\" + name + \"' of custom rule at index \" +\n            customIndex + ' is already used as a name or tag.')\n        }\n        allIds[nameUpper] = true\n      })\n      rule.tags.forEach(function forTag (tag) {\n        const tagUpper = tag.toUpperCase()\n        if (!result && allIds[tagUpper]) {\n          result = new Error(\"Tag '\" + tag + \"' of custom rule at index \" +\n            customIndex + ' is already used as a name.')\n        }\n        allIds[tagUpper] = false\n      })\n    }\n  })\n  return result\n}\n\n/**\n * Creates a LintResults instance with toString for pretty display.\n *\n * @param {Rule[]} ruleList List of rules.\n * @returns {LintResults} New LintResults instance.\n */\nfunction newResults (ruleList) {\n  function Results () {}\n  Results.prototype.toString = function toString (useAlias) {\n    const that = this\n    let ruleNameToRule = null\n    const results = []\n    Object.keys(that).forEach(function forFile (file) {\n      const fileResults = that[file]\n      if (Array.isArray(fileResults)) {\n        fileResults.forEach(function forResult (result) {\n          const ruleMoniker = result.ruleNames\n            ? result.ruleNames.join('/')\n            : (result.ruleName + '/' + result.ruleAlias)\n          results.push(\n            file + ': ' +\n            result.lineNumber + ': ' +\n            ruleMoniker + ' ' +\n            result.ruleDescription +\n            (result.errorDetail\n              ? ' [' + result.errorDetail + ']'\n              : '') +\n            (result.errorContext\n              ? ' [Context: \"' + result.errorContext + '\"]'\n              : ''))\n        })\n      } else {\n        if (!ruleNameToRule) {\n          ruleNameToRule = {}\n          ruleList.forEach(function forRule (rule) {\n            const ruleName = rule.names[0].toUpperCase()\n            ruleNameToRule[ruleName] = rule\n          })\n        }\n        Object.keys(fileResults).forEach(function forRule (ruleName) {\n          const rule = ruleNameToRule[ruleName.toUpperCase()]\n          const ruleResults = fileResults[ruleName]\n          ruleResults.forEach(function forLine (lineNumber) {\n            const nameIndex = Math.min(useAlias ? 1 : 0, rule.names.length - 1)\n            const result =\n              file + ': ' +\n              lineNumber + ': ' +\n              rule.names[nameIndex] + ' ' +\n              rule.description\n            results.push(result)\n          })\n        })\n      }\n    })\n    return results.join('\\n')\n  }\n  // @ts-ignore\n  return new Results()\n}\n\n/**\n * Remove front matter (if present at beginning of content).\n *\n * @param {string} content Markdown content.\n * @param {RegExp} frontMatter Regular expression to match front matter.\n * @returns {Object} Trimmed content and front matter lines.\n */\nfunction removeFrontMatter (content, frontMatter) {\n  let frontMatterLines = []\n  if (frontMatter) {\n    const frontMatterMatch = content.match(frontMatter)\n    if (frontMatterMatch && !frontMatterMatch.index) {\n      const contentMatched = frontMatterMatch[0]\n      content = content.slice(contentMatched.length)\n      frontMatterLines = contentMatched.split(helpers.newLineRe)\n      if (frontMatterLines.length &&\n          (frontMatterLines[frontMatterLines.length - 1] === '')) {\n        frontMatterLines.length--\n      }\n    }\n  }\n  return {\n    content: content,\n    frontMatterLines: frontMatterLines\n  }\n}\n\n/**\n * Annotate tokens with line/lineNumber.\n *\n * @param {MarkdownItToken[]} tokens Array of markdown-it tokens.\n * @param {string[]} lines Lines of Markdown content.\n * @returns {void}\n */\nfunction annotateTokens (tokens, lines) {\n  let tbodyMap = null\n  tokens.forEach(function forToken (token) {\n    // Handle missing maps for table body\n    if (token.type === 'tbody_open') {\n      tbodyMap = token.map.slice()\n    } else if ((token.type === 'tr_close') && tbodyMap) {\n      tbodyMap[0]++\n    } else if (token.type === 'tbody_close') {\n      tbodyMap = null\n    }\n    if (tbodyMap && !token.map) {\n      token.map = tbodyMap.slice()\n    }\n    // Update token metadata\n    if (token.map) {\n      token.line = lines[token.map[0]]\n      token.lineNumber = token.map[0] + 1\n      // Trim bottom of token to exclude whitespace lines\n      while (token.map[1] && !((lines[token.map[1] - 1] || '').trim())) {\n        token.map[1]--\n      }\n      // Annotate children with lineNumber\n      let lineNumber = token.lineNumber\n      const codeSpanExtraLines = []\n      helpers.forEachInlineCodeSpan(\n        token.content,\n        function handleInlineCodeSpan (code) {\n          codeSpanExtraLines.push(code.split(helpers.newLineRe).length - 1)\n        }\n      );\n      (token.children || []).forEach(function forChild (child) {\n        child.lineNumber = lineNumber\n        child.line = lines[lineNumber - 1]\n        if ((child.type === 'softbreak') || (child.type === 'hardbreak')) {\n          lineNumber++\n        } else if (child.type === 'code_inline') {\n          lineNumber += codeSpanExtraLines.shift()\n        }\n      })\n    }\n  })\n}\n\n/**\n * Map rule names/tags to canonical rule name.\n *\n * @param {Rule[]} ruleList List of rules.\n * @returns {Object.<string, string[]>} Map of alias to rule name.\n */\nfunction mapAliasToRuleNames (ruleList) {\n  const aliasToRuleNames = {}\n  // const tagToRuleNames = {};\n  ruleList.forEach(function forRule (rule) {\n    const ruleName = rule.names[0].toUpperCase()\n    // The following is useful for updating README.md: review\n    // console.log(\n    //   \"* **[\" + ruleName + \"](doc/Rules.md#\" + ruleName.toLowerCase() +\n    //    \")** *\" + rule.names.slice(1).join(\"/\") + \"* - \" + rule.description);\n    rule.names.forEach(function forName (name) {\n      const nameUpper = name.toUpperCase()\n      aliasToRuleNames[nameUpper] = [ruleName]\n    })\n    rule.tags.forEach(function forTag (tag) {\n      const tagUpper = tag.toUpperCase()\n      const ruleNames = aliasToRuleNames[tagUpper] || []\n      ruleNames.push(ruleName)\n      aliasToRuleNames[tagUpper] = ruleNames\n      // tagToRuleNames[tag] = ruleName;\n    })\n  })\n  // The following is useful for updating README.md:  review\n  // Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {\n  //   console.log(\"* **\" + tag + \"** - \" +\n  //     aliasToRuleNames[tag.toUpperCase()].join(\", \"));\n  // });\n  // @ts-ignore\n  return aliasToRuleNames\n}\n\n/**\n * Apply (and normalize) configuration object.\n *\n * @param {Rule[]} ruleList List of rules.\n * @param {Configuration} config Configuration object.\n * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule\n * names.\n * @returns {Configuration} Effective configuration.\n */\nfunction getEffectiveConfig (ruleList, config, aliasToRuleNames) {\n  const defaultKey = Object.keys(config).filter(\n    (key) => key.toUpperCase() === 'DEFAULT'\n  )\n  const ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]]\n  const effectiveConfig = {}\n  ruleList.forEach((rule) => {\n    const ruleName = rule.names[0].toUpperCase()\n    effectiveConfig[ruleName] = ruleDefault\n  })\n  deprecatedRuleNames.forEach((ruleName) => {\n    effectiveConfig[ruleName] = false\n  })\n  Object.keys(config).forEach((key) => {\n    let value = config[key]\n    if (value) {\n      if (!(value instanceof Object)) {\n        value = {}\n      }\n    } else {\n      value = false\n    }\n    const keyUpper = key.toUpperCase();\n    (aliasToRuleNames[keyUpper] || []).forEach((ruleName) => {\n      effectiveConfig[ruleName] = value\n    })\n  })\n  return effectiveConfig\n}\n\n/**\n * Create a mapping of enabled rules per line.\n *\n * @param {Rule[]} ruleList List of rules.\n * @param {string[]} lines List of content lines.\n * @param {string[]} frontMatterLines List of front matter lines.\n * @param {boolean} noInlineConfig Whether to allow inline configuration.\n * @param {Configuration} effectiveConfig Effective configuration.\n * @param {Object.<string, string[]>} aliasToRuleNames Map of alias to rule\n * names.\n * @returns {Object.<string, RuleConfiguration>[]} Enabled rules for each line.\n */\nfunction getEnabledRulesPerLineNumber (\n  ruleList,\n  lines,\n  frontMatterLines,\n  noInlineConfig,\n  effectiveConfig,\n  aliasToRuleNames) {\n  let enabledRules = {}\n  const allRuleNames = []\n  ruleList.forEach((rule) => {\n    const ruleName = rule.names[0].toUpperCase()\n    allRuleNames.push(ruleName)\n    enabledRules[ruleName] = !!effectiveConfig[ruleName]\n  })\n  let capturedRules = enabledRules\n  function forMatch (match, byLine) {\n    const action = match[1].toUpperCase()\n    if (action === 'CAPTURE') {\n      if (byLine) {\n        capturedRules = { ...enabledRules }\n      }\n    } else if (action === 'RESTORE') {\n      if (byLine) {\n        enabledRules = { ...capturedRules }\n      }\n    } else {\n      // action in [ENABLE, DISABLE, ENABLE-FILE, DISABLE-FILE]\n      const isfile = action.endsWith('-FILE')\n      if ((byLine && !isfile) || (!byLine && isfile)) {\n        const enabled = (action.startsWith('ENABLE'))\n        const items = match[2]\n          ? match[2].trim().toUpperCase().split(/\\s+/)\n          : allRuleNames\n        items.forEach((nameUpper) => {\n          (aliasToRuleNames[nameUpper] || []).forEach((ruleName) => {\n            enabledRules[ruleName] = enabled\n          })\n        })\n      }\n    }\n  }\n  const enabledRulesPerLineNumber = new Array(1 + frontMatterLines.length);\n  [false, true].forEach((byLine) => {\n    lines.forEach((line) => {\n      if (!noInlineConfig) {\n        let match = helpers.inlineCommentRe.exec(line)\n        if (match) {\n          enabledRules = { ...enabledRules }\n          while (match) {\n            forMatch(match, byLine)\n            match = helpers.inlineCommentRe.exec(line)\n          }\n        }\n      }\n      if (byLine) {\n        enabledRulesPerLineNumber.push(enabledRules)\n      }\n    })\n  })\n  return enabledRulesPerLineNumber\n}\n\n/**\n * Compare function for Array.prototype.sort for ascending order of errors.\n *\n * @param {LintError} a First error.\n * @param {LintError} b Second error.\n * @returns {number} Positive value if a>b, negative value if b<a, 0 otherwise.\n */\nfunction lineNumberComparison (a, b) {\n  return a.lineNumber - b.lineNumber\n}\n\n/**\n * Filter function to include everything.\n *\n * @returns {boolean} True.\n */\nfunction filterAllValues () {\n  return true\n}\n\n/**\n * Function to return unique values from a sorted errors array.\n *\n * @param {LintError} value Error instance.\n * @param {number} index Index in array.\n * @param {LintError[]} array Array of errors.\n * @returns {boolean} Filter value.\n */\nfunction uniqueFilterForSortedErrors (value, index, array) {\n  return (index === 0) || (value.lineNumber > array[index - 1].lineNumber)\n}\n\n/**\n * Lints a string containing Markdown content.\n *\n * @param {Rule[]} ruleList List of rules.\n * @param {string} name Identifier for the content.\n * @param {string} content Markdown content\n * @param {Object} md markdown-it instance.\n * @param {Configuration} config Configuration object.\n * @param {RegExp} frontMatter Regular expression for front matter.\n * @param {boolean} handleRuleFailures Whether to handle exceptions in rules.\n * @param {boolean} noInlineConfig Whether to allow inline configuration.\n * @param {number} resultVersion Version of the LintResults object to return.\n * @param {Function} callback Callback (err, result) function.\n * @returns {void}\n */\nfunction lintContent (\n  ruleList,\n  name,\n  content,\n  md,\n  config,\n  frontMatter,\n  handleRuleFailures,\n  noInlineConfig,\n  resultVersion,\n  callback) {\n  // Remove UTF-8 byte order marker (if present)\n  content = content.replace(/^\\ufeff/, '')\n  // Remove front matter\n  const removeFrontMatterResult = removeFrontMatter(content, frontMatter)\n  const frontMatterLines = removeFrontMatterResult.frontMatterLines\n  // Ignore the content of HTML comments\n  content = helpers.clearHtmlCommentText(removeFrontMatterResult.content)\n  // Parse content into tokens and lines\n  const tokens = md.parse(content, {})\n  const lines = content.split(helpers.newLineRe)\n  annotateTokens(tokens, lines)\n  const aliasToRuleNames = mapAliasToRuleNames(ruleList)\n  const effectiveConfig =\n    getEffectiveConfig(ruleList, config, aliasToRuleNames)\n  const enabledRulesPerLineNumber = getEnabledRulesPerLineNumber(\n    ruleList, lines, frontMatterLines, noInlineConfig,\n    effectiveConfig, aliasToRuleNames)\n  // Create parameters for rules\n  const params = {\n    name,\n    tokens,\n    lines,\n    frontMatterLines\n  }\n  cache.lineMetadata(helpers.getLineMetadata(params))\n  cache.flattenedLists(helpers.flattenLists(params))\n  // Function to run for each rule\n  const result = (resultVersion === 0) ? {} : []\n  function forRule (rule) {\n    // Configure rule\n    const ruleNameFriendly = rule.names[0]\n    const ruleName = ruleNameFriendly.toUpperCase()\n    params.config = effectiveConfig[ruleName]\n    function throwError (property) {\n      throw new Error(\n        \"Property '\" + property + \"' of onError parameter is incorrect.\")\n    }\n    const errors = []\n    function onError (errorInfo) {\n      if (!errorInfo ||\n        !helpers.isNumber(errorInfo.lineNumber) ||\n        (errorInfo.lineNumber < 1) ||\n        (errorInfo.lineNumber > lines.length)) {\n        throwError('lineNumber')\n      }\n      if (errorInfo.detail &&\n        !helpers.isString(errorInfo.detail)) {\n        throwError('detail')\n      }\n      if (errorInfo.context &&\n        !helpers.isString(errorInfo.context)) {\n        throwError('context')\n      }\n      if (errorInfo.range &&\n        (!Array.isArray(errorInfo.range) ||\n         (errorInfo.range.length !== 2) ||\n         !helpers.isNumber(errorInfo.range[0]) ||\n         (errorInfo.range[0] < 1) ||\n         !helpers.isNumber(errorInfo.range[1]) ||\n         (errorInfo.range[1] < 1) ||\n         ((errorInfo.range[0] + errorInfo.range[1] - 1) >\n          lines[errorInfo.lineNumber - 1].length))) {\n        throwError('range')\n      }\n      const fixInfo = errorInfo.fixInfo\n      const cleanFixInfo = {}\n      if (fixInfo) {\n        if (!helpers.isObject(fixInfo)) {\n          throwError('fixInfo')\n        }\n        if (fixInfo.lineNumber !== undefined) {\n          if ((!helpers.isNumber(fixInfo.lineNumber) ||\n            (fixInfo.lineNumber < 1) ||\n            (fixInfo.lineNumber > lines.length))) {\n            throwError('fixInfo.lineNumber')\n          }\n          cleanFixInfo.lineNumber =\n            fixInfo.lineNumber + frontMatterLines.length\n        }\n        const effectiveLineNumber = fixInfo.lineNumber || errorInfo.lineNumber\n        if (fixInfo.editColumn !== undefined) {\n          if ((!helpers.isNumber(fixInfo.editColumn) ||\n            (fixInfo.editColumn < 1) ||\n            (fixInfo.editColumn >\n              lines[effectiveLineNumber - 1].length + 1))) {\n            throwError('fixInfo.editColumn')\n          }\n          cleanFixInfo.editColumn = fixInfo.editColumn\n        }\n        if (fixInfo.deleteCount !== undefined) {\n          if ((!helpers.isNumber(fixInfo.deleteCount) ||\n            (fixInfo.deleteCount < -1) ||\n            (fixInfo.deleteCount >\n              lines[effectiveLineNumber - 1].length))) {\n            throwError('fixInfo.deleteCount')\n          }\n          cleanFixInfo.deleteCount = fixInfo.deleteCount\n        }\n        if (fixInfo.insertText !== undefined) {\n          if (!helpers.isString(fixInfo.insertText)) {\n            throwError('fixInfo.insertText')\n          }\n          cleanFixInfo.insertText = fixInfo.insertText\n        }\n      }\n      errors.push({\n        lineNumber: errorInfo.lineNumber + frontMatterLines.length,\n        detail: errorInfo.detail || null,\n        context: errorInfo.context || null,\n        range: errorInfo.range ? [...errorInfo.range] : null,\n        fixInfo: fixInfo ? cleanFixInfo : null\n      })\n    }\n    // Call (possibly external) rule function\n    if (handleRuleFailures) {\n      try {\n        rule.function(params, onError)\n      } catch (ex) {\n        onError({\n          lineNumber: 1,\n          detail: `This rule threw an exception: ${ex.message}`\n        })\n      }\n    } else {\n      rule.function(params, onError)\n    }\n    // Record any errors (significant performance benefit from length check)\n    if (errors.length) {\n      errors.sort(lineNumberComparison)\n      const filteredErrors = errors\n        .filter((resultVersion === 3)\n          ? filterAllValues\n          : uniqueFilterForSortedErrors)\n        .filter(function removeDisabledRules (error) {\n          return enabledRulesPerLineNumber[error.lineNumber][ruleName]\n        })\n        .map(function formatResults (error) {\n          if (resultVersion === 0) {\n            return error.lineNumber\n          }\n          const errorObject = {}\n          errorObject.lineNumber = error.lineNumber\n          if (resultVersion === 1) {\n            errorObject.ruleName = ruleNameFriendly\n            errorObject.ruleAlias = rule.names[1] || rule.names[0]\n          } else {\n            errorObject.ruleNames = rule.names\n          }\n          errorObject.ruleDescription = rule.description\n          errorObject.ruleInformation =\n            rule.information ? rule.information.href : null\n          errorObject.errorDetail = error.detail\n          errorObject.errorContext = error.context\n          errorObject.errorRange = error.range\n          if (resultVersion === 3) {\n            errorObject.fixInfo = error.fixInfo\n          }\n          return errorObject\n        })\n      if (filteredErrors.length) {\n        if (resultVersion === 0) {\n          result[ruleNameFriendly] = filteredErrors\n        } else {\n          Array.prototype.push.apply(result, filteredErrors)\n        }\n      }\n    }\n  }\n  // Run all rules\n  try {\n    ruleList.forEach(forRule)\n  } catch (ex) {\n    cache.clear()\n    return callback(ex)\n  }\n  cache.clear()\n  return callback(null, result)\n}\n\n/**\n * Lints a file containing Markdown content.\n *\n * @param {Rule[]} ruleList List of rules.\n * @param {string} file Path of file to lint.\n * @param {Object} md markdown-it instance.\n * @param {Configuration} config Configuration object.\n * @param {RegExp} frontMatter Regular expression for front matter.\n * @param {boolean} handleRuleFailures Whether to handle exceptions in rules.\n * @param {boolean} noInlineConfig Whether to allow inline configuration.\n * @param {number} resultVersion Version of the LintResults object to return.\n * @param {boolean} synchronous Whether to execute synchronously.\n * @param {Function} callback Callback (err, result) function.\n * @returns {void}\n */\nfunction lintFile (\n  ruleList,\n  file,\n  md,\n  config,\n  frontMatter,\n  handleRuleFailures,\n  noInlineConfig,\n  resultVersion,\n  synchronous,\n  callback) {\n  function lintContentWrapper (err, content) {\n    if (err) {\n      return callback(err)\n    }\n    return lintContent(ruleList, file, content, md, config, frontMatter,\n      handleRuleFailures, noInlineConfig, resultVersion, callback)\n  }\n  // Make a/synchronous call to read file\n  if (synchronous) {\n    lintContentWrapper(null, fs.readFileSync(file, helpers.utf8Encoding))\n  } else {\n    fs.readFile(file, helpers.utf8Encoding, lintContentWrapper)\n  }\n}\n\n/**\n * Lint files and strings specified in the Options object.\n *\n * @param {Options} options Options object.\n * @param {boolean} synchronous Whether to execute synchronously.\n * @param {Function} callback Callback (err, result) function.\n * @returns {void}\n */\nfunction lintInput (options, synchronous, callback) {\n  // Normalize inputs\n  options = options || {}\n  callback = callback || function noop () {}\n  const ruleList = rules.concat(options.customRules || [])\n  const ruleErr = validateRuleList(ruleList)\n  if (ruleErr) {\n    return callback(ruleErr)\n  }\n  let files = []\n  if (Array.isArray(options.files)) {\n    files = options.files.slice()\n  } else if (options.files) {\n    files = [String(options.files)]\n  }\n  const strings = options.strings || {}\n  const stringsKeys = Object.keys(strings)\n  const config = options.config || { default: true }\n  const frontMatter = (options.frontMatter === undefined)\n    ? helpers.frontMatterRe : options.frontMatter\n  const handleRuleFailures = !!options.handleRuleFailures\n  const noInlineConfig = !!options.noInlineConfig\n  const resultVersion = (options.resultVersion === undefined)\n    ? 2 : options.resultVersion\n  const md = markdownIt({ html: true })\n  const markdownItPlugins = options.markdownItPlugins || []\n  markdownItPlugins.forEach(function forPlugin (plugin) {\n    // @ts-ignore\n    md.use(...plugin)\n  })\n  const results = newResults(ruleList)\n  // Helper to lint the next string or file\n  /* eslint-disable consistent-return */\n  function lintNextItem () {\n    let iterating = true\n    let item = null\n    function lintNextItemCallback (err, result) {\n      if (err) {\n        iterating = false\n        return callback(err)\n      }\n      results[item] = result\n      return iterating || lintNextItem()\n    }\n    while (iterating) {\n      if ((item = stringsKeys.shift())) {\n        lintContent(\n          ruleList,\n          item,\n          strings[item] || '',\n          md,\n          config,\n          frontMatter,\n          handleRuleFailures,\n          noInlineConfig,\n          resultVersion,\n          lintNextItemCallback)\n      } else if ((item = files.shift())) {\n        iterating = synchronous\n        lintFile(\n          ruleList,\n          item,\n          md,\n          config,\n          frontMatter,\n          handleRuleFailures,\n          noInlineConfig,\n          resultVersion,\n          synchronous,\n          lintNextItemCallback)\n      } else {\n        return callback(null, results)\n      }\n    }\n  }\n  return lintNextItem()\n}\n\n/**\n * Lint specified Markdown files.\n *\n * @param {Options} options Configuration options.\n * @param {LintCallback} callback Callback (err, result) function.\n * @returns {void}\n */\nfunction markdownlint (options, callback) {\n  return lintInput(options, false, callback)\n}\n\n/**\n * Lint specified Markdown files synchronously.\n *\n * @param {Options} options Configuration options.\n * @returns {LintResults} Results object.\n */\nfunction markdownlintSync (options) {\n  let results = null\n  lintInput(options, true, function callback (error, res) {\n    if (error) {\n      throw error\n    }\n    results = res\n  })\n  return results\n}\n\n/**\n * Parse the content of a configuration file.\n *\n * @param {string} name Name of the configuration file.\n * @param {string} content Configuration content.\n * @param {ConfigurationParser[]} parsers Parsing function(s).\n * @returns {Object} Configuration object and error message.\n */\nfunction parseConfiguration (name, content, parsers) {\n  let config = null\n  let message = ''\n  const errors = [];\n  // Try each parser\n  (parsers || [JSON.parse]).every((parser) => {\n    try {\n      config = parser(content)\n    } catch (ex) {\n      errors.push(ex.message)\n    }\n    return !config\n  })\n  // Message if unable to parse\n  if (!config) {\n    errors.unshift(`Unable to parse '${name}'`)\n    message = errors.join('; ')\n  }\n  return {\n    config,\n    message\n  }\n}\n\n/**\n * Read specified configuration file.\n *\n * @param {string} file Configuration file name.\n * @param {ConfigurationParser[] | ReadConfigCallback} parsers Parsing\n * function(s).\n * @param {ReadConfigCallback} [callback] Callback (err, result) function.\n * @returns {void}\n */\nfunction readConfig (file, parsers, callback) {\n  if (!callback) {\n    // @ts-ignore\n    callback = parsers\n    parsers = null\n  }\n  // Read file\n  fs.readFile(file, helpers.utf8Encoding, (err, content) => {\n    if (err) {\n      return callback(err)\n    }\n    // Try to parse file\n    // @ts-ignore\n    const { config, message } = parseConfiguration(file, content, parsers)\n    if (!config) {\n      return callback(new Error(message))\n    }\n    // Extend configuration\n    const configExtends = config.extends\n    if (configExtends) {\n      delete config.extends\n      const extendsFile = path.resolve(path.dirname(file), configExtends)\n      return readConfig(extendsFile, parsers, (errr, extendsConfig) => {\n        if (errr) {\n          return callback(errr)\n        }\n        return callback(null, {\n          ...extendsConfig,\n          ...config\n        })\n      })\n    }\n    return callback(null, config)\n  })\n}\n\n/**\n * Read specified configuration file synchronously.\n *\n * @param {string} file Configuration file name.\n * @param {ConfigurationParser[]} [parsers] Parsing function(s).\n * @returns {Configuration} Configuration object.\n */\nfunction readConfigSync (file, parsers) {\n  // Read file\n  const content = fs.readFileSync(file, helpers.utf8Encoding)\n  // Try to parse file\n  const { config, message } = parseConfiguration(file, content, parsers)\n  if (!config) {\n    throw new Error(message)\n  }\n  // Extend configuration\n  const configExtends = config.extends\n  if (configExtends) {\n    delete config.extends\n    return {\n      ...readConfigSync(\n        path.resolve(path.dirname(file), configExtends),\n        parsers\n      ),\n      ...config\n    }\n  }\n  return config\n}\n\n// Export a/synchronous APIs\nmarkdownlint.sync = markdownlintSync\nmarkdownlint.readConfig = readConfig\nmarkdownlint.readConfigSync = readConfigSync\nmodule.exports = markdownlint\n\n// Type declarations\n\n/**\n * Function to implement rule logic.\n *\n * @callback RuleFunction\n * @param {RuleParams} params Rule parameters.\n * @param {RuleOnError} onError Error-reporting callback.\n * @returns {void}\n */\n\n/**\n * Rule parameters.\n *\n * @typedef {Object} RuleParams\n * @property {string} name File/string name.\n * @property {MarkdownItToken[]} tokens markdown-it token objects.\n * @property {string[]} lines File/string lines.\n * @property {string[]} frontMatterLines Front matter lines.\n * @property {RuleConfiguration} config Rule configuration.\n */\n\n/**\n * Markdown-It token.\n *\n * @typedef {Object} MarkdownItToken\n * @property {string[][]} attrs HTML attributes.\n * @property {boolean} block Block-level token.\n * @property {MarkdownItToken[]} children Child nodes.\n * @property {string} content Tag contents.\n * @property {boolean} hidden Ignore element.\n * @property {string} info Fence info.\n * @property {number} level Nesting level.\n * @property {number[]} map Beginning/ending line numbers.\n * @property {string} markup Markup text.\n * @property {Object} meta Arbitrary data.\n * @property {number} nesting Level change.\n * @property {string} tag HTML tag name.\n * @property {string} type Token type.\n * @property {number} lineNumber Line number (1-based).\n * @property {string} line Line content.\n */\n\n/**\n * Error-reporting callback.\n *\n * @callback RuleOnError\n * @param {RuleOnErrorInfo} onErrorInfo Error information.\n * @returns {void}\n */\n\n/**\n * Fix information for RuleOnError callback.\n *\n * @typedef {Object} RuleOnErrorInfo\n * @property {number} lineNumber Line number (1-based).\n * @property {string} [details] Details about the error.\n * @property {string} [context] Context for the error.\n * @property {number[]} [range] Column number (1-based) and length.\n * @property {RuleOnErrorFixInfo} [fixInfo] Fix information.\n */\n\n/**\n * Fix information for RuleOnErrorInfo.\n *\n * @typedef {Object} RuleOnErrorFixInfo\n * @property {number} [lineNumber] Line number (1-based).\n * @property {number} [editColumn] Column of the fix (1-based).\n * @property {number} [deleteCount] Count of characters to delete.\n * @property {string} [insertText] Text to insert (after deleting).\n */\n\n/**\n * Rule definition.\n *\n * @typedef {Object} Rule\n * @property {string[]} names Rule name(s).\n * @property {string} description Rule description.\n * @property {URL} [information] Link to more information.\n * @property {string[]} tags Rule tag(s).\n * @property {RuleFunction} function Rule implementation.\n */\n\n/**\n * Configuration options.\n *\n * @typedef {Object} Options\n * @property {string[] | string} [files] Files to lint.\n * @property {Object.<string, string>} [strings] Strings to lint.\n * @property {Configuration} [config] Configuration object.\n * @property {Rule[] | Rule} [customRules] Custom rules.\n * @property {RegExp} [frontMatter] Front matter pattern.\n * @property {boolean} [handleRuleFailures] True to catch exceptions.\n * @property {boolean} [noInlineConfig] True to ignore HTML directives.\n * @property {number} [resultVersion] Results object version.\n * @property {Plugin[]} [markdownItPlugins] Additional plugins.\n */\n\n/**\n * markdown-it plugin.\n *\n * @typedef {Array} Plugin\n */\n\n/**\n * Function to pretty-print lint results.\n *\n * @callback ToStringCallback\n * @param {boolean} [ruleAliases] True to use rule aliases.\n * @returns {string}\n */\n\n/**\n * Lint results (for resultVersion 3).\n *\n * @typedef {Object.<string, LintError[]>} LintResults\n */\n// The following should be part of the LintResults typedef, but that causes\n// TypeScript to \"forget\" about the string map.\n// * @property {ToStringCallback} toString String representation.\n// https://github.com/microsoft/TypeScript/issues/34911\n\n/**\n * Lint error.\n *\n * @typedef {Object} LintError\n * @property {number} lineNumber Line number (1-based).\n * @property {string[]} ruleNames Rule name(s).\n * @property {string} ruleDescription Rule description.\n * @property {string} ruleInformation Link to more information.\n * @property {string} errorDetail Detail about the error.\n * @property {string} errorContext Context for the error.\n * @property {number[]} errorRange Column number (1-based) and length.\n * @property {FixInfo} fixInfo Fix information.\n */\n\n/**\n * Fix information.\n *\n * @typedef {Object} FixInfo\n * @property {number} [editColumn] Column of the fix (1-based).\n * @property {number} [deleteCount] Count of characters to delete.\n * @property {string} [insertText] Text to insert (after deleting).\n */\n\n/**\n * Called with the result of the lint operation.\n *\n * @callback LintCallback\n * @param {Error | null} err Error object or null.\n * @param {LintResults} [results] Lint results.\n * @returns {void}\n */\n\n/**\n * Configuration object for linting rules. For a detailed schema, see\n * {@link ../schema/markdownlint-config-schema.json}.\n *\n * @typedef {Object.<string, RuleConfiguration>} Configuration\n */\n\n/**\n * Rule configuration object.\n *\n * @typedef {boolean | Object} RuleConfiguration Rule configuration.\n */\n\n/**\n * Parses a configuration string and returns a configuration object.\n *\n * @callback ConfigurationParser\n * @param {string} text Configuration string.\n * @returns {Configuration}\n */\n\n/**\n * Called with the result of the readConfig operation.\n *\n * @callback ReadConfigCallback\n * @param {Error | null} err Error object or null.\n * @param {Configuration} [config] Configuration object.\n * @returns {void}\n */\n"]}