diff --git a/dist/index.mjs b/dist/index.mjs index 933a43a..1c5113f 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -38934,16 +38934,17 @@ module.exports.promise = queueAsPromised /***/ 3810: /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { +var __webpack_unused_export__; // @ts-check const micromark = __nccwpck_require__(1670); -const { newLineRe, nextLinesRe } = __nccwpck_require__(3408); +const { newlineRe, nextLinesRe } = __nccwpck_require__(3408); -module.exports.newLineRe = newLineRe; -module.exports.nextLinesRe = nextLinesRe; +module.exports.Or = newlineRe; +module.exports.gi = nextLinesRe; /** @typedef {import("../lib/exports.mjs").RuleOnError} RuleOnError */ /** @typedef {import("../lib/exports.mjs").RuleOnErrorFixInfo} RuleOnErrorFixInfo */ @@ -38955,28 +38956,28 @@ module.exports.nextLinesRe = nextLinesRe; // Regular expression for matching common front matter (YAML and TOML) // @ts-ignore -module.exports.frontMatterRe = +module.exports.Q9 = /((^---[^\S\r\n\u2028\u2029]*$[\s\S]+?^---\s*)|(^\+\+\+[^\S\r\n\u2028\u2029]*$[\s\S]+?^(\+\+\+|\.\.\.)\s*)|(^\{[^\S\r\n\u2028\u2029]*$[\s\S]+?^\}\s*))(\r\n|\r|\n|$)/m; // Regular expression for matching the start of inline disable/enable comments const inlineCommentStartRe = /()/gi; -module.exports.inlineCommentStartRe = inlineCommentStartRe; +module.exports.q5 = inlineCommentStartRe; // Regular expression for identifying an HTML entity at the end of a line -module.exports.endOfLineHtmlEntityRe = +module.exports.oo = /&(?:#\d+|#[xX][\da-fA-F]+|[a-zA-Z]{2,31}|blk\d{2}|emsp1[34]|frac\d{2}|sup\d|there4);$/; // Regular expression for identifying a GitHub emoji code at the end of a line -module.exports.endOfLineGemojiCodeRe = +module.exports.Uj = /:(?:[abmovx]|[-+]1|100|1234|(?:1st|2nd|3rd)_place_medal|8ball|clock\d{1,4}|e-mail|non-potable_water|o2|t-rex|u5272|u5408|u55b6|u6307|u6708|u6709|u6e80|u7121|u7533|u7981|u7a7a|[a-z]{2,15}2?|[a-z]{1,14}(?:_[a-z\d]{1,16})+):$/; // All punctuation characters (normal and full-width) const allPunctuation = ".,;:!?。,;:!?"; -module.exports.allPunctuation = allPunctuation; +module.exports.qA = allPunctuation; // All punctuation characters without question mark (normal and full-width) -module.exports.allPunctuationNoQuestion = allPunctuation.replace(/[??]/gu, ""); +module.exports.f4 = allPunctuation.replace(/[??]/gu, ""); /** * Returns true iff the input is a Number. @@ -38987,7 +38988,7 @@ module.exports.allPunctuationNoQuestion = allPunctuation.replace(/[??]/gu, "") function isNumber(obj) { return typeof obj === "number"; } -module.exports.isNumber = isNumber; +module.exports.Et = isNumber; /** * Returns true iff the input is a String. @@ -38998,7 +38999,7 @@ module.exports.isNumber = isNumber; function isString(obj) { return typeof obj === "string"; } -module.exports.isString = isString; +module.exports.Kg = isString; /** * Returns true iff the input String is empty. @@ -39009,7 +39010,7 @@ module.exports.isString = isString; function isEmptyString(str) { return str.length === 0; } -module.exports.isEmptyString = isEmptyString; +module.exports.jw = isEmptyString; /** * Returns true iff the input is an Object. @@ -39020,7 +39021,7 @@ module.exports.isEmptyString = isEmptyString; function isObject(obj) { return !!obj && (typeof obj === "object") && !Array.isArray(obj); } -module.exports.isObject = isObject; +module.exports.Gv = isObject; /** * Returns true iff the input is a URL. @@ -39031,7 +39032,7 @@ module.exports.isObject = isObject; function isUrl(obj) { return !!obj && (Object.getPrototypeOf(obj) === URL.prototype); } -module.exports.isUrl = isUrl; +module.exports.gU = isUrl; /** * Clones the input if it is an Array. @@ -39042,7 +39043,7 @@ module.exports.isUrl = isUrl; function cloneIfArray(arr) { return Array.isArray(arr) ? [ ...arr ] : arr; } -module.exports.cloneIfArray = cloneIfArray; +module.exports.YW = cloneIfArray; /** * Clones the input if it is a URL. @@ -39054,7 +39055,7 @@ function cloneIfUrl(url) { // @ts-ignore return isUrl(url) ? new URL(url) : url; } -module.exports.cloneIfUrl = cloneIfUrl; +module.exports.c0 = cloneIfUrl; /** * Gets a Regular Expression for matching the specified HTML attribute. @@ -39062,7 +39063,7 @@ module.exports.cloneIfUrl = cloneIfUrl; * @param {string} name HTML attribute name. * @returns {RegExp} Regular Expression for matching. */ -module.exports.getHtmlAttributeRe = function getHtmlAttributeRe(name) { +module.exports.Xi = function getHtmlAttributeRe(name) { return new RegExp(`\\s${name}\\s*=\\s*['"]?([^'"\\s>]*)`, "iu"); }; @@ -39101,7 +39102,7 @@ function isBlankLine(line) { !removeComments(line).replace(/>/g, "").trim() ); } -module.exports.isBlankLine = isBlankLine; +module.exports.pB = isBlankLine; // Replaces the content of properly-formatted CommonMark comments with "." // This preserves the line/column information for the rest of the document @@ -39115,7 +39116,7 @@ const notCrLfRe = /[^\r\n]/g; const notSpaceCrLfRe = /[^ \r\n]/g; const trailingSpaceRe = / +[\r\n]/g; const replaceTrailingSpace = (/** @type {string} */ s) => s.replace(notCrLfRe, safeCommentCharacter); -module.exports.clearHtmlCommentText = function clearHtmlCommentText(/** @type {string} */ text) { +module.exports.X6 = function clearHtmlCommentText(/** @type {string} */ text) { let i = 0; while ((i = text.indexOf(htmlCommentBegin, i)) !== -1) { const j = text.indexOf(htmlCommentEnd, i + 2); @@ -39157,7 +39158,7 @@ module.exports.clearHtmlCommentText = function clearHtmlCommentText(/** @type {s }; // Escapes a string for use in a RegExp -module.exports.escapeForRegExp = function escapeForRegExp(/** @type {string} */ str) { +module.exports.If = function escapeForRegExp(/** @type {string} */ str) { return str.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); }; @@ -39181,7 +39182,7 @@ function ellipsify(text, start, end) { } return text; } -module.exports.ellipsify = ellipsify; +module.exports.qq = ellipsify; /** * Adds a generic error object via the onError callback. @@ -39203,7 +39204,7 @@ function addError(onError, lineNumber, detail, context, range, fixInfo) { fixInfo }); } -module.exports.addError = addError; +module.exports.CN = addError; /** * Adds an error object with details conditionally via the onError callback. @@ -39231,7 +39232,7 @@ function addErrorDetailIf( fixInfo); } } -module.exports.addErrorDetailIf = addErrorDetailIf; +module.exports.qC = addErrorDetailIf; /** * Adds an error object with context via the onError callback. @@ -39247,10 +39248,10 @@ module.exports.addErrorDetailIf = addErrorDetailIf; */ function addErrorContext(onError, lineNumber, context, start, end, range, fixInfo) { // Normalize new line characters so Linux and Windows trim consistently - context = ellipsify(context.replace(newLineRe, "\n"), start, end); + context = ellipsify(context.replace(newlineRe, "\n"), start, end); addError(onError, lineNumber, undefined, context, range, fixInfo); } -module.exports.addErrorContext = addErrorContext; +module.exports.Xr = addErrorContext; /** * Defines a range within a file (start line/column to end line/column, subset of MicromarkToken). @@ -39283,7 +39284,7 @@ const positionLessThanOrEqual = (lineA, columnA, lineB, columnB) => ( * @param {FileRange|MicromarkToken} rangeB Range B. * @returns {boolean} True iff the two ranges overlap. */ -module.exports.hasOverlap = function hasOverlap(rangeA, rangeB) { +module.exports.UM = function hasOverlap(rangeA, rangeB) { const lte = positionLessThanOrEqual(rangeA.startLine, rangeA.startColumn, rangeB.startLine, rangeB.startColumn); const first = lte ? rangeA : rangeB; const second = lte ? rangeB : rangeA; @@ -39291,7 +39292,7 @@ module.exports.hasOverlap = function hasOverlap(rangeA, rangeB) { }; // Determines if the front matter includes a title -module.exports.frontMatterHasTitle = +module.exports.Fl = function frontMatterHasTitle(/** @type {readonly string[]} */ frontMatterLines, /** @type {string} */ frontMatterTitlePattern) { const ignoreFrontMatter = (frontMatterTitlePattern !== undefined) && !frontMatterTitlePattern; @@ -39374,59 +39375,59 @@ function getReferenceLinkImageData(tokens) { case "gfmFootnoteDefinitionLabelString": labelPrefix = "^"; case "definitionLabelString": // eslint-disable-line no-fallthrough - { - // definitions and definitionLineIndices - const reference = normalizeReference(`${labelPrefix}${token.text}`); - if (definitions.has(reference)) { - duplicateDefinitions.push([ reference, token.startLine - 1 ]); - } else { - const parent = - micromark.getParentOfType(token, [ "definition" ]); - const destinationString = parent && - micromark.getDescendantsByType(parent, [ "definitionDestination", "definitionDestinationRaw", "definitionDestinationString" ])[0]?.text; - definitions.set( - reference, - [ token.startLine - 1, destinationString || "" ] - ); - } + { + // definitions and definitionLineIndices + const reference = normalizeReference(`${labelPrefix}${token.text}`); + if (definitions.has(reference)) { + duplicateDefinitions.push([ reference, token.startLine - 1 ]); + } else { + const parent = + micromark.getParentOfType(token, [ "definition" ]); + const destinationString = parent && + micromark.getDescendantsByType(parent, [ "definitionDestination", "definitionDestinationRaw", "definitionDestinationString" ])[0]?.text; + definitions.set( + reference, + [ token.startLine - 1, destinationString || "" ] + ); } break; + } case "gfmFootnoteCall": case "image": case "link": - { - // Identify if shortcut or full/collapsed - let isShortcut = (token.children.length === 1); - const isFullOrCollapsed = (token.children.length === 2) && !token.children.some((t) => t.type === "resource"); - const [ labelText ] = micromark.getDescendantsByType(token, [ "label", "labelText" ]); - const [ referenceString ] = micromark.getDescendantsByType(token, [ "reference", "referenceString" ]); - let label = getText(labelText); - // Identify if footnote - if (!isShortcut && !isFullOrCollapsed) { - const [ footnoteCallMarker, footnoteCallString ] = token.children.filter( - (t) => [ "gfmFootnoteCallMarker", "gfmFootnoteCallString" ].includes(t.type) - ); - if (footnoteCallMarker && footnoteCallString) { - label = `${footnoteCallMarker.text}${footnoteCallString.text}`; - isShortcut = true; - } - } - // Track link (handle shortcuts separately due to ambiguity in "text [text] text") - if (isShortcut || isFullOrCollapsed) { - addReferenceToDictionary(token, getText(referenceString) || label, isShortcut); + { + // Identify if shortcut or full/collapsed + let isShortcut = (token.children.length === 1); + const isFullOrCollapsed = (token.children.length === 2) && !token.children.some((t) => t.type === "resource"); + const [ labelText ] = micromark.getDescendantsByType(token, [ "label", "labelText" ]); + const [ referenceString ] = micromark.getDescendantsByType(token, [ "reference", "referenceString" ]); + let label = getText(labelText); + // Identify if footnote + if (!isShortcut && !isFullOrCollapsed) { + const [ footnoteCallMarker, footnoteCallString ] = token.children.filter( + (t) => [ "gfmFootnoteCallMarker", "gfmFootnoteCallString" ].includes(t.type) + ); + if (footnoteCallMarker && footnoteCallString) { + label = `${footnoteCallMarker.text}${footnoteCallString.text}`; + isShortcut = true; } } + // Track link (handle shortcuts separately due to ambiguity in "text [text] text") + if (isShortcut || isFullOrCollapsed) { + addReferenceToDictionary(token, getText(referenceString) || label, isShortcut); + } break; + } case "undefinedReferenceCollapsed": case "undefinedReferenceFull": case "undefinedReferenceShortcut": - { - const undefinedReference = micromark.getDescendantsByType(token, [ "undefinedReference" ])[0]; - const label = undefinedReference.children.map((t) => t.text).join(""); - const isShortcut = (token.type === "undefinedReferenceShortcut"); - addReferenceToDictionary(token, label, isShortcut); - } + { + const undefinedReference = micromark.getDescendantsByType(token, [ "undefinedReference" ])[0]; + const label = undefinedReference.children.map((t) => t.text).join(""); + const isShortcut = (token.type === "undefinedReferenceShortcut"); + addReferenceToDictionary(token, label, isShortcut); break; + } } } return { @@ -39437,7 +39438,7 @@ function getReferenceLinkImageData(tokens) { definitionLineIndices }; } -module.exports.getReferenceLinkImageData = getReferenceLinkImageData; +module.exports.fL = getReferenceLinkImageData; /** * Gets the most common line ending, falling back to the platform default. @@ -39450,7 +39451,7 @@ function getPreferredLineEnding(input, os) { let cr = 0; let lf = 0; let crlf = 0; - const endings = input.match(newLineRe) || []; + const endings = input.match(newlineRe) || []; for (const ending of endings) { // eslint-disable-next-line default-case switch (ending) { @@ -39477,7 +39478,7 @@ function getPreferredLineEnding(input, os) { } return preferredLineEnding; } -module.exports.getPreferredLineEnding = getPreferredLineEnding; +module.exports.Z_ = getPreferredLineEnding; /** * Expands a path with a tilde to an absolute path. @@ -39490,7 +39491,7 @@ function expandTildePath(file, os) { const homedir = os && os.homedir && os.homedir(); return homedir ? file.replace(/^~($|\/|\\)/, `${homedir}$1`) : file; } -module.exports.expandTildePath = expandTildePath; +module.exports.ww = expandTildePath; /** @typedef {import("../lib/markdownlint.mjs").LintError[]} LintErrors */ /** @typedef {import("../lib/markdownlint.mjs").LintResults} LintResults */ @@ -39566,7 +39567,6 @@ function convertLintErrorsVersion2To0(errors) { function copyAndTransformResults(results, transform) { /** @type {Object.} */ const newResults = {}; - Object.defineProperty(newResults, "toString", { "value": results.toString }); for (const key of Object.keys(results)) { const arr = results[key].map((r) => ({ ...r })); newResults[key] = transform(arr); @@ -39581,7 +39581,7 @@ function copyAndTransformResults(results, transform) { * @param {LintResults} results Lint results (v3). * @returns {LintResults} Lint results (v0). */ -module.exports.convertToResultVersion0 = function convertToResultVersion0(results) { +__webpack_unused_export__ = function convertToResultVersion0(results) { return copyAndTransformResults(results, (r) => convertLintErrorsVersion2To0(convertLintErrorsVersion3To2(r))); }; @@ -39591,7 +39591,7 @@ module.exports.convertToResultVersion0 = function convertToResultVersion0(result * @param {LintResults} results Lint results (v3). * @returns {LintResults} Lint results (v1). */ -module.exports.convertToResultVersion1 = function convertToResultVersion1(results) { +__webpack_unused_export__ = function convertToResultVersion1(results) { return copyAndTransformResults(results, (r) => convertLintErrorsVersion2To1(convertLintErrorsVersion3To2(r))); }; @@ -39601,7 +39601,7 @@ module.exports.convertToResultVersion1 = function convertToResultVersion1(result * @param {LintResults} results Lint results (v3). * @returns {LintResults} Lint results (v2). */ -module.exports.convertToResultVersion2 = function convertToResultVersion2(results) { +__webpack_unused_export__ = function convertToResultVersion2(results) { return copyAndTransformResults(results, convertLintErrorsVersion3To2); }; @@ -39611,7 +39611,7 @@ module.exports.convertToResultVersion2 = function convertToResultVersion2(result * @param {LintResults|undefined} lintResults Lint results. * @returns {string[]} Lint error strings. */ -module.exports.formatLintResults = function formatLintResults(lintResults) { +__webpack_unused_export__ = function formatLintResults(lintResults) { const results = []; const entries = Object.entries(lintResults || {}); entries.sort((a, b) => a[0].localeCompare(b[0])); @@ -39641,7 +39641,7 @@ module.exports.formatLintResults = function formatLintResults(lintResults) { -const { flatTokensSymbol, htmlFlowSymbol, newLineRe } = __nccwpck_require__(3408); +const { flatTokensSymbol, htmlFlowSymbol, newlineRe } = __nccwpck_require__(3408); // eslint-disable-next-line jsdoc/valid-types /** @typedef {import("micromark-util-types", { with: { "resolution-mode": "import" } }).TokenType} TokenType */ @@ -39791,7 +39791,6 @@ function getBlockQuotePrefixText(tokens, lineNumber, count = 1) { .map((prefix) => prefix.text) .join("") .trimEnd() - // eslint-disable-next-line unicorn/prefer-spread .concat("\n") .repeat(count); }; @@ -39863,7 +39862,7 @@ function getHeadingText(heading) { .flatMap((descendant) => descendant.children.filter((child) => child.type !== "htmlText")) .map((data) => data.text) .join("") - .replace(newLineRe, " "); + .replace(newlineRe, " "); } /** @@ -39924,7 +39923,9 @@ function isDocfxTab(heading) { // See https://dotnet.github.io/docfx/docs/markdown.html?tabs=linux%2Cdotnet#tabs if (heading?.type === "atxHeading") { const headingTexts = getDescendantsByType(heading, [ "atxHeadingText" ]); + // eslint-disable-next-line unicorn/better-dom-traversing if ((headingTexts.length === 1) && (headingTexts[0].children.length === 1) && (headingTexts[0].children[0].type === "link")) { + // eslint-disable-next-line unicorn/better-dom-traversing const resourceDestinationStrings = filterByTypes(headingTexts[0].children[0].children, [ "resourceDestinationString" ]); return (resourceDestinationStrings.length === 1) && docfxTabSyntaxRe.test(resourceDestinationStrings[0].text); } @@ -39987,7 +39988,7 @@ module.exports.htmlFlowSymbol = Symbol("html-flow"); // Regular expression for matching common newline characters // See NEWLINES_RE in markdown-it/lib/rules_core/normalize.js -module.exports.newLineRe = /\r\n?|\n/g; +module.exports.newlineRe = /\r\n?|\n/g; // Regular expression for matching next lines module.exports.nextLinesRe = /[\r\n][\s\S]*$/; @@ -40027,10 +40028,11 @@ module.exports = { -const { newLineRe } = __nccwpck_require__(3810); +const { newlineRe } = __nccwpck_require__(3408); // @ts-expect-error https://github.com/microsoft/TypeScript/issues/52529 /** @typedef {import("markdownlint").MarkdownIt} MarkdownIt */ +/** @typedef {import("markdownlint").MarkdownItBaseToken} MarkdownItBaseToken */ /** @typedef {import("markdownlint").MarkdownItToken} MarkdownItToken */ /** @typedef {import("markdownlint").Plugin} Plugin */ @@ -40059,7 +40061,7 @@ function forEachInlineCodeSpan(input, handler) { backticksLengthAndIndex.push([ match[0].length, match.index ]); } const newLinesIndex = []; - while ((match = newLineRe.exec(input)) !== null) { + while ((match = newlineRe.exec(input)) !== null) { newLinesIndex.push(match.index); } let lineIndex = 0; @@ -40072,12 +40074,12 @@ function forEachInlineCodeSpan(input, handler) { const [ endLength, endIndex ] = backticksLengthAndIndex[j]; if (startLength === endLength) { for (; k < newLinesIndex.length; k++) { - const newLineIndex = newLinesIndex[k]; - if (startIndex < newLineIndex) { + const newlineIndex = newLinesIndex[k]; + if (startIndex < newlineIndex) { break; } lineIndex++; - lineStartIndex = newLineIndex + 1; + lineStartIndex = newlineIndex + 1; } const columnIndex = startIndex - lineStartIndex + startLength; handler( @@ -40122,7 +40124,7 @@ function freezeToken(token) { /** * Annotate tokens with line/lineNumber and freeze them. * - * @param {import("markdown-it").Token[]} tokens Array of markdown-it tokens. + * @param {MarkdownItBaseToken[]} tokens Array of markdown-it tokens. * @param {string[]} lines Lines of Markdown content. * @returns {void} */ @@ -40156,7 +40158,7 @@ function annotateAndFreezeTokens(tokens, lines) { const codeSpanExtraLines = []; if (token.children.some((child) => child.type === "code_inline")) { forEachInlineCodeSpan(token.content, (code) => { - codeSpanExtraLines.push(code.split(newLineRe).length - 1); + codeSpanExtraLines.push(code.split(newlineRe).length - 1); }); } let lineNumber = token.lineNumber; @@ -40204,10 +40206,10 @@ module.exports = { -// @ts-ignore -// eslint-disable-next-line camelcase, no-inline-comments, no-undef -const nativeRequire = (typeof __WEBPACK_EXTERNAL_createRequire(import.meta.url) === "undefined") ? __nccwpck_require__(1484) : /* c8 ignore next */ __WEBPACK_EXTERNAL_createRequire(import.meta.url); // Captures the native require implementation (even under webpack). +// @ts-ignore +// eslint-disable-next-line no-underscore-dangle +const nativeRequire = globalThis.__non_webpack_require__ ?? __nccwpck_require__(1484); /** * @typedef RequireResolveOptions @@ -40294,6 +40296,7 @@ var utils_namespaceObject = {}; __nccwpck_require__.r(utils_namespaceObject); __nccwpck_require__.d(utils_namespaceObject, { arrayReplaceAt: () => (arrayReplaceAt), + asciiTrim: () => (asciiTrim), assign: () => (utils_assign), escapeHtml: () => (escapeHtml), escapeRE: () => (escapeRE), @@ -40301,6 +40304,7 @@ __nccwpck_require__.d(utils_namespaceObject, { has: () => (has), isMdAsciiPunct: () => (isMdAsciiPunct), isPunctChar: () => (isPunctChar), + isPunctCharCode: () => (isPunctCharCode), isSpace: () => (isSpace), isString: () => (isString), isValidEntityCode: () => (isValidEntityCode), @@ -41949,6 +41953,10 @@ function isPunctChar (ch) { return regex.test(ch) || S_regex.test(ch) } +function isPunctCharCode (code) { + return isPunctChar(utils_fromCodePoint(code)) +} + // Markdown ASCII punctuation characters. // // !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \, ], ^, _, `, {, |, }, or ~ @@ -42010,6 +42018,7 @@ function normalizeReference (str) { // (remove this when node v10 is no longer supported). // if ('ẞ'.toLowerCase() === 'Ṿ') { + /* c8 ignore next 2 */ str = str.replace(/ẞ/g, 'ß') } @@ -42048,6 +42057,28 @@ function normalizeReference (str) { return str.toLowerCase().toUpperCase() } +function isAsciiTrimmable (c) { + return c === 0x20 || c === 0x09 || c === 0x0a || c === 0x0d +} + +// "Light" .trim() for blocks (headers, paragraphs), where unicode spaces +// should be preserved. +function asciiTrim (str) { + let start = 0 + for (; start < str.length; start++) { + if (!isAsciiTrimmable(str.charCodeAt(start))) { + break + } + } + let end = str.length - 1 + for (; end >= start; end--) { + if (!isAsciiTrimmable(str.charCodeAt(end))) { + break + } + } + return str.slice(start, end + 1) +} + // Re-export libraries commonly used in both markdown-it and its plugins, // so plugins won't have to depend on them explicitly, which reduces their // bundled size (e.g. a browser build). @@ -43437,14 +43468,36 @@ const QUOTE_TEST_RE = /['"]/ const QUOTE_RE = /['"]/g const APOSTROPHE = '\u2019' /* ’ */ -function replaceAt (str, index, ch) { - return str.slice(0, index) + ch + str.slice(index + 1) +function addReplacement (replacements, tokenIdx, pos, ch) { + if (!replacements[tokenIdx]) { + replacements[tokenIdx] = [] + } + + replacements[tokenIdx].push({ pos, ch }) +} + +function applyReplacements (str, replacements) { + let result = '' + let lastPos = 0 + + replacements.sort((a, b) => a.pos - b.pos) + + for (let i = 0; i < replacements.length; i++) { + const replacement = replacements[i] + + result += str.slice(lastPos, replacement.pos) + replacement.ch + lastPos = replacement.pos + 1 + } + + return result + str.slice(lastPos) } function process_inlines (tokens, state) { let j const stack = [] + // token index -> list of replacements in the original token content + const replacements = {} for (let i = 0; i < tokens.length; i++) { const token = tokens[i] @@ -43458,9 +43511,9 @@ function process_inlines (tokens, state) { if (token.type !== 'text') { continue } - let text = token.content + const text = token.content let pos = 0 - let max = text.length + const max = text.length /* eslint no-labels:0,block-scoped-var:0 */ OUTER: @@ -43508,8 +43561,8 @@ function process_inlines (tokens, state) { } } - const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar)) - const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar)) + const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctCharCode(lastChar) + const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctCharCode(nextChar) const isLastWhiteSpace = isWhiteSpace(lastChar) const isNextWhiteSpace = isWhiteSpace(nextChar) @@ -43552,7 +43605,7 @@ function process_inlines (tokens, state) { if (!canOpen && !canClose) { // middle of word if (isSingle) { - token.content = replaceAt(token.content, t.index, APOSTROPHE) + addReplacement(replacements, i, t.index, APOSTROPHE) } continue } @@ -43575,18 +43628,8 @@ function process_inlines (tokens, state) { closeQuote = state.md.options.quotes[1] } - // replace token.content *before* tokens[item.token].content, - // because, if they are pointing at the same token, replaceAt - // could mess up indices when quote length != 1 - token.content = replaceAt(token.content, t.index, closeQuote) - tokens[item.token].content = replaceAt( - tokens[item.token].content, item.pos, openQuote) - - pos += closeQuote.length - 1 - if (item.token === i) { pos += openQuote.length - 1 } - - text = token.content - max = text.length + addReplacement(replacements, i, t.index, closeQuote) + addReplacement(replacements, item.token, item.pos, openQuote) stack.length = j continue OUTER @@ -43602,10 +43645,14 @@ function process_inlines (tokens, state) { level: thisLevel }) } else if (canClose && isSingle) { - token.content = replaceAt(token.content, t.index, APOSTROPHE) + addReplacement(replacements, i, t.index, APOSTROPHE) } } } + + Object.keys(replacements).forEach(function (tokenIdx) { + tokens[tokenIdx].content = applyReplacements(tokens[tokenIdx].content, replacements[tokenIdx]) + }) } function smartquotes (state) { @@ -45252,11 +45299,22 @@ function html_block (state, startLine, endLine, silent) { let nextLine = startLine + 1 + // Block types 6 and 7 (the only ones whose end condition is a blank line) + // have `/^$/` as their closing regexp. For all other types (1-5, e.g. + // `", startIndex); @@ -73742,7 +73935,7 @@ function lintContent( const { effectiveConfig, enabledRulesPerLineNumber, enabledRuleList, rulesSeverity } = getEnabledRulesPerLineNumber( ruleList, - content.split(helpers_helpers.newLineRe), + content.split(helpers_helpers/* newLineRe */.Or), frontMatterLines, noInlineConfig, config, @@ -73762,9 +73955,9 @@ function lintContent( []; // Hide the content of HTML comments from rules const preClearedContent = content; - content = helpers_helpers.clearHtmlCommentText(content); + content = helpers_helpers/* clearHtmlCommentText */.X6(content); // Parse content into lines and get markdown-it tokens - const lines = content.split(helpers_helpers.newLineRe); + const lines = content.split(helpers_helpers/* newLineRe */.Or); // Function to run after fetching markdown-it tokens (when needed) const lintContentInternal = (/** @type {MarkdownItToken[]} */ markdownitTokens) => { // Create (frozen) parameters for rules @@ -73794,7 +73987,7 @@ function lintContent( initialize({ ...paramsBase, "parsers": parsersMicromark, - "config": null + "config": {} }); // Function to run for each rule /** @type {LintError[]} */ @@ -73832,7 +74025,7 @@ function lintContent( // eslint-disable-next-line jsdoc/require-jsdoc function onError(/** @type {RuleOnErrorInfo} */ errorInfo) { if (!errorInfo || - !helpers_helpers.isNumber(errorInfo.lineNumber) || + !helpers_helpers/* isNumber */.Et(errorInfo.lineNumber) || (errorInfo.lineNumber < 1) || (errorInfo.lineNumber > lines.length)) { throwError("lineNumber"); @@ -73842,23 +74035,23 @@ function lintContent( return; } if (errorInfo.detail && - !helpers_helpers.isString(errorInfo.detail)) { + !helpers_helpers/* isString */.Kg(errorInfo.detail)) { throwError("detail"); } if (errorInfo.context && - !helpers_helpers.isString(errorInfo.context)) { + !helpers_helpers/* isString */.Kg(errorInfo.context)) { throwError("context"); } if (errorInfo.information && - !helpers_helpers.isUrl(errorInfo.information)) { + !helpers_helpers/* isUrl */.gU(errorInfo.information)) { throwError("information"); } if (errorInfo.range && (!Array.isArray(errorInfo.range) || (errorInfo.range.length !== 2) || - !helpers_helpers.isNumber(errorInfo.range[0]) || + !helpers_helpers/* isNumber */.Et(errorInfo.range[0]) || (errorInfo.range[0] < 1) || - !helpers_helpers.isNumber(errorInfo.range[1]) || + !helpers_helpers/* isNumber */.Et(errorInfo.range[1]) || (errorInfo.range[1] < 1) || ((errorInfo.range[0] + errorInfo.range[1] - 1) > lines[errorInfo.lineNumber - 1].length))) { @@ -73867,11 +74060,11 @@ function lintContent( const fixInfo = errorInfo.fixInfo; const cleanFixInfo = {}; if (fixInfo) { - if (!helpers_helpers.isObject(fixInfo)) { + if (!helpers_helpers/* isObject */.Gv(fixInfo)) { throwError("fixInfo"); } if (fixInfo.lineNumber !== undefined) { - if ((!helpers_helpers.isNumber(fixInfo.lineNumber) || + if ((!helpers_helpers/* isNumber */.Et(fixInfo.lineNumber) || (fixInfo.lineNumber < 1) || (fixInfo.lineNumber > lines.length))) { throwError("fixInfo.lineNumber"); @@ -73881,7 +74074,7 @@ function lintContent( } const effectiveLineNumber = fixInfo.lineNumber || errorInfo.lineNumber; if (fixInfo.editColumn !== undefined) { - if ((!helpers_helpers.isNumber(fixInfo.editColumn) || + if ((!helpers_helpers/* isNumber */.Et(fixInfo.editColumn) || (fixInfo.editColumn < 1) || (fixInfo.editColumn > lines[effectiveLineNumber - 1].length + 1))) { @@ -73890,7 +74083,7 @@ function lintContent( cleanFixInfo.editColumn = fixInfo.editColumn; } if (fixInfo.deleteCount !== undefined) { - if ((!helpers_helpers.isNumber(fixInfo.deleteCount) || + if ((!helpers_helpers/* isNumber */.Et(fixInfo.deleteCount) || (fixInfo.deleteCount < -1) || (fixInfo.deleteCount > lines[effectiveLineNumber - 1].length))) { @@ -73899,7 +74092,7 @@ function lintContent( cleanFixInfo.deleteCount = fixInfo.deleteCount; } if (fixInfo.insertText !== undefined) { - if (!helpers_helpers.isString(fixInfo.insertText)) { + if (!helpers_helpers/* isString */.Kg(fixInfo.insertText)) { throwError("fixInfo.insertText"); } cleanFixInfo.insertText = fixInfo.insertText; @@ -73911,8 +74104,8 @@ function lintContent( "ruleNames": rule.names, "ruleDescription": rule.description, "ruleInformation": information ? information.href : null, - "errorDetail": errorInfo.detail?.replace(helpers_helpers.newLineRe, " ") || null, - "errorContext": errorInfo.context?.replace(helpers_helpers.newLineRe, " ") || null, + "errorDetail": errorInfo.detail?.replace(helpers_helpers/* newLineRe */.Or, " ") || null, + "errorContext": errorInfo.context?.replace(helpers_helpers/* newLineRe */.Or, " ") || null, "errorRange": errorInfo.range ? [ ...errorInfo.range ] : null, "fixInfo": fixInfo ? cleanFixInfo : null, // @ts-ignore @@ -74073,10 +74266,10 @@ function lintInput(options, synchronous, callback) { [ options.customRules || [] ] .flat() .map((rule) => ({ - "names": helpers_helpers.cloneIfArray(rule.names), + "names": helpers_helpers/* cloneIfArray */.YW(rule.names), "description": rule.description, - "information": helpers_helpers.cloneIfUrl(rule.information), - "tags": helpers_helpers.cloneIfArray(rule.tags), + "information": helpers_helpers/* cloneIfUrl */.c0(rule.information), + "tags": helpers_helpers/* cloneIfArray */.YW(rule.tags), "parser": rule.parser, "asynchronous": rule.asynchronous, "function": rule.function @@ -74100,13 +74293,10 @@ function lintInput(options, synchronous, callback) { const config = options.config || { "default": true }; const configParsers = options.configParsers || undefined; const frontMatter = (options.frontMatter === undefined) ? - helpers_helpers.frontMatterRe : + helpers_helpers/* frontMatterRe */.Q9 : options.frontMatter; const handleRuleFailures = !!options.handleRuleFailures; const noInlineConfig = !!options.noInlineConfig; - // @ts-ignore - // eslint-disable-next-line dot-notation - const resultVersion = (options["resultVersion"] === undefined) ? 3 : options["resultVersion"]; const markdownItFactory = options.markdownItFactory || (() => { throw new Error("The option 'markdownItFactory' was required (due to the option 'customRules' including a rule requiring the 'markdown-it' parser), but 'markdownItFactory' was not set."); }); @@ -74114,7 +74304,7 @@ function lintInput(options, synchronous, callback) { // @ts-ignore const fs = options.fs || node_imports_node_fs; const aliasToRuleNames = mapAliasToRuleNames(ruleList); - const results = newResults(ruleList); + const results = {}; let done = false; let concurrency = 0; // eslint-disable-next-line jsdoc/require-jsdoc @@ -74172,18 +74362,12 @@ function lintInput(options, synchronous, callback) { lintWorkerCallback ); } else if (concurrency === 0) { - // Finish + // Finished, sort keys for consistency done = true; - // Deprecated: Convert results to specified resultVersion - let convertedResults = results; - if (resultVersion === 0) { - convertedResults = helpers_helpers.convertToResultVersion0(results); - } else if (resultVersion === 1) { - convertedResults = helpers_helpers.convertToResultVersion1(results); - } else if (resultVersion === 2) { - convertedResults = helpers_helpers.convertToResultVersion2(results); - } - return callback(null, convertedResults); + const sortedEntries = Object.entries(results); + sortedEntries.sort(([ a ], [ b ]) => a.localeCompare(b)); + const sortedResults = Object.fromEntries(sortedEntries); + return callback(null, sortedResults); } return null; } @@ -74333,7 +74517,7 @@ function extendConfig(config, file, parsers, fs, callback) { if (configExtends) { return resolveConfigExtends( file, - helpers_helpers.expandTildePath(configExtends, node_imports_node_os), + helpers_helpers/* expandTildePath */.ww(configExtends, node_imports_node_os), fs, // eslint-disable-next-line no-use-before-define (_, resolvedExtends) => readConfigAsync( @@ -74406,7 +74590,7 @@ function readConfigAsync(file, parsers, fs, callback) { // @ts-ignore const fsLike = fs || node_imports_node_fs; // Read file - file = helpers_helpers.expandTildePath(file, node_imports_node_os); + file = helpers_helpers/* expandTildePath */.ww(file, node_imports_node_os); fsLike.readFile(file, "utf8", (err, content) => { if (err) { // @ts-ignore @@ -74523,8 +74707,8 @@ function applyFix(line, fixInfo, lineEnding = "\n") { * @returns {string} Fixed content. */ function applyFixes(input, errors) { - const lineEnding = helpers_helpers.getPreferredLineEnding(input, node_imports_node_os); - const lines = input.split(helpers_helpers.newLineRe); + const lineEnding = helpers_helpers/* getPreferredLineEnding */.Z_(input, node_imports_node_os); + const lines = input.split(helpers_helpers/* newLineRe */.Or); // Normalize fixInfo objects let fixInfos = errors .filter((error) => error.fixInfo) @@ -74650,26 +74834,39 @@ function getVersion() { */ /** - * markdown-it token. + * markdown-it base token. * - * @typedef {Object} MarkdownItToken - * @property {string[][]} attrs HTML attributes. + * @typedef {Object} MarkdownItBaseToken + * @property {string[][] | null} attrs HTML attributes. * @property {boolean} block Block-level token. - * @property {MarkdownItToken[]} children Child nodes. + * @property {MarkdownItBaseToken[] | null} children Child nodes. * @property {string} content Tag contents. * @property {boolean} hidden Ignore element. * @property {string} info Fence info. * @property {number} level Nesting level. - * @property {number[]} map Beginning/ending line numbers. + * @property {number[] | null} map Beginning/ending line numbers. * @property {string} markup Markup text. * @property {Object} meta Arbitrary data. * @property {number} nesting Level change. * @property {string} tag HTML tag name. * @property {string} type Token type. + */ + +/** + * markdown-it extended token. + * + * @typedef {Object} MarkdownItExtendedToken + * @property {MarkdownItExtendedToken[] | null} children Child nodes. * @property {number} lineNumber Line number (1-based). * @property {string} line Line content. */ +/** + * markdown-it token. + * + * @typedef {MarkdownItBaseToken & MarkdownItExtendedToken} MarkdownItToken + */ + /** @typedef {import("micromark-util-types").TokenType} MicromarkTokenType */ /** @@ -74735,7 +74932,7 @@ function getVersion() { * @callback MarkdownItParse * @param {string} src Source string. * @param {Object} env Environment sandbox. - * @returns {import("markdown-it").Token[]} Tokens. + * @returns {MarkdownItBaseToken[]} Tokens. */ /** @@ -74847,12 +75044,6 @@ function getVersion() { * @typedef {import("./configuration-strict.d.ts").ConfigurationStrict} ConfigurationStrict */ -/** - * Rule configuration object. - * - * @typedef {boolean | Object} RuleConfiguration Rule configuration. - */ - /** * Parses a configuration string and returns a configuration object. * @@ -74879,6 +75070,14 @@ function getVersion() { * @returns {void} */ +/* eslint-disable jsdoc/reject-any-type */ + +/** + * Rule configuration object. + * + * @typedef {boolean | any} RuleConfiguration Rule configuration. + */ + ;// CONCATENATED MODULE: ./node_modules/markdownlint/lib/exports.mjs // @ts-check @@ -74895,6 +75094,7 @@ function getVersion() { /** @typedef {import("./markdownlint.mjs").LintError} LintError */ /** @typedef {import("./markdownlint.mjs").LintResults} LintResults */ /** @typedef {import("./markdownlint.mjs").MarkdownItFactory} MarkdownItFactory */ +/** @typedef {import("./markdownlint.mjs").MarkdownItBaseToken} MarkdownItBaseToken */ /** @typedef {import("./markdownlint.mjs").MarkdownItToken} MarkdownItToken */ /** @typedef {import("./markdownlint.mjs").MarkdownParsers} MarkdownParsers */ /** @typedef {import("./markdownlint.mjs").MicromarkToken} MicromarkToken */ @@ -74948,7 +75148,7 @@ const appendToArray = (destination, source) => { // @ts-check const packageName = "markdownlint-cli2"; -const packageVersion = "0.22.1"; +const packageVersion = "0.23.0"; const libraryName = "markdownlint"; @@ -74966,11 +75166,48 @@ const cli2SchemaKeys = new Set([ "noInlineConfig", "noProgress", "outputFormatters", + "overrides", "showFound" ]); +;// CONCATENATED MODULE: ./node_modules/markdownlint-cli2/clone-options.mjs +// @ts-check + +/** @typedef {import("markdownlint-cli2").Options} Options */ + +/** + * Clones (the necessary parts of) an options (or configuration) object. + * @param {Options | null | undefined} obj Options object. + * @returns {Options} Cloned object. + */ +const cloneOptions = (obj) => { + if (!obj) { + // @ts-ignore + return obj; + } + const clone = { + ...obj + }; + if (clone.config) { + clone.config = { ...clone.config }; + } + if (clone.overrides) { + clone.overrides = clone.overrides.map( + (override) => override.config + ? { + ...override, + "config": { ...override.config } + } + : override + ); + } + return clone; +}; + +/* harmony default export */ const clone_options = (cloneOptions); + ;// CONCATENATED MODULE: ./node_modules/markdownlint-cli2/merge-options.mjs // @ts-check @@ -75026,184 +75263,6 @@ const jsoncParse = (text) => { /* harmony default export */ const jsonc_parse = (jsoncParse); -;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/error.js -/*! - * Copyright (c) Squirrel Chat et al., All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -function getLineColFromPtr(string, ptr) { - let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g); - return [lines.length, lines.pop().length + 1]; -} -function makeCodeBlock(string, line, column) { - let lines = string.split(/\r\n|\n|\r/g); - let codeblock = ''; - let numberLen = (Math.log10(line + 1) | 0) + 1; - for (let i = line - 1; i <= line + 1; i++) { - let l = lines[i - 1]; - if (!l) - continue; - codeblock += i.toString().padEnd(numberLen, ' '); - codeblock += ': '; - codeblock += l; - codeblock += '\n'; - if (i === line) { - codeblock += ' '.repeat(numberLen + column + 2); - codeblock += '^\n'; - } - } - return codeblock; -} -class TomlError extends Error { - line; - column; - codeblock; - constructor(message, options) { - const [line, column] = getLineColFromPtr(options.toml, options.ptr); - const codeblock = makeCodeBlock(options.toml, line, column); - super(`Invalid TOML document: ${message}\n\n${codeblock}`, options); - this.line = line; - this.column = column; - this.codeblock = codeblock; - } -} - -;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/util.js -/*! - * Copyright (c) Squirrel Chat et al., All rights reserved. - * SPDX-License-Identifier: BSD-3-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -function isEscaped(str, ptr) { - let i = 0; - while (str[ptr - ++i] === '\\') - ; - return --i && (i % 2); -} -function indexOfNewline(str, start = 0, end = str.length) { - let idx = str.indexOf('\n', start); - if (str[idx - 1] === '\r') - idx--; - return idx <= end ? idx : -1; -} -function skipComment(str, ptr) { - for (let i = ptr; i < str.length; i++) { - let c = str[i]; - if (c === '\n') - return i; - if (c === '\r' && str[i + 1] === '\n') - return i + 1; - if ((c < '\x20' && c !== '\t') || c === '\x7f') { - throw new TomlError('control characters are not allowed in comments', { - toml: str, - ptr: ptr, - }); - } - } - return str.length; -} -function skipVoid(str, ptr, banNewLines, banComments) { - let c; - while (1) { - while ((c = str[ptr]) === ' ' || c === '\t' || (!banNewLines && (c === '\n' || c === '\r' && str[ptr + 1] === '\n'))) - ptr++; - // Tucking the return statement here would save 5 characters >:) - // But TypeScript fails to detect there is no way to exit the loop so it complains about the lack of final return - if (banComments || c !== '#') - break; - ptr = skipComment(str, ptr); - } - return ptr; -} -function skipUntil(str, ptr, sep, end, banNewLines = false) { - if (!end) { - ptr = indexOfNewline(str, ptr); - return ptr < 0 ? str.length : ptr; - } - for (let i = ptr; i < str.length; i++) { - let c = str[i]; - if (c === '#') { - i = indexOfNewline(str, i); - } - else if (c === sep) { - return i + 1; - } - else if (c === end || (banNewLines && (c === '\n' || (c === '\r' && str[i + 1] === '\n')))) { - return i; - } - } - throw new TomlError('cannot find end of structure', { - toml: str, - ptr: ptr - }); -} -function getStringEnd(str, seek) { - let first = str[seek]; - let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] - ? str.slice(seek, seek + 3) - : first; - seek += target.length - 1; - do - seek = str.indexOf(target, ++seek); - while (seek > -1 && first !== "'" && isEscaped(str, seek)); - if (seek > -1) { - seek += target.length; - if (target.length > 1) { - if (str[seek] === first) - seek++; - if (str[seek] === first) - seek++; - } - } - return seek; -} - ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/date.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -75332,7 +75391,72 @@ class TomlDate extends Date { return date; } } - +//# sourceMappingURL=date.js.map +;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/error.js +/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +function getLineColFromPtr(string, ptr) { + let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g); + return [lines.length, lines.pop().length + 1]; +} +function makeCodeBlock(string, line, column) { + let lines = string.split(/\r\n|\n|\r/g); + let codeblock = ''; + let numberLen = (Math.log10(line + 1) | 0) + 1; + for (let i = line - 1; i <= line + 1; i++) { + let l = lines[i - 1]; + if (!l) + continue; + codeblock += i.toString().padEnd(numberLen, ' '); + codeblock += ': '; + codeblock += l; + codeblock += '\n'; + if (i === line) { + codeblock += ' '.repeat(numberLen + column + 2); + codeblock += '^\n'; + } + } + return codeblock; +} +class TomlError extends Error { + line; + column; + codeblock; + constructor(message, options) { + const [line, column] = getLineColFromPtr(options.toml, options.ptr); + const codeblock = makeCodeBlock(options.toml, line, column); + super(`Invalid TOML document: ${message}\n\n${codeblock}`, options); + this.line = line; + this.column = column; + this.codeblock = codeblock; + } +} +//# sourceMappingURL=error.js.map ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/primitive.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -75363,102 +75487,159 @@ class TomlDate extends Date { */ - +// let CTRL_REGEX = /[\x00-\x08\x0f-\x1f\x7f]/ let INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/; let FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/; let LEADING_ZERO = /^[+-]?0[0-9_]/; -let ESCAPE_REGEX = /^[0-9a-f]{2,8}$/i; -let ESC_MAP = { - b: '\b', - t: '\t', - n: '\n', - f: '\f', - r: '\r', - e: '\x1b', - '"': '"', - '\\': '\\', -}; -function parseString(str, ptr = 0, endPtr = str.length) { - let isLiteral = str[ptr] === '\''; - let isMultiline = str[ptr++] === str[ptr] && str[ptr] === str[ptr + 1]; +function parseString(str, ptr) { + let c = str[ptr++]; + let first = c; + let isLiteral = c === "'"; + let isMultiline = c === str[ptr] && c === str[ptr + 1]; if (isMultiline) { - endPtr -= 2; - if (str[ptr += 2] === '\r') - ptr++; - if (str[ptr] === '\n') + // Trim initial newline + if (str[ptr += 2] === '\n') ptr++; + else if (str[ptr] === '\r' && str[ptr + 1] === '\n') + ptr += 2; } - let tmp = 0; - let isEscape; + /* + The fast path does not seem to bring significant performance gains, so it's commented out. + Kept for reference and/or future fafoing. + + Without: spec 5.08 µs/iter 3.88 ipc (99.44% cache) 23.90 branch misses 28.61k cycles 111.01k instructions + 5MB 115.73 ms/iter 2.51 ipc (98.36% cache) 3.12M branch misses 619.30M cycles 1.56G instructions + + With: spec 5.09 µs/iter 3.90 ipc (99.46% cache) 24.42 branch misses 28.57k cycles 111.49k instructions + 5MB 113.89 ms/iter 2.47 ipc (98.38% cache) 3.12M branch misses 611.94M cycles 1.51G instructions + + if (c === "'") { + // Literal strings fast path - no transform needs to occur; just grab the str and that's it + let endPtr = str.indexOf(isMultiline ? "'''" : "'", ptr) + if (endPtr < 0) { + throw new TomlError("unfinished string literal", { toml: str, ptr }) + } + + if (isMultiline) { + // If the string ends with 4-5 quotes, then the first 1-2 are part of the string + if (str[endPtr + 3] === "'") endPtr++ + if (str[endPtr + 3] === "'") endPtr++ + } + + let string = str.slice(ptr, endPtr) + if (CTRL_REGEX.test(string)) { + let match = string.match(CTRL_REGEX)! + throw new TomlError('control characters are not allowed in strings', { toml: str, ptr: ptr + (match.index ?? 0) }) + } + return [string, endPtr + (isMultiline ? 3 : 1)] + } + */ let parsed = ''; let sliceStart = ptr; - while (ptr < endPtr - 1) { - let c = str[ptr++]; - if (c === '\n' || (c === '\r' && str[ptr] === '\n')) { - if (!isMultiline) { - throw new TomlError('newlines are not allowed in strings', { - toml: str, - ptr: ptr - 1, - }); - } + // states: + // 0 - decoding + // 1 - decoding escape + // 2 - whitespace escape (no newline encountered yet, must fail on non-whitespace) + // 3 - whitespace escape (newline encountered, allowed to transition back to normal decode) + let state = 0; + for (let i = ptr; i < str.length; i++) { + c = str[i]; + // Deal with newlines first, since that simplifies control character checking and handling across all states + if (isMultiline && (c === '\n' || (c === '\r' && str[i + 1] === '\n'))) { + state = state && 3; } + // Control characters are banned in TOML, so we throw an error if we encounter them else if ((c < '\x20' && c !== '\t') || c === '\x7f') { throw new TomlError('control characters are not allowed in strings', { toml: str, - ptr: ptr - 1, + ptr: i, }); } - if (isEscape) { - isEscape = false; - if (c === 'x' || c === 'u' || c === 'U') { - // Unicode escape - let code = str.slice(ptr, (ptr += (c === 'x' ? 2 : c === 'u' ? 4 : 8))); - if (!ESCAPE_REGEX.test(code)) { - throw new TomlError('invalid unicode escape', { - toml: str, - ptr: tmp, - }); - } - try { - parsed += String.fromCodePoint(parseInt(code, 16)); - } - catch { - throw new TomlError('invalid unicode escape', { - toml: str, - ptr: tmp, - }); - } + // The string might terminate while we're parsing through a newline escape. + // It must have encountered a newline; otherwise, it'll simply fail in another branch. + else if ((!state || state === 3) && c === first && (!isMultiline || (str[i + 1] === first && str[i + 2] === first))) { + if (isMultiline) { + // If the string ends with 4-5 quotes, then the first 1-2 are part of the string + if (str[i + 3] === first) + i++; + if (str[i + 3] === first) + i++; } - else if (isMultiline && (c === '\n' || c === ' ' || c === '\t' || c === '\r')) { - // Multiline escape - ptr = skipVoid(str, ptr - 1, true); - if (str[ptr] !== '\n' && str[ptr] !== '\r') { - throw new TomlError('invalid escape: only line-ending whitespace may be escaped', { - toml: str, - ptr: tmp, - }); - } - ptr = skipVoid(str, ptr); + return [ + // If we're in a newline escape still, then there's nothing to add. + // Also try to avoid concat if there's nothing to add to parsed, or nothing has been added to parsed. + state ? parsed : parsed + str.slice(sliceStart, i), + i + (isMultiline ? 3 : 1), + ]; + } + else if (!state) { + if (!isLiteral && c === '\\') { + parsed += str.slice(sliceStart, (sliceStart = i)); + state = 1; } - else if (c in ESC_MAP) { - // Classic escape - parsed += ESC_MAP[c]; + } + else if (state === 1) { + if (c === 'x' || c === 'u' || c === 'U') { // Unicode escape + let value = 0; + let len = c === 'x' ? 2 : c === 'u' ? 4 : 8; + for (let j = 0; j < len; j++, i++) { + let hex = str.charCodeAt(i + 1); + let digit = + /* 0-9 */ hex >= 0x30 && hex <= 0x39 ? hex - 0x30 : + /* A-F */ hex >= 0x41 && hex <= 0x46 ? hex - 0x41 + 10 : + /* a-f */ hex >= 0x61 && hex <= 0x66 ? hex - 0x61 + 10 : -1; + if (digit < 0) + throw new TomlError('invalid non-hex character in unicode escape', { toml: str, ptr: i + 1 }); + value = (value << 4) | digit; + } + // Because JS does bitwise on signed 32bit integers, all 0xfzzzzzzz values are actually seen as negative + if (value < 0 || value > 0x10ffff || (value >= 0xd800 && value <= 0xdfff)) { + throw new TomlError('invalid unicode escape', { toml: str, ptr: i }); + } + parsed += String.fromCodePoint(value); + sliceStart = i + 1; + state = 0; + } + else if (c === ' ' || c === '\t') { // If it was a newline, it'd have been handled earlier + state = 2; } else { - throw new TomlError('unrecognized escape sequence', { + if (c === 'b') + parsed += '\b'; + else if (c === 't') + parsed += '\t'; + else if (c === 'n') + parsed += '\n'; + else if (c === 'f') + parsed += '\f'; + else if (c === 'r') + parsed += '\r'; + else if (c === 'e') + parsed += '\x1b'; + else if (c === '"') + parsed += '"'; + else if (c === '\\') + parsed += '\\'; + else + throw new TomlError('unrecognized escape sequence', { toml: str, ptr: i }); + sliceStart = i + 1; + state = 0; + } + } + else if (c !== ' ' && c !== '\t') { + if (state === 2) { + throw new TomlError('invalid escape: only line-ending whitespace may be escaped', { toml: str, - ptr: tmp, + ptr: sliceStart, }); } - sliceStart = ptr; - } - else if (!isLiteral && c === '\\') { - tmp = ptr - 1; - isEscape = true; - parsed += str.slice(sliceStart, tmp); + // State cannot be zero, or we'd have branched earlier already. + // If it's a backslash, immediately transition to the escape state so it can be processed. + state = !isLiteral && c === '\\' ? 1 : 0; + sliceStart = i; } } - return parsed + str.slice(sliceStart, endPtr - 1); + throw new TomlError('unfinished string', { toml: str, ptr }); } function parseValue(value, toml, ptr, integersAsBigInt) { // Constant values @@ -75513,7 +75694,94 @@ function parseValue(value, toml, ptr, integersAsBigInt) { } return date; } +//# sourceMappingURL=primitive.js.map +;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/util.js +/*! + * Copyright (c) Squirrel Chat et al., All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +function indexOfNewline(str, start = 0, end = str.length) { + let idx = str.indexOf('\n', start); + if (str[idx - 1] === '\r') + idx--; + return idx <= end ? idx : -1; +} +function skipComment(str, ptr) { + for (let i = ptr; i < str.length; i++) { + let c = str[i]; + if (c === '\n') + return i; + if (c === '\r' && str[i + 1] === '\n') + return i + 1; + if ((c < '\x20' && c !== '\t') || c === '\x7f') { + throw new TomlError('control characters are not allowed in comments', { + toml: str, + ptr: ptr, + }); + } + } + return str.length; +} +function skipVoid(str, ptr, banNewLines, banComments) { + let c; + while (1) { + while ((c = str[ptr]) === ' ' || c === '\t' || (!banNewLines && (c === '\n' || (c === '\r' && str[ptr + 1] === '\n')))) + ptr++; + // Tucking the return statement here would save 5 characters >:) + // But TypeScript fails to detect there is no way to exit the loop so it complains about the lack of final return + if (banComments || c !== '#') + break; + ptr = skipComment(str, ptr); + } + return ptr; +} +function skipUntil(str, ptr, sep, end, banNewLines = false) { + if (!end) { + ptr = indexOfNewline(str, ptr); + return ptr < 0 ? str.length : ptr; + } + for (let i = ptr; i < str.length; i++) { + let c = str[i]; + if (c === '#') { + i = indexOfNewline(str, i); + } + else if (c === sep) { + return i + 1; + } + else if (c === end || (banNewLines && (c === '\n' || (c === '\r' && str[i + 1] === '\n')))) { + return i; + } + } + throw new TomlError('cannot find end of structure', { + toml: str, + ptr: ptr, + }); +} +//# sourceMappingURL=util.js.map ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/extract.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -75561,7 +75829,7 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) { if (depth === 0) { throw new TomlError('document contains excessively nested structures. aborting.', { toml: str, - ptr: ptr + ptr: ptr, }); } let c = str[ptr]; @@ -75582,10 +75850,8 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) { } return [value, endPtr]; } - let endPtr; if (c === '"' || c === "'") { - endPtr = getStringEnd(str, ptr); - let parsed = parseString(str, ptr, endPtr); + let [parsed, endPtr] = parseString(str, ptr); if (end) { endPtr = skipVoid(str, endPtr); if (str[endPtr] && str[endPtr] !== ',' && str[endPtr] !== end && str[endPtr] !== '\n' && str[endPtr] !== '\r') { @@ -75594,28 +75860,30 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) { ptr: endPtr, }); } - endPtr += (+(str[endPtr] === ',')); + if (str[endPtr] === ',') + endPtr++; } return [parsed, endPtr]; } - endPtr = skipUntil(str, ptr, ',', end); - let slice = sliceAndTrimEndOf(str, ptr, endPtr - (+(str[endPtr - 1] === ','))); + let endPtr = skipUntil(str, ptr, ',', end); + let slice = sliceAndTrimEndOf(str, ptr, endPtr - (str[endPtr - 1] === ',' ? 1 : 0)); if (!slice[0]) { throw new TomlError('incomplete key-value declaration: no value specified', { toml: str, - ptr: ptr + ptr: ptr, }); } if (end && slice[1] > -1) { endPtr = skipVoid(str, ptr + slice[1]); - endPtr += +(str[endPtr] === ','); + if (str[endPtr] === ',') + endPtr++; } return [ parseValue(slice[0], str, ptr, integersAsBigInt), endPtr, ]; } - +//# sourceMappingURL=extract.js.map ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/struct.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -75660,24 +75928,18 @@ function parseKey(str, ptr, end = '=') { }); } do { - let c = str[ptr = ++dot]; + let c = str[(ptr = ++dot)]; // If it's whitespace, ignore if (c !== ' ' && c !== '\t') { // If it's a string - if (c === '"' || c === '\'') { + if (c === '"' || c === "'") { if (c === str[ptr + 1] && c === str[ptr + 2]) { throw new TomlError('multiline strings are not allowed in keys', { toml: str, ptr: ptr, }); } - let eos = getStringEnd(str, ptr); - if (eos < 0) { - throw new TomlError('unfinished string encountered', { - toml: str, - ptr: ptr, - }); - } + let [part, eos] = parseString(str, ptr); dot = str.indexOf('.', eos); let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot); let newLine = indexOfNewline(strEnd); @@ -75702,7 +75964,7 @@ function parseKey(str, ptr, end = '=') { }); } } - parsed.push(parseString(str, ptr, eos)); + parsed.push(part); } else { // Normal raw key part consumption and validation @@ -75801,7 +76063,7 @@ function parseArray(str, ptr, depth, integersAsBigInt) { } return [res, ptr]; } - +//# sourceMappingURL=struct.js.map ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/parse.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -75864,8 +76126,7 @@ function peekTable(key, table, meta, type) { } m[k] = { t: i < key.length - 1 && type === 2 /* Type.ARRAY */ - ? 3 /* Type.ARRAY_DOTTED */ - : type, + ? 3 /* Type.ARRAY_DOTTED */ : type, d: false, i: 0, c: {}, @@ -75906,7 +76167,7 @@ function parse_parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) { for (let ptr = skipVoid(toml, 0); ptr < toml.length;) { if (toml[ptr] === '[') { let isTableArray = toml[++ptr] === '['; - let k = parseKey(toml, ptr += +isTableArray, ']'); + let k = parseKey(toml, (ptr += +isTableArray), ']'); if (isTableArray) { if (toml[k[1] - 1] !== ']') { throw new TomlError('expected end of table declaration', { @@ -75944,14 +76205,14 @@ function parse_parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) { if (toml[ptr] && toml[ptr] !== '\n' && toml[ptr] !== '\r') { throw new TomlError('each key-value declaration must be followed by an end-of-line', { toml: toml, - ptr: ptr + ptr: ptr, }); } ptr = skipVoid(toml, ptr); } return res; } - +//# sourceMappingURL=parse.js.map ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/stringify.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -76012,7 +76273,7 @@ function stringifyValue(val, type, depth, numberAsFloat) { return 'inf'; if (val === -Infinity) return '-inf'; - if (numberAsFloat && Number.isInteger(val)) + if (Number.isInteger(val) && (numberAsFloat || !Number.isSafeInteger(val))) return val.toFixed(1); return val.toString(); } @@ -76120,7 +76381,7 @@ function stringify(obj, { maxDepth = 1000, numbersAsFloat = false } = {}) { return str + '\n'; return str; } - +//# sourceMappingURL=stringify.js.map ;// CONCATENATED MODULE: ./node_modules/smol-toml/dist/index.js /*! * Copyright (c) Squirrel Chat et al., All rights reserved. @@ -76155,7 +76416,7 @@ function stringify(obj, { maxDepth = 1000, numbersAsFloat = false } = {}) { /* harmony default export */ const dist = ({ parse: parse_parse, stringify: stringify, TomlDate: TomlDate, TomlError: TomlError }); - +//# sourceMappingURL=index.js.map ;// CONCATENATED MODULE: ./node_modules/markdownlint-cli2/parsers/toml-parse.mjs // @ts-check @@ -76170,3863 +76431,3132 @@ const tomlParse = (text) => parse_parse(text); /* harmony default export */ const toml_parse = (tomlParse); ;// CONCATENATED MODULE: ./node_modules/js-yaml/dist/js-yaml.mjs - -/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */ -function isNothing(subject) { - return (typeof subject === 'undefined') || (subject === null); +/*! js-yaml 5.2.0 https://github.com/nodeca/js-yaml @license MIT */ +//#region src/tag.ts +var NOT_RESOLVED = Symbol("NOT_RESOLVED"); +var MERGE_KEY = Symbol("MERGE_KEY"); +function defineScalarTag(tagName, options) { + return { + tagName, + nodeKind: "scalar", + implicit: options.implicit ?? false, + matchByTagPrefix: options.matchByTagPrefix ?? false, + implicitFirstChars: options.implicitFirstChars ?? null, + resolve: options.resolve, + identify: options.identify ?? null, + represent: options.represent ?? ((data) => String(data)), + representTagName: options.representTagName ?? null + }; } - - -function isObject(subject) { - return (typeof subject === 'object') && (subject !== null); +function defineSequenceTag(tagName, options) { + const carrierIsResult = options.finalize === void 0; + return { + tagName, + nodeKind: "sequence", + implicit: false, + matchByTagPrefix: options.matchByTagPrefix ?? false, + create: options.create, + addItem: options.addItem, + finalize: options.finalize ?? ((carrier) => carrier), + carrierIsResult, + identify: options.identify ?? null, + represent: options.represent ?? ((data) => data), + representTagName: options.representTagName ?? null + }; } - - -function toArray(sequence) { - if (Array.isArray(sequence)) return sequence; - else if (isNothing(sequence)) return []; - - return [ sequence ]; +function defineMappingTag(tagName, options) { + const carrierIsResult = options.finalize === void 0; + return { + tagName, + nodeKind: "mapping", + implicit: false, + matchByTagPrefix: options.matchByTagPrefix ?? false, + create: options.create, + addPair: options.addPair, + has: options.has, + keys: options.keys, + get: options.get, + finalize: options.finalize ?? ((carrier) => carrier), + carrierIsResult, + identify: options.identify ?? null, + represent: options.represent ?? ((data) => data), + representTagName: options.representTagName ?? null + }; } - - -function extend(target, source) { - var index, length, key, sourceKeys; - - if (source) { - sourceKeys = Object.keys(source); - - for (index = 0, length = sourceKeys.length; index < length; index += 1) { - key = sourceKeys[index]; - target[key] = source[key]; - } - } - - return target; +//#endregion +//#region src/tag/scalar/str.ts +var strTag = defineScalarTag("tag:yaml.org,2002:str", { + resolve: (source) => source, + identify: (data) => typeof data === "string" +}); +//#endregion +//#region src/tag/scalar/null_core.ts +var NULL_VALUES$1 = [ + "", + "~", + "null", + "Null", + "NULL" +]; +var nullCoreTag = defineScalarTag("tag:yaml.org,2002:null", { + implicit: true, + implicitFirstChars: [ + "", + "~", + "n", + "N" + ], + resolve: (source) => { + if (NULL_VALUES$1.indexOf(source) !== -1) return null; + return NOT_RESOLVED; + }, + identify: (object) => object === null, + represent: () => "null" +}); +//#endregion +//#region src/tag/scalar/null_json.ts +var nullJsonTag = defineScalarTag("tag:yaml.org,2002:null", { + implicit: true, + implicitFirstChars: ["n"], + resolve: (source, isExplicit) => { + if (source === "null" || isExplicit && source === "") return null; + return NOT_RESOLVED; + }, + identify: (object) => object === null, + represent: () => "null" +}); +//#endregion +//#region src/tag/scalar/null_yaml11.ts +var NULL_VALUES = [ + "", + "~", + "null", + "Null", + "NULL" +]; +var nullYaml11Tag = defineScalarTag("tag:yaml.org,2002:null", { + implicit: true, + implicitFirstChars: [ + "", + "~", + "n", + "N" + ], + resolve: (source) => { + if (NULL_VALUES.indexOf(source) !== -1) return null; + return NOT_RESOLVED; + }, + identify: (object) => object === null, + represent: () => "null" +}); +//#endregion +//#region src/tag/scalar/bool_core.ts +var TRUE_VALUES$2 = [ + "true", + "True", + "TRUE" +]; +var FALSE_VALUES$2 = [ + "false", + "False", + "FALSE" +]; +var boolCoreTag = defineScalarTag("tag:yaml.org,2002:bool", { + implicit: true, + implicitFirstChars: [ + "t", + "T", + "f", + "F" + ], + resolve: (source) => { + if (TRUE_VALUES$2.indexOf(source) !== -1) return true; + if (FALSE_VALUES$2.indexOf(source) !== -1) return false; + return NOT_RESOLVED; + }, + identify: (object) => Object.prototype.toString.call(object) === "[object Boolean]", + represent: (object) => object ? "true" : "false" +}); +//#endregion +//#region src/tag/scalar/bool_json.ts +var TRUE_VALUES$1 = ["true"]; +var FALSE_VALUES$1 = ["false"]; +var boolJsonTag = defineScalarTag("tag:yaml.org,2002:bool", { + implicit: true, + implicitFirstChars: ["t", "f"], + resolve: (source) => { + if (TRUE_VALUES$1.indexOf(source) !== -1) return true; + if (FALSE_VALUES$1.indexOf(source) !== -1) return false; + return NOT_RESOLVED; + }, + identify: (object) => Object.prototype.toString.call(object) === "[object Boolean]", + represent: (object) => object ? "true" : "false" +}); +//#endregion +//#region src/tag/scalar/bool_yaml11.ts +var TRUE_VALUES = [ + "true", + "True", + "TRUE", + "y", + "Y", + "yes", + "Yes", + "YES", + "on", + "On", + "ON" +]; +var FALSE_VALUES = [ + "false", + "False", + "FALSE", + "n", + "N", + "no", + "No", + "NO", + "off", + "Off", + "OFF" +]; +var boolYaml11Tag = defineScalarTag("tag:yaml.org,2002:bool", { + implicit: true, + implicitFirstChars: [ + "y", + "Y", + "n", + "N", + "t", + "T", + "f", + "F", + "o", + "O" + ], + resolve: (source) => { + if (TRUE_VALUES.indexOf(source) !== -1) return true; + if (FALSE_VALUES.indexOf(source) !== -1) return false; + return NOT_RESOLVED; + }, + identify: (object) => Object.prototype.toString.call(object) === "[object Boolean]", + represent: (object) => object ? "true" : "false" +}); +//#endregion +//#region src/tag/scalar/int_core.ts +var YAML_INTEGER_IMPLICIT_PATTERN$1 = /* @__PURE__ */ new RegExp("^(?:0o[0-7]+|0x[0-9a-fA-F]+|[-+]?[0-9]+)$"); +var YAML_INTEGER_EXPLICIT_PATTERN$1 = /* @__PURE__ */ new RegExp("^(?:[-+]?0b[0-1]+|[-+]?0o[0-7]+|[-+]?0x[0-9a-fA-F]+|[-+]?[0-9]+)$"); +function parseYamlInteger$2(source) { + let value = source; + let sign = 1; + if (value[0] === "-" || value[0] === "+") { + if (value[0] === "-") sign = -1; + value = value.slice(1); + } + if (value.startsWith("0b")) return sign * parseInt(value.slice(2), 2); + if (value.startsWith("0o")) return sign * parseInt(value.slice(2), 8); + if (value.startsWith("0x")) return sign * parseInt(value.slice(2), 16); + return sign * parseInt(value, 10); } - - -function repeat(string, count) { - var result = '', cycle; - - for (cycle = 0; cycle < count; cycle += 1) { - result += string; - } - - return result; +function resolveYamlInteger$2(source, isExplicit) { + if (isExplicit) { + if (!YAML_INTEGER_EXPLICIT_PATTERN$1.test(source)) return NOT_RESOLVED; + } else if (!YAML_INTEGER_IMPLICIT_PATTERN$1.test(source)) return NOT_RESOLVED; + const result = parseYamlInteger$2(source); + return Number.isFinite(result) ? result : NOT_RESOLVED; } - - -function isNegativeZero(number) { - return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); +var intCoreTag = defineScalarTag("tag:yaml.org,2002:int", { + implicit: true, + implicitFirstChars: [ + "-", + "+", + ..."0123456789" + ], + resolve: resolveYamlInteger$2, + identify: (object) => Number.isInteger(object) && !Object.is(object, -0) && object.toString(10).indexOf("e") < 0, + represent: (object) => object.toString(10) +}); +//#endregion +//#region src/tag/scalar/int_json.ts +var YAML_INTEGER_IMPLICIT_PATTERN = /* @__PURE__ */ new RegExp("^-?(?:0|[1-9][0-9]*)$"); +var YAML_INTEGER_EXPLICIT_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?0b[0-1]+|[-+]?0o[0-7]+|[-+]?0x[0-9a-fA-F]+|[-+]?[0-9]+)$"); +function parseYamlInteger$1(source) { + let value = source; + let sign = 1; + if (value[0] === "-" || value[0] === "+") { + if (value[0] === "-") sign = -1; + value = value.slice(1); + } + if (value.startsWith("0b")) return sign * parseInt(value.slice(2), 2); + if (value.startsWith("0o")) return sign * parseInt(value.slice(2), 8); + if (value.startsWith("0x")) return sign * parseInt(value.slice(2), 16); + return sign * parseInt(value, 10); } - - -var isNothing_1 = isNothing; -var isObject_1 = isObject; -var toArray_1 = toArray; -var repeat_1 = repeat; -var isNegativeZero_1 = isNegativeZero; -var extend_1 = extend; - -var common = { - isNothing: isNothing_1, - isObject: isObject_1, - toArray: toArray_1, - repeat: repeat_1, - isNegativeZero: isNegativeZero_1, - extend: extend_1 +function resolveYamlInteger$1(source, isExplicit) { + if (isExplicit) { + if (!YAML_INTEGER_EXPLICIT_PATTERN.test(source)) return NOT_RESOLVED; + } else if (!YAML_INTEGER_IMPLICIT_PATTERN.test(source)) return NOT_RESOLVED; + const result = parseYamlInteger$1(source); + return Number.isFinite(result) ? result : NOT_RESOLVED; +} +var intJsonTag = defineScalarTag("tag:yaml.org,2002:int", { + implicit: true, + implicitFirstChars: ["-", ..."0123456789"], + resolve: resolveYamlInteger$1, + identify: (object) => Number.isInteger(object) && !Object.is(object, -0) && object.toString(10).indexOf("e") < 0, + represent: (object) => object.toString(10) +}); +//#endregion +//#region src/tag/scalar/int_yaml11.ts +var YAML_INTEGER_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?0b[0-1_]+|[-+]?0[0-7_]+|[-+]?0x[0-9a-fA-F_]+|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+|[-+]?(?:0|[1-9][0-9_]*))$"); +function parseYamlInteger(source) { + let value = source.replace(/_/g, ""); + let sign = 1; + if (value[0] === "-" || value[0] === "+") { + if (value[0] === "-") sign = -1; + value = value.slice(1); + } + if (value.startsWith("0b")) return sign * parseInt(value.slice(2), 2); + if (value.startsWith("0x")) return sign * parseInt(value.slice(2), 16); + if (value.includes(":")) { + let result = 0; + for (const part of value.split(":")) result = result * 60 + Number(part); + return sign * result; + } + if (value !== "0" && value[0] === "0") return sign * parseInt(value, 8); + return sign * parseInt(value, 10); +} +function resolveYamlInteger(source) { + if (!YAML_INTEGER_PATTERN.test(source)) return NOT_RESOLVED; + const result = parseYamlInteger(source); + return Number.isFinite(result) ? result : NOT_RESOLVED; +} +var intYaml11Tag = defineScalarTag("tag:yaml.org,2002:int", { + implicit: true, + implicitFirstChars: [ + "-", + "+", + ..."0123456789" + ], + resolve: resolveYamlInteger, + identify: (object) => Number.isInteger(object) && !Object.is(object, -0) && object.toString(10).indexOf("e") < 0, + represent: (object) => object.toString(10) +}); +//#endregion +//#region src/tag/scalar/float_core.ts +var YAML_FLOAT_PATTERN$1 = /* @__PURE__ */ new RegExp("^(?:[-+]?[0-9]+(?:\\.[0-9]*)?(?:[eE][-+]?[0-9]+)?|[-+]?\\.[0-9]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"); +var YAML_FLOAT_SPECIAL_PATTERN$1 = /* @__PURE__ */ new RegExp("^(?:[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"); +function resolveYamlFloat$2(source) { + if (!YAML_FLOAT_PATTERN$1.test(source)) return NOT_RESOLVED; + let value = source.toLowerCase(); + const sign = value[0] === "-" ? -1 : 1; + if ("+-".includes(value[0])) value = value.slice(1); + if (value === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + if (value === ".nan") return NaN; + const result = sign * parseFloat(value); + if (Number.isFinite(result) || YAML_FLOAT_SPECIAL_PATTERN$1.test(source)) return result; + return NOT_RESOLVED; +} +function representYamlFloat$2(object) { + if (isNaN(object)) return ".nan"; + if (object === Number.POSITIVE_INFINITY) return ".inf"; + if (object === Number.NEGATIVE_INFINITY) return "-.inf"; + if (Object.is(object, -0)) return "-0.0"; + const result = object.toString(10); + return /^[-+]?[0-9]+e/.test(result) ? result.replace("e", ".e") : result; +} +var floatCoreTag = defineScalarTag("tag:yaml.org,2002:float", { + implicit: true, + implicitFirstChars: [ + "-", + "+", + ".", + ..."0123456789" + ], + resolve: resolveYamlFloat$2, + identify: (object) => typeof object === "number" && (!Number.isInteger(object) || Object.is(object, -0) || object.toString(10).indexOf("e") >= 0), + represent: representYamlFloat$2 +}); +//#endregion +//#region src/tag/scalar/float_json.ts +var YAML_FLOAT_IMPLICIT_PATTERN = /* @__PURE__ */ new RegExp("^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$"); +var YAML_FLOAT_EXPLICIT_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?[0-9]+(?:\\.[0-9]*)?(?:[eE][-+]?[0-9]+)?|[-+]?\\.[0-9]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"); +function resolveYamlFloat$1(source, isExplicit) { + if (isExplicit) { + if (!YAML_FLOAT_EXPLICIT_PATTERN.test(source)) return NOT_RESOLVED; + let value = source.toLowerCase(); + const sign = value[0] === "-" ? -1 : 1; + if ("+-".includes(value[0])) value = value.slice(1); + if (value === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + if (value === ".nan") return NaN; + const result = sign * parseFloat(value); + return Number.isFinite(result) ? result : NOT_RESOLVED; + } + if (!YAML_FLOAT_IMPLICIT_PATTERN.test(source)) return NOT_RESOLVED; + const result = Number(source); + if (Number.isFinite(result)) return result; + return NOT_RESOLVED; +} +function representYamlFloat$1(object) { + if (isNaN(object)) return ".nan"; + if (object === Number.POSITIVE_INFINITY) return ".inf"; + if (object === Number.NEGATIVE_INFINITY) return "-.inf"; + if (Object.is(object, -0)) return "-0.0"; + const result = object.toString(10); + return /^[-+]?[0-9]+e/.test(result) ? result.replace("e", ".e") : result; +} +var floatJsonTag = defineScalarTag("tag:yaml.org,2002:float", { + implicit: true, + implicitFirstChars: ["-", ..."0123456789"], + resolve: resolveYamlFloat$1, + identify: (object) => typeof object === "number" && (!Number.isInteger(object) || Object.is(object, -0) || object.toString(10).indexOf("e") >= 0), + represent: representYamlFloat$1 +}); +//#endregion +//#region src/tag/scalar/float_yaml11.ts +var YAML_FLOAT_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?(?:(?:[0-9][0-9_]*)?\\.[0-9_]*)(?:[eE][-+][0-9]+)?|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"); +var YAML_FLOAT_SPECIAL_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"); +function resolveYamlFloat(source) { + if (!YAML_FLOAT_PATTERN.test(source)) return NOT_RESOLVED; + let value = source.toLowerCase().replace(/_/g, ""); + const sign = value[0] === "-" ? -1 : 1; + if ("+-".includes(value[0])) value = value.slice(1); + if (value === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; + if (value === ".nan") return NaN; + let result = 0; + if (value.includes(":")) { + for (const part of value.split(":")) result = result * 60 + Number(part); + result *= sign; + } else result = sign * parseFloat(value); + if (Number.isFinite(result) || YAML_FLOAT_SPECIAL_PATTERN.test(source)) return result; + return NOT_RESOLVED; +} +function representYamlFloat(object) { + if (isNaN(object)) return ".nan"; + if (object === Number.POSITIVE_INFINITY) return ".inf"; + if (object === Number.NEGATIVE_INFINITY) return "-.inf"; + if (Object.is(object, -0)) return "-0.0"; + const result = object.toString(10); + return /^[-+]?[0-9]+e/.test(result) ? result.replace("e", ".e") : result; +} +var floatYaml11Tag = defineScalarTag("tag:yaml.org,2002:float", { + implicit: true, + implicitFirstChars: [ + "-", + "+", + ".", + ..."0123456789" + ], + resolve: resolveYamlFloat, + identify: (object) => typeof object === "number" && (!Number.isInteger(object) || Object.is(object, -0) || object.toString(10).indexOf("e") >= 0), + represent: representYamlFloat +}); +//#endregion +//#region src/tag/scalar/merge.ts +var mergeTag = defineScalarTag("tag:yaml.org,2002:merge", { + implicit: true, + implicitFirstChars: ["<"], + resolve: (source, isExplicit) => { + if (source === "<<" || isExplicit && source === "") return MERGE_KEY; + return NOT_RESOLVED; + } +}); +//#endregion +//#region src/tag/scalar/binary.ts +var BASE64_PATTERN = /^[A-Za-z0-9+/]*={0,2}$/; +function resolveYamlBinary(source) { + const input = source.replace(/\s/g, ""); + if (input.length % 4 !== 0 || !BASE64_PATTERN.test(input)) return NOT_RESOLVED; + const binary = atob(input); + const result = new Uint8Array(binary.length); + for (let index = 0; index < binary.length; index++) result[index] = binary.charCodeAt(index); + return result; +} +function representYamlBinary(object) { + let binary = ""; + for (let index = 0; index < object.length; index++) binary += String.fromCharCode(object[index]); + return btoa(binary); +} +var binaryTag = defineScalarTag("tag:yaml.org,2002:binary", { + resolve: resolveYamlBinary, + identify: (object) => Object.prototype.toString.call(object) === "[object Uint8Array]", + represent: representYamlBinary +}); +//#endregion +//#region src/tag/scalar/timestamp.ts +var YAML_DATE_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"); +var YAML_TIMESTAMP_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$"); +function resolveYamlTimestamp(source) { + let match = YAML_DATE_REGEXP.exec(source); + if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(source); + if (match === null) return NOT_RESOLVED; + const year = +match[1]; + const month = +match[2] - 1; + const day = +match[3]; + if (!match[4]) { + const date = new Date(Date.UTC(year, month, day)); + if (date.getUTCFullYear() !== year || date.getUTCMonth() !== month || date.getUTCDate() !== day) return NOT_RESOLVED; + return date; + } + const hour = +match[4]; + const minute = +match[5]; + const second = +match[6]; + let fraction = 0; + if (hour > 23 || minute > 59 || second > 59) return NOT_RESOLVED; + if (match[7]) { + let value = match[7].slice(0, 3); + while (value.length < 3) value += "0"; + fraction = +value; + } + const date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); + if (date.getUTCFullYear() !== year || date.getUTCMonth() !== month || date.getUTCDate() !== day) return NOT_RESOLVED; + if (match[9]) { + const offsetHour = +match[10]; + const offsetMinute = +(match[11] || 0); + if (offsetHour > 23 || offsetMinute > 59) return NOT_RESOLVED; + const offset = (offsetHour * 60 + offsetMinute) * 6e4; + date.setTime(date.getTime() - (match[9] === "-" ? -offset : offset)); + } + return date; +} +var timestampTag = defineScalarTag("tag:yaml.org,2002:timestamp", { + implicit: true, + implicitFirstChars: [..."0123456789"], + resolve: resolveYamlTimestamp, + identify: (object) => object instanceof Date, + represent: (object) => object.toISOString() +}); +//#endregion +//#region src/tag/sequence/seq.ts +var seqTag = defineSequenceTag("tag:yaml.org,2002:seq", { + create: () => [], + addItem: (container, item) => { + container.push(item); + }, + identify: Array.isArray +}); +//#endregion +//#region src/tag/sequence/omap.ts +var omapTag = defineSequenceTag("tag:yaml.org,2002:omap", { + create: () => [], + addItem: (container, item) => { + if (Object.prototype.toString.call(item) !== "[object Object]") return "cannot resolve an ordered map item"; + const object = item; + const itemKeys = Object.keys(object); + if (itemKeys.length !== 1) return "cannot resolve an ordered map item"; + for (const existing of container) if (Object.prototype.hasOwnProperty.call(existing, itemKeys[0])) return "cannot resolve an ordered map item"; + container.push(object); + return ""; + } +}); +//#endregion +//#region src/tag/sequence/pairs.ts +var pairsTag = defineSequenceTag("tag:yaml.org,2002:pairs", { + create: () => [], + addItem: (container, item) => { + if (item instanceof Map) { + if (item.size !== 1) return "cannot resolve a pairs item"; + container.push(item.entries().next().value); + return ""; + } + if (Object.prototype.toString.call(item) !== "[object Object]") return "cannot resolve a pairs item"; + const object = item; + const keys = Object.keys(object); + if (keys.length !== 1) return "cannot resolve a pairs item"; + container.push([keys[0], object[keys[0]]]); + return ""; + } +}); +//#endregion +//#region src/common/object.ts +function isPlainObject(data) { + if (data === null || typeof data !== "object" || Array.isArray(data)) return false; + const prototype = Object.getPrototypeOf(data); + return prototype === null || prototype === Object.prototype; +} +function pick(object, keys) { + const result = {}; + for (const key of keys) if (object[key] !== void 0) result[key] = object[key]; + return result; +} +//#endregion +//#region src/tag/mapping/map.ts +var mapTag = defineMappingTag("tag:yaml.org,2002:map", { + create: () => ({}), + identify: isPlainObject, + represent: (o) => { + const map = /* @__PURE__ */ new Map(); + for (const key of Object.keys(o)) map.set(key, o[key]); + return map; + }, + addPair: (container, key, value) => { + if (key !== null && typeof key === "object") return "object-based map does not support complex keys"; + const normalizedKey = String(key); + if (normalizedKey === "__proto__") Object.defineProperty(container, normalizedKey, { + value, + enumerable: true, + configurable: true, + writable: true + }); + else container[normalizedKey] = value; + return ""; + }, + has: (container, key) => { + if (key !== null && typeof key === "object") return false; + return Object.prototype.hasOwnProperty.call(container, String(key)); + }, + keys: (container) => Object.keys(container), + get: (container, key) => container[String(key)] +}); +//#endregion +//#region src/tag/mapping/set.ts +var setTag = defineMappingTag("tag:yaml.org,2002:set", { + create: () => /* @__PURE__ */ new Set(), + identify: (data) => data instanceof Set, + represent: (data) => { + const map = /* @__PURE__ */ new Map(); + for (const key of data) map.set(key, null); + return map; + }, + addPair: (container, key, value) => { + if (value !== null) return "cannot resolve a set item"; + container.add(key); + return ""; + }, + has: (container, key) => container.has(key), + keys: (container) => container.keys(), + get: () => null +}); +//#endregion +//#region src/schema.ts +function createTagDefinitionMap() { + return { + scalar: {}, + sequence: {}, + mapping: {} + }; +} +function createTagDefinitionListMap() { + return { + scalar: [], + sequence: [], + mapping: [] + }; +} +function compileTags(tags) { + const result = []; + for (const tag of tags) { + let index = result.length; + for (let previousIndex = 0; previousIndex < result.length; previousIndex++) { + const previous = result[previousIndex]; + if (previous.nodeKind === tag.nodeKind && previous.tagName === tag.tagName && previous.matchByTagPrefix === tag.matchByTagPrefix) { + index = previousIndex; + break; + } + } + result[index] = tag; + } + return result; +} +var Schema = class Schema { + tags; + implicitScalarTags; + implicitScalarByFirstChar; + implicitScalarAnyFirstChar; + defaultScalarTag; + defaultSequenceTag; + defaultMappingTag; + exact; + prefix; + constructor(tags) { + const compiledTags = compileTags(tags); + const implicitScalarTags = []; + const exact = createTagDefinitionMap(); + const prefix = createTagDefinitionListMap(); + for (const tag of compiledTags) { + if (tag.nodeKind === "scalar" && tag.implicit) { + if (tag.matchByTagPrefix) throw new Error("Implicit scalar tags cannot match by tag prefix"); + implicitScalarTags.push(tag); + } + switch (tag.nodeKind) { + case "scalar": + if (tag.matchByTagPrefix) prefix.scalar.push(tag); + else exact.scalar[tag.tagName] = tag; + break; + case "sequence": + if (tag.matchByTagPrefix) prefix.sequence.push(tag); + else exact.sequence[tag.tagName] = tag; + break; + case "mapping": + if (tag.matchByTagPrefix) prefix.mapping.push(tag); + else exact.mapping[tag.tagName] = tag; + break; + } + } + const implicitScalarAnyFirstChar = implicitScalarTags.filter((tag) => tag.implicitFirstChars === null); + const keys = /* @__PURE__ */ new Set(); + for (const tag of implicitScalarTags) if (tag.implicitFirstChars !== null) for (const key of tag.implicitFirstChars) keys.add(key); + const implicitScalarByFirstChar = /* @__PURE__ */ new Map(); + for (const key of keys) implicitScalarByFirstChar.set(key, implicitScalarTags.filter((tag) => tag.implicitFirstChars === null || tag.implicitFirstChars.indexOf(key) !== -1)); + const defaultScalarTag = exact.scalar["tag:yaml.org,2002:str"]; + if (!defaultScalarTag) throw new Error("schema does not define the default scalar tag (tag:yaml.org,2002:str)"); + this.tags = compiledTags; + this.implicitScalarTags = implicitScalarTags; + this.implicitScalarByFirstChar = implicitScalarByFirstChar; + this.implicitScalarAnyFirstChar = implicitScalarAnyFirstChar; + this.defaultScalarTag = defaultScalarTag; + this.defaultSequenceTag = exact.sequence["tag:yaml.org,2002:seq"]; + this.defaultMappingTag = exact.mapping["tag:yaml.org,2002:map"]; + this.exact = exact; + this.prefix = prefix; + } + withTags(...tags) { + let flatTags = []; + for (const tag of tags) flatTags = flatTags.concat(tag); + return new Schema([...this.tags, ...flatTags]); + } }; - -// YAML error class. http://stackoverflow.com/questions/8458984 - - -function formatError(exception, compact) { - var where = '', message = exception.reason || '(unknown reason)'; - - if (!exception.mark) return message; - - if (exception.mark.name) { - where += 'in "' + exception.mark.name + '" '; - } - - where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; - - if (!compact && exception.mark.snippet) { - where += '\n\n' + exception.mark.snippet; - } - - return message + ' ' + where; +var FAILSAFE_SCHEMA = new Schema([ + strTag, + seqTag, + mapTag +]); +var JSON_SCHEMA = new Schema([ + ...FAILSAFE_SCHEMA.tags, + nullJsonTag, + boolJsonTag, + intJsonTag, + floatJsonTag +]); +var CORE_SCHEMA = new Schema([ + ...FAILSAFE_SCHEMA.tags, + nullCoreTag, + boolCoreTag, + intCoreTag, + floatCoreTag +]); +var YAML11_SCHEMA = new Schema([ + ...FAILSAFE_SCHEMA.tags, + nullYaml11Tag, + boolYaml11Tag, + intYaml11Tag, + floatYaml11Tag, + timestampTag, + mergeTag, + binaryTag, + omapTag, + pairsTag, + setTag +]); +//#endregion +//#region src/tag/mapping/real_map.ts +var realMapTag = defineMappingTag("tag:yaml.org,2002:map", { + create: () => /* @__PURE__ */ new Map(), + addPair: (container, key, value) => { + container.set(key, value); + return ""; + }, + has: (container, key) => container.has(key), + keys: (container) => container.keys(), + get: (container, key) => container.get(key), + identify: (data) => data instanceof Map || isPlainObject(data), + represent: (data) => { + if (data instanceof Map) return data; + const map = /* @__PURE__ */ new Map(); + const obj = data; + for (const key of Object.keys(obj)) map.set(key, obj[key]); + return map; + } +}); +//#endregion +//#region src/tag/mapping/legacy_map.ts +function normalizeKey(key) { + if (Array.isArray(key)) { + const array = Array.prototype.slice.call(key); + for (let index = 0; index < array.length; index++) { + if (Array.isArray(array[index])) return null; + if (typeof array[index] === "object" && Object.prototype.toString.call(array[index]) === "[object Object]") array[index] = "[object Object]"; + } + return String(array); + } + if (typeof key === "object" && Object.prototype.toString.call(key) === "[object Object]") return "[object Object]"; + return String(key); } - - -function YAMLException$1(reason, mark) { - // Super constructor - Error.call(this); - - this.name = 'YAMLException'; - this.reason = reason; - this.mark = mark; - this.message = formatError(this, false); - - // Include stack trace in error object - if (Error.captureStackTrace) { - // Chrome and NodeJS - Error.captureStackTrace(this, this.constructor); - } else { - // FF, IE 10+ and Safari 6+. Fallback for others - this.stack = (new Error()).stack || ''; - } -} - - -// Inherit from Error -YAMLException$1.prototype = Object.create(Error.prototype); -YAMLException$1.prototype.constructor = YAMLException$1; - - -YAMLException$1.prototype.toString = function toString(compact) { - return this.name + ': ' + formatError(this, compact); +var legacyMapTag = defineMappingTag("tag:yaml.org,2002:map", { + create: () => ({}), + identify: isPlainObject, + represent: (o) => { + const map = /* @__PURE__ */ new Map(); + for (const key of Object.keys(o)) map.set(key, o[key]); + return map; + }, + addPair: (container, key, value) => { + const normalizedKey = normalizeKey(key); + if (normalizedKey === null) return "nested arrays are not supported inside keys"; + if (normalizedKey === "__proto__") Object.defineProperty(container, normalizedKey, { + value, + enumerable: true, + configurable: true, + writable: true + }); + else container[normalizedKey] = value; + return ""; + }, + has: (container, key) => { + const normalizedKey = normalizeKey(key); + return normalizedKey !== null && Object.prototype.hasOwnProperty.call(container, normalizedKey); + }, + keys: (container) => Object.keys(container), + get: (container, key) => container[String(key)] +}); +//#endregion +//#region src/common/snippet.ts +var DEFAULT_SNIPPET_OPTIONS = { + maxLength: 79, + indent: 1, + linesBefore: 3, + linesAfter: 2 }; - - -var exception = YAMLException$1; - -// get snippet for a single line, respecting maxLength -function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { - var head = ''; - var tail = ''; - var maxHalfLength = Math.floor(maxLineLength / 2) - 1; - - if (position - lineStart > maxHalfLength) { - head = ' ... '; - lineStart = position - maxHalfLength + head.length; - } - - if (lineEnd - position > maxHalfLength) { - tail = ' ...'; - lineEnd = position + maxHalfLength - tail.length; - } - - return { - str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, - pos: position - lineStart + head.length // relative position - }; +function js_yaml_getLine(buffer, lineStart, lineEnd, position, maxLineLength) { + let head = ""; + let tail = ""; + const maxHalfLength = Math.floor(maxLineLength / 2) - 1; + if (position - lineStart > maxHalfLength) { + head = " ... "; + lineStart = position - maxHalfLength + head.length; + } + if (lineEnd - position > maxHalfLength) { + tail = " ..."; + lineEnd = position + maxHalfLength - tail.length; + } + return { + str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, "→") + tail, + pos: position - lineStart + head.length + }; } - - function padStart(string, max) { - return common.repeat(' ', max - string.length) + string; + return " ".repeat(Math.max(max - string.length, 0)) + string; } - - function makeSnippet(mark, options) { - options = Object.create(options || null); - - if (!mark.buffer) return null; - - if (!options.maxLength) options.maxLength = 79; - if (typeof options.indent !== 'number') options.indent = 1; - if (typeof options.linesBefore !== 'number') options.linesBefore = 3; - if (typeof options.linesAfter !== 'number') options.linesAfter = 2; - - var re = /\r?\n|\r|\0/g; - var lineStarts = [ 0 ]; - var lineEnds = []; - var match; - var foundLineNo = -1; - - while ((match = re.exec(mark.buffer))) { - lineEnds.push(match.index); - lineStarts.push(match.index + match[0].length); - - if (mark.position <= match.index && foundLineNo < 0) { - foundLineNo = lineStarts.length - 2; - } - } - - if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; - - var result = '', i, line; - var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; - var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); - - for (i = 1; i <= options.linesBefore; i++) { - if (foundLineNo - i < 0) break; - line = getLine( - mark.buffer, - lineStarts[foundLineNo - i], - lineEnds[foundLineNo - i], - mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), - maxLineLength - ); - result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n' + result; - } - - line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); - result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n'; - result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; - - for (i = 1; i <= options.linesAfter; i++) { - if (foundLineNo + i >= lineEnds.length) break; - line = getLine( - mark.buffer, - lineStarts[foundLineNo + i], - lineEnds[foundLineNo + i], - mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), - maxLineLength - ); - result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n'; - } - - return result.replace(/\n$/, ''); + if (!mark.buffer) return null; + const opts = { + ...DEFAULT_SNIPPET_OPTIONS, + ...options + }; + const re = /\r?\n|\r|\0/g; + const lineStarts = [0]; + const lineEnds = []; + let match; + let foundLineNo = -1; + while (match = re.exec(mark.buffer)) { + lineEnds.push(match.index); + lineStarts.push(match.index + match[0].length); + if (mark.position <= match.index && foundLineNo < 0) foundLineNo = lineStarts.length - 2; + } + if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; + let result = ""; + const lineNoLength = Math.min(mark.line + opts.linesAfter, lineEnds.length).toString().length; + const maxLineLength = opts.maxLength - (opts.indent + lineNoLength + 3); + for (let i = 1; i <= opts.linesBefore; i++) { + if (foundLineNo - i < 0) break; + const line = js_yaml_getLine(mark.buffer, lineStarts[foundLineNo - i], lineEnds[foundLineNo - i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), maxLineLength); + result = `${" ".repeat(opts.indent)}${padStart((mark.line - i + 1).toString(), lineNoLength)} | ${line.str}\n${result}`; + } + const line = js_yaml_getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); + result += `${" ".repeat(opts.indent)}${padStart((mark.line + 1).toString(), lineNoLength)} | ${line.str}\n`; + result += `${"-".repeat(opts.indent + lineNoLength + 3 + line.pos)}^\n`; + for (let i = 1; i <= opts.linesAfter; i++) { + if (foundLineNo + i >= lineEnds.length) break; + const line = js_yaml_getLine(mark.buffer, lineStarts[foundLineNo + i], lineEnds[foundLineNo + i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), maxLineLength); + result += `${" ".repeat(opts.indent)}${padStart((mark.line + i + 1).toString(), lineNoLength)} | ${line.str}\n`; + } + return result.replace(/\n$/, ""); } - - -var snippet = makeSnippet; - -var TYPE_CONSTRUCTOR_OPTIONS = [ - 'kind', - 'multi', - 'resolve', - 'construct', - 'instanceOf', - 'predicate', - 'represent', - 'representName', - 'defaultStyle', - 'styleAliases' -]; - -var YAML_NODE_KINDS = [ - 'scalar', - 'sequence', - 'mapping' -]; - -function compileStyleAliases(map) { - var result = {}; - - if (map !== null) { - Object.keys(map).forEach(function (style) { - map[style].forEach(function (alias) { - result[String(alias)] = style; - }); - }); - } - - return result; +//#endregion +//#region src/common/exception.ts +function formatError(exception, compact) { + let where = ""; + if (!exception.mark) return exception.reason; + if (exception.mark.name) where += `in "${exception.mark.name}" `; + where += `(${exception.mark.line + 1}:${exception.mark.column + 1})`; + if (!compact && exception.mark.snippet) where += `\n\n${exception.mark.snippet}`; + return `${exception.reason} ${where}`; } - -function Type$1(tag, options) { - options = options || {}; - - Object.keys(options).forEach(function (name) { - if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { - throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); - } - }); - - // TODO: Add tag format check. - this.options = options; // keep original options in case user wants to extend this type later - this.tag = tag; - this.kind = options['kind'] || null; - this.resolve = options['resolve'] || function () { return true; }; - this.construct = options['construct'] || function (data) { return data; }; - this.instanceOf = options['instanceOf'] || null; - this.predicate = options['predicate'] || null; - this.represent = options['represent'] || null; - this.representName = options['representName'] || null; - this.defaultStyle = options['defaultStyle'] || null; - this.multi = options['multi'] || false; - this.styleAliases = compileStyleAliases(options['styleAliases'] || null); - - if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { - throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); - } -} - -var type = Type$1; - -/*eslint-disable max-len*/ - - - - - -function compileList(schema, name) { - var result = []; - - schema[name].forEach(function (currentType) { - var newIndex = result.length; - - result.forEach(function (previousType, previousIndex) { - if (previousType.tag === currentType.tag && - previousType.kind === currentType.kind && - previousType.multi === currentType.multi) { - - newIndex = previousIndex; - } - }); - - result[newIndex] = currentType; - }); - - return result; -} - - -function compileMap(/* lists... */) { - var result = { - scalar: {}, - sequence: {}, - mapping: {}, - fallback: {}, - multi: { - scalar: [], - sequence: [], - mapping: [], - fallback: [] - } - }, index, length; - - function collectType(type) { - if (type.multi) { - result.multi[type.kind].push(type); - result.multi['fallback'].push(type); - } else { - result[type.kind][type.tag] = result['fallback'][type.tag] = type; - } - } - - for (index = 0, length = arguments.length; index < length; index += 1) { - arguments[index].forEach(collectType); - } - return result; -} - - -function Schema$1(definition) { - return this.extend(definition); -} - - -Schema$1.prototype.extend = function extend(definition) { - var implicit = []; - var explicit = []; - - if (definition instanceof type) { - // Schema.extend(type) - explicit.push(definition); - - } else if (Array.isArray(definition)) { - // Schema.extend([ type1, type2, ... ]) - explicit = explicit.concat(definition); - - } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { - // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) - if (definition.implicit) implicit = implicit.concat(definition.implicit); - if (definition.explicit) explicit = explicit.concat(definition.explicit); - - } else { - throw new exception('Schema.extend argument should be a Type, [ Type ], ' + - 'or a schema definition ({ implicit: [...], explicit: [...] })'); - } - - implicit.forEach(function (type$1) { - if (!(type$1 instanceof type)) { - throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - - if (type$1.loadKind && type$1.loadKind !== 'scalar') { - throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); - } - - if (type$1.multi) { - throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); - } - }); - - explicit.forEach(function (type$1) { - if (!(type$1 instanceof type)) { - throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - }); - - var result = Object.create(Schema$1.prototype); - - result.implicit = (this.implicit || []).concat(implicit); - result.explicit = (this.explicit || []).concat(explicit); - - result.compiledImplicit = compileList(result, 'implicit'); - result.compiledExplicit = compileList(result, 'explicit'); - result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); - - return result; +var YAMLException = class extends Error { + reason; + mark; + constructor(reason, mark) { + super(); + this.name = "YAMLException"; + this.reason = reason; + this.mark = mark; + this.message = formatError(this, false); + if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor); + } + toString(compact) { + return `${this.name}: ${formatError(this, compact)}`; + } }; - - -var schema = Schema$1; - -var str = new type('tag:yaml.org,2002:str', { - kind: 'scalar', - construct: function (data) { return data !== null ? data : ''; } -}); - -var seq = new type('tag:yaml.org,2002:seq', { - kind: 'sequence', - construct: function (data) { return data !== null ? data : []; } -}); - -var js_yaml_map = new type('tag:yaml.org,2002:map', { - kind: 'mapping', - construct: function (data) { return data !== null ? data : {}; } -}); - -var failsafe = new schema({ - explicit: [ - str, - seq, - js_yaml_map - ] -}); - -function resolveYamlNull(data) { - if (data === null) return true; - - var max = data.length; - - return (max === 1 && data === '~') || - (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); +function throwErrorAt(source, position, message, filename = "") { + let line = 0; + let lineStart = 0; + for (let index = 0; index < position; index++) { + const ch = source.charCodeAt(index); + if (ch === 10) { + line++; + lineStart = index + 1; + } else if (ch === 13) { + line++; + if (source.charCodeAt(index + 1) === 10) index++; + lineStart = index + 1; + } + } + const mark = { + name: filename, + buffer: source, + position, + line, + column: position - lineStart + }; + mark.snippet = makeSnippet(mark); + throw new YAMLException(message, mark); } - -function constructYamlNull() { - return null; -} - -function isNull(object) { - return object === null; -} - -var _null = new type('tag:yaml.org,2002:null', { - kind: 'scalar', - resolve: resolveYamlNull, - construct: constructYamlNull, - predicate: isNull, - represent: { - canonical: function () { return '~'; }, - lowercase: function () { return 'null'; }, - uppercase: function () { return 'NULL'; }, - camelcase: function () { return 'Null'; }, - empty: function () { return ''; } - }, - defaultStyle: 'lowercase' -}); - -function resolveYamlBoolean(data) { - if (data === null) return false; - - var max = data.length; - - return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || - (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); -} - -function constructYamlBoolean(data) { - return data === 'true' || - data === 'True' || - data === 'TRUE'; -} - -function isBoolean(object) { - return Object.prototype.toString.call(object) === '[object Boolean]'; -} - -var bool = new type('tag:yaml.org,2002:bool', { - kind: 'scalar', - resolve: resolveYamlBoolean, - construct: constructYamlBoolean, - predicate: isBoolean, - represent: { - lowercase: function (object) { return object ? 'true' : 'false'; }, - uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, - camelcase: function (object) { return object ? 'True' : 'False'; } - }, - defaultStyle: 'lowercase' -}); - -function isHexCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || - ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || - ((0x61/* a */ <= c) && (c <= 0x66/* f */)); -} - -function isOctCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); -} - -function isDecCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); -} - -function resolveYamlInteger(data) { - if (data === null) return false; - - var max = data.length, - index = 0, - hasDigits = false, - ch; - - if (!max) return false; - - ch = data[index]; - - // sign - if (ch === '-' || ch === '+') { - ch = data[++index]; - } - - if (ch === '0') { - // 0 - if (index + 1 === max) return true; - ch = data[++index]; - - // base 2, base 8, base 16 - - if (ch === 'b') { - // base 2 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (ch !== '0' && ch !== '1') return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - - - if (ch === 'x') { - // base 16 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isHexCode(data.charCodeAt(index))) return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - - - if (ch === 'o') { - // base 8 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isOctCode(data.charCodeAt(index))) return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - } - - // base 10 (except 0) - - // value should not start with `_`; - if (ch === '_') return false; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isDecCode(data.charCodeAt(index))) { - return false; - } - hasDigits = true; - } - - // Should have digits and should not end with `_` - if (!hasDigits || ch === '_') return false; - - return true; -} - -function constructYamlInteger(data) { - var value = data, sign = 1, ch; - - if (value.indexOf('_') !== -1) { - value = value.replace(/_/g, ''); - } - - ch = value[0]; - - if (ch === '-' || ch === '+') { - if (ch === '-') sign = -1; - value = value.slice(1); - ch = value[0]; - } - - if (value === '0') return 0; - - if (ch === '0') { - if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); - if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); - if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); - } - - return sign * parseInt(value, 10); -} - -function isInteger(object) { - return (Object.prototype.toString.call(object)) === '[object Number]' && - (object % 1 === 0 && !common.isNegativeZero(object)); -} - -var js_yaml_int = new type('tag:yaml.org,2002:int', { - kind: 'scalar', - resolve: resolveYamlInteger, - construct: constructYamlInteger, - predicate: isInteger, - represent: { - binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, - octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, - decimal: function (obj) { return obj.toString(10); }, - /* eslint-disable max-len */ - hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } - }, - defaultStyle: 'decimal', - styleAliases: { - binary: [ 2, 'bin' ], - octal: [ 8, 'oct' ], - decimal: [ 10, 'dec' ], - hexadecimal: [ 16, 'hex' ] - } -}); - -var YAML_FLOAT_PATTERN = new RegExp( - // 2.5e4, 2.5 and integers - '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + - // .2e4, .2 - // special case, seems not from spec - '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + - // .inf - '|[-+]?\\.(?:inf|Inf|INF)' + - // .nan - '|\\.(?:nan|NaN|NAN))$'); - -function resolveYamlFloat(data) { - if (data === null) return false; - - if (!YAML_FLOAT_PATTERN.test(data) || - // Quick hack to not allow integers end with `_` - // Probably should update regexp & check speed - data[data.length - 1] === '_') { - return false; - } - - return true; -} - -function constructYamlFloat(data) { - var value, sign; - - value = data.replace(/_/g, '').toLowerCase(); - sign = value[0] === '-' ? -1 : 1; - - if ('+-'.indexOf(value[0]) >= 0) { - value = value.slice(1); - } - - if (value === '.inf') { - return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; - - } else if (value === '.nan') { - return NaN; - } - return sign * parseFloat(value, 10); -} - - -var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; - -function representYamlFloat(object, style) { - var res; - - if (isNaN(object)) { - switch (style) { - case 'lowercase': return '.nan'; - case 'uppercase': return '.NAN'; - case 'camelcase': return '.NaN'; - } - } else if (Number.POSITIVE_INFINITY === object) { - switch (style) { - case 'lowercase': return '.inf'; - case 'uppercase': return '.INF'; - case 'camelcase': return '.Inf'; - } - } else if (Number.NEGATIVE_INFINITY === object) { - switch (style) { - case 'lowercase': return '-.inf'; - case 'uppercase': return '-.INF'; - case 'camelcase': return '-.Inf'; - } - } else if (common.isNegativeZero(object)) { - return '-0.0'; - } - - res = object.toString(10); - - // JS stringifier can build scientific format without dots: 5e-100, - // while YAML requres dot: 5.e-100. Fix it with simple hack - - return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; -} - -function isFloat(object) { - return (Object.prototype.toString.call(object) === '[object Number]') && - (object % 1 !== 0 || common.isNegativeZero(object)); -} - -var js_yaml_float = new type('tag:yaml.org,2002:float', { - kind: 'scalar', - resolve: resolveYamlFloat, - construct: constructYamlFloat, - predicate: isFloat, - represent: representYamlFloat, - defaultStyle: 'lowercase' -}); - -var json = failsafe.extend({ - implicit: [ - _null, - bool, - js_yaml_int, - js_yaml_float - ] -}); - -var core = json; - -var YAML_DATE_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9])' + // [2] month - '-([0-9][0-9])$'); // [3] day - -var YAML_TIMESTAMP_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9]?)' + // [2] month - '-([0-9][0-9]?)' + // [3] day - '(?:[Tt]|[ \\t]+)' + // ... - '([0-9][0-9]?)' + // [4] hour - ':([0-9][0-9])' + // [5] minute - ':([0-9][0-9])' + // [6] second - '(?:\\.([0-9]*))?' + // [7] fraction - '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour - '(?::([0-9][0-9]))?))?$'); // [11] tz_minute - -function resolveYamlTimestamp(data) { - if (data === null) return false; - if (YAML_DATE_REGEXP.exec(data) !== null) return true; - if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; - return false; -} - -function constructYamlTimestamp(data) { - var match, year, month, day, hour, minute, second, fraction = 0, - delta = null, tz_hour, tz_minute, date; - - match = YAML_DATE_REGEXP.exec(data); - if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); - - if (match === null) throw new Error('Date resolve error'); - - // match: [1] year [2] month [3] day - - year = +(match[1]); - month = +(match[2]) - 1; // JS month starts with 0 - day = +(match[3]); - - if (!match[4]) { // no hour - return new Date(Date.UTC(year, month, day)); - } - - // match: [4] hour [5] minute [6] second [7] fraction - - hour = +(match[4]); - minute = +(match[5]); - second = +(match[6]); - - if (match[7]) { - fraction = match[7].slice(0, 3); - while (fraction.length < 3) { // milli-seconds - fraction += '0'; - } - fraction = +fraction; - } - - // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute - - if (match[9]) { - tz_hour = +(match[10]); - tz_minute = +(match[11] || 0); - delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds - if (match[9] === '-') delta = -delta; - } - - date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); - - if (delta) date.setTime(date.getTime() - delta); - - return date; -} - -function representYamlTimestamp(object /*, style*/) { - return object.toISOString(); -} - -var timestamp = new type('tag:yaml.org,2002:timestamp', { - kind: 'scalar', - resolve: resolveYamlTimestamp, - construct: constructYamlTimestamp, - instanceOf: Date, - represent: representYamlTimestamp -}); - -function resolveYamlMerge(data) { - return data === '<<' || data === null; -} - -var merge = new type('tag:yaml.org,2002:merge', { - kind: 'scalar', - resolve: resolveYamlMerge -}); - -/*eslint-disable no-bitwise*/ - - - - - -// [ 64, 65, 66 ] -> [ padding, CR, LF ] -var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; - - -function resolveYamlBinary(data) { - if (data === null) return false; - - var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; - - // Convert one by one. - for (idx = 0; idx < max; idx++) { - code = map.indexOf(data.charAt(idx)); - - // Skip CR/LF - if (code > 64) continue; - - // Fail on illegal characters - if (code < 0) return false; - - bitlen += 6; - } - - // If there are any bits left, source was corrupted - return (bitlen % 8) === 0; -} - -function constructYamlBinary(data) { - var idx, tailbits, - input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan - max = input.length, - map = BASE64_MAP, - bits = 0, - result = []; - - // Collect by 6*4 bits (3 bytes) - - for (idx = 0; idx < max; idx++) { - if ((idx % 4 === 0) && idx) { - result.push((bits >> 16) & 0xFF); - result.push((bits >> 8) & 0xFF); - result.push(bits & 0xFF); - } - - bits = (bits << 6) | map.indexOf(input.charAt(idx)); - } - - // Dump tail - - tailbits = (max % 4) * 6; - - if (tailbits === 0) { - result.push((bits >> 16) & 0xFF); - result.push((bits >> 8) & 0xFF); - result.push(bits & 0xFF); - } else if (tailbits === 18) { - result.push((bits >> 10) & 0xFF); - result.push((bits >> 2) & 0xFF); - } else if (tailbits === 12) { - result.push((bits >> 4) & 0xFF); - } - - return new Uint8Array(result); -} - -function representYamlBinary(object /*, style*/) { - var result = '', bits = 0, idx, tail, - max = object.length, - map = BASE64_MAP; - - // Convert every three bytes to 4 ASCII characters. - - for (idx = 0; idx < max; idx++) { - if ((idx % 3 === 0) && idx) { - result += map[(bits >> 18) & 0x3F]; - result += map[(bits >> 12) & 0x3F]; - result += map[(bits >> 6) & 0x3F]; - result += map[bits & 0x3F]; - } - - bits = (bits << 8) + object[idx]; - } - - // Dump tail - - tail = max % 3; - - if (tail === 0) { - result += map[(bits >> 18) & 0x3F]; - result += map[(bits >> 12) & 0x3F]; - result += map[(bits >> 6) & 0x3F]; - result += map[bits & 0x3F]; - } else if (tail === 2) { - result += map[(bits >> 10) & 0x3F]; - result += map[(bits >> 4) & 0x3F]; - result += map[(bits << 2) & 0x3F]; - result += map[64]; - } else if (tail === 1) { - result += map[(bits >> 2) & 0x3F]; - result += map[(bits << 4) & 0x3F]; - result += map[64]; - result += map[64]; - } - - return result; -} - -function isBinary(obj) { - return Object.prototype.toString.call(obj) === '[object Uint8Array]'; -} - -var binary = new type('tag:yaml.org,2002:binary', { - kind: 'scalar', - resolve: resolveYamlBinary, - construct: constructYamlBinary, - predicate: isBinary, - represent: representYamlBinary -}); - -var _hasOwnProperty$3 = Object.prototype.hasOwnProperty; -var _toString$2 = Object.prototype.toString; - -function resolveYamlOmap(data) { - if (data === null) return true; - - var objectKeys = [], index, length, pair, pairKey, pairHasKey, - object = data; - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - pairHasKey = false; - - if (_toString$2.call(pair) !== '[object Object]') return false; - - for (pairKey in pair) { - if (_hasOwnProperty$3.call(pair, pairKey)) { - if (!pairHasKey) pairHasKey = true; - else return false; - } - } - - if (!pairHasKey) return false; - - if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); - else return false; - } - - return true; -} - -function constructYamlOmap(data) { - return data !== null ? data : []; -} - -var omap = new type('tag:yaml.org,2002:omap', { - kind: 'sequence', - resolve: resolveYamlOmap, - construct: constructYamlOmap -}); - -var _toString$1 = Object.prototype.toString; - -function resolveYamlPairs(data) { - if (data === null) return true; - - var index, length, pair, keys, result, - object = data; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - if (_toString$1.call(pair) !== '[object Object]') return false; - - keys = Object.keys(pair); - - if (keys.length !== 1) return false; - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return true; -} - -function constructYamlPairs(data) { - if (data === null) return []; - - var index, length, pair, keys, result, - object = data; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - keys = Object.keys(pair); - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return result; -} - -var pairs = new type('tag:yaml.org,2002:pairs', { - kind: 'sequence', - resolve: resolveYamlPairs, - construct: constructYamlPairs -}); - -var _hasOwnProperty$2 = Object.prototype.hasOwnProperty; - -function resolveYamlSet(data) { - if (data === null) return true; - - var key, object = data; - - for (key in object) { - if (_hasOwnProperty$2.call(object, key)) { - if (object[key] !== null) return false; - } - } - - return true; -} - -function constructYamlSet(data) { - return data !== null ? data : {}; -} - -var set = new type('tag:yaml.org,2002:set', { - kind: 'mapping', - resolve: resolveYamlSet, - construct: constructYamlSet -}); - -var _default = core.extend({ - implicit: [ - timestamp, - merge - ], - explicit: [ - binary, - omap, - pairs, - set - ] -}); - -/*eslint-disable max-len,no-use-before-define*/ - - - - - - - -var _hasOwnProperty$1 = Object.prototype.hasOwnProperty; - - -var CONTEXT_FLOW_IN = 1; -var CONTEXT_FLOW_OUT = 2; -var CONTEXT_BLOCK_IN = 3; -var CONTEXT_BLOCK_OUT = 4; - - -var CHOMPING_CLIP = 1; +//#endregion +//#region src/parser/events.ts +var EVENT_DOCUMENT = 1; +var EVENT_SEQUENCE = 2; +var EVENT_MAPPING = 3; +var EVENT_SCALAR = 4; +var EVENT_ALIAS = 5; +var EVENT_POP = 6; +var SCALAR_STYLE_PLAIN = 1; +var SCALAR_STYLE_SINGLE_QUOTED = 2; +var SCALAR_STYLE_DOUBLE_QUOTED = 3; +var SCALAR_STYLE_LITERAL_BLOCK = 4; +var SCALAR_STYLE_FOLDED_BLOCK = 5; +var COLLECTION_STYLE_BLOCK = 1; +var COLLECTION_STYLE_FLOW = 2; +var CHOMPING_CLIP = 1; var CHOMPING_STRIP = 2; -var CHOMPING_KEEP = 3; - - -var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; -var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; -var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; -var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; -var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; - - -function _class(obj) { return Object.prototype.toString.call(obj); } - -function is_EOL(c) { - return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); -} - -function is_WHITE_SPACE(c) { - return (c === 0x09/* Tab */) || (c === 0x20/* Space */); -} - -function is_WS_OR_EOL(c) { - return (c === 0x09/* Tab */) || - (c === 0x20/* Space */) || - (c === 0x0A/* LF */) || - (c === 0x0D/* CR */); -} - -function is_FLOW_INDICATOR(c) { - return c === 0x2C/* , */ || - c === 0x5B/* [ */ || - c === 0x5D/* ] */ || - c === 0x7B/* { */ || - c === 0x7D/* } */; -} - -function fromHexCode(c) { - var lc; - - if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { - return c - 0x30; - } - - /*eslint-disable no-bitwise*/ - lc = c | 0x20; - - if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { - return lc - 0x61 + 10; - } - - return -1; -} - -function escapedHexLen(c) { - if (c === 0x78/* x */) { return 2; } - if (c === 0x75/* u */) { return 4; } - if (c === 0x55/* U */) { return 8; } - return 0; -} - -function fromDecimalCode(c) { - if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { - return c - 0x30; - } - - return -1; -} - +var CHOMPING_KEEP = 3; +//#endregion +//#region src/parser/parser_scalar.ts +var NO_RANGE$3 = -1; function simpleEscapeSequence(c) { - /* eslint-disable indent */ - return (c === 0x30/* 0 */) ? '\x00' : - (c === 0x61/* a */) ? '\x07' : - (c === 0x62/* b */) ? '\x08' : - (c === 0x74/* t */) ? '\x09' : - (c === 0x09/* Tab */) ? '\x09' : - (c === 0x6E/* n */) ? '\x0A' : - (c === 0x76/* v */) ? '\x0B' : - (c === 0x66/* f */) ? '\x0C' : - (c === 0x72/* r */) ? '\x0D' : - (c === 0x65/* e */) ? '\x1B' : - (c === 0x20/* Space */) ? ' ' : - (c === 0x22/* " */) ? '\x22' : - (c === 0x2F/* / */) ? '/' : - (c === 0x5C/* \ */) ? '\x5C' : - (c === 0x4E/* N */) ? '\x85' : - (c === 0x5F/* _ */) ? '\xA0' : - (c === 0x4C/* L */) ? '\u2028' : - (c === 0x50/* P */) ? '\u2029' : ''; + switch (c) { + case 48: return "\0"; + case 97: return "\x07"; + case 98: return "\b"; + case 116: return " "; + case 9: return " "; + case 110: return "\n"; + case 118: return "\v"; + case 102: return "\f"; + case 114: return "\r"; + case 101: return "\x1B"; + case 32: return " "; + case 34: return "\""; + case 47: return "/"; + case 92: return "\\"; + case 78: return "…"; + case 95: return "\xA0"; + case 76: return "\u2028"; + case 80: return "\u2029"; + default: return ""; + } } - -function charFromCodepoint(c) { - if (c <= 0xFFFF) { - return String.fromCharCode(c); - } - // Encode UTF-16 surrogate pair - // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF - return String.fromCharCode( - ((c - 0x010000) >> 10) + 0xD800, - ((c - 0x010000) & 0x03FF) + 0xDC00 - ); -} - -// set a property of a literal object, while protecting against prototype pollution, -// see https://github.com/nodeca/js-yaml/issues/164 for more details -function setProperty(object, key, value) { - // used for this specific key only because Object.defineProperty is slow - if (key === '__proto__') { - Object.defineProperty(object, key, { - configurable: true, - enumerable: true, - writable: true, - value: value - }); - } else { - object[key] = value; - } -} - -var simpleEscapeCheck = new Array(256); // integer, for fast access +var simpleEscapeCheck = new Array(256); var simpleEscapeMap = new Array(256); -for (var i = 0; i < 256; i++) { - simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; - simpleEscapeMap[i] = simpleEscapeSequence(i); +for (let i = 0; i < 256; i++) { + simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; + simpleEscapeMap[i] = simpleEscapeSequence(i); } - - -function State$1(input, options) { - this.input = input; - - this.filename = options['filename'] || null; - this.schema = options['schema'] || _default; - this.onWarning = options['onWarning'] || null; - // (Hidden) Remove? makes the loader to expect YAML 1.1 documents - // if such documents have no explicit %YAML directive - this.legacy = options['legacy'] || false; - - this.json = options['json'] || false; - this.listener = options['listener'] || null; - - this.implicitTypes = this.schema.compiledImplicit; - this.typeMap = this.schema.compiledTypeMap; - - this.length = input.length; - this.position = 0; - this.line = 0; - this.lineStart = 0; - this.lineIndent = 0; - - // position of first leading tab in the current line, - // used to make sure there are no tabs in the indentation - this.firstTabInLine = -1; - - this.documents = []; - - /* - this.version; - this.checkLineBreaks; - this.tagMap; - this.anchorMap; - this.tag; - this.anchor; - this.kind; - this.result;*/ - +function charFromCodepoint(c) { + if (c <= 65535) return String.fromCharCode(c); + return String.fromCharCode((c - 65536 >> 10) + 55296, (c - 65536 & 1023) + 56320); } - - -function generateError(state, message) { - var mark = { - name: state.filename, - buffer: state.input.slice(0, -1), // omit trailing \0 - position: state.position, - line: state.line, - column: state.position - state.lineStart - }; - - mark.snippet = snippet(mark); - - return new exception(message, mark); +function fromHexCode$1(c) { + if (c >= 48 && c <= 57) return c - 48; + return (c | 32) - 97 + 10; +} +function escapedHexLen$1(c) { + if (c === 120) return 2; + if (c === 117) return 4; + return 8; +} +function skipFoldedBreaks(input, position, end) { + let breaks = 0; + while (position < end) { + const ch = input.charCodeAt(position); + if (ch === 10) { + breaks++; + position++; + } else if (ch === 13) { + breaks++; + position++; + if (input.charCodeAt(position) === 10) position++; + } else if (ch === 32 || ch === 9) position++; + else break; + } + return { + position, + breaks + }; +} +function foldedBreaks(count) { + if (count === 1) return " "; + return "\n".repeat(count - 1); +} +function getPlainValue(input, start, end) { + let result = ""; + let position = start; + let captureStart = start; + let captureEnd = start; + while (position < end) { + const ch = input.charCodeAt(position); + if (ch === 10 || ch === 13) { + result += input.slice(captureStart, captureEnd); + const fold = skipFoldedBreaks(input, position, end); + result += foldedBreaks(fold.breaks); + position = captureStart = captureEnd = fold.position; + } else { + position++; + if (ch !== 32 && ch !== 9) captureEnd = position; + } + } + return result + input.slice(captureStart, captureEnd); +} +function getSingleQuotedValue(input, start, end) { + let result = ""; + let position = start; + let captureStart = start; + let captureEnd = start; + while (position < end) { + const ch = input.charCodeAt(position); + if (ch === 39) { + result += input.slice(captureStart, position) + "'"; + position += 2; + captureStart = captureEnd = position; + } else if (ch === 10 || ch === 13) { + result += input.slice(captureStart, captureEnd); + const fold = skipFoldedBreaks(input, position, end); + result += foldedBreaks(fold.breaks); + position = captureStart = captureEnd = fold.position; + } else { + position++; + if (ch !== 32 && ch !== 9) captureEnd = position; + } + } + return result + input.slice(captureStart, end); +} +function getDoubleQuotedValue(input, start, end) { + let result = ""; + let position = start; + let captureStart = start; + let captureEnd = start; + while (position < end) { + const ch = input.charCodeAt(position); + if (ch === 92) { + result += input.slice(captureStart, position); + position++; + const escaped = input.charCodeAt(position); + if (escaped === 10 || escaped === 13) position = skipFoldedBreaks(input, position, end).position; + else if (escaped < 256 && simpleEscapeCheck[escaped]) { + result += simpleEscapeMap[escaped]; + position++; + } else { + let hexLength = escapedHexLen$1(escaped); + let hexResult = 0; + for (; hexLength > 0; hexLength--) { + position++; + const digit = fromHexCode$1(input.charCodeAt(position)); + hexResult = (hexResult << 4) + digit; + } + result += charFromCodepoint(hexResult); + position++; + } + captureStart = captureEnd = position; + } else if (ch === 10 || ch === 13) { + result += input.slice(captureStart, captureEnd); + const fold = skipFoldedBreaks(input, position, end); + result += foldedBreaks(fold.breaks); + position = captureStart = captureEnd = fold.position; + } else { + position++; + if (ch !== 32 && ch !== 9) captureEnd = position; + } + } + return result + input.slice(captureStart, end); +} +function getBlockValue(input, start, end, indent, chomping, folded) { + const textIndent = indent < 0 ? 0 : indent; + const region = input.slice(start, end).replace(/\r\n?/g, "\n"); + const lines = region === "" ? [] : (region.endsWith("\n") ? region.slice(0, -1) : region).split("\n"); + let result = ""; + let didReadContent = false; + let emptyLines = 0; + let atMoreIndented = false; + for (const line of lines) { + let column = 0; + while (column < textIndent && line.charCodeAt(column) === 32) column++; + if (indent < 0 || column >= line.length) { + emptyLines++; + continue; + } + const content = line.slice(textIndent); + const first = content.charCodeAt(0); + if (folded) if (first === 32 || first === 9) { + atMoreIndented = true; + result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + } else if (atMoreIndented) { + atMoreIndented = false; + result += "\n".repeat(emptyLines + 1); + } else if (emptyLines === 0) { + if (didReadContent) result += " "; + } else result += "\n".repeat(emptyLines); + else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + result += content; + didReadContent = true; + emptyLines = 0; + } + if (chomping === 3) result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines); + else if (chomping !== 2) { + if (didReadContent) result += "\n"; + } + return result; +} +function getScalarValue(input, scalar) { + if (scalar.valueStart === NO_RANGE$3) return ""; + const { valueStart, valueEnd } = scalar; + if (scalar.fast) return input.slice(valueStart, valueEnd); + switch (scalar.style) { + case 2: return getSingleQuotedValue(input, valueStart, valueEnd); + case 3: return getDoubleQuotedValue(input, valueStart, valueEnd); + case 4: return getBlockValue(input, valueStart, valueEnd, scalar.indent, scalar.chomping, false); + case 5: return getBlockValue(input, valueStart, valueEnd, scalar.indent, scalar.chomping, true); + default: return getPlainValue(input, valueStart, valueEnd); + } +} +//#endregion +//#region src/common/tagname.ts +var DEFAULT_TAG_HANDLERS = { + "!": "!", + "!!": "tag:yaml.org,2002:" +}; +function tagPercentEncode(source) { + return encodeURI(source).replace(/!/g, "%21"); +} +function tagNameFull(rawTag, tagHandlers) { + if (rawTag.startsWith("!<") && rawTag.endsWith(">")) return decodeURIComponent(rawTag.slice(2, -1)); + const handleEnd = rawTag.indexOf("!", 1); + const handle = handleEnd === -1 ? "!" : rawTag.slice(0, handleEnd + 1); + const prefix = tagHandlers?.[handle] ?? DEFAULT_TAG_HANDLERS[handle] ?? handle; + return decodeURIComponent(prefix) + decodeURIComponent(rawTag.slice(handle.length)); +} +function tagNameShort(fullTag) { + let tag = fullTag; + if (tag.charCodeAt(0) === 33) { + tag = tag.slice(1); + return `!${tagPercentEncode(tag)}`; + } + if (tag.slice(0, 18) === "tag:yaml.org,2002:") return `!!${tagPercentEncode(tag.slice(18))}`; + return `!<${tagPercentEncode(tag)}>`; +} +//#endregion +//#region src/parser/constructor.ts +var NO_RANGE$2 = -1; +var DEFAULT_CONSTRUCTOR_OPTIONS = { + filename: "", + schema: CORE_SCHEMA, + json: false, + maxTotalMergeKeys: 1e4, + maxAliases: -1 +}; +function eventPosition$1(event) { + if ("tagStart" in event && event.tagStart !== NO_RANGE$2) return event.tagStart; + if ("anchorStart" in event && event.anchorStart !== NO_RANGE$2) return event.anchorStart; + if ("valueStart" in event && event.valueStart !== NO_RANGE$2) return event.valueStart; + if ("start" in event) return event.start; + return 0; +} +function throwError$1(state, message) { + throwErrorAt(state.source, state.position, message, state.filename); +} +function finalizeCollection(state, position, tag, carrier) { + try { + return tag.finalize(carrier); + } catch (error) { + if (error instanceof YAMLException) throw error; + throwErrorAt(state.source, position, error instanceof Error ? error.message : String(error), state.filename); + } +} +function lookupTag(exact, prefix, tagName) { + const exactTag = exact[tagName]; + if (exactTag) return exactTag; + for (const tag of prefix) if (tagName.startsWith(tag.tagName)) return tag; +} +function findExplicitTag(state, exact, prefix, tagName, nodeKind) { + const tag = lookupTag(exact, prefix, tagName); + if (tag) return tag; + throwError$1(state, `unknown ${nodeKind} tag !<${tagName}>`); +} +function constructScalar(state, event) { + const source = getScalarValue(state.source, event); + const rawTag = event.tagStart === NO_RANGE$2 ? "" : state.source.slice(event.tagStart, event.tagEnd); + const strTag = state.schema.defaultScalarTag; + if (rawTag !== "") { + if (rawTag === "!") return { + value: source, + tag: strTag + }; + const tagName = tagNameFull(rawTag, state.tagHandlers); + const scalarTag = lookupTag(state.schema.exact.scalar, state.schema.prefix.scalar, tagName); + if (scalarTag) { + const result = scalarTag.resolve(source, true, tagName); + if (result === NOT_RESOLVED) throwError$1(state, `cannot resolve a node with !<${tagName}> explicit tag`); + return { + value: result, + tag: scalarTag + }; + } + const collectionTagDef = lookupTag(state.schema.exact.mapping, state.schema.prefix.mapping, tagName) ?? lookupTag(state.schema.exact.sequence, state.schema.prefix.sequence, tagName); + if (collectionTagDef) { + if (source !== "") throwError$1(state, `cannot resolve a node with !<${tagName}> explicit tag`); + const carrier = collectionTagDef.create(tagName); + return { + value: collectionTagDef.carrierIsResult ? carrier : finalizeCollection(state, state.position, collectionTagDef, carrier), + tag: collectionTagDef + }; + } + throwError$1(state, `unknown scalar tag !<${tagName}>`); + } + if (event.style === 1) { + const candidates = state.schema.implicitScalarByFirstChar.get(source.charAt(0)) ?? state.schema.implicitScalarAnyFirstChar; + for (const tag of candidates) { + const result = tag.resolve(source, false, tag.tagName); + if (result !== NOT_RESOLVED) return { + value: result, + tag + }; + } + } + return { + value: strTag.resolve(source, false, strTag.tagName), + tag: strTag + }; +} +function collectionTag(state, event, exact, prefix, defaultTagName, nodeKind) { + const rawTag = event.tagStart === NO_RANGE$2 ? "" : state.source.slice(event.tagStart, event.tagEnd); + const tagName = rawTag === "" || rawTag === "!" ? defaultTagName : tagNameFull(rawTag, state.tagHandlers); + return { + tagName, + tag: findExplicitTag(state, exact, prefix, tagName, nodeKind) + }; +} +function isMappingTag(tag) { + return tag.nodeKind === "mapping"; +} +function mergeKeys(state, frame, source, sourceTag) { + for (const sourceKey of sourceTag.keys(source)) { + if (state.maxTotalMergeKeys !== -1 && ++state.totalMergeKeys > state.maxTotalMergeKeys) throwError$1(state, `merge keys exceeded maxTotalMergeKeys (${state.maxTotalMergeKeys})`); + if (frame.tag.has(frame.value, sourceKey)) continue; + const err = frame.tag.addPair(frame.value, sourceKey, sourceTag.get(source, sourceKey)); + if (err) throwError$1(state, err); + (frame.overridable ??= /* @__PURE__ */ new Set()).add(sourceKey); + } +} +function mergeSource(state, frame, source, sourceTag) { + state.position = frame.keyPosition; + if (isMappingTag(sourceTag)) mergeKeys(state, frame, source, sourceTag); + else if (sourceTag.nodeKind === "sequence" && Array.isArray(source)) for (const element of source) mergeKeys(state, frame, element, frame.tag); + else throwError$1(state, "cannot merge mappings; the provided source object is unacceptable"); +} +function addMappingValue(state, frame, key, value, tag) { + state.position = frame.keyPosition; + if (key === MERGE_KEY) { + mergeSource(state, frame, value, tag); + return; + } + if (!state.json && frame.tag.has(frame.value, key) && !frame.overridable?.has(key)) throwError$1(state, "duplicated mapping key"); + const err = frame.tag.addPair(frame.value, key, value); + if (err) throwError$1(state, err); + frame.overridable?.delete(key); +} +function addValue(state, value, tag) { + const frame = state.frames[state.frames.length - 1]; + if (frame.kind === "document") { + frame.value = value; + frame.hasValue = true; + } else if (frame.kind === "sequence") { + if (frame.merge) { + if (!isMappingTag(tag)) throwError$1(state, "cannot merge mappings; the provided source object is unacceptable"); + } + const err = frame.tag.addItem(frame.value, value, frame.index++); + if (err) throwError$1(state, err); + } else if (frame.hasKey) { + const key = frame.key; + frame.key = void 0; + frame.hasKey = false; + addMappingValue(state, frame, key, value, tag); + } else { + frame.key = value; + frame.keyPosition = state.position; + frame.hasKey = true; + } +} +function storeAnchor(state, event, value, tag, isValueFinal) { + if (event.anchorStart !== NO_RANGE$2) { + const anchor = { + value, + tag, + isValueFinal + }; + state.anchors.set(state.source.slice(event.anchorStart, event.anchorEnd), anchor); + return anchor; + } + return null; +} +function constructFromEvents(events, options) { + const state = { + ...DEFAULT_CONSTRUCTOR_OPTIONS, + ...options, + events, + documents: [], + eventIndex: 0, + position: 0, + frames: [], + anchors: /* @__PURE__ */ new Map(), + tagHandlers: Object.create(null), + totalMergeKeys: 0, + aliasCount: 0 + }; + while (state.eventIndex < state.events.length) { + const event = state.events[state.eventIndex++]; + state.position = eventPosition$1(event); + switch (event.type) { + case 1: + state.anchors = /* @__PURE__ */ new Map(); + state.aliasCount = 0; + state.tagHandlers = Object.create(null); + for (const directive of event.directives) if (directive.kind === "tag") state.tagHandlers[directive.handle] = directive.prefix; + state.frames.push({ + kind: "document", + position: state.position, + value: void 0, + hasValue: false + }); + break; + case 4: { + const { value, tag } = constructScalar(state, event); + storeAnchor(state, event, value, tag, true); + addValue(state, value, tag); + break; + } + case 2: { + const definition = collectionTag(state, event, state.schema.exact.sequence, state.schema.prefix.sequence, "tag:yaml.org,2002:seq", "sequence"); + const value = definition.tag.create(definition.tagName); + const anchor = storeAnchor(state, event, value, definition.tag, definition.tag.carrierIsResult); + const parent = state.frames[state.frames.length - 1]; + const merge = parent !== void 0 && parent.kind === "mapping" && parent.hasKey && parent.key === MERGE_KEY; + state.frames.push({ + kind: "sequence", + position: state.position, + value, + tag: definition.tag, + anchor, + index: 0, + merge + }); + break; + } + case 3: { + const definition = collectionTag(state, event, state.schema.exact.mapping, state.schema.prefix.mapping, "tag:yaml.org,2002:map", "mapping"); + const value = definition.tag.create(definition.tagName); + const anchor = storeAnchor(state, event, value, definition.tag, definition.tag.carrierIsResult); + state.frames.push({ + kind: "mapping", + position: state.position, + value, + tag: definition.tag, + anchor, + key: void 0, + keyPosition: state.position, + hasKey: false, + overridable: null + }); + break; + } + case 5: { + if (state.maxAliases !== -1 && ++state.aliasCount > state.maxAliases) throwError$1(state, `aliases exceeded maxAliases (${state.maxAliases})`); + const name = state.source.slice(event.anchorStart, event.anchorEnd); + const anchor = state.anchors.get(name); + if (!anchor) throwError$1(state, `unidentified alias "${name}"`); + if (!anchor.isValueFinal) throwError$1(state, `recursive alias "${name}" is not supported for tag ${anchor.tag.tagName} because it uses finalize()`); + addValue(state, anchor.value, anchor.tag); + break; + } + case 6: { + const frame = state.frames.pop(); + if (frame.kind === "document") state.documents.push(frame.value); + else { + const value = frame.tag.carrierIsResult ? frame.value : finalizeCollection(state, frame.position, frame.tag, frame.value); + if (frame.anchor) { + frame.anchor.value = value; + frame.anchor.isValueFinal = true; + } + addValue(state, value, frame.tag); + } + break; + } + } + } + return state.documents; +} +//#endregion +//#region src/parser/parser.ts +var NO_RANGE$1 = -1; +var HAS_OWN = Object.prototype.hasOwnProperty; +var CONTEXT_FLOW_IN = 1; +var CONTEXT_FLOW_OUT = 2; +var CONTEXT_BLOCK_IN = 3; +var CONTEXT_BLOCK_OUT = 4; +var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; +var PATTERN_FLOW_INDICATORS = /[,\[\]{}]/; +var PATTERN_TAG_HANDLE = /^(?:!|!!|![0-9A-Za-z-]+!)$/; +var NS_URI_CHAR = String.raw`(?:%[0-9A-Fa-f]{2}|[0-9A-Za-z\-#;/?:@&=+$,_.!~*'()\[\]])`; +var NS_TAG_CHAR = String.raw`(?:%[0-9A-Fa-f]{2}|[0-9A-Za-z\-#;/?:@&=+$.~*'()_])`; +var PATTERN_TAG_URI = new RegExp(`^(?:${NS_URI_CHAR})*$`); +var PATTERN_TAG_SUFFIX = new RegExp(`^(?:${NS_TAG_CHAR})+$`); +var PATTERN_TAG_PREFIX = new RegExp(`^(?:!(?:${NS_URI_CHAR})*|${NS_TAG_CHAR}(?:${NS_URI_CHAR})*)$`); +var DEFAULT_PARSER_OPTIONS = { + filename: "", + maxDepth: 100 +}; +function addDocumentEvent(state, explicitStart, explicitEnd) { + state.events.push({ + type: 1, + explicitStart, + explicitEnd, + directives: state.directives + }); +} +function addSequenceEvent(state, start, anchorStart, anchorEnd, tagStart, tagEnd, style) { + state.events.push({ + type: 2, + start, + anchorStart, + anchorEnd, + tagStart, + tagEnd, + style + }); +} +function addMappingEvent(state, start, anchorStart, anchorEnd, tagStart, tagEnd, style) { + state.events.push({ + type: 3, + start, + anchorStart, + anchorEnd, + tagStart, + tagEnd, + style + }); +} +function addScalarEvent(state, valueStart, valueEnd, anchorStart, anchorEnd, tagStart, tagEnd, style, chomping = 1, indent = -1, fast = false) { + state.events.push({ + type: 4, + valueStart, + valueEnd, + anchorStart, + anchorEnd, + tagStart, + tagEnd, + style, + chomping, + indent, + fast + }); +} +function addAliasEvent(state, anchorStart, anchorEnd) { + state.events.push({ + type: 5, + anchorStart, + anchorEnd + }); +} +function addPopEvent(state) { + state.events.push({ type: 6 }); +} +function addEmptyScalarEvent(state) { + addScalarEvent(state, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, 1); +} +function emptyProperties() { + return { + anchorStart: NO_RANGE$1, + anchorEnd: NO_RANGE$1, + tagStart: NO_RANGE$1, + tagEnd: NO_RANGE$1 + }; +} +function snapshotState(state) { + return { + position: state.position, + line: state.line, + lineStart: state.lineStart, + lineIndent: state.lineIndent, + firstTabInLine: state.firstTabInLine, + eventsLength: state.events.length + }; +} +function restoreState(state, snapshot) { + state.position = snapshot.position; + state.line = snapshot.line; + state.lineStart = snapshot.lineStart; + state.lineIndent = snapshot.lineIndent; + state.firstTabInLine = snapshot.firstTabInLine; + state.events.length = snapshot.eventsLength; } - function throwError(state, message) { - throw generateError(state, message); + throwErrorAt(state.input.slice(0, state.length), state.position, message, state.filename); } - -function throwWarning(state, message) { - if (state.onWarning) { - state.onWarning.call(null, generateError(state, message)); - } +function isEol(c) { + return c === 10 || c === 13; } - - -var directiveHandlers = { - - YAML: function handleYamlDirective(state, name, args) { - - var match, major, minor; - - if (state.version !== null) { - throwError(state, 'duplication of %YAML directive'); - } - - if (args.length !== 1) { - throwError(state, 'YAML directive accepts exactly one argument'); - } - - match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); - - if (match === null) { - throwError(state, 'ill-formed argument of the YAML directive'); - } - - major = parseInt(match[1], 10); - minor = parseInt(match[2], 10); - - if (major !== 1) { - throwError(state, 'unacceptable YAML version of the document'); - } - - state.version = args[0]; - state.checkLineBreaks = (minor < 2); - - if (minor !== 1 && minor !== 2) { - throwWarning(state, 'unsupported YAML version of the document'); - } - }, - - TAG: function handleTagDirective(state, name, args) { - - var handle, prefix; - - if (args.length !== 2) { - throwError(state, 'TAG directive accepts exactly two arguments'); - } - - handle = args[0]; - prefix = args[1]; - - if (!PATTERN_TAG_HANDLE.test(handle)) { - throwError(state, 'ill-formed tag handle (first argument) of the TAG directive'); - } - - if (_hasOwnProperty$1.call(state.tagMap, handle)) { - throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); - } - - if (!PATTERN_TAG_URI.test(prefix)) { - throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive'); - } - - try { - prefix = decodeURIComponent(prefix); - } catch (err) { - throwError(state, 'tag prefix is malformed: ' + prefix); - } - - state.tagMap[handle] = prefix; - } -}; - - -function captureSegment(state, start, end, checkJson) { - var _position, _length, _character, _result; - - if (start < end) { - _result = state.input.slice(start, end); - - if (checkJson) { - for (_position = 0, _length = _result.length; _position < _length; _position += 1) { - _character = _result.charCodeAt(_position); - if (!(_character === 0x09 || - (0x20 <= _character && _character <= 0x10FFFF))) { - throwError(state, 'expected valid JSON character'); - } - } - } else if (PATTERN_NON_PRINTABLE.test(_result)) { - throwError(state, 'the stream contains non-printable characters'); - } - - state.result += _result; - } +function isWhiteSpace(c) { + return c === 9 || c === 32; } - -function mergeMappings(state, destination, source, overridableKeys) { - var sourceKeys, key, index, quantity; - - if (!common.isObject(source)) { - throwError(state, 'cannot merge mappings; the provided source object is unacceptable'); - } - - sourceKeys = Object.keys(source); - - for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { - key = sourceKeys[index]; - - if (!_hasOwnProperty$1.call(destination, key)) { - setProperty(destination, key, source[key]); - overridableKeys[key] = true; - } - } +function isWsOrEol(c) { + return isWhiteSpace(c) || isEol(c); } - -function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, - startLine, startLineStart, startPos) { - - var index, quantity; - - // The output is a plain object here, so keys can only be strings. - // We need to convert keyNode to a string, but doing so can hang the process - // (deeply nested arrays that explode exponentially using aliases). - if (Array.isArray(keyNode)) { - keyNode = Array.prototype.slice.call(keyNode); - - for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { - if (Array.isArray(keyNode[index])) { - throwError(state, 'nested arrays are not supported inside keys'); - } - - if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { - keyNode[index] = '[object Object]'; - } - } - } - - // Avoid code execution in load() via toString property - // (still use its own toString for arrays, timestamps, - // and whatever user schema extensions happen to have @@toStringTag) - if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { - keyNode = '[object Object]'; - } - - - keyNode = String(keyNode); - - if (_result === null) { - _result = {}; - } - - if (keyTag === 'tag:yaml.org,2002:merge') { - if (Array.isArray(valueNode)) { - for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { - mergeMappings(state, _result, valueNode[index], overridableKeys); - } - } else { - mergeMappings(state, _result, valueNode, overridableKeys); - } - } else { - if (!state.json && - !_hasOwnProperty$1.call(overridableKeys, keyNode) && - _hasOwnProperty$1.call(_result, keyNode)) { - state.line = startLine || state.line; - state.lineStart = startLineStart || state.lineStart; - state.position = startPos || state.position; - throwError(state, 'duplicated mapping key'); - } - - setProperty(_result, keyNode, valueNode); - delete overridableKeys[keyNode]; - } - - return _result; +function isWsOrEolOrEnd(c) { + return c === 0 || isWsOrEol(c); } - -function readLineBreak(state) { - var ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x0A/* LF */) { - state.position++; - } else if (ch === 0x0D/* CR */) { - state.position++; - if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { - state.position++; - } - } else { - throwError(state, 'a line break is expected'); - } - - state.line += 1; - state.lineStart = state.position; - state.firstTabInLine = -1; +function isFlowIndicator(c) { + return c === 44 || c === 91 || c === 93 || c === 123 || c === 125; } - -function skipSeparationSpace(state, allowComments, checkIndent) { - var lineBreaks = 0, - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - while (is_WHITE_SPACE(ch)) { - if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { - state.firstTabInLine = state.position; - } - ch = state.input.charCodeAt(++state.position); - } - - if (allowComments && ch === 0x23/* # */) { - do { - ch = state.input.charCodeAt(++state.position); - } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); - } - - if (is_EOL(ch)) { - readLineBreak(state); - - ch = state.input.charCodeAt(state.position); - lineBreaks++; - state.lineIndent = 0; - - while (ch === 0x20/* Space */) { - state.lineIndent++; - ch = state.input.charCodeAt(++state.position); - } - } else { - break; - } - } - - if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { - throwWarning(state, 'deficient indentation'); - } - - return lineBreaks; +function fromDecimalCode(c) { + return c >= 48 && c <= 57 ? c - 48 : -1; } - -function testDocumentSeparator(state) { - var _position = state.position, - ch; - - ch = state.input.charCodeAt(_position); - - // Condition state.position === state.lineStart is tested - // in parent on each call, for efficiency. No needs to test here again. - if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && - ch === state.input.charCodeAt(_position + 1) && - ch === state.input.charCodeAt(_position + 2)) { - - _position += 3; - - ch = state.input.charCodeAt(_position); - - if (ch === 0 || is_WS_OR_EOL(ch)) { - return true; - } - } - - return false; +function fromHexCode(c) { + if (c >= 48 && c <= 57) return c - 48; + const lc = c | 32; + if (lc >= 97 && lc <= 102) return lc - 97 + 10; + return -1; } - -function writeFoldedLines(state, count) { - if (count === 1) { - state.result += ' '; - } else if (count > 1) { - state.result += common.repeat('\n', count - 1); - } +function escapedHexLen(c) { + if (c === 120) return 2; + if (c === 117) return 4; + if (c === 85) return 8; + return 0; } - - -function readPlainScalar(state, nodeIndent, withinFlowCollection) { - var preceding, - following, - captureStart, - captureEnd, - hasPendingContent, - _line, - _lineStart, - _lineIndent, - _kind = state.kind, - _result = state.result, - ch; - - ch = state.input.charCodeAt(state.position); - - if (is_WS_OR_EOL(ch) || - is_FLOW_INDICATOR(ch) || - ch === 0x23/* # */ || - ch === 0x26/* & */ || - ch === 0x2A/* * */ || - ch === 0x21/* ! */ || - ch === 0x7C/* | */ || - ch === 0x3E/* > */ || - ch === 0x27/* ' */ || - ch === 0x22/* " */ || - ch === 0x25/* % */ || - ch === 0x40/* @ */ || - ch === 0x60/* ` */) { - return false; - } - - if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following) || - withinFlowCollection && is_FLOW_INDICATOR(following)) { - return false; - } - } - - state.kind = 'scalar'; - state.result = ''; - captureStart = captureEnd = state.position; - hasPendingContent = false; - - while (ch !== 0) { - if (ch === 0x3A/* : */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following) || - withinFlowCollection && is_FLOW_INDICATOR(following)) { - break; - } - - } else if (ch === 0x23/* # */) { - preceding = state.input.charCodeAt(state.position - 1); - - if (is_WS_OR_EOL(preceding)) { - break; - } - - } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || - withinFlowCollection && is_FLOW_INDICATOR(ch)) { - break; - - } else if (is_EOL(ch)) { - _line = state.line; - _lineStart = state.lineStart; - _lineIndent = state.lineIndent; - skipSeparationSpace(state, false, -1); - - if (state.lineIndent >= nodeIndent) { - hasPendingContent = true; - ch = state.input.charCodeAt(state.position); - continue; - } else { - state.position = captureEnd; - state.line = _line; - state.lineStart = _lineStart; - state.lineIndent = _lineIndent; - break; - } - } - - if (hasPendingContent) { - captureSegment(state, captureStart, captureEnd, false); - writeFoldedLines(state, state.line - _line); - captureStart = captureEnd = state.position; - hasPendingContent = false; - } - - if (!is_WHITE_SPACE(ch)) { - captureEnd = state.position + 1; - } - - ch = state.input.charCodeAt(++state.position); - } - - captureSegment(state, captureStart, captureEnd, false); - - if (state.result) { - return true; - } - - state.kind = _kind; - state.result = _result; - return false; +function isSimpleEscape(c) { + return c === 48 || c === 97 || c === 98 || c === 116 || c === 9 || c === 110 || c === 118 || c === 102 || c === 114 || c === 101 || c === 32 || c === 34 || c === 47 || c === 92 || c === 78 || c === 95 || c === 76 || c === 80; } - -function readSingleQuotedScalar(state, nodeIndent) { - var ch, - captureStart, captureEnd; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x27/* ' */) { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - state.position++; - captureStart = captureEnd = state.position; - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - if (ch === 0x27/* ' */) { - captureSegment(state, captureStart, state.position, true); - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x27/* ' */) { - captureStart = state.position; - state.position++; - captureEnd = state.position; - } else { - return true; - } - - } else if (is_EOL(ch)) { - captureSegment(state, captureStart, captureEnd, true); - writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); - captureStart = captureEnd = state.position; - - } else if (state.position === state.lineStart && testDocumentSeparator(state)) { - throwError(state, 'unexpected end of the document within a single quoted scalar'); - - } else { - state.position++; - captureEnd = state.position; - } - } - - throwError(state, 'unexpected end of the stream within a single quoted scalar'); +function consumeLineBreak(state) { + if (state.input.charCodeAt(state.position) === 10) state.position++; + else { + state.position++; + if (state.input.charCodeAt(state.position) === 10) state.position++; + } + state.line++; + state.lineStart = state.position; + state.lineIndent = 0; + state.firstTabInLine = -1; } - -function readDoubleQuotedScalar(state, nodeIndent) { - var captureStart, - captureEnd, - hexLength, - hexResult, - tmp, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x22/* " */) { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - state.position++; - captureStart = captureEnd = state.position; - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - if (ch === 0x22/* " */) { - captureSegment(state, captureStart, state.position, true); - state.position++; - return true; - - } else if (ch === 0x5C/* \ */) { - captureSegment(state, captureStart, state.position, true); - ch = state.input.charCodeAt(++state.position); - - if (is_EOL(ch)) { - skipSeparationSpace(state, false, nodeIndent); - - // TODO: rework to inline fn with no type cast? - } else if (ch < 256 && simpleEscapeCheck[ch]) { - state.result += simpleEscapeMap[ch]; - state.position++; - - } else if ((tmp = escapedHexLen(ch)) > 0) { - hexLength = tmp; - hexResult = 0; - - for (; hexLength > 0; hexLength--) { - ch = state.input.charCodeAt(++state.position); - - if ((tmp = fromHexCode(ch)) >= 0) { - hexResult = (hexResult << 4) + tmp; - - } else { - throwError(state, 'expected hexadecimal character'); - } - } - - state.result += charFromCodepoint(hexResult); - - state.position++; - - } else { - throwError(state, 'unknown escape sequence'); - } - - captureStart = captureEnd = state.position; - - } else if (is_EOL(ch)) { - captureSegment(state, captureStart, captureEnd, true); - writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); - captureStart = captureEnd = state.position; - - } else if (state.position === state.lineStart && testDocumentSeparator(state)) { - throwError(state, 'unexpected end of the document within a double quoted scalar'); - - } else { - state.position++; - captureEnd = state.position; - } - } - - throwError(state, 'unexpected end of the stream within a double quoted scalar'); +function skipSeparationSpace(state, allowComments) { + let lineBreaks = 0; + let ch = state.input.charCodeAt(state.position); + let hasSeparation = state.position === state.lineStart || isWsOrEol(state.input.charCodeAt(state.position - 1)); + while (ch !== 0) { + while (isWhiteSpace(ch)) { + hasSeparation = true; + if (ch === 9 && state.firstTabInLine === -1) state.firstTabInLine = state.position; + ch = state.input.charCodeAt(++state.position); + } + if (allowComments && hasSeparation && ch === 35) do + ch = state.input.charCodeAt(++state.position); + while (!isEol(ch) && ch !== 0); + if (!isEol(ch)) break; + consumeLineBreak(state); + lineBreaks++; + hasSeparation = true; + ch = state.input.charCodeAt(state.position); + while (ch === 32) { + state.lineIndent++; + ch = state.input.charCodeAt(++state.position); + } + } + return lineBreaks; } - -function readFlowCollection(state, nodeIndent) { - var readNext = true, - _line, - _lineStart, - _pos, - _tag = state.tag, - _result, - _anchor = state.anchor, - following, - terminator, - isPair, - isExplicitPair, - isMapping, - overridableKeys = Object.create(null), - keyNode, - keyTag, - valueNode, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x5B/* [ */) { - terminator = 0x5D;/* ] */ - isMapping = false; - _result = []; - } else if (ch === 0x7B/* { */) { - terminator = 0x7D;/* } */ - isMapping = true; - _result = {}; - } else { - return false; - } - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(++state.position); - - while (ch !== 0) { - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if (ch === terminator) { - state.position++; - state.tag = _tag; - state.anchor = _anchor; - state.kind = isMapping ? 'mapping' : 'sequence'; - state.result = _result; - return true; - } else if (!readNext) { - throwError(state, 'missed comma between flow collection entries'); - } else if (ch === 0x2C/* , */) { - // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 - throwError(state, "expected the node content, but found ','"); - } - - keyTag = keyNode = valueNode = null; - isPair = isExplicitPair = false; - - if (ch === 0x3F/* ? */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following)) { - isPair = isExplicitPair = true; - state.position++; - skipSeparationSpace(state, true, nodeIndent); - } - } - - _line = state.line; // Save the current line. - _lineStart = state.lineStart; - _pos = state.position; - composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); - keyTag = state.tag; - keyNode = state.result; - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { - isPair = true; - ch = state.input.charCodeAt(++state.position); - skipSeparationSpace(state, true, nodeIndent); - composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); - valueNode = state.result; - } - - if (isMapping) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); - } else if (isPair) { - _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); - } else { - _result.push(keyNode); - } - - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x2C/* , */) { - readNext = true; - ch = state.input.charCodeAt(++state.position); - } else { - readNext = false; - } - } - - throwError(state, 'unexpected end of the stream within a flow collection'); +function testDocumentSeparator(state, position = state.position) { + const ch = state.input.charCodeAt(position); + if ((ch === 45 || ch === 46) && ch === state.input.charCodeAt(position + 1) && ch === state.input.charCodeAt(position + 2)) { + const following = state.input.charCodeAt(position + 3); + return following === 0 || isWsOrEol(following); + } + return false; } - -function readBlockScalar(state, nodeIndent) { - var captureStart, - folding, - chomping = CHOMPING_CLIP, - didReadContent = false, - detectedIndent = false, - textIndent = nodeIndent, - emptyLines = 0, - atMoreIndented = false, - tmp, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x7C/* | */) { - folding = false; - } else if (ch === 0x3E/* > */) { - folding = true; - } else { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - - while (ch !== 0) { - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - if (CHOMPING_CLIP === chomping) { - chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; - } else { - throwError(state, 'repeat of a chomping mode identifier'); - } - - } else if ((tmp = fromDecimalCode(ch)) >= 0) { - if (tmp === 0) { - throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); - } else if (!detectedIndent) { - textIndent = nodeIndent + tmp - 1; - detectedIndent = true; - } else { - throwError(state, 'repeat of an indentation width identifier'); - } - - } else { - break; - } - } - - if (is_WHITE_SPACE(ch)) { - do { ch = state.input.charCodeAt(++state.position); } - while (is_WHITE_SPACE(ch)); - - if (ch === 0x23/* # */) { - do { ch = state.input.charCodeAt(++state.position); } - while (!is_EOL(ch) && (ch !== 0)); - } - } - - while (ch !== 0) { - readLineBreak(state); - state.lineIndent = 0; - - ch = state.input.charCodeAt(state.position); - - while ((!detectedIndent || state.lineIndent < textIndent) && - (ch === 0x20/* Space */)) { - state.lineIndent++; - ch = state.input.charCodeAt(++state.position); - } - - if (!detectedIndent && state.lineIndent > textIndent) { - textIndent = state.lineIndent; - } - - if (is_EOL(ch)) { - emptyLines++; - continue; - } - - // End of the scalar. - if (state.lineIndent < textIndent) { - - // Perform the chomping. - if (chomping === CHOMPING_KEEP) { - state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - } else if (chomping === CHOMPING_CLIP) { - if (didReadContent) { // i.e. only if the scalar is not empty. - state.result += '\n'; - } - } - - // Break this `while` cycle and go to the funciton's epilogue. - break; - } - - // Folded style: use fancy rules to handle line breaks. - if (folding) { - - // Lines starting with white space characters (more-indented lines) are not folded. - if (is_WHITE_SPACE(ch)) { - atMoreIndented = true; - // except for the first content line (cf. Example 8.1) - state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - - // End of more-indented block. - } else if (atMoreIndented) { - atMoreIndented = false; - state.result += common.repeat('\n', emptyLines + 1); - - // Just one line break - perceive as the same line. - } else if (emptyLines === 0) { - if (didReadContent) { // i.e. only if we have already read some scalar content. - state.result += ' '; - } - - // Several line breaks - perceive as different lines. - } else { - state.result += common.repeat('\n', emptyLines); - } - - // Literal style: just add exact number of line breaks between content lines. - } else { - // Keep all line breaks except the header line break. - state.result += common.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - } - - didReadContent = true; - detectedIndent = true; - emptyLines = 0; - captureStart = state.position; - - while (!is_EOL(ch) && (ch !== 0)) { - ch = state.input.charCodeAt(++state.position); - } - - captureSegment(state, captureStart, state.position, false); - } - - return true; +function skipUntilLineEnd(state) { + let ch = state.input.charCodeAt(state.position); + while (ch !== 0 && !isEol(ch)) ch = state.input.charCodeAt(++state.position); } - -function readBlockSequence(state, nodeIndent) { - var _line, - _tag = state.tag, - _anchor = state.anchor, - _result = [], - following, - detected = false, - ch; - - // there is a leading tab before this token, so it can't be a block sequence/mapping; - // it can still be flow sequence/mapping or a scalar - if (state.firstTabInLine !== -1) return false; - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - if (state.firstTabInLine !== -1) { - state.position = state.firstTabInLine; - throwError(state, 'tab characters must not be used in indentation'); - } - - if (ch !== 0x2D/* - */) { - break; - } - - following = state.input.charCodeAt(state.position + 1); - - if (!is_WS_OR_EOL(following)) { - break; - } - - detected = true; - state.position++; - - if (skipSeparationSpace(state, true, -1)) { - if (state.lineIndent <= nodeIndent) { - _result.push(null); - ch = state.input.charCodeAt(state.position); - continue; - } - } - - _line = state.line; - composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); - _result.push(state.result); - skipSeparationSpace(state, true, -1); - - ch = state.input.charCodeAt(state.position); - - if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { - throwError(state, 'bad indentation of a sequence entry'); - } else if (state.lineIndent < nodeIndent) { - break; - } - } - - if (detected) { - state.tag = _tag; - state.anchor = _anchor; - state.kind = 'sequence'; - state.result = _result; - return true; - } - return false; +function checkPrintable(state, start, end) { + if (PATTERN_NON_PRINTABLE.test(state.input.slice(start, end))) throwError(state, "the stream contains non-printable characters"); } - -function readBlockMapping(state, nodeIndent, flowIndent) { - var following, - allowCompact, - _line, - _keyLine, - _keyLineStart, - _keyPos, - _tag = state.tag, - _anchor = state.anchor, - _result = {}, - overridableKeys = Object.create(null), - keyTag = null, - keyNode = null, - valueNode = null, - atExplicitKey = false, - detected = false, - ch; - - // there is a leading tab before this token, so it can't be a block sequence/mapping; - // it can still be flow sequence/mapping or a scalar - if (state.firstTabInLine !== -1) return false; - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - if (!atExplicitKey && state.firstTabInLine !== -1) { - state.position = state.firstTabInLine; - throwError(state, 'tab characters must not be used in indentation'); - } - - following = state.input.charCodeAt(state.position + 1); - _line = state.line; // Save the current line. - - // - // Explicit notation case. There are two separate blocks: - // first for the key (denoted by "?") and second for the value (denoted by ":") - // - if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { - - if (ch === 0x3F/* ? */) { - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = true; - allowCompact = true; - - } else if (atExplicitKey) { - // i.e. 0x3A/* : */ === character after the explicit key. - atExplicitKey = false; - allowCompact = true; - - } else { - throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); - } - - state.position += 1; - ch = following; - - // - // Implicit notation case. Flow-style node as the key first, then ":", and the value. - // - } else { - _keyLine = state.line; - _keyLineStart = state.lineStart; - _keyPos = state.position; - - if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { - // Neither implicit nor explicit notation. - // Reading is done. Go to the epilogue. - break; - } - - if (state.line === _line) { - ch = state.input.charCodeAt(state.position); - - while (is_WHITE_SPACE(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (ch === 0x3A/* : */) { - ch = state.input.charCodeAt(++state.position); - - if (!is_WS_OR_EOL(ch)) { - throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping'); - } - - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = false; - allowCompact = false; - keyTag = state.tag; - keyNode = state.result; - - } else if (detected) { - throwError(state, 'can not read an implicit mapping pair; a colon is missed'); - - } else { - state.tag = _tag; - state.anchor = _anchor; - return true; // Keep the result of `composeNode`. - } - - } else if (detected) { - throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); - - } else { - state.tag = _tag; - state.anchor = _anchor; - return true; // Keep the result of `composeNode`. - } - } - - // - // Common reading code for both explicit and implicit notations. - // - if (state.line === _line || state.lineIndent > nodeIndent) { - if (atExplicitKey) { - _keyLine = state.line; - _keyLineStart = state.lineStart; - _keyPos = state.position; - } - - if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { - if (atExplicitKey) { - keyNode = state.result; - } else { - valueNode = state.result; - } - } - - if (!atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - skipSeparationSpace(state, true, -1); - ch = state.input.charCodeAt(state.position); - } - - if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { - throwError(state, 'bad indentation of a mapping entry'); - } else if (state.lineIndent < nodeIndent) { - break; - } - } - - // - // Epilogue. - // - - // Special case: last mapping's node contains only the key in explicit notation. - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - } - - // Expose the resulting mapping. - if (detected) { - state.tag = _tag; - state.anchor = _anchor; - state.kind = 'mapping'; - state.result = _result; - } - - return detected; +function readTagProperty(state, props, inFlow) { + if (state.input.charCodeAt(state.position) !== 33) return false; + if (props.tagStart !== NO_RANGE$1) throwError(state, "duplication of a tag property"); + const start = state.position; + let isVerbatim = false; + let isNamed = false; + let tagHandle = "!"; + let ch = state.input.charCodeAt(++state.position); + if (ch === 60) { + isVerbatim = true; + ch = state.input.charCodeAt(++state.position); + } else if (ch === 33) { + isNamed = true; + tagHandle = "!!"; + ch = state.input.charCodeAt(++state.position); + } + let suffixStart = state.position; + let tagName; + if (isVerbatim) { + while (ch !== 0 && ch !== 62) ch = state.input.charCodeAt(++state.position); + if (ch !== 62) throwError(state, "unexpected end of the stream within a verbatim tag"); + tagName = state.input.slice(suffixStart, state.position); + state.position++; + } else { + while (ch !== 0 && !isWsOrEol(ch) && !(inFlow && isFlowIndicator(ch))) { + if (ch === 33) if (!isNamed) { + tagHandle = state.input.slice(suffixStart - 1, state.position + 1); + if (!PATTERN_TAG_HANDLE.test(tagHandle)) throwError(state, "named tag handle cannot contain such characters"); + isNamed = true; + suffixStart = state.position + 1; + } else throwError(state, "tag suffix cannot contain exclamation marks"); + ch = state.input.charCodeAt(++state.position); + } + tagName = state.input.slice(suffixStart, state.position); + if (PATTERN_FLOW_INDICATORS.test(tagName)) throwError(state, "tag suffix cannot contain flow indicator characters"); + } + if (tagName && !(isVerbatim ? PATTERN_TAG_URI.test(tagName) : PATTERN_TAG_SUFFIX.test(tagName))) throwError(state, `tag name cannot contain such characters: ${tagName}`); + if (!isVerbatim && tagHandle !== "!" && tagHandle !== "!!" && !HAS_OWN.call(state.tagHandlers, tagHandle)) throwError(state, `undeclared tag handle "${tagHandle}"`); + props.tagStart = start; + props.tagEnd = state.position; + return true; } - -function readTagProperty(state) { - var _position, - isVerbatim = false, - isNamed = false, - tagHandle, - tagName, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x21/* ! */) return false; - - if (state.tag !== null) { - throwError(state, 'duplication of a tag property'); - } - - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x3C/* < */) { - isVerbatim = true; - ch = state.input.charCodeAt(++state.position); - - } else if (ch === 0x21/* ! */) { - isNamed = true; - tagHandle = '!!'; - ch = state.input.charCodeAt(++state.position); - - } else { - tagHandle = '!'; - } - - _position = state.position; - - if (isVerbatim) { - do { ch = state.input.charCodeAt(++state.position); } - while (ch !== 0 && ch !== 0x3E/* > */); - - if (state.position < state.length) { - tagName = state.input.slice(_position, state.position); - ch = state.input.charCodeAt(++state.position); - } else { - throwError(state, 'unexpected end of the stream within a verbatim tag'); - } - } else { - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - - if (ch === 0x21/* ! */) { - if (!isNamed) { - tagHandle = state.input.slice(_position - 1, state.position + 1); - - if (!PATTERN_TAG_HANDLE.test(tagHandle)) { - throwError(state, 'named tag handle cannot contain such characters'); - } - - isNamed = true; - _position = state.position + 1; - } else { - throwError(state, 'tag suffix cannot contain exclamation marks'); - } - } - - ch = state.input.charCodeAt(++state.position); - } - - tagName = state.input.slice(_position, state.position); - - if (PATTERN_FLOW_INDICATORS.test(tagName)) { - throwError(state, 'tag suffix cannot contain flow indicator characters'); - } - } - - if (tagName && !PATTERN_TAG_URI.test(tagName)) { - throwError(state, 'tag name cannot contain such characters: ' + tagName); - } - - try { - tagName = decodeURIComponent(tagName); - } catch (err) { - throwError(state, 'tag name is malformed: ' + tagName); - } - - if (isVerbatim) { - state.tag = tagName; - - } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) { - state.tag = state.tagMap[tagHandle] + tagName; - - } else if (tagHandle === '!') { - state.tag = '!' + tagName; - - } else if (tagHandle === '!!') { - state.tag = 'tag:yaml.org,2002:' + tagName; - - } else { - throwError(state, 'undeclared tag handle "' + tagHandle + '"'); - } - - return true; +function readAnchorProperty(state, props) { + if (state.input.charCodeAt(state.position) !== 38) return false; + if (props.anchorStart !== NO_RANGE$1) throwError(state, "duplication of an anchor property"); + state.position++; + const start = state.position; + while (state.input.charCodeAt(state.position) !== 0 && !isWsOrEol(state.input.charCodeAt(state.position)) && !isFlowIndicator(state.input.charCodeAt(state.position))) state.position++; + if (state.position === start) throwError(state, "name of an anchor node must contain at least one character"); + props.anchorStart = start; + props.anchorEnd = state.position; + return true; } - -function readAnchorProperty(state) { - var _position, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x26/* & */) return false; - - if (state.anchor !== null) { - throwError(state, 'duplication of an anchor property'); - } - - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (state.position === _position) { - throwError(state, 'name of an anchor node must contain at least one character'); - } - - state.anchor = state.input.slice(_position, state.position); - return true; +function readAlias(state, props) { + if (state.input.charCodeAt(state.position) !== 42) return false; + if (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1) throwError(state, "alias node should not have any properties"); + state.position++; + const start = state.position; + while (state.input.charCodeAt(state.position) !== 0 && !isWsOrEol(state.input.charCodeAt(state.position)) && !isFlowIndicator(state.input.charCodeAt(state.position))) state.position++; + if (state.position === start) throwError(state, "name of an alias node must contain at least one character"); + addAliasEvent(state, start, state.position); + return true; } - -function readAlias(state) { - var _position, alias, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x2A/* * */) return false; - - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (state.position === _position) { - throwError(state, 'name of an alias node must contain at least one character'); - } - - alias = state.input.slice(_position, state.position); - - if (!_hasOwnProperty$1.call(state.anchorMap, alias)) { - throwError(state, 'unidentified alias "' + alias + '"'); - } - - state.result = state.anchorMap[alias]; - skipSeparationSpace(state, true, -1); - return true; +function readFlowScalarBreak(state, nodeIndent) { + skipSeparationSpace(state, false); + if (state.lineIndent < nodeIndent) throwError(state, "deficient indentation"); } - -function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { - var allowBlockStyles, - allowBlockScalars, - allowBlockCollections, - indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { - indentStatus = 1; - } else if (state.lineIndent === parentIndent) { - indentStatus = 0; - } else if (state.lineIndent < parentIndent) { - indentStatus = -1; - } - } - } - - if (indentStatus === 1) { - while (readTagProperty(state) || readAnchorProperty(state)) { - if (skipSeparationSpace(state, true, -1)) { - atNewLine = true; - allowBlockCollections = allowBlockStyles; - - if (state.lineIndent > parentIndent) { - indentStatus = 1; - } else if (state.lineIndent === parentIndent) { - indentStatus = 0; - } else if (state.lineIndent < parentIndent) { - indentStatus = -1; - } - } else { - allowBlockCollections = false; - } - } - } - - if (allowBlockCollections) { - allowBlockCollections = atNewLine || allowCompact; - } - - if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { - if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { - flowIndent = parentIndent; - } else { - flowIndent = parentIndent + 1; - } - - blockIndent = state.position - state.lineStart; - - if (indentStatus === 1) { - if (allowBlockCollections && - (readBlockSequence(state, blockIndent) || - readBlockMapping(state, blockIndent, flowIndent)) || - readFlowCollection(state, flowIndent)) { - hasContent = true; - } else { - if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || - readSingleQuotedScalar(state, flowIndent) || - readDoubleQuotedScalar(state, flowIndent)) { - hasContent = true; - - } else if (readAlias(state)) { - hasContent = true; - - if (state.tag !== null || state.anchor !== null) { - throwError(state, 'alias node should not have any properties'); - } - - } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { - hasContent = true; - - if (state.tag === null) { - state.tag = '?'; - } - } - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - } - } else if (indentStatus === 0) { - // Special case: block sequences are allowed to have same indentation level as the parent. - // http://www.yaml.org/spec/1.2/spec.html#id2799784 - hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); - } - } - - if (state.tag === null) { - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - - } else if (state.tag === '?') { - // Implicit resolving is not allowed for non-scalar types, and '?' - // non-specific tag is only automatically assigned to plain scalars. - // - // We only need to check kind conformity in case user explicitly assigns '?' - // tag, for example like this: "! [0]" - // - if (state.result !== null && state.kind !== 'scalar') { - throwError(state, 'unacceptable node kind for ! tag; it should be "scalar", not "' + state.kind + '"'); - } - - for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { - type = state.implicitTypes[typeIndex]; - - if (type.resolve(state.result)) { // `state.result` updated in resolver if matched - state.result = type.construct(state.result); - state.tag = type.tag; - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - break; - } - } - } else if (state.tag !== '!') { - if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) { - type = state.typeMap[state.kind || 'fallback'][state.tag]; - } else { - // looking for multi type - type = null; - typeList = state.typeMap.multi[state.kind || 'fallback']; - - for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { - if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { - type = typeList[typeIndex]; - break; - } - } - } - - if (!type) { - throwError(state, 'unknown tag !<' + state.tag + '>'); - } - - if (state.result !== null && type.kind !== state.kind) { - throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); - } - - if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched - throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); - } else { - state.result = type.construct(state.result, state.tag); - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - } - } - - if (state.listener !== null) { - state.listener('close', state); - } - return state.tag !== null || state.anchor !== null || hasContent; +function readSingleQuotedScalar(state, nodeIndent, props) { + if (state.input.charCodeAt(state.position) !== 39) return false; + state.position++; + const start = state.position; + let simple = true; + while (state.input.charCodeAt(state.position) !== 0) { + const ch = state.input.charCodeAt(state.position); + if (ch === 39) { + if (state.input.charCodeAt(state.position + 1) === 39) { + simple = false; + state.position += 2; + continue; + } + const end = state.position; + state.position++; + addScalarEvent(state, start, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 2, 1, -1, simple); + return true; + } + if (isEol(ch)) { + simple = false; + readFlowScalarBreak(state, nodeIndent); + } else if (state.position === state.lineStart && testDocumentSeparator(state)) throwError(state, "unexpected end of the document within a single quoted scalar"); + else if (ch !== 9 && ch < 32) throwError(state, "expected valid JSON character"); + else state.position++; + } + throwError(state, "unexpected end of the stream within a single quoted scalar"); +} +function readDoubleQuotedScalar(state, nodeIndent, props) { + if (state.input.charCodeAt(state.position) !== 34) return false; + state.position++; + const start = state.position; + let simple = true; + while (state.input.charCodeAt(state.position) !== 0) { + const ch = state.input.charCodeAt(state.position); + if (ch === 34) { + const end = state.position; + state.position++; + addScalarEvent(state, start, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 3, 1, -1, simple); + return true; + } + if (ch === 92) { + simple = false; + const escaped = state.input.charCodeAt(++state.position); + if (isEol(escaped)) readFlowScalarBreak(state, nodeIndent); + else if (isSimpleEscape(escaped)) state.position++; + else { + let hexLength = escapedHexLen(escaped); + if (hexLength === 0) throwError(state, "unknown escape sequence"); + while (hexLength-- > 0) { + state.position++; + if (fromHexCode(state.input.charCodeAt(state.position)) < 0) throwError(state, "expected hexadecimal character"); + } + state.position++; + } + } else if (isEol(ch)) { + simple = false; + readFlowScalarBreak(state, nodeIndent); + } else if (state.position === state.lineStart && testDocumentSeparator(state)) throwError(state, "unexpected end of the document within a double quoted scalar"); + else if (ch !== 9 && ch < 32) throwError(state, "expected valid JSON character"); + else state.position++; + } + throwError(state, "unexpected end of the stream within a double quoted scalar"); +} +function readBlockScalar(state, parentIndent, props) { + const ch = state.input.charCodeAt(state.position); + let chomping = 1; + let indent = -1; + let detectedIndent = false; + if (ch !== 124 && ch !== 62) return false; + const style = ch === 124 ? 4 : 5; + state.position++; + while (state.input.charCodeAt(state.position) !== 0) { + const current = state.input.charCodeAt(state.position); + const digit = fromDecimalCode(current); + if (current === 43 || current === 45) { + if (chomping !== 1) throwError(state, "repeat of a chomping mode identifier"); + chomping = current === 43 ? 3 : 2; + state.position++; + } else if (digit >= 0) { + if (digit === 0) throwError(state, "bad explicit indentation width of a block scalar; it cannot be less than one"); + if (detectedIndent) throwError(state, "repeat of an indentation width identifier"); + indent = parentIndent + digit - 1; + detectedIndent = true; + state.position++; + } else break; + } + let hadWhitespace = false; + while (isWhiteSpace(state.input.charCodeAt(state.position))) { + hadWhitespace = true; + state.position++; + } + if (hadWhitespace && state.input.charCodeAt(state.position) === 35) skipUntilLineEnd(state); + if (isEol(state.input.charCodeAt(state.position))) consumeLineBreak(state); + else if (state.input.charCodeAt(state.position) !== 0) throwError(state, "a line break is expected"); + let contentIndent = detectedIndent ? indent : -1; + let maxLeadingIndent = 0; + const valueStart = state.position; + let valueEnd = state.position; + while (state.input.charCodeAt(state.position) !== 0) { + const linePosition = state.position; + let column = 0; + while (state.input.charCodeAt(linePosition + column) === 32) column++; + const first = state.input.charCodeAt(linePosition + column); + if (first === 0) { + if (contentIndent >= 0) { + if (column > contentIndent) valueEnd = linePosition + column; + } else if (column > 0) valueEnd = linePosition + column; + break; + } + if (linePosition === state.lineStart && testDocumentSeparator(state, linePosition)) break; + if (!detectedIndent && contentIndent === -1 && isEol(first)) maxLeadingIndent = Math.max(maxLeadingIndent, column); + if (!detectedIndent && contentIndent === -1 && !isEol(first)) { + if (first === 9 && column < parentIndent) { + state.position = linePosition + column; + throwError(state, "tab characters must not be used in indentation"); + } + if (column < maxLeadingIndent) { + state.position = linePosition + column; + throwError(state, "bad indentation of a mapping entry"); + } + } + if (contentIndent === -1 && first !== 0 && !isEol(first) && column < parentIndent) { + state.lineIndent = column; + state.position = linePosition + column; + break; + } + if (!detectedIndent && first !== 0 && !isEol(first) && contentIndent === -1) contentIndent = column; + const requiredIndent = contentIndent === -1 ? parentIndent + 1 : contentIndent; + if (first !== 0 && !isEol(first) && column < requiredIndent) { + state.lineIndent = column; + state.position = linePosition + column; + break; + } + skipUntilLineEnd(state); + valueEnd = state.position; + if (isEol(state.input.charCodeAt(state.position))) { + consumeLineBreak(state); + valueEnd = state.position; + } + } + checkPrintable(state, valueStart, valueEnd); + addScalarEvent(state, valueStart, valueEnd, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, style, chomping, contentIndent); + return true; +} +function canStartPlainScalar(state, nodeContext) { + const ch = state.input.charCodeAt(state.position); + const inFlow = nodeContext === CONTEXT_FLOW_IN; + if (ch === 0 || isWsOrEol(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96 || inFlow && isFlowIndicator(ch)) return false; + if (ch === 63 || ch === 45) { + const following = state.input.charCodeAt(state.position + 1); + if (isWsOrEolOrEnd(following) || inFlow && isFlowIndicator(following)) return false; + } + return true; +} +function readPlainScalar(state, nodeIndent, nodeContext, props) { + if (!canStartPlainScalar(state, nodeContext)) return false; + const start = state.position; + let end = state.position; + let ch = state.input.charCodeAt(state.position); + const inFlow = nodeContext === CONTEXT_FLOW_IN; + let multiline = false; + while (ch !== 0) { + if (state.position === state.lineStart && testDocumentSeparator(state)) break; + if (ch === 58) { + const following = state.input.charCodeAt(state.position + 1); + if (isWsOrEolOrEnd(following) || inFlow && isFlowIndicator(following)) break; + } else if (ch === 35) { + if (isWsOrEol(state.input.charCodeAt(state.position - 1))) break; + } else if (inFlow && isFlowIndicator(ch)) break; + else if (isEol(ch)) { + const savedPosition = state.position; + const savedLine = state.line; + const savedLineStart = state.lineStart; + const savedLineIndent = state.lineIndent; + skipSeparationSpace(state, false); + if (state.lineIndent >= nodeIndent) { + multiline = true; + ch = state.input.charCodeAt(state.position); + continue; + } + state.position = savedPosition; + state.line = savedLine; + state.lineStart = savedLineStart; + state.lineIndent = savedLineIndent; + break; + } + if (!isWhiteSpace(ch)) end = state.position + 1; + ch = state.input.charCodeAt(++state.position); + } + if (end === start) return false; + checkPrintable(state, start, end); + addScalarEvent(state, start, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 1, 1, -1, !multiline); + return true; +} +function skipFlowSeparationSpace(state, nodeIndent) { + const startLine = state.line; + skipSeparationSpace(state, true); + if (state.line > startLine && state.lineIndent < nodeIndent || state.firstTabInLine !== -1 && state.lineIndent < nodeIndent) throwError(state, "deficient indentation"); +} +function readFlowCollection(state, nodeIndent, props) { + const ch = state.input.charCodeAt(state.position); + const isMapping = ch === 123; + const start = state.position; + let readNext = true; + if (ch !== 91 && ch !== 123) return false; + const terminator = isMapping ? 125 : 93; + if (isMapping) addMappingEvent(state, start, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 2); + else addSequenceEvent(state, start, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 2); + state.position++; + while (state.input.charCodeAt(state.position) !== 0) { + skipFlowSeparationSpace(state, nodeIndent); + let ch = state.input.charCodeAt(state.position); + if (ch === terminator) { + state.position++; + addPopEvent(state); + return true; + } else if (!readNext) throwError(state, "missed comma between flow collection entries"); + else if (ch === 44) throwError(state, "expected the node content, but found ','"); + let isPair = false; + let isExplicitPair = false; + if (ch === 63 && isWsOrEol(state.input.charCodeAt(state.position + 1))) { + isPair = isExplicitPair = true; + state.position += 1; + skipFlowSeparationSpace(state, nodeIndent); + } + const entryLine = state.line; + const entryStart = snapshotState(state); + const keyWasRead = parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + skipFlowSeparationSpace(state, nodeIndent); + ch = state.input.charCodeAt(state.position); + if ((isMapping || isExplicitPair || state.line === entryLine) && ch === 58) { + isPair = true; + state.position++; + skipFlowSeparationSpace(state, nodeIndent); + if (!isMapping) { + restoreState(state, entryStart); + addMappingEvent(state, entryStart.position, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, 2); + if (!parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true)) addEmptyScalarEvent(state); + skipFlowSeparationSpace(state, nodeIndent); + state.position++; + skipFlowSeparationSpace(state, nodeIndent); + } else if (!keyWasRead) addEmptyScalarEvent(state); + if (!parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true)) addEmptyScalarEvent(state); + skipFlowSeparationSpace(state, nodeIndent); + if (!isMapping) addPopEvent(state); + } else if (isMapping && isPair) { + if (!keyWasRead) addEmptyScalarEvent(state); + addEmptyScalarEvent(state); + } else if (isMapping) addEmptyScalarEvent(state); + else if (isPair) { + restoreState(state, entryStart); + addMappingEvent(state, entryStart.position, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, 2); + parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); + addEmptyScalarEvent(state); + addPopEvent(state); + } + ch = state.input.charCodeAt(state.position); + if (ch === 44) { + readNext = true; + state.position++; + } else readNext = false; + } + throwError(state, "unexpected end of the stream within a flow collection"); +} +function readBlockSequence(state, nodeIndent, props) { + if (state.firstTabInLine !== -1 || state.input.charCodeAt(state.position) !== 45 || !isWsOrEolOrEnd(state.input.charCodeAt(state.position + 1))) return false; + addSequenceEvent(state, state.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 1); + while (state.input.charCodeAt(state.position) === 45 && isWsOrEolOrEnd(state.input.charCodeAt(state.position + 1))) { + if (state.firstTabInLine !== -1) { + state.position = state.firstTabInLine; + throwError(state, "tab characters must not be used in indentation"); + } + const entryLine = state.line; + state.position++; + const hadBreak = skipSeparationSpace(state, true) > 0; + if (state.firstTabInLine !== -1 && state.input.charCodeAt(state.position) === 45 && isWsOrEolOrEnd(state.input.charCodeAt(state.position + 1))) throwError(state, "bad indentation of a sequence entry"); + if (hadBreak && state.lineIndent <= nodeIndent) addEmptyScalarEvent(state); + else parseNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); + skipSeparationSpace(state, true); + if (state.lineIndent < nodeIndent || state.position >= state.length) break; + if (state.lineIndent > nodeIndent) throwError(state, "bad indentation of a sequence entry"); + if (state.line === entryLine && state.input.charCodeAt(state.position) === 45 && isWsOrEolOrEnd(state.input.charCodeAt(state.position + 1))) throwError(state, "bad indentation of a sequence entry"); + } + addPopEvent(state); + return true; +} +function readBlockMapping(state, nodeIndent, flowIndent, props) { + let atExplicitKey = false; + let detected = false; + let mappingOpened = false; + let pendingExplicitKey = false; + if (state.firstTabInLine !== -1) return false; + let ch = state.input.charCodeAt(state.position); + while (ch !== 0) { + if (!atExplicitKey && state.firstTabInLine !== -1) { + state.position = state.firstTabInLine; + throwError(state, "tab characters must not be used in indentation"); + } + const following = state.input.charCodeAt(state.position + 1); + const entryLine = state.line; + if ((ch === 63 || ch === 58) && isWsOrEolOrEnd(following)) { + if (!mappingOpened) { + addMappingEvent(state, state.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 1); + mappingOpened = true; + } + if (ch === 63) { + if (atExplicitKey) addEmptyScalarEvent(state); + detected = true; + atExplicitKey = true; + } else if (atExplicitKey) atExplicitKey = false; + else { + addEmptyScalarEvent(state); + detected = true; + atExplicitKey = false; + } + state.position += 1; + pendingExplicitKey = true; + } else { + if (atExplicitKey) { + addEmptyScalarEvent(state); + atExplicitKey = false; + } + const beforeKey = snapshotState(state); + if (!parseNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) break; + if (state.line === entryLine) { + ch = state.input.charCodeAt(state.position); + while (isWhiteSpace(ch)) ch = state.input.charCodeAt(++state.position); + if (ch === 58) { + ch = state.input.charCodeAt(++state.position); + if (!isWsOrEolOrEnd(ch)) throwError(state, "a whitespace character is expected after the key-value separator within a block mapping"); + if (!mappingOpened) { + restoreState(state, beforeKey); + addMappingEvent(state, beforeKey.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 1); + mappingOpened = true; + parseNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true); + ch = state.input.charCodeAt(state.position); + while (isWhiteSpace(ch)) ch = state.input.charCodeAt(++state.position); + state.position++; + } + detected = true; + atExplicitKey = false; + pendingExplicitKey = false; + } else if (detected) throwError(state, "expected ':' after a mapping key"); + else { + if (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1) { + restoreState(state, beforeKey); + return false; + } + return true; + } + } else if (detected) throwError(state, "can not read a block mapping entry; a multiline key may not be an implicit key"); + else { + if (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1) { + restoreState(state, beforeKey); + return false; + } + return true; + } + } + if (parseNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, pendingExplicitKey)) pendingExplicitKey = false; + if (!atExplicitKey) { + if (pendingExplicitKey) { + addEmptyScalarEvent(state); + pendingExplicitKey = false; + } + } + skipSeparationSpace(state, true); + ch = state.input.charCodeAt(state.position); + if ((state.line === entryLine || state.lineIndent > nodeIndent) && ch !== 0) throwError(state, "bad indentation of a mapping entry"); + else if (state.lineIndent < nodeIndent) break; + } + if (!detected) return false; + if (atExplicitKey) addEmptyScalarEvent(state); + if (mappingOpened) addPopEvent(state); + return true; +} +function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact, allowPropertyMapping = true) { + if (state.depth >= state.maxDepth) throwError(state, `nesting exceeded maxDepth (${state.maxDepth})`); + state.depth++; + let indentStatus = 1; + let atNewLine = false; + let hasContent = false; + let propertyStart = null; + const props = emptyProperties(); + let allowBlockScalars = nodeContext === CONTEXT_BLOCK_OUT || nodeContext === CONTEXT_BLOCK_IN; + let allowBlockCollections = allowBlockScalars; + const allowBlockStyles = allowBlockScalars; + if (allowToSeek && skipSeparationSpace(state, true)) { + atNewLine = true; + if (state.lineIndent > parentIndent) indentStatus = 1; + else if (state.lineIndent === parentIndent) indentStatus = 0; + else indentStatus = -1; + } + if (state.position === state.lineStart && testDocumentSeparator(state)) { + state.depth--; + return false; + } + if (indentStatus === 1) while (true) { + const ch = state.input.charCodeAt(state.position); + const propertyState = snapshotState(state); + if (atNewLine && indentStatus !== 1 && (ch === 33 || ch === 38)) break; + if (atNewLine && allowBlockStyles && (props.tagStart !== NO_RANGE$1 || props.anchorStart !== NO_RANGE$1) && (ch === 33 || ch === 38)) { + const fallbackState = snapshotState(state); + const flowIndent = parentIndent + 1; + if (readBlockMapping(state, state.position - state.lineStart, flowIndent, props) && state.events[fallbackState.eventsLength]?.type === 3) { + state.depth--; + return true; + } + restoreState(state, fallbackState); + } + if (atNewLine && (ch === 33 && props.tagStart !== NO_RANGE$1 || ch === 38 && props.anchorStart !== NO_RANGE$1)) break; + if (!readTagProperty(state, props, nodeContext === CONTEXT_FLOW_IN) && !readAnchorProperty(state, props)) break; + if (propertyStart === null) propertyStart = propertyState; + if (skipSeparationSpace(state, true)) { + atNewLine = true; + allowBlockCollections = allowBlockStyles; + if (state.lineIndent > parentIndent) indentStatus = 1; + else if (state.lineIndent === parentIndent) indentStatus = 0; + else indentStatus = -1; + } else allowBlockCollections = false; + } + if (allowBlockCollections) allowBlockCollections = atNewLine || allowCompact; + if (indentStatus === 1 || nodeContext === CONTEXT_BLOCK_OUT) { + const flowIndent = nodeContext === CONTEXT_FLOW_IN || nodeContext === CONTEXT_FLOW_OUT ? parentIndent : parentIndent + 1; + const blockIndent = state.position - state.lineStart; + if (indentStatus === 1) if (allowBlockCollections && (readBlockSequence(state, blockIndent, props) || readBlockMapping(state, blockIndent, flowIndent, props)) || readFlowCollection(state, flowIndent, props)) hasContent = true; + else { + const ch = state.input.charCodeAt(state.position); + if (propertyStart !== null && allowPropertyMapping && allowBlockStyles && !allowBlockCollections && ch !== 124 && ch !== 62) { + const fallbackState = snapshotState(state); + const propertyIndent = propertyStart.position - propertyStart.lineStart; + restoreState(state, propertyStart); + if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type === 3) hasContent = true; + else restoreState(state, fallbackState); + } + if (!hasContent && (allowBlockScalars && readBlockScalar(state, flowIndent, props) || readSingleQuotedScalar(state, flowIndent, props) || readDoubleQuotedScalar(state, flowIndent, props) || readAlias(state, props) || readPlainScalar(state, flowIndent, nodeContext, props))) hasContent = true; + } + else if (indentStatus === 0) hasContent = allowBlockCollections && readBlockSequence(state, blockIndent, props); + } + allowBlockScalars = allowBlockScalars && !hasContent; + if (!hasContent && (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1 || allowBlockScalars)) { + addScalarEvent(state, NO_RANGE$1, NO_RANGE$1, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, 1); + hasContent = true; + } + state.depth--; + return hasContent || props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1; +} +function readDirective(state) { + if (state.lineIndent > 0 || state.input.charCodeAt(state.position) !== 37) return false; + state.position++; + const nameStart = state.position; + while (state.input.charCodeAt(state.position) !== 0 && !isWsOrEol(state.input.charCodeAt(state.position))) state.position++; + const name = state.input.slice(nameStart, state.position); + const args = []; + if (name.length === 0) throwError(state, "directive name must not be less than one character in length"); + while (state.input.charCodeAt(state.position) !== 0 && !isEol(state.input.charCodeAt(state.position))) { + while (isWhiteSpace(state.input.charCodeAt(state.position))) state.position++; + if (state.input.charCodeAt(state.position) === 35 || isEol(state.input.charCodeAt(state.position)) || state.input.charCodeAt(state.position) === 0) break; + const start = state.position; + while (state.input.charCodeAt(state.position) !== 0 && !isWsOrEol(state.input.charCodeAt(state.position))) state.position++; + args.push(state.input.slice(start, state.position)); + } + if (isEol(state.input.charCodeAt(state.position))) consumeLineBreak(state); + if (name === "YAML") { + if (state.directives.some((directive) => directive.kind === "yaml")) throwError(state, "duplication of %YAML directive"); + if (args.length !== 1) throwError(state, "YAML directive accepts exactly one argument"); + const match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); + if (match === null) throwError(state, "ill-formed argument of the YAML directive"); + if (parseInt(match[1], 10) !== 1) throwError(state, "unacceptable YAML version of the document"); + state.directives.push({ + kind: "yaml", + version: args[0] + }); + } else if (name === "TAG") { + if (args.length !== 2) throwError(state, "TAG directive accepts exactly two arguments"); + const [handle, prefix] = args; + if (!PATTERN_TAG_HANDLE.test(handle)) throwError(state, "ill-formed tag handle (first argument) of the TAG directive"); + if (HAS_OWN.call(state.tagHandlers, handle)) throwError(state, `there is a previously declared suffix for "${handle}" tag handle`); + if (!PATTERN_TAG_PREFIX.test(prefix)) throwError(state, "ill-formed tag prefix (second argument) of the TAG directive"); + state.tagHandlers[handle] = prefix; + state.directives.push({ + kind: "tag", + handle, + prefix + }); + } + return true; } - function readDocument(state) { - var documentStart = state.position, - _position, - directiveName, - directiveArgs, - hasDirectives = false, - ch; - - state.version = null; - state.checkLineBreaks = state.legacy; - state.tagMap = Object.create(null); - state.anchorMap = Object.create(null); - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - skipSeparationSpace(state, true, -1); - - ch = state.input.charCodeAt(state.position); - - if (state.lineIndent > 0 || ch !== 0x25/* % */) { - break; - } - - hasDirectives = true; - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - directiveName = state.input.slice(_position, state.position); - directiveArgs = []; - - if (directiveName.length < 1) { - throwError(state, 'directive name must not be less than one character in length'); - } - - while (ch !== 0) { - while (is_WHITE_SPACE(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (ch === 0x23/* # */) { - do { ch = state.input.charCodeAt(++state.position); } - while (ch !== 0 && !is_EOL(ch)); - break; - } - - if (is_EOL(ch)) break; - - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - directiveArgs.push(state.input.slice(_position, state.position)); - } - - if (ch !== 0) readLineBreak(state); - - if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) { - directiveHandlers[directiveName](state, directiveName, directiveArgs); - } else { - throwWarning(state, 'unknown document directive "' + directiveName + '"'); - } - } - - skipSeparationSpace(state, true, -1); - - if (state.lineIndent === 0 && - state.input.charCodeAt(state.position) === 0x2D/* - */ && - state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && - state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { - state.position += 3; - skipSeparationSpace(state, true, -1); - - } else if (hasDirectives) { - throwError(state, 'directives end mark is expected'); - } - - composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); - skipSeparationSpace(state, true, -1); - - if (state.checkLineBreaks && - PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { - throwWarning(state, 'non-ASCII line breaks are interpreted as content'); - } - - state.documents.push(state.result); - - if (state.position === state.lineStart && testDocumentSeparator(state)) { - - if (state.input.charCodeAt(state.position) === 0x2E/* . */) { - state.position += 3; - skipSeparationSpace(state, true, -1); - } - return; - } - - if (state.position < (state.length - 1)) { - throwError(state, 'end of the stream or a document separator is expected'); - } else { - return; - } + state.directives = []; + state.tagHandlers = Object.create(null); + let hasDirectives = false; + skipSeparationSpace(state, true); + while (readDirective(state)) { + hasDirectives = true; + skipSeparationSpace(state, true); + } + let explicitStart = false; + let explicitEnd = false; + let allowCompact = true; + if (state.lineIndent === 0 && state.input.charCodeAt(state.position) === 45 && state.input.charCodeAt(state.position + 1) === 45 && state.input.charCodeAt(state.position + 2) === 45 && isWsOrEolOrEnd(state.input.charCodeAt(state.position + 3))) { + explicitStart = true; + const markerLine = state.line; + state.position += 3; + skipSeparationSpace(state, true); + allowCompact = state.line > markerLine; + } else if (hasDirectives) throwError(state, "directives end mark is expected"); + const documentEventIndex = state.events.length; + if (!explicitStart && state.position === state.lineStart && state.input.charCodeAt(state.position) === 46 && testDocumentSeparator(state)) { + state.position += 3; + skipSeparationSpace(state, true); + return; + } + addDocumentEvent(state, explicitStart, false); + if (!parseNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, allowCompact, allowCompact)) addEmptyScalarEvent(state); + skipSeparationSpace(state, true); + if (state.position === state.lineStart && testDocumentSeparator(state)) { + explicitEnd = state.input.charCodeAt(state.position) === 46; + if (explicitEnd) { + const markerLine = state.line; + state.position += 3; + skipSeparationSpace(state, true); + if (state.line === markerLine && state.position < state.length) throwError(state, "end of the stream or a document separator is expected"); + } + } + const documentEvent = state.events[documentEventIndex]; + if (documentEvent?.type === 1) documentEvent.explicitEnd = explicitEnd; + addPopEvent(state); + if (!explicitEnd && state.position < state.length && !(state.position === state.lineStart && testDocumentSeparator(state))) throwError(state, "end of the stream or a document separator is expected"); } - - -function loadDocuments(input, options) { - input = String(input); - options = options || {}; - - if (input.length !== 0) { - - // Add tailing `\n` if not exists - if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && - input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { - input += '\n'; - } - - // Strip BOM - if (input.charCodeAt(0) === 0xFEFF) { - input = input.slice(1); - } - } - - var state = new State$1(input, options); - - var nullpos = input.indexOf('\0'); - - if (nullpos !== -1) { - state.position = nullpos; - throwError(state, 'null byte is not allowed in input'); - } - - // Use 0 as string terminator. That significantly simplifies bounds check. - state.input += '\0'; - - while (state.input.charCodeAt(state.position) === 0x20/* Space */) { - state.lineIndent += 1; - state.position += 1; - } - - while (state.position < (state.length - 1)) { - readDocument(state); - } - - return state.documents; +function parseEvents(input, options) { + const length = input.length; + const state = { + ...DEFAULT_PARSER_OPTIONS, + ...options, + input: `${input}\0`, + length, + position: 0, + line: 0, + lineStart: 0, + lineIndent: 0, + firstTabInLine: -1, + depth: 0, + directives: [], + tagHandlers: Object.create(null), + events: [] + }; + const nullpos = input.indexOf("\0"); + if (nullpos !== -1) throwErrorAt(input, nullpos, "null byte is not allowed in input", state.filename); + if (state.input.charCodeAt(state.position) === 65279) state.position++; + while (state.position < state.length) { + skipSeparationSpace(state, true); + if (state.position >= state.length) break; + const documentStart = state.position; + readDocument(state); + if (state.position === documentStart) + /* c8 ignore next */ + throwError(state, "can not read a document"); + } + return state.events; } - - -function loadAll$1(input, iterator, options) { - if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { - options = iterator; - iterator = null; - } - - var documents = loadDocuments(input, options); - - if (typeof iterator !== 'function') { - return documents; - } - - for (var index = 0, length = documents.length; index < length; index += 1) { - iterator(documents[index]); - } -} - - -function load$1(input, options) { - var documents = loadDocuments(input, options); - - if (documents.length === 0) { - /*eslint-disable no-undefined*/ - return undefined; - } else if (documents.length === 1) { - return documents[0]; - } - throw new exception('expected a single document in the stream, but found more'); -} - - -var loadAll_1 = loadAll$1; -var load_1 = load$1; - -var loader = { - loadAll: loadAll_1, - load: load_1 +//#endregion +//#region src/load.ts +var DEFAULT_LOAD_OPTIONS = { + ...DEFAULT_PARSER_OPTIONS, + ...DEFAULT_CONSTRUCTOR_OPTIONS }; - -/*eslint-disable no-use-before-define*/ - - - - - -var _toString = Object.prototype.toString; -var _hasOwnProperty = Object.prototype.hasOwnProperty; - -var CHAR_BOM = 0xFEFF; -var CHAR_TAB = 0x09; /* Tab */ -var CHAR_LINE_FEED = 0x0A; /* LF */ -var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ -var CHAR_SPACE = 0x20; /* Space */ -var CHAR_EXCLAMATION = 0x21; /* ! */ -var CHAR_DOUBLE_QUOTE = 0x22; /* " */ -var CHAR_SHARP = 0x23; /* # */ -var CHAR_PERCENT = 0x25; /* % */ -var CHAR_AMPERSAND = 0x26; /* & */ -var CHAR_SINGLE_QUOTE = 0x27; /* ' */ -var CHAR_ASTERISK = 0x2A; /* * */ -var CHAR_COMMA = 0x2C; /* , */ -var CHAR_MINUS = 0x2D; /* - */ -var CHAR_COLON = 0x3A; /* : */ -var CHAR_EQUALS = 0x3D; /* = */ -var CHAR_GREATER_THAN = 0x3E; /* > */ -var CHAR_QUESTION = 0x3F; /* ? */ -var CHAR_COMMERCIAL_AT = 0x40; /* @ */ -var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ -var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ -var CHAR_GRAVE_ACCENT = 0x60; /* ` */ -var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ -var CHAR_VERTICAL_LINE = 0x7C; /* | */ -var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ - +function loadDocuments(input, options = {}) { + const opts = { + ...DEFAULT_LOAD_OPTIONS, + ...options + }; + const source = String(input); + const PARSER_OPT_KEYS = Object.keys(DEFAULT_PARSER_OPTIONS); + const CONSTRUCTOR_OPT_KEYS = Object.keys(DEFAULT_CONSTRUCTOR_OPTIONS); + return constructFromEvents(parseEvents(source, pick(opts, PARSER_OPT_KEYS)), { + ...pick(opts, CONSTRUCTOR_OPT_KEYS), + source + }); +} +function loadAll(input, iteratorOrOptions, options) { + let iterator = null; + if (typeof iteratorOrOptions === "function") iterator = iteratorOrOptions; + else if (iteratorOrOptions !== null && typeof iteratorOrOptions === "object") options = iteratorOrOptions; + const documents = loadDocuments(input, options); + if (iterator === null) return documents; + for (const document of documents) iterator(document); +} +function load(input, options) { + const documents = loadDocuments(input, options); + if (documents.length === 0) throw new YAMLException("expected a document, but the input is empty"); + if (documents.length === 1) return documents[0]; + throw new YAMLException("expected a single document in the stream, but found more"); +} +//#endregion +//#region src/ast/nodes.ts +var Style = class { + tagged = false; + flow = false; + singleQuoted = false; + doubleQuoted = false; + literal = false; + folded = false; +}; +//#endregion +//#region src/ast/from_js.ts +var INVALID = Symbol("INVALID"); +function buildRepresentTypes(schema) { + const defaultTags = new Set([ + schema.defaultScalarTag, + schema.defaultSequenceTag, + schema.defaultMappingTag + ].filter((t) => t !== void 0)); + const implicitScalars = schema.implicitScalarTags; + const explicitTags = schema.tags.filter((t) => !(t.nodeKind === "scalar" && t.implicit) && !defaultTags.has(t)); + const defaultTagsLast = schema.tags.filter((t) => defaultTags.has(t)); + return [ + ...implicitScalars.map((tag) => ({ + tag, + implicitTag: true + })), + ...explicitTags.map((tag) => ({ + tag, + implicitTag: false + })), + ...defaultTagsLast.map((tag) => ({ + tag, + implicitTag: true + })) + ]; +} +function matchTag(state, object) { + for (let index = 0, length = state.representTypes.length; index < length; index += 1) { + const { tag, implicitTag } = state.representTypes[index]; + if (tag.identify && tag.identify(object)) { + let tagName; + if (tag.matchByTagPrefix && tag.representTagName) tagName = tag.representTagName(object); + else tagName = tag.tagName; + return { + tag, + tagName, + implicitTag + }; + } + } + return null; +} +function build(state, object) { + if (!state.noRefs && object !== null && typeof object === "object") { + const existing = state.refs.get(object); + if (existing) { + if (existing.anchor === void 0) existing.anchor = `ref_${state.refCounter++}`; + return { + kind: "alias", + tag: "", + style: new Style(), + anchor: existing.anchor + }; + } + } + const matched = matchTag(state, object); + if (!matched) { + if (object === void 0) return INVALID; + if (state.skipInvalid) return INVALID; + throw new YAMLException(`unacceptable kind of an object to dump ${Object.prototype.toString.call(object)}`); + } + const { tag, tagName, implicitTag } = matched; + const nodeTagName = implicitTag ? tagName : tagNameShort(tagName); + if (tag.nodeKind === "scalar") { + const style = new Style(); + style.tagged = !implicitTag; + return { + kind: "scalar", + tag: nodeTagName, + style, + value: tag.represent(object) + }; + } + if (tag.nodeKind === "sequence") { + const container = tag.represent(object); + const style = new Style(); + style.tagged = !implicitTag; + const node = { + kind: "sequence", + tag: nodeTagName, + style, + items: [] + }; + if (!state.noRefs) state.refs.set(object, node); + for (let index = 0, length = container.length; index < length; index += 1) { + let item = build(state, container[index]); + if (item === INVALID && container[index] === void 0) item = build(state, null); + if (item === INVALID) continue; + node.items.push(item); + } + return node; + } + const map = tag.represent(object); + const style = new Style(); + style.tagged = !implicitTag; + const node = { + kind: "mapping", + tag: nodeTagName, + style, + items: [] + }; + if (!state.noRefs) state.refs.set(object, node); + for (const [objectKey, objectValue] of map) { + const key = build(state, objectKey); + if (key === INVALID) continue; + const value = build(state, objectValue); + if (value === INVALID) continue; + node.items.push({ + key, + value + }); + } + return node; +} +function jsToAst(input, schema, options = {}) { + const root = build({ + representTypes: buildRepresentTypes(schema), + noRefs: options.noRefs ?? false, + skipInvalid: options.skipInvalid ?? false, + refs: /* @__PURE__ */ new Map(), + refCounter: 0 + }, input); + return [{ + contents: root === INVALID ? null : root, + directives: [] + }]; +} +//#endregion +//#region src/ast/visit.ts +var VISIT_BREAK = Symbol("visit:break"); +var VISIT_SKIP = Symbol("visit:skip"); +function visitNode(node, visitor, ctx) { + const control = visitor(node, ctx); + if (control === VISIT_BREAK) return true; + if (control === VISIT_SKIP) return false; + const depth = ctx.depth + 1; + switch (node.kind) { + case "sequence": + for (const item of node.items) if (visitNode(item, visitor, { + depth, + parent: node, + isKey: false + })) return true; + break; + case "mapping": + for (const { key, value } of node.items) { + if (visitNode(key, visitor, { + depth, + parent: node, + isKey: true + })) return true; + if (visitNode(value, visitor, { + depth, + parent: node, + isKey: false + })) return true; + } + break; + } + return false; +} +function visit(documents, visitor) { + for (const doc of documents) if (doc.contents && visitNode(doc.contents, visitor, { + depth: 0, + parent: null, + isKey: false + })) return; +} +//#endregion +//#region src/ast/presenter.ts +var CHAR_BOM = 65279; +var CHAR_TAB = 9; +var CHAR_LINE_FEED = 10; +var CHAR_CARRIAGE_RETURN = 13; +var CHAR_SPACE = 32; +var CHAR_EXCLAMATION = 33; +var CHAR_DOUBLE_QUOTE = 34; +var CHAR_SHARP = 35; +var CHAR_PERCENT = 37; +var CHAR_AMPERSAND = 38; +var CHAR_SINGLE_QUOTE = 39; +var CHAR_ASTERISK = 42; +var CHAR_COMMA = 44; +var CHAR_MINUS = 45; +var CHAR_COLON = 58; +var CHAR_EQUALS = 61; +var CHAR_GREATER_THAN = 62; +var CHAR_QUESTION = 63; +var CHAR_COMMERCIAL_AT = 64; +var CHAR_LEFT_SQUARE_BRACKET = 91; +var CHAR_RIGHT_SQUARE_BRACKET = 93; +var CHAR_GRAVE_ACCENT = 96; +var CHAR_LEFT_CURLY_BRACKET = 123; +var CHAR_VERTICAL_LINE = 124; +var CHAR_RIGHT_CURLY_BRACKET = 125; var ESCAPE_SEQUENCES = {}; - -ESCAPE_SEQUENCES[0x00] = '\\0'; -ESCAPE_SEQUENCES[0x07] = '\\a'; -ESCAPE_SEQUENCES[0x08] = '\\b'; -ESCAPE_SEQUENCES[0x09] = '\\t'; -ESCAPE_SEQUENCES[0x0A] = '\\n'; -ESCAPE_SEQUENCES[0x0B] = '\\v'; -ESCAPE_SEQUENCES[0x0C] = '\\f'; -ESCAPE_SEQUENCES[0x0D] = '\\r'; -ESCAPE_SEQUENCES[0x1B] = '\\e'; -ESCAPE_SEQUENCES[0x22] = '\\"'; -ESCAPE_SEQUENCES[0x5C] = '\\\\'; -ESCAPE_SEQUENCES[0x85] = '\\N'; -ESCAPE_SEQUENCES[0xA0] = '\\_'; -ESCAPE_SEQUENCES[0x2028] = '\\L'; -ESCAPE_SEQUENCES[0x2029] = '\\P'; - -var DEPRECATED_BOOLEANS_SYNTAX = [ - 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', - 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' -]; - -var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; - -function compileStyleMap(schema, map) { - var result, keys, index, length, tag, style, type; - - if (map === null) return {}; - - result = {}; - keys = Object.keys(map); - - for (index = 0, length = keys.length; index < length; index += 1) { - tag = keys[index]; - style = String(map[tag]); - - if (tag.slice(0, 2) === '!!') { - tag = 'tag:yaml.org,2002:' + tag.slice(2); - } - type = schema.compiledTypeMap['fallback'][tag]; - - if (type && _hasOwnProperty.call(type.styleAliases, style)) { - style = type.styleAliases[style]; - } - - result[tag] = style; - } - - return result; +ESCAPE_SEQUENCES[0] = "\\0"; +ESCAPE_SEQUENCES[7] = "\\a"; +ESCAPE_SEQUENCES[8] = "\\b"; +ESCAPE_SEQUENCES[9] = "\\t"; +ESCAPE_SEQUENCES[10] = "\\n"; +ESCAPE_SEQUENCES[11] = "\\v"; +ESCAPE_SEQUENCES[12] = "\\f"; +ESCAPE_SEQUENCES[13] = "\\r"; +ESCAPE_SEQUENCES[27] = "\\e"; +ESCAPE_SEQUENCES[34] = "\\\""; +ESCAPE_SEQUENCES[92] = "\\\\"; +ESCAPE_SEQUENCES[133] = "\\N"; +ESCAPE_SEQUENCES[160] = "\\_"; +ESCAPE_SEQUENCES[8232] = "\\L"; +ESCAPE_SEQUENCES[8233] = "\\P"; +var DEFAULT_PRESENTER_OPTIONS = { + indent: 2, + seqNoIndent: false, + seqInlineFirst: true, + sortKeys: false, + lineWidth: 80, + flowBracketPadding: false, + flowSkipCommaSpace: false, + flowSkipColonSpace: false, + quoteFlowKeys: false, + quoteStyle: "single", + forceQuotes: false, + tagBeforeAnchor: false +}; +function nodeTagShort(node) { + return node.style.tagged ? node.tag : tagNameShort(node.tag); } - -function encodeHex(character) { - var string, handle, length; - - string = character.toString(16).toUpperCase(); - - if (character <= 0xFF) { - handle = 'x'; - length = 2; - } else if (character <= 0xFFFF) { - handle = 'u'; - length = 4; - } else if (character <= 0xFFFFFFFF) { - handle = 'U'; - length = 8; - } else { - throw new exception('code point within a string may not be greater than 0xFFFFFFFF'); - } - - return '\\' + handle + common.repeat('0', length - string.length) + string; +function createPresenterState(options) { + const opts = { + ...DEFAULT_PRESENTER_OPTIONS, + ...options + }; + return { + ...opts, + defaultScalarTagName: opts.schema.defaultScalarTag.tagName, + implicitResolvers: opts.schema.implicitScalarTags + }; } - - -var QUOTING_TYPE_SINGLE = 1, - QUOTING_TYPE_DOUBLE = 2; - -function State(options) { - this.schema = options['schema'] || _default; - this.indent = Math.max(1, (options['indent'] || 2)); - this.noArrayIndent = options['noArrayIndent'] || false; - this.skipInvalid = options['skipInvalid'] || false; - this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); - this.styleMap = compileStyleMap(this.schema, options['styles'] || null); - this.sortKeys = options['sortKeys'] || false; - this.lineWidth = options['lineWidth'] || 80; - this.noRefs = options['noRefs'] || false; - this.noCompatMode = options['noCompatMode'] || false; - this.condenseFlow = options['condenseFlow'] || false; - this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; - this.forceQuotes = options['forceQuotes'] || false; - this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; - - this.implicitTypes = this.schema.compiledImplicit; - this.explicitTypes = this.schema.compiledExplicit; - - this.tag = null; - this.result = ''; - - this.duplicates = []; - this.usedDuplicates = null; +function encodeNonPrintable(character) { + const string = character.toString(16).toUpperCase(); + const handle = character <= 255 ? "x" : "u"; + const length = character <= 255 ? 2 : 4; + return `\\${handle}${"0".repeat(length - string.length)}${string}`; } - -// Indents every line in a string. Empty lines (\n only) are not indented. function indentString(string, spaces) { - var ind = common.repeat(' ', spaces), - position = 0, - next = -1, - result = '', - line, - length = string.length; - - while (position < length) { - next = string.indexOf('\n', position); - if (next === -1) { - line = string.slice(position); - position = length; - } else { - line = string.slice(position, next + 1); - position = next + 1; - } - - if (line.length && line !== '\n') result += ind; - - result += line; - } - - return result; + const ind = " ".repeat(spaces); + let position = 0; + let result = ""; + const length = string.length; + while (position < length) { + let line; + const next = string.indexOf("\n", position); + if (next === -1) { + line = string.slice(position); + position = length; + } else { + line = string.slice(position, next + 1); + position = next + 1; + } + if (line.length && line !== "\n") result += ind; + result += line; + } + return result; } - function generateNextLine(state, level) { - return '\n' + common.repeat(' ', state.indent * level); + return `\n${" ".repeat(state.indent * level)}`; } - -function testImplicitResolving(state, str) { - var index, length, type; - - for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { - type = state.implicitTypes[index]; - - if (type.resolve(str)) { - return true; - } - } - - return false; +function scalarLayout(state, level) { + const indent = state.indent * Math.max(1, level); + return { + indent, + blockIndent: level === 0 ? state.indent + 1 : state.indent, + lineWidth: state.lineWidth === -1 ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent) + }; +} +function resolveImplicitTag(state, str) { + for (let index = 0, length = state.implicitResolvers.length; index < length; index += 1) { + const tagDefinition = state.implicitResolvers[index]; + if (tagDefinition.resolve(str, false, tagDefinition.tagName) !== NOT_RESOLVED) return tagDefinition.tagName; + } + return state.defaultScalarTagName; } - -// [33] s-white ::= s-space | s-tab function isWhitespace(c) { - return c === CHAR_SPACE || c === CHAR_TAB; + return c === CHAR_SPACE || c === CHAR_TAB; +} +function startsWithDocumentSeparator(string) { + const marker = string.charCodeAt(0); + if (marker !== CHAR_MINUS && marker !== 46 || string.charCodeAt(1) !== marker || string.charCodeAt(2) !== marker) return false; + if (string.length === 3) return true; + const following = string.charCodeAt(3); + return isWhitespace(following) || following === CHAR_CARRIAGE_RETURN || following === CHAR_LINE_FEED; } - -// Returns true if the character can be printed without escaping. -// From YAML 1.2: "any allowed characters known to be non-printable -// should also be escaped. [However,] This isn’t mandatory" -// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. function isPrintable(c) { - return (0x00020 <= c && c <= 0x00007E) - || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) - || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) - || (0x10000 <= c && c <= 0x10FFFF); + return c >= 32 && c <= 126 || c >= 161 && c <= 55295 && c !== 8232 && c !== 8233 || c >= 57344 && c <= 65533 && c !== CHAR_BOM || c >= 65536 && c <= 1114111; } - -// [34] ns-char ::= nb-char - s-white -// [27] nb-char ::= c-printable - b-char - c-byte-order-mark -// [26] b-char ::= b-line-feed | b-carriage-return -// Including s-white (for some reason, examples doesn't match specs in this aspect) -// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark function isNsCharOrWhitespace(c) { - return isPrintable(c) - && c !== CHAR_BOM - // - b-char - && c !== CHAR_CARRIAGE_RETURN - && c !== CHAR_LINE_FEED; + return isPrintable(c) && c !== CHAR_BOM && c !== CHAR_CARRIAGE_RETURN && c !== CHAR_LINE_FEED; } - -// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out -// c = flow-in ⇒ ns-plain-safe-in -// c = block-key ⇒ ns-plain-safe-out -// c = flow-key ⇒ ns-plain-safe-in -// [128] ns-plain-safe-out ::= ns-char -// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator -// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) -// | ( /* An ns-char preceding */ “#” ) -// | ( “:” /* Followed by an ns-plain-safe(c) */ ) function isPlainSafe(c, prev, inblock) { - var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); - var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); - return ( - // ns-plain-safe - inblock ? // c = flow-in - cIsNsCharOrWhitespace - : cIsNsCharOrWhitespace - // - c-flow-indicator - && c !== CHAR_COMMA - && c !== CHAR_LEFT_SQUARE_BRACKET - && c !== CHAR_RIGHT_SQUARE_BRACKET - && c !== CHAR_LEFT_CURLY_BRACKET - && c !== CHAR_RIGHT_CURLY_BRACKET - ) - // ns-plain-char - && c !== CHAR_SHARP // false on '#' - && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' - || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' - || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' + const cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); + const cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); + return (inblock ? cIsNsCharOrWhitespace : cIsNsCharOrWhitespace && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET) && c !== CHAR_SHARP && !(prev === CHAR_COLON && !cIsNsChar) || isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP || prev === CHAR_COLON && cIsNsChar; } - -// Simplified test for values allowed as the first character in plain style. function isPlainSafeFirst(c) { - // Uses a subset of ns-char - c-indicator - // where ns-char = nb-char - s-white. - // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part - return isPrintable(c) && c !== CHAR_BOM - && !isWhitespace(c) // - s-white - // - (c-indicator ::= - // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” - && c !== CHAR_MINUS - && c !== CHAR_QUESTION - && c !== CHAR_COLON - && c !== CHAR_COMMA - && c !== CHAR_LEFT_SQUARE_BRACKET - && c !== CHAR_RIGHT_SQUARE_BRACKET - && c !== CHAR_LEFT_CURLY_BRACKET - && c !== CHAR_RIGHT_CURLY_BRACKET - // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” - && c !== CHAR_SHARP - && c !== CHAR_AMPERSAND - && c !== CHAR_ASTERISK - && c !== CHAR_EXCLAMATION - && c !== CHAR_VERTICAL_LINE - && c !== CHAR_EQUALS - && c !== CHAR_GREATER_THAN - && c !== CHAR_SINGLE_QUOTE - && c !== CHAR_DOUBLE_QUOTE - // | “%” | “@” | “`”) - && c !== CHAR_PERCENT - && c !== CHAR_COMMERCIAL_AT - && c !== CHAR_GRAVE_ACCENT; + return isPrintable(c) && c !== CHAR_BOM && !isWhitespace(c) && c !== CHAR_MINUS && c !== CHAR_QUESTION && c !== CHAR_COLON && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET && c !== CHAR_SHARP && c !== CHAR_AMPERSAND && c !== CHAR_ASTERISK && c !== CHAR_EXCLAMATION && c !== CHAR_VERTICAL_LINE && c !== CHAR_EQUALS && c !== CHAR_GREATER_THAN && c !== CHAR_SINGLE_QUOTE && c !== CHAR_DOUBLE_QUOTE && c !== CHAR_PERCENT && c !== CHAR_COMMERCIAL_AT && c !== CHAR_GRAVE_ACCENT; +} +function isPlainSafeAtStart(string, inblock) { + const first = codePointAt(string, 0); + if (isPlainSafeFirst(first)) return true; + if (string.length > 1 && (first === CHAR_MINUS || first === CHAR_QUESTION || first === CHAR_COLON)) { + const second = codePointAt(string, 1); + return !isWhitespace(second) && isPlainSafe(second, first, inblock); + } + return false; } - -// Simplified test for values allowed as the last character in plain style. function isPlainSafeLast(c) { - // just not whitespace or colon, it will be checked to be plain character later - return !isWhitespace(c) && c !== CHAR_COLON; + return !isWhitespace(c) && c !== CHAR_COLON; } - -// Same as 'string'.codePointAt(pos), but works in older browsers. function codePointAt(string, pos) { - var first = string.charCodeAt(pos), second; - if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { - second = string.charCodeAt(pos + 1); - if (second >= 0xDC00 && second <= 0xDFFF) { - // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae - return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; - } - } - return first; + const first = string.charCodeAt(pos); + let second; + if (first >= 55296 && first <= 56319 && pos + 1 < string.length) { + second = string.charCodeAt(pos + 1); + if (second >= 56320 && second <= 57343) return (first - 55296) * 1024 + second - 56320 + 65536; + } + return first; } - -// Determines whether block indentation indicator is required. function needIndentIndicator(string) { - var leadingSpaceRe = /^\n* /; - return leadingSpaceRe.test(string); + return /^\n* /.test(string); } - -var STYLE_PLAIN = 1, - STYLE_SINGLE = 2, - STYLE_LITERAL = 3, - STYLE_FOLDED = 4, - STYLE_DOUBLE = 5; - -// Determines which scalar styles are possible and returns the preferred style. -// lineWidth = -1 => no limit. -// Pre-conditions: str.length > 0. -// Post-conditions: -// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. -// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). -// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). -function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, - testAmbiguousType, quotingType, forceQuotes, inblock) { - - var i; - var char = 0; - var prevChar = null; - var hasLineBreak = false; - var hasFoldableLine = false; // only checked if shouldTrackWidth - var shouldTrackWidth = lineWidth !== -1; - var previousLineBreak = -1; // count the first line correctly - var plain = isPlainSafeFirst(codePointAt(string, 0)) - && isPlainSafeLast(codePointAt(string, string.length - 1)); - - if (singleLineOnly || forceQuotes) { - // Case: no block styles. - // Check for disallowed characters to rule out plain and single. - for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - if (!isPrintable(char)) { - return STYLE_DOUBLE; - } - plain = plain && isPlainSafe(char, prevChar, inblock); - prevChar = char; - } - } else { - // Case: block styles permitted. - for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - if (char === CHAR_LINE_FEED) { - hasLineBreak = true; - // Check if any line can be folded. - if (shouldTrackWidth) { - hasFoldableLine = hasFoldableLine || - // Foldable line = too long, and not more-indented. - (i - previousLineBreak - 1 > lineWidth && - string[previousLineBreak + 1] !== ' '); - previousLineBreak = i; - } - } else if (!isPrintable(char)) { - return STYLE_DOUBLE; - } - plain = plain && isPlainSafe(char, prevChar, inblock); - prevChar = char; - } - // in case the end is missing a \n - hasFoldableLine = hasFoldableLine || (shouldTrackWidth && - (i - previousLineBreak - 1 > lineWidth && - string[previousLineBreak + 1] !== ' ')); - } - // Although every style can represent \n without escaping, prefer block styles - // for multiline, since they're more readable and they don't add empty lines. - // Also prefer folding a super-long line. - if (!hasLineBreak && !hasFoldableLine) { - // Strings interpretable as another type have to be quoted; - // e.g. the string 'true' vs. the boolean true. - if (plain && !forceQuotes && !testAmbiguousType(string)) { - return STYLE_PLAIN; - } - return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; - } - // Edge case: block indentation indicator can only have one digit. - if (indentPerLevel > 9 && needIndentIndicator(string)) { - return STYLE_DOUBLE; - } - // At this point we know block styles are valid. - // Prefer literal style unless we want to fold. - if (!forceQuotes) { - return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; - } - return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; +var STYLE_PLAIN = 1; +var STYLE_SINGLE = 2; +var STYLE_LITERAL = 3; +var STYLE_FOLDED = 4; +var STYLE_DOUBLE = 5; +function chooseScalarStyle(state, string, layout, singleLineOnly, forceQuote, inblock) { + const { blockIndent, lineWidth } = layout; + let i; + let char = 0; + let prevChar = -1; + let hasLineBreak = false; + let hasFoldableLine = false; + const shouldTrackWidth = lineWidth !== -1; + let previousLineBreak = -1; + let plain = !startsWithDocumentSeparator(string) && isPlainSafeAtStart(string, inblock) && isPlainSafeLast(codePointAt(string, string.length - 1)); + if (singleLineOnly || forceQuote) for (i = 0; i < string.length; char >= 65536 ? i += 2 : i++) { + char = codePointAt(string, i); + if (!isPrintable(char)) return STYLE_DOUBLE; + plain = plain && isPlainSafe(char, prevChar, inblock); + prevChar = char; + } + else { + for (i = 0; i < string.length; char >= 65536 ? i += 2 : i++) { + char = codePointAt(string, i); + if (char === CHAR_LINE_FEED) { + hasLineBreak = true; + if (shouldTrackWidth) { + hasFoldableLine = hasFoldableLine || i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== " "; + previousLineBreak = i; + } + } else if (!isPrintable(char)) return STYLE_DOUBLE; + plain = plain && isPlainSafe(char, prevChar, inblock); + prevChar = char; + } + hasFoldableLine = hasFoldableLine || shouldTrackWidth && i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== " "; + } + if (!hasLineBreak && !hasFoldableLine) { + if (plain && !forceQuote) return STYLE_PLAIN; + return state.quoteStyle === "double" ? STYLE_DOUBLE : STYLE_SINGLE; + } + if (blockIndent > 9 && needIndentIndicator(string)) return STYLE_DOUBLE; + return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; } - -// Note: line breaking/folding is implemented for only the folded style. -// NB. We drop the last trailing newline (if any) of a returned block scalar -// since the dumper adds its own newline. This always works: -// • No ending newline => unaffected; already using strip "-" chomping. -// • Ending newline => removed then restored. -// Importantly, this keeps the "+" chomp indicator from gaining an extra line. -function writeScalar(state, string, level, iskey, inblock) { - state.dump = (function () { - if (string.length === 0) { - return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; - } - if (!state.noCompatMode) { - if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { - return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); - } - } - - var indent = state.indent * Math.max(1, level); // no 0-indent scalars - // As indentation gets deeper, let the width decrease monotonically - // to the lower bound min(state.lineWidth, 40). - // Note that this implies - // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. - // state.lineWidth > 40 + state.indent: width decreases until the lower bound. - // This behaves better than a constant minimum width which disallows narrower options, - // or an indent threshold which causes the width to suddenly increase. - var lineWidth = state.lineWidth === -1 - ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); - - // Without knowing if keys are implicit/explicit, assume implicit for safety. - var singleLineOnly = iskey - // No block styles in flow mode. - || (state.flowLevel > -1 && level >= state.flowLevel); - function testAmbiguity(string) { - return testImplicitResolving(state, string); - } - - switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, - testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { - - case STYLE_PLAIN: - return string; - case STYLE_SINGLE: - return "'" + string.replace(/'/g, "''") + "'"; - case STYLE_LITERAL: - return '|' + blockHeader(string, state.indent) - + dropEndingNewline(indentString(string, indent)); - case STYLE_FOLDED: - return '>' + blockHeader(string, state.indent) - + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); - case STYLE_DOUBLE: - return '"' + escapeString(string) + '"'; - default: - throw new exception('impossible error: invalid scalar style'); - } - }()); +function renderScalarStyle(string, style, layout) { + const { indent, blockIndent, lineWidth } = layout; + switch (style) { + case STYLE_PLAIN: return encodeFlowBreaks(string, indent); + case STYLE_SINGLE: return `'${encodeFlowBreaks(string, indent).replace(/'/g, "''")}'`; + case STYLE_LITERAL: return "|" + blockHeader(string, blockIndent) + dropEndingNewline(indentString(string, indent)); + case STYLE_FOLDED: return ">" + blockHeader(string, blockIndent) + dropEndingNewline(indentString(foldBlockScalar(string, lineWidth), indent)); + case STYLE_DOUBLE: return `"${escapeString(string)}"`; + } +} +function resolveScalarStyle(state, node, layout, iskey, inblock) { + const singleLineOnly = iskey || !inblock; + if (node.style.singleQuoted) return STYLE_SINGLE; + if (node.style.doubleQuoted) return STYLE_DOUBLE; + if (!singleLineOnly) { + if (node.style.literal) return STYLE_LITERAL; + if (node.style.folded) return STYLE_FOLDED; + } + const string = node.value; + if (string.length === 0) { + if (node.style.tagged || resolveImplicitTag(state, string) === node.tag) return STYLE_PLAIN; + return state.quoteStyle === "double" ? STYLE_DOUBLE : STYLE_SINGLE; + } + const style = chooseScalarStyle(state, string, layout, singleLineOnly, state.forceQuotes && !iskey, inblock); + if (style === STYLE_PLAIN && !node.style.tagged && resolveImplicitTag(state, string) !== node.tag) return state.quoteStyle === "double" ? STYLE_DOUBLE : STYLE_SINGLE; + return style; } - -// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. function blockHeader(string, indentPerLevel) { - var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; - - // note the special case: the string '\n' counts as a "trailing" empty line. - var clip = string[string.length - 1] === '\n'; - var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); - var chomp = keep ? '+' : (clip ? '' : '-'); - - return indentIndicator + chomp + '\n'; + const indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ""; + const clip = string[string.length - 1] === "\n"; + return `${indentIndicator}${clip && (string[string.length - 2] === "\n" || string === "\n") ? "+" : clip ? "" : "-"}\n`; +} +function encodeFlowBreaks(string, indent) { + let nextLF = string.indexOf("\n"); + if (nextLF === -1) return string; + const pad = " ".repeat(indent); + let result = string.slice(0, nextLF); + const lineRe = /(\n+)([^\n]*)/g; + lineRe.lastIndex = nextLF; + let match; + while (match = lineRe.exec(string)) { + const breaks = match[1].length; + const line = match[2]; + result += "\n".repeat(breaks + 1) + pad + line; + } + return result; } - -// (See the note for writeScalar.) function dropEndingNewline(string) { - return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; + return string[string.length - 1] === "\n" ? string.slice(0, -1) : string; } - -// Note: a long line without a suitable break point will exceed the width limit. -// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. -function foldString(string, width) { - // In folded style, $k$ consecutive newlines output as $k+1$ newlines— - // unless they're before or after a more-indented line, or at the very - // beginning or end, in which case $k$ maps to $k$. - // Therefore, parse each chunk as newline(s) followed by a content line. - var lineRe = /(\n+)([^\n]*)/g; - - // first line (possibly an empty line) - var result = (function () { - var nextLF = string.indexOf('\n'); - nextLF = nextLF !== -1 ? nextLF : string.length; - lineRe.lastIndex = nextLF; - return foldLine(string.slice(0, nextLF), width); - }()); - // If we haven't reached the first content line yet, don't add an extra \n. - var prevMoreIndented = string[0] === '\n' || string[0] === ' '; - var moreIndented; - - // rest of the lines - var match; - while ((match = lineRe.exec(string))) { - var prefix = match[1], line = match[2]; - moreIndented = (line[0] === ' '); - result += prefix - + (!prevMoreIndented && !moreIndented && line !== '' - ? '\n' : '') - + foldLine(line, width); - prevMoreIndented = moreIndented; - } - - return result; +function foldBlockScalar(string, width) { + const lineRe = /(\n+)([^\n]*)/g; + let nextLF = string.indexOf("\n"); + if (nextLF === -1) nextLF = string.length; + lineRe.lastIndex = nextLF; + let result = foldLine(string.slice(0, nextLF), width); + let prevMoreIndented = string[0] === "\n" || string[0] === " "; + let moreIndented; + let match; + while (match = lineRe.exec(string)) { + const prefix = match[1]; + const line = match[2]; + moreIndented = line[0] === " "; + result += prefix + (!prevMoreIndented && !moreIndented && line !== "" ? "\n" : "") + foldLine(line, width); + prevMoreIndented = moreIndented; + } + return result; } - -// Greedy line breaking. -// Picks the longest line under the limit each time, -// otherwise settles for the shortest line over the limit. -// NB. More-indented lines *cannot* be folded, as that would add an extra \n. function foldLine(line, width) { - if (line === '' || line[0] === ' ') return line; - - // Since a more-indented line adds a \n, breaks can't be followed by a space. - var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. - var match; - // start is an inclusive index. end, curr, and next are exclusive. - var start = 0, end, curr = 0, next = 0; - var result = ''; - - // Invariants: 0 <= start <= length-1. - // 0 <= curr <= next <= max(0, length-2). curr - start <= width. - // Inside the loop: - // A match implies length >= 2, so curr and next are <= length-2. - while ((match = breakRe.exec(line))) { - next = match.index; - // maintain invariant: curr - start <= width - if (next - start > width) { - end = (curr > start) ? curr : next; // derive end <= length-2 - result += '\n' + line.slice(start, end); - // skip the space that was output as \n - start = end + 1; // derive start <= length-1 - } - curr = next; - } - - // By the invariants, start <= length-1, so there is something left over. - // It is either the whole string or a part starting from non-whitespace. - result += '\n'; - // Insert a break if the remainder is too long and there is a break available. - if (line.length - start > width && curr > start) { - result += line.slice(start, curr) + '\n' + line.slice(curr + 1); - } else { - result += line.slice(start); - } - - return result.slice(1); // drop extra \n joiner + if (line === "" || line[0] === " ") return line; + const breakRe = / [^ ]/g; + let match; + let start = 0; + let end; + let curr = 0; + let next = 0; + let result = ""; + while (match = breakRe.exec(line)) { + next = match.index; + if (next - start > width) { + end = curr > start ? curr : next; + result += `\n${line.slice(start, end)}`; + start = end + 1; + } + curr = next; + } + result += "\n"; + if (line.length - start > width && curr > start) result += `${line.slice(start, curr)}\n${line.slice(curr + 1)}`; + else result += line.slice(start); + return result.slice(1); } - -// Escapes a double-quoted string. function escapeString(string) { - var result = ''; - var char = 0; - var escapeSeq; - - for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - escapeSeq = ESCAPE_SEQUENCES[char]; - - if (!escapeSeq && isPrintable(char)) { - result += string[i]; - if (char >= 0x10000) result += string[i + 1]; - } else { - result += escapeSeq || encodeHex(char); - } - } - - return result; + let result = ""; + let char = 0; + for (let i = 0; i < string.length; char >= 65536 ? i += 2 : i++) { + char = codePointAt(string, i); + const escapeSeq = ESCAPE_SEQUENCES[char]; + if (escapeSeq) { + result += escapeSeq; + continue; + } + if (isPrintable(char)) { + result += string[i]; + if (char >= 65536) result += string[i + 1]; + continue; + } + result += encodeNonPrintable(char); + } + return result; } - -function writeFlowSequence(state, level, object) { - var _result = '', - _tag = state.tag, - index, - length, - value; - - for (index = 0, length = object.length; index < length; index += 1) { - value = object[index]; - - if (state.replacer) { - value = state.replacer.call(object, String(index), value); - } - - // Write only valid elements, put null instead of invalid elements. - if (writeNode(state, level, value, false, false) || - (typeof value === 'undefined' && - writeNode(state, level, null, false, false))) { - - if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); - _result += state.dump; - } - } - - state.tag = _tag; - state.dump = '[' + _result + ']'; +function writeFlowSequence(state, level, node) { + let result = ""; + for (let index = 0, length = node.items.length; index < length; index += 1) { + const item = writeNode(state, level, node.items[index], {}); + if (result !== "") result += `,${!state.flowSkipCommaSpace ? " " : ""}`; + result += item; + } + const pad = state.flowBracketPadding && result !== "" ? " " : ""; + return `[${pad}${result}${pad}]`; } - -function writeBlockSequence(state, level, object, compact) { - var _result = '', - _tag = state.tag, - index, - length, - value; - - for (index = 0, length = object.length; index < length; index += 1) { - value = object[index]; - - if (state.replacer) { - value = state.replacer.call(object, String(index), value); - } - - // Write only valid elements, put null instead of invalid elements. - if (writeNode(state, level + 1, value, true, true, false, true) || - (typeof value === 'undefined' && - writeNode(state, level + 1, null, true, true, false, true))) { - - if (!compact || _result !== '') { - _result += generateNextLine(state, level); - } - - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - _result += '-'; - } else { - _result += '- '; - } - - _result += state.dump; - } - } - - state.tag = _tag; - state.dump = _result || '[]'; // Empty sequence if no valid values. +function writeBlockSequence(state, level, node, compact) { + let result = ""; + for (let index = 0, length = node.items.length; index < length; index += 1) { + const item = writeNode(state, level + 1, node.items[index], { + block: true, + compact: state.seqInlineFirst, + isblockseq: true + }); + if (!compact || result !== "") result += generateNextLine(state, level); + if (item === "" || CHAR_LINE_FEED === item.charCodeAt(0)) result += "-"; + else result += "- "; + result += item; + } + return result; } - -function writeFlowMapping(state, level, object) { - var _result = '', - _tag = state.tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - pairBuffer; - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - - pairBuffer = ''; - if (_result !== '') pairBuffer += ', '; - - if (state.condenseFlow) pairBuffer += '"'; - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - if (state.replacer) { - objectValue = state.replacer.call(object, objectKey, objectValue); - } - - if (!writeNode(state, level, objectKey, false, false)) { - continue; // Skip this pair because of invalid key; - } - - if (state.dump.length > 1024) pairBuffer += '? '; - - pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); - - if (!writeNode(state, level, objectValue, false, false)) { - continue; // Skip this pair because of invalid value. - } - - pairBuffer += state.dump; - - // Both key and value are valid. - _result += pairBuffer; - } - - state.tag = _tag; - state.dump = '{' + _result + '}'; +function writeFlowMapping(state, level, node) { + let result = ""; + const items = sortMappingItems(state, node.items); + for (const { key, value } of items) { + let pairBuffer = ""; + if (result !== "") pairBuffer += `,${!state.flowSkipCommaSpace ? " " : ""}`; + const keyText = writeNode(state, level, key, { iskey: true }); + const explicitPair = keyText.length > 1024; + if (explicitPair) pairBuffer += "? "; + else if (state.quoteFlowKeys) pairBuffer += "\""; + const valueText = writeNode(state, level, value, {}); + const sep = state.flowSkipColonSpace || valueText === "" ? "" : " "; + pairBuffer += `${keyText}${state.quoteFlowKeys && !explicitPair ? "\"" : ""}:${sep}${valueText}`; + result += pairBuffer; + } + const pad = state.flowBracketPadding && result !== "" ? " " : ""; + return `{${pad}${result}${pad}}`; } - -function writeBlockMapping(state, level, object, compact) { - var _result = '', - _tag = state.tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - explicitPair, - pairBuffer; - - // Allow sorting keys so that the output file is deterministic - if (state.sortKeys === true) { - // Default sorting - objectKeyList.sort(); - } else if (typeof state.sortKeys === 'function') { - // Custom sort function - objectKeyList.sort(state.sortKeys); - } else if (state.sortKeys) { - // Something is wrong - throw new exception('sortKeys must be a boolean or a function'); - } - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - pairBuffer = ''; - - if (!compact || _result !== '') { - pairBuffer += generateNextLine(state, level); - } - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - if (state.replacer) { - objectValue = state.replacer.call(object, objectKey, objectValue); - } - - if (!writeNode(state, level + 1, objectKey, true, true, true)) { - continue; // Skip this pair because of invalid key. - } - - explicitPair = (state.tag !== null && state.tag !== '?') || - (state.dump && state.dump.length > 1024); - - if (explicitPair) { - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - pairBuffer += '?'; - } else { - pairBuffer += '? '; - } - } - - pairBuffer += state.dump; - - if (explicitPair) { - pairBuffer += generateNextLine(state, level); - } - - if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { - continue; // Skip this pair because of invalid value. - } - - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - pairBuffer += ':'; - } else { - pairBuffer += ': '; - } - - pairBuffer += state.dump; - - // Both key and value are valid. - _result += pairBuffer; - } - - state.tag = _tag; - state.dump = _result || '{}'; // Empty mapping if no valid pairs. +function sortKeyValue(key) { + return key.kind === "scalar" ? key.value : key; } - -function detectType(state, object, explicit) { - var _result, typeList, index, length, type, style; - - typeList = explicit ? state.explicitTypes : state.implicitTypes; - - for (index = 0, length = typeList.length; index < length; index += 1) { - type = typeList[index]; - - if ((type.instanceOf || type.predicate) && - (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && - (!type.predicate || type.predicate(object))) { - - if (explicit) { - if (type.multi && type.representName) { - state.tag = type.representName(object); - } else { - state.tag = type.tag; - } - } else { - state.tag = '?'; - } - - if (type.represent) { - style = state.styleMap[type.tag] || type.defaultStyle; - - if (_toString.call(type.represent) === '[object Function]') { - _result = type.represent(object, style); - } else if (_hasOwnProperty.call(type.represent, style)) { - _result = type.represent[style](object, style); - } else { - throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); - } - - state.dump = _result; - } - - return true; - } - } - - return false; +function sortMappingItems(state, items) { + if (!state.sortKeys) return items; + const copy = items.slice(); + if (state.sortKeys === true) copy.sort((a, b) => { + const x = sortKeyValue(a.key); + const y = sortKeyValue(b.key); + if (x < y) return -1; + if (x > y) return 1; + return 0; + }); + else { + const fn = state.sortKeys; + copy.sort((a, b) => fn(sortKeyValue(a.key), sortKeyValue(b.key))); + } + return copy; } - -// Serializes `object` and writes it to global `result`. -// Returns true on success, or false on invalid object. -// -function writeNode(state, level, object, block, compact, iskey, isblockseq) { - state.tag = null; - state.dump = object; - - if (!detectType(state, object, false)) { - detectType(state, object, true); - } - - var type = _toString.call(state.dump); - var inblock = block; - var tagStr; - - if (block) { - block = (state.flowLevel < 0 || state.flowLevel > level); - } - - var objectOrArray = type === '[object Object]' || type === '[object Array]', - duplicateIndex, - duplicate; - - if (objectOrArray) { - duplicateIndex = state.duplicates.indexOf(object); - duplicate = duplicateIndex !== -1; - } - - if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { - compact = false; - } - - if (duplicate && state.usedDuplicates[duplicateIndex]) { - state.dump = '*ref_' + duplicateIndex; - } else { - if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { - state.usedDuplicates[duplicateIndex] = true; - } - if (type === '[object Object]') { - if (block && (Object.keys(state.dump).length !== 0)) { - writeBlockMapping(state, level, state.dump, compact); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + state.dump; - } - } else { - writeFlowMapping(state, level, state.dump); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; - } - } - } else if (type === '[object Array]') { - if (block && (state.dump.length !== 0)) { - if (state.noArrayIndent && !isblockseq && level > 0) { - writeBlockSequence(state, level - 1, state.dump, compact); - } else { - writeBlockSequence(state, level, state.dump, compact); - } - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + state.dump; - } - } else { - writeFlowSequence(state, level, state.dump); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; - } - } - } else if (type === '[object String]') { - if (state.tag !== '?') { - writeScalar(state, state.dump, level, iskey, inblock); - } - } else if (type === '[object Undefined]') { - return false; - } else { - if (state.skipInvalid) return false; - throw new exception('unacceptable kind of an object to dump ' + type); - } - - if (state.tag !== null && state.tag !== '?') { - // Need to encode all characters except those allowed by the spec: - // - // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ - // [36] ns-hex-digit ::= ns-dec-digit - // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ - // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ - // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” - // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” - // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” - // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” - // - // Also need to encode '!' because it has special meaning (end of tag prefix). - // - tagStr = encodeURI( - state.tag[0] === '!' ? state.tag.slice(1) : state.tag - ).replace(/!/g, '%21'); - - if (state.tag[0] === '!') { - tagStr = '!' + tagStr; - } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { - tagStr = '!!' + tagStr.slice(18); - } else { - tagStr = '!<' + tagStr + '>'; - } - - state.dump = tagStr + ' ' + state.dump; - } - } - - return true; +function writeBlockMapping(state, level, node, compact) { + let result = ""; + const items = sortMappingItems(state, node.items); + for (let index = 0, length = items.length; index < length; index += 1) { + let pairBuffer = ""; + if (!compact || result !== "") pairBuffer += generateNextLine(state, level); + const { key, value } = items[index]; + const keyIsBlock = (key.kind === "mapping" || key.kind === "sequence") && !key.style.flow && key.items.length !== 0 || key.kind === "scalar" && (key.style.literal || key.style.folded); + const keyText = keyIsBlock ? writeNode(state, level + 1, key, { + block: true, + compact: true, + isblockseq: !cannotBeCompact(state, key, level + 1) + }) : writeNode(state, level + 1, key, { + block: true, + compact: true, + iskey: true + }); + const keyHasLineBreak = key.kind === "scalar" && key.value.indexOf("\n") !== -1; + const explicitPair = keyIsBlock || keyHasLineBreak || keyText.length > 1024; + if (explicitPair) if (keyText && CHAR_LINE_FEED === keyText.charCodeAt(0)) pairBuffer += "?"; + else pairBuffer += "? "; + pairBuffer += keyText; + if (explicitPair) pairBuffer += generateNextLine(state, level); + const valueText = writeNode(state, level + 1, value, { + block: true, + compact: explicitPair, + isblockseq: explicitPair && !cannotBeCompact(state, value, level + 1) + }); + const keyIsBareProps = key.kind === "scalar" && key.value === "" && keyText !== "" && keyText.charCodeAt(keyText.length - 1) !== CHAR_SINGLE_QUOTE && keyText.charCodeAt(keyText.length - 1) !== CHAR_DOUBLE_QUOTE; + const keyColonSep = !explicitPair && (key.kind === "alias" || keyIsBareProps) ? " " : ""; + if (valueText === "" || CHAR_LINE_FEED === valueText.charCodeAt(0)) pairBuffer += `${keyColonSep}:`; + else pairBuffer += `${keyColonSep}: `; + pairBuffer += valueText; + result += pairBuffer; + } + return result; } - -function getDuplicateReferences(object, state) { - var objects = [], - duplicatesIndexes = [], - index, - length; - - inspectNode(object, objects, duplicatesIndexes); - - for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { - state.duplicates.push(objects[duplicatesIndexes[index]]); - } - state.usedDuplicates = new Array(length); +function cannotBeCompact(state, node, level) { + return node.style.tagged || node.anchor !== void 0 || state.indent < 2 && level > 0; } - -function inspectNode(object, objects, duplicatesIndexes) { - var objectKeyList, - index, - length; - - if (object !== null && typeof object === 'object') { - index = objects.indexOf(object); - if (index !== -1) { - if (duplicatesIndexes.indexOf(index) === -1) { - duplicatesIndexes.push(index); - } - } else { - objects.push(object); - - if (Array.isArray(object)) { - for (index = 0, length = object.length; index < length; index += 1) { - inspectNode(object[index], objects, duplicatesIndexes); - } - } else { - objectKeyList = Object.keys(object); - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); - } - } - } - } +function writeNode(state, level, node, ctx) { + if (node.kind === "alias") return `*${node.anchor}`; + const { block = false, iskey = false, isblockseq = false } = ctx; + let compact = ctx.compact ?? false; + const hasAnchor = node.anchor !== void 0; + if (cannotBeCompact(state, node, level)) compact = false; + let body; + let shouldPrintTag = node.style.tagged; + const useBlockCollection = block && (node.kind === "mapping" || node.kind === "sequence") && !node.style.flow && node.items.length !== 0; + if (node.kind === "mapping") if (useBlockCollection) body = writeBlockMapping(state, level, node, compact); + else body = writeFlowMapping(state, level, node); + else if (node.kind === "sequence") if (useBlockCollection) if (state.seqNoIndent && !isblockseq && level > 0) body = writeBlockSequence(state, level - 1, node, compact); + else body = writeBlockSequence(state, level, node, compact); + else body = writeFlowSequence(state, level, node); + else { + const layout = scalarLayout(state, level); + const style = resolveScalarStyle(state, node, layout, iskey, block); + body = renderScalarStyle(node.value, style, layout); + shouldPrintTag = node.style.tagged || style !== STYLE_PLAIN && node.tag !== state.defaultScalarTagName; + } + if (useBlockCollection && compact && level > 0 && state.indent > 2) body = `${" ".repeat(state.indent - 2)}${body}`; + if (shouldPrintTag || hasAnchor) { + const props = []; + const tag = shouldPrintTag ? nodeTagShort(node) : null; + const anchor = hasAnchor ? `&${node.anchor}` : null; + if (state.tagBeforeAnchor) { + if (tag !== null) props.push(tag); + if (anchor !== null) props.push(anchor); + } else { + if (anchor !== null) props.push(anchor); + if (tag !== null) props.push(tag); + } + const sep = body === "" || body.charCodeAt(0) === CHAR_LINE_FEED ? "" : " "; + body = `${props.join(" ")}${sep}${body}`; + } + return body; } - -function dump$1(input, options) { - options = options || {}; - - var state = new State(options); - - if (!state.noRefs) getDuplicateReferences(input, state); - - var value = input; - - if (state.replacer) { - value = state.replacer.call({ '': value }, '', value); - } - - if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; - - return ''; +function rootStartsOwnLine(node) { + return (node.kind === "sequence" || node.kind === "mapping") && !node.style.flow && node.items.length !== 0 && !node.style.tagged && node.anchor === void 0; } - -var dump_1 = dump$1; - -var dumper = { - dump: dump_1 +function isOpenEnded(node) { + let leaf = node; + while ((leaf.kind === "sequence" || leaf.kind === "mapping") && !leaf.style.flow && leaf.items.length !== 0) leaf = leaf.kind === "sequence" ? leaf.items[leaf.items.length - 1] : leaf.items[leaf.items.length - 1].value; + if (leaf.kind !== "scalar" || !(leaf.style.literal || leaf.style.folded)) return false; + const { value } = leaf; + return value.endsWith("\n\n") || value === "\n"; +} +function writeDocumentDirectives(doc) { + let result = ""; + for (const directive of doc.directives) { + if (directive.kind === "yaml") { + result += `%YAML ${directive.version}\n`; + continue; + } + const { handle, prefix } = directive; + result += `%TAG ${handle} ${prefix}\n`; + } + return result; +} +function present(documents, options) { + const state = createPresenterState(options); + let result = ""; + let previousEnded = false; + for (let index = 0; index < documents.length; index += 1) { + const doc = documents[index]; + const directives = writeDocumentDirectives(doc); + const hasDirectives = directives !== ""; + const marker = doc.explicitStart || hasDirectives || index > 0 && !previousEnded; + result += directives; + if (doc.contents === null) { + if (marker) result += "---\n"; + } else if (marker) { + const body = writeNode(state, 0, doc.contents, { + block: true, + compact: true + }); + const sep = body === "" ? "" : hasDirectives || rootStartsOwnLine(doc.contents) ? "\n" : " "; + result += `---${sep}${body}\n`; + } else result += writeNode(state, 0, doc.contents, { + block: true, + compact: true + }) + "\n"; + previousEnded = doc.explicitEnd || doc.contents !== null && isOpenEnded(doc.contents); + if (previousEnded) result += "...\n"; + } + return result; +} +//#endregion +//#region src/dump.ts +var DEFAULT_DUMP_SCHEMA = YAML11_SCHEMA.withTags({ + ...intYaml11Tag, + resolve: (source, isExplicit, tagName) => { + const result = intYaml11Tag.resolve(source, isExplicit, tagName); + return result === NOT_RESOLVED ? intCoreTag.resolve(source, isExplicit, tagName) : result; + } +}, { + ...floatYaml11Tag, + resolve: (source, isExplicit, tagName) => { + const result = floatYaml11Tag.resolve(source, isExplicit, tagName); + return result === NOT_RESOLVED ? floatCoreTag.resolve(source, isExplicit, tagName) : result; + } +}); +var DEFAULT_DUMP_OPTIONS = { + ...DEFAULT_PRESENTER_OPTIONS, + schema: DEFAULT_DUMP_SCHEMA, + skipInvalid: false, + noRefs: false, + flowLevel: -1, + transform: () => {} }; - -function renamed(from, to) { - return function () { - throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + - 'Use yaml.' + to + ' instead, which is now safe by default.'); - }; +function dump(input, options = {}) { + const opts = { + ...DEFAULT_DUMP_OPTIONS, + ...options + }; + const documents = jsToAst(input, opts.schema, { + noRefs: opts.noRefs, + skipInvalid: opts.skipInvalid + }); + if (opts.flowLevel >= 0) visit(documents, (node, ctx) => { + if (ctx.depth < opts.flowLevel) return; + node.style.flow = true; + return VISIT_SKIP; + }); + opts.transform(documents); + return present(documents, { + ...pick(opts, Object.keys(DEFAULT_PRESENTER_OPTIONS)), + schema: opts.schema + }); } +//#endregion +//#region src/ast/from_events.ts +var NO_RANGE = (/* unused pure expression or super */ null && (-1)); +function eventPosition(event) { + if ("tagStart" in event && event.tagStart !== NO_RANGE) return event.tagStart; + if ("anchorStart" in event && event.anchorStart !== NO_RANGE) return event.anchorStart; + if ("valueStart" in event && event.valueStart !== NO_RANGE) return event.valueStart; + if ("start" in event) return event.start; + return 0; +} +function rawTag(state, event) { + return event.tagStart === NO_RANGE ? "" : state.source.slice(event.tagStart, event.tagEnd); +} +function anchorName(state, event) { + return event.anchorStart === NO_RANGE ? void 0 : state.source.slice(event.anchorStart, event.anchorEnd); +} +function implicitScalarTagName(state, source) { + const { schema } = state; + const candidates = schema.implicitScalarByFirstChar.get(source.charAt(0)) ?? schema.implicitScalarAnyFirstChar; + for (const tag of candidates) if (tag.resolve(source, false, tag.tagName) !== NOT_RESOLVED) return tag.tagName; + return schema.defaultScalarTag.tagName; +} +function buildScalar(state, event) { + const value = getScalarValue(state.source, event); + const raw = rawTag(state, event); + const style = new Style(); + switch (event.style) { + case 2: + style.singleQuoted = true; + break; + case 3: + style.doubleQuoted = true; + break; + case 4: + style.literal = true; + break; + case 5: + style.folded = true; + break; + } + let tag; + if (raw !== "") { + style.tagged = true; + tag = raw; + } else if (event.style === 1) tag = implicitScalarTagName(state, value); + else tag = state.schema.defaultScalarTag.tagName; + return { + kind: "scalar", + tag, + style, + anchor: anchorName(state, event), + value + }; +} +function buildCollection(state, event, defaultTagName) { + const raw = rawTag(state, event); + const style = new Style(); + if (event.style === 2) style.flow = true; + let tag; + if (raw === "") tag = defaultTagName; + else { + tag = raw; + style.tagged = true; + } + return { + tag, + style, + anchor: anchorName(state, event) + }; +} +function addNode(state, node) { + const frame = state.frames[state.frames.length - 1]; + if (frame.kind === "document") frame.doc.contents = node; + else if (frame.kind === "sequence") frame.node.items.push(node); + else if (frame.key) { + frame.node.items.push({ + key: frame.key, + value: node + }); + frame.key = null; + } else frame.key = node; +} +function eventsToAst(events, options) { + const state = { + source: options.source, + schema: options.schema, + eventIndex: 0, + position: 0, + frames: [], + documents: [] + }; + while (state.eventIndex < events.length) { + const event = events[state.eventIndex++]; + state.position = eventPosition(event); + switch (event.type) { + case 1: { + const doc = { + contents: null, + explicitStart: event.explicitStart, + explicitEnd: event.explicitEnd, + directives: event.directives + }; + state.frames.push({ + kind: "document", + doc + }); + break; + } + case 4: + addNode(state, buildScalar(state, event)); + break; + case 2: { + const { tag, style, anchor } = buildCollection(state, event, "tag:yaml.org,2002:seq"); + const node = { + kind: "sequence", + tag, + style, + anchor, + items: [] + }; + state.frames.push({ + kind: "sequence", + node + }); + break; + } + case 3: { + const { tag, style, anchor } = buildCollection(state, event, "tag:yaml.org,2002:map"); + const node = { + kind: "mapping", + tag, + style, + anchor, + items: [] + }; + state.frames.push({ + kind: "mapping", + node, + key: null + }); + break; + } + case 5: { + const name = state.source.slice(event.anchorStart, event.anchorEnd); + addNode(state, { + kind: "alias", + tag: "", + style: new Style(), + anchor: name + }); + break; + } + case 6: { + const frame = state.frames.pop(); + if (frame.kind === "document") state.documents.push(frame.doc); + else addNode(state, frame.node); + break; + } + } + } + return state.documents; +} +//#endregion -var Type = type; -var Schema = schema; -var FAILSAFE_SCHEMA = failsafe; -var JSON_SCHEMA = json; -var CORE_SCHEMA = core; -var DEFAULT_SCHEMA = _default; -var load = loader.load; -var loadAll = loader.loadAll; -var dump = dumper.dump; -var YAMLException = exception; - -// Re-export all types in case user wants to create custom schema -var types = { - binary: binary, - float: js_yaml_float, - map: js_yaml_map, - null: _null, - pairs: pairs, - set: set, - timestamp: timestamp, - bool: bool, - int: js_yaml_int, - merge: merge, - omap: omap, - seq: seq, - str: str -}; - -// Removed functions from JS-YAML 3.0.x -var safeLoad = renamed('safeLoad', 'load'); -var safeLoadAll = renamed('safeLoadAll', 'loadAll'); -var safeDump = renamed('safeDump', 'dump'); - -var jsYaml = { - Type: Type, - Schema: Schema, - FAILSAFE_SCHEMA: FAILSAFE_SCHEMA, - JSON_SCHEMA: JSON_SCHEMA, - CORE_SCHEMA: CORE_SCHEMA, - DEFAULT_SCHEMA: DEFAULT_SCHEMA, - load: load, - loadAll: loadAll, - dump: dump, - YAMLException: YAMLException, - types: types, - safeLoad: safeLoad, - safeLoadAll: safeLoadAll, - safeDump: safeDump -}; - - - +//# sourceMappingURL=js-yaml.mjs.map ;// CONCATENATED MODULE: ./node_modules/markdownlint-cli2/parsers/yaml-parse.mjs // @ts-check @@ -80040,7 +79570,7 @@ var jsYaml = { */ const yamlParse = (text) => { // @ts-ignore - return jsYaml.load(text); + return load(text); }; /* harmony default export */ const yaml_parse = (yamlParse); @@ -80087,6 +79617,7 @@ const pathPosix = external_node_path_namespaceObject.posix; + /* eslint-disable jsdoc/reject-any-type */ // Variables @@ -80118,23 +79649,24 @@ const throwForConfigurationFile = (/** @type {string} */ file, /** @type {Error ); }; -// Return a posix path (even on Windows) +// Return a POSIX path (even on Windows) const posixPath = (/** @type {string} */ p) => p.split(external_node_path_namespaceObject.sep).join(pathPosix.sep); // Resolves module paths relative to the specified directory const resolveModulePaths = (/** @type {string} */ dir, /** @type {string[]} */ modulePaths) => ( - modulePaths.map((path) => external_node_path_namespaceObject.resolve(dir, (0,helpers_helpers.expandTildePath)(path, external_node_os_namespaceObject))) + modulePaths.map((path) => external_node_path_namespaceObject.resolve(dir, (0,helpers_helpers/* expandTildePath */.ww)(path, external_node_os_namespaceObject))) ); // Import a module ID with a custom directory in the path const importModule = async (/** @type {string[] | string} */ dirOrDirs, /** @type {any} */ id, /** @type {boolean} */ noImport) => { if (typeof id !== "string") { return id; - } else if (noImport) { + } + if (noImport) { return null; } const dirs = Array.isArray(dirOrDirs) ? dirOrDirs : [ dirOrDirs ]; - const expandId = (0,helpers_helpers.expandTildePath)(id, external_node_os_namespaceObject); + const expandId = (0,helpers_helpers/* expandTildePath */.ww)(id, external_node_os_namespaceObject); const errors = []; let moduleName = null; try { @@ -80180,19 +79712,33 @@ const importModuleIdsAndParams = (/** @type {string[]} */ dirs, /** @type {any[] ).then((results) => results.filter(Boolean)) ); -// Extend a config object if it has 'extends' property -const getExtendedConfig = (/** @type {ExecutionContext} */ context, /** @type {Configuration} */ config, /** @type {string} */ configPath) => { - if (config.extends) { +// Update a config object (in place) if it has an "extends" property +const extendConfigObject = async (/** @type {ExecutionContext} */ context, /** @type {Configuration | null | undefined} */ config, /** @type {string} */ configPath) => { + if (config?.extends) { const { fs, parsers } = context; - return extendConfigPromise( + const extended = await extendConfigPromise( config, configPath, parsers, fs ); + for (const [ key, value ] of Object.entries(extended)) { + config[key] = value; + } } + return config; +}; - return Promise.resolve(config); +const extendOptionsObject = (/** @type {ExecutionContext} */ context, /** @type {Options | null | undefined} */ options, /** @type {string} */ configPath) => { + const configs = [ options?.config ]; + append_to_array(configs, (options?.overrides || []).map((override) => override.config)); + return Promise.all(configs. + map((config) => extendConfigObject( + context, + config, + configPath + )) + ); }; // Read an options or config file in any format and return the object @@ -80209,13 +79755,13 @@ const readOptionsOrConfig = async (/** @type {ExecutionContext} */ context, /** } else if (basename.endsWith(".markdownlint-cli2.yaml")) { options = await readYaml(configPath, fs); } else if (basename.endsWith(".markdownlint-cli2.cjs") || basename.endsWith(".markdownlint-cli2.mjs")) { - options = await importModule(dirname, basename, noImport); + options = clone_options(await importModule(dirname, basename, noImport)); } else if (basename.endsWith(".markdownlint.jsonc") || basename.endsWith(".markdownlint.json")) { config = await readJsonc(configPath, fs); } else if (basename.endsWith(".markdownlint.yaml") || basename.endsWith(".markdownlint.yml")) { config = await readYaml(configPath, fs); } else if (basename.endsWith(".markdownlint.cjs") || basename.endsWith(".markdownlint.mjs")) { - config = await importModule(dirname, basename, noImport); + config = clone_options(await importModule(dirname, basename, noImport)); } else if (basename.endsWith(".jsonc") || basename.endsWith(".json")) { unknown = await readJsonc(configPath, fs); } else if (basename.endsWith(".toml")) { @@ -80223,7 +79769,7 @@ const readOptionsOrConfig = async (/** @type {ExecutionContext} */ context, /** } else if (basename.endsWith(".yaml") || basename.endsWith(".yml")) { unknown = await readYaml(configPath, fs); } else if (basename.endsWith(".cjs") || basename.endsWith(".mjs")) { - unknown = await importModule(dirname, basename, noImport); + unknown = clone_options(await importModule(dirname, basename, noImport)); } else { throw new Error( "Configuration file should be one of the supported names " + @@ -80248,20 +79794,18 @@ const readOptionsOrConfig = async (/** @type {ExecutionContext} */ context, /** } } if (options) { - if (options.config) { - options.config = await getExtendedConfig(context, options.config, configPath); - } + await extendOptionsObject(context, options, configPath); return options; } - config = await getExtendedConfig(context, config, configPath); + await extendConfigObject(context, config, configPath); return { config }; }; -// Filter a list of files to ignore by glob -const removeIgnoredFiles = (/** @type {string} */ dir, /** @type {string[]} */ files, /** @type {string[]} */ ignores) => ( +// Filter a list of files by glob(s) +const filterByGlobs = (/** @type {string} */ dir, /** @type {string[]} */ files, /** @type {string[]} */ globs) => ( micromatch( files.map((file) => pathPosix.relative(dir, file)), - ignores, + globs, { "dot": true } ).map((file) => pathPosix.join(dir, file)) ); @@ -80344,17 +79888,22 @@ $ markdownlint-cli2 "**/*.md" "#node_modules"` }; // Helpers for getAndProcessDirInfo/handleFirstMatchingConfigurationFile +// Options inputs do not need special handling const readJsoncWrapper = (/** @type {ConfigurationHandlerParams} */ { file, fs }) => readJsonc(file, fs); const readYamlWrapper = (/** @type {ConfigurationHandlerParams} */ { file, fs }) => readYaml(file, fs); +const importOptionsModuleWrapper = async (/** @type {ConfigurationHandlerParams} */ { dir, file, noImport }) => + clone_options(await importModule(dir, file, noImport)); +// Configuration inputs need "extends" handled const readConfigWrapper = (/** @type {ConfigurationHandlerParams} */ { file, fs, parsers }) => readConfigPromise(file, parsers, fs); -const importModuleWrapper = (/** @type {ConfigurationHandlerParams} */ { dir, file, noImport }) => importModule(dir, file, noImport); +const importConfigModuleWrapper = async (/** @type {ConfigurationHandlerParams} */ { context, dir, file, noImport }) => + extendConfigObject(context, clone_options(await importModule(dir, file, noImport)), file); /** @type {ConfigurationFileAndHandler[] } */ const optionsFiles = [ [ ".markdownlint-cli2.jsonc", readJsoncWrapper ], [ ".markdownlint-cli2.yaml", readYamlWrapper ], - [ ".markdownlint-cli2.cjs", importModuleWrapper ], - [ ".markdownlint-cli2.mjs", importModuleWrapper ] + [ ".markdownlint-cli2.cjs", importOptionsModuleWrapper ], + [ ".markdownlint-cli2.mjs", importOptionsModuleWrapper ] ]; /** @type {ConfigurationFileAndHandler[] } */ @@ -80363,8 +79912,8 @@ const configurationFiles = [ [ ".markdownlint.json", readConfigWrapper ], [ ".markdownlint.yaml", readConfigWrapper ], [ ".markdownlint.yml", readConfigWrapper ], - [ ".markdownlint.cjs", importModuleWrapper ], - [ ".markdownlint.mjs", importModuleWrapper ] + [ ".markdownlint.cjs", importConfigModuleWrapper ], + [ ".markdownlint.mjs", importConfigModuleWrapper ] ]; /** @@ -80387,7 +79936,7 @@ const processFirstMatchingConfigurationFile = (context, fileAndHandlers, dir, me /** @type {ConfigurationFileAndHandler} */ const [ file, handler ] = values.find((result) => (result.status === "fulfilled"))?.value || [ "[UNUSED]", markdownlint_cli2_noop ]; memoizeFile(file); - return handler({ dir, file, fs, noImport, parsers }); + return handler({ context, dir, file, fs, noImport, parsers }); }); }; @@ -80419,17 +79968,7 @@ const getAndProcessDirInfo = ( processFirstMatchingConfigurationFile(context, optionsFiles, dir, (file) => { cli2File = file; }). then((/** @type {Options | null} */ options) => { dirInfo.markdownlintOptions = options; - return options && - options.config && - getExtendedConfig( - context, - options.config, - // Just need to identify the right directory - pathPosix.join(dir, utf8) - ). - then((config) => { - options.config = config; - }); + return extendOptionsObject(context, options, cli2File); }). catch((/** @type {Error} */ error) => { throwForConfigurationFile(cli2File, error); @@ -80539,7 +80078,7 @@ const enumerateFiles = async ( filter((glob) => glob.startsWith("!")); const filteredLiteralFiles = ((literalFiles.length > 0) && (globsForIgnore.length > 0)) - ? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore) + ? filterByGlobs(baseDir, literalFiles, globsForIgnore) : literalFiles; // Process glob patterns const files = [ @@ -80576,6 +80115,7 @@ const enumerateParents = async ( do { baseDirParents[baseDirParent] = true; baseDirParent = pathPosix.dirname(baseDirParent); + // eslint-disable-next-line unicorn/no-computed-property-existence-check } while (!baseDirParents[baseDirParent]); // Visit parents of each dirInfo @@ -80583,6 +80123,7 @@ const enumerateParents = async ( let { dir } = lastDirInfo; let lastDir = dir; while ( + // eslint-disable-next-line unicorn/no-computed-property-existence-check !baseDirParents[dir] && (dir = pathPosix.dirname(dir)) && (dir !== lastDir) @@ -80630,8 +80171,10 @@ const createDirInfos = async ( ); // Merge file lists with identical configuration + // (Sort so parents are handled before children) const dirs = Object.keys(dirToDirInfo); dirs.sort((a, b) => b.length - a.length); + /** @type {DirInfo[]} */ const dirInfos = []; const tasks = []; for (const dir of dirs) { @@ -80678,6 +80221,7 @@ const createDirInfos = async ( } await Promise.all(tasks); for (const dirInfo of dirInfos) { + // eslint-disable-next-line unicorn/no-computed-property-existence-check while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) { dirInfo.parent = dirInfo.parent.parent; } @@ -80693,7 +80237,7 @@ const createDirInfos = async ( // } // if ( // dirInfos.filter( - // (di) => !di.parent && (di.dir !== baseDir) + // (di) => !di.parent && (di.dir !== context.baseDir) // ).length > 0 // ) { // throw new Error("Missing parent"); @@ -80738,6 +80282,32 @@ const createDirInfos = async ( ); dirInfo.markdownlintConfig = markdownlintConfig; } + + // Apply configuration overrides + /** @type {DirInfo[]} */ + const overrideDirInfos = []; + for (const dirInfo of dirInfos) { + const overrides = dirInfo.markdownlintOptions?.overrides || []; + for (const override of overrides) { + const { filter, config, combine } = override; + if (filter && (filter.length > 0) && config && ((combine === "merge") || (combine === "replace"))) { + const filteredFiles = filterByGlobs(dirInfo.dir, dirInfo.files, filter); + if (filteredFiles.length > 0) { + dirInfo.files = dirInfo.files.filter((file) => !filteredFiles.includes(file)); + const overrideConfig = (combine === "merge") ? { ...dirInfo.markdownlintOptions?.config, ...config } : config; + const overrideDirInfo = { + ...dirInfo, + "files": filteredFiles, + "markdownlintOptions": { ...dirInfo.markdownlintOptions, "config": overrideConfig } + }; + overrideDirInfos.push(overrideDirInfo); + } + } + } + } + append_to_array(dirInfos, overrideDirInfos); + + // Return results return dirInfos; }; @@ -80762,7 +80332,7 @@ const lintFiles = ( ) { // eslint-disable-next-line unicorn/no-array-callback-reference const ignores = markdownlintOptions.ignores.map(negateGlob); - filesAfterIgnores = removeIgnoredFiles(dir, files, ignores); + filesAfterIgnores = filterByGlobs(dir, files, ignores); } const filteredFiles = filesAfterIgnores.filter( (file) => fileContents[file] === undefined @@ -80775,12 +80345,12 @@ const lintFiles = ( } } // Create markdown-it factory - // eslint-disable-next-line unicorn/consistent-function-scoping const markdownItFactory = async () => { // eslint-disable-next-line no-inline-comments const module = await Promise.resolve(/* import() eager */).then(__nccwpck_require__.bind(__nccwpck_require__, 9193)); const markdownIt = module.default({ "html": true }); - for (const plugin of (markdownlintOptions?.markdownItPlugins || [])) { + const plugins = markdownlintOptions?.markdownItPlugins || []; + for (const plugin of plugins) { // @ts-ignore markdownIt.use(...plugin); } @@ -80891,6 +80461,7 @@ const outputResults = async ( /** @type {Logger} */ logError, /** @type {boolean} */ noImport ) => { + // eslint-disable-next-line unicorn/prefer-early-return if ((results.length > 0) || outputFormatters) { /** @type {OutputFormatterOptions} */ const formatterOptions = { @@ -80951,6 +80522,7 @@ const markdownlint_cli2_main = async (/** @type {Parameters} */ params) => { const argvFiltered = (argv || []).filter((arg) => { if (sawDashDash) { return true; + // eslint-disable-next-line unicorn/no-useless-else } else if (configPath === null) { configPath = arg; } else if (configPointer === null) { @@ -81067,6 +80639,7 @@ const markdownlint_cli2_main = async (/** @type {Parameters} */ params) => { const fileCount = fileNames.length; if (baseMarkdownlintOptions.showFound) { fileNames.push(""); + // eslint-disable-next-line unicorn/require-array-sort-compare fileNames.sort(); logMessage(`Found:${fileNames.join("\n ")}`); } @@ -81101,7 +80674,7 @@ const markdownlint_cli2_main = async (/** @type {Parameters} */ params) => { modulePaths, logMessage, logError, - Boolean(noImport) + noImport ); } // Return result @@ -81150,6 +80723,7 @@ const markdownlint_cli2_main = async (/** @type {Parameters} */ params) => { /** * @typedef ConfigurationHandlerParams + * @property {ExecutionContext} context Execution context. * @property {string} dir Configuration file directory. * @property {string} file Configuration file. * @property {FsLike} fs File system object. @@ -81159,6 +80733,13 @@ const markdownlint_cli2_main = async (/** @type {Parameters} */ params) => { /** @typedef {[ string, (params: ConfigurationHandlerParams) => Promise ] } ConfigurationFileAndHandler */ +/** + * @typedef Override + * @property {string[]} filter Globs to filter. + * @property {Configuration} config Configuration object. + * @property {"merge"|"replace"} combine Combine strategy. + */ + /** * @typedef DirInfo * @property {string} dir Directory. @@ -81179,20 +80760,21 @@ const markdownlint_cli2_main = async (/** @type {Parameters} */ params) => { /** * @typedef Options - * @property {Configuration} [config] Config. + * @property {Configuration} [config] Configuration object. + * @property {Override[]} [overrides] Configuration overrides. * @property {Rule[] | string[]} [customRules] Custom rules. - * @property {boolean} [fix] Fix. - * @property {string} [frontMatter] Front matter. - * @property {boolean | string} [gitignore] Git ignore. - * @property {string[]} [globs] Globs. - * @property {string[]} [ignores] Ignores. + * @property {boolean} [fix] Fix supported violations. + * @property {string} [frontMatter] Front matter regular expression. + * @property {boolean | string} [gitignore] Switch or glob for .gitignore. + * @property {string[]} [globs] Globs to lint. + * @property {string[]} [ignores] Globs to ignore. * @property {MarkdownItPluginConfiguration[]} [markdownItPlugins] Markdown-it plugins. - * @property {string[]} [modulePaths] Module paths. - * @property {boolean} [noBanner] No banner. - * @property {boolean} [noInlineConfig] No inline config. - * @property {boolean} [noProgress] No progress. + * @property {string[]} [modulePaths] Additional module paths. + * @property {boolean} [noBanner] Disable banner display. + * @property {boolean} [noInlineConfig] Disable inline config. + * @property {boolean} [noProgress] Disable progress display. * @property {OutputFormatterConfiguration[]} [outputFormatters] Output formatters. - * @property {boolean} [showFound] Show found. + * @property {boolean} [showFound] Show found files. */ /**