{"version":3,"file":"./lib/fxparser.min.js","mappings":"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","sources":["webpack://XMLParser/webpack/universalModuleDefinition","webpack://XMLParser/webpack/bootstrap","webpack://XMLParser/webpack/runtime/define property getters","webpack://XMLParser/webpack/runtime/hasOwnProperty shorthand","webpack://XMLParser/webpack/runtime/make namespace object","webpack://XMLParser/./src/util.js","webpack://XMLParser/./src/xmlparser/OptionsBuilder.js","webpack://XMLParser/./src/xmlparser/xmlNode.js","webpack://XMLParser/./node_modules/xml-naming/src/index.js","webpack://XMLParser/./src/xmlparser/DocTypeReader.js","webpack://XMLParser/./node_modules/anynum/digitTable.js","webpack://XMLParser/./node_modules/anynum/anynum.js","webpack://XMLParser/./node_modules/strnum/strnum.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/Matcher.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/Expression.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/ExpressionSet.js","webpack://XMLParser/./node_modules/@nodable/entities/src/entities.js","webpack://XMLParser/./node_modules/@nodable/entities/src/EntityDecoder.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/sql.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/sql-strict.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/html.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/xml.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/svg.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/shell.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/redos.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/nosql.js","webpack://XMLParser/./node_modules/is-unsafe/src/contexts/log.js","webpack://XMLParser/./node_modules/is-unsafe/src/index.js","webpack://XMLParser/./src/xmlparser/OrderedObjParser.js","webpack://XMLParser/./src/ignoreAttributes.js","webpack://XMLParser/./src/xmlparser/node2json.js","webpack://XMLParser/./src/validator.js","webpack://XMLParser/./src/xmlparser/XMLParser.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"XMLParser\"] = factory();\n\telse\n\t\troot[\"XMLParser\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n/**\n * Dangerous property names that could lead to prototype pollution or security issues\n */\nexport const DANGEROUS_PROPERTY_NAMES = [\n // '__proto__',\n // 'constructor',\n // 'prototype',\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__'\n];\n\nexport const criticalProperties = [\"__proto__\", \"constructor\", \"prototype\"];","import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from \"../util.js\";\nimport { COMMON_HTML, CURRENCY } from '@nodable/entities';\n\nconst defaultOnDangerousProperty = (name) => {\n if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return \"__\" + name;\n }\n return name;\n};\n\n\nexport const defaultOptions = {\n preserveOrder: false,\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n removeNSPrefix: false, // remove NS from tag name or attribute name if true\n allowBooleanAttributes: false, //a tag can have attributes without any value\n //ignoreRootElement : false,\n parseTagValue: true,\n parseAttributeValue: false,\n trimValues: true, //Trim string values of tag and attributes\n cdataPropName: false,\n numberParseOptions: {\n hex: true,\n leadingZeros: true,\n eNotation: true,\n unicode: false\n },\n tagValueProcessor: function (tagName, val) {\n return val;\n },\n attributeValueProcessor: function (attrName, val) {\n return val;\n },\n stopNodes: [], //nested tags will not be parsed even for errors\n alwaysCreateTextNode: false,\n isArray: () => false,\n commentPropName: false,\n unpairedTags: [],\n processEntities: true,\n htmlEntities: false,\n entityDecoder: null,\n ignoreDeclaration: false,\n ignorePiTags: false,\n transformTagName: false,\n transformAttributeName: false,\n updateTag: function (tagName, jPath, attrs) {\n return tagName\n },\n // skipEmptyListItem: false\n captureMetaData: false,\n maxNestedTags: 100,\n strictReservedNames: true,\n jPath: true, // if true, pass jPath string to callbacks; if false, pass matcher instance\n onDangerousProperty: defaultOnDangerousProperty\n};\n\n\n/**\n * Validates that a property name is safe to use\n * @param {string} propertyName - The property name to validate\n * @param {string} optionName - The option field name (for error message)\n * @throws {Error} If property name is dangerous\n */\nfunction validatePropertyName(propertyName, optionName) {\n if (typeof propertyName !== 'string') {\n return; // Only validate string property names\n }\n\n const normalized = propertyName.toLowerCase();\n if (DANGEROUS_PROPERTY_NAMES.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n\n if (criticalProperties.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n}\n\n/**\n * Normalizes processEntities option for backward compatibility\n * @param {boolean|object} value \n * @returns {object} Always returns normalized object\n */\nfunction normalizeProcessEntities(value, htmlEntities) {\n // Boolean backward compatibility\n if (typeof value === 'boolean') {\n return {\n enabled: value, // true or false\n maxEntitySize: 10000,\n maxExpansionDepth: 10000,\n maxTotalExpansions: Infinity,\n maxExpandedLength: 100000,\n maxEntityCount: 1000,\n allowedTags: null,\n tagFilter: null,\n appliesTo: \"all\",\n };\n }\n\n // Object config - merge with defaults\n if (typeof value === 'object' && value !== null) {\n return {\n enabled: value.enabled !== false,\n maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000),\n maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10000),\n maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),\n maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000),\n maxEntityCount: Math.max(1, value.maxEntityCount ?? 1000),\n allowedTags: value.allowedTags ?? null,\n tagFilter: value.tagFilter ?? null,\n appliesTo: value.appliesTo ?? \"all\",\n };\n }\n\n // Default to enabled with limits\n return normalizeProcessEntities(true);\n}\n\nexport const buildOptions = function (options) {\n const built = Object.assign({}, defaultOptions, options);\n\n // Validate property names to prevent prototype pollution\n const propertyNameOptions = [\n { value: built.attributeNamePrefix, name: 'attributeNamePrefix' },\n { value: built.attributesGroupName, name: 'attributesGroupName' },\n { value: built.textNodeName, name: 'textNodeName' },\n { value: built.cdataPropName, name: 'cdataPropName' },\n { value: built.commentPropName, name: 'commentPropName' }\n ];\n\n for (const { value, name } of propertyNameOptions) {\n if (value) {\n validatePropertyName(value, name);\n }\n }\n\n if (built.onDangerousProperty === null) {\n built.onDangerousProperty = defaultOnDangerousProperty;\n }\n\n // Always normalize processEntities for backward compatibility and validation\n built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities);\n built.unpairedTagsSet = new Set(built.unpairedTags);\n // Convert old-style stopNodes for backward compatibility\n if (built.stopNodes && Array.isArray(built.stopNodes)) {\n built.stopNodes = built.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Old syntax: *.tagname meant \"tagname anywhere\"\n // Convert to new syntax: ..tagname\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n //console.debug(built.processEntities)\n return built;\n};","'use strict';\n\nlet METADATA_SYMBOL;\n\nif (typeof Symbol !== \"function\") {\n METADATA_SYMBOL = \"@@xmlMetadata\";\n} else {\n METADATA_SYMBOL = Symbol(\"XML Node Metadata\");\n}\n\nexport default class XmlNode {\n constructor(tagname) {\n this.tagname = tagname;\n this.child = []; //nested tags, text, cdata, comments in order\n this[\":@\"] = Object.create(null); //attributes map\n }\n add(key, val) {\n // this.child.push( {name : key, val: val, isCdata: isCdata });\n if (key === \"__proto__\") key = \"#__proto__\";\n this.child.push({ [key]: val });\n }\n addChild(node, startIndex) {\n if (node.tagname === \"__proto__\") node.tagname = \"#__proto__\";\n if (node[\":@\"] && Object.keys(node[\":@\"]).length > 0) {\n this.child.push({ [node.tagname]: node.child, [\":@\"]: node[\":@\"] });\n } else {\n this.child.push({ [node.tagname]: node.child });\n }\n // if requested, add the startIndex\n this.addStartIndex(startIndex);\n }\n\n addStartIndex(startIndex) {\n if (startIndex !== undefined) {\n // Note: for now we just overwrite the metadata. If we had more complex metadata,\n // we might need to do an object append here: metadata = { ...metadata, startIndex }\n this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };\n }\n }\n\n addEndIndex(endIndex) {\n const lastChild = this.child[this.child.length - 1];\n // endIndex is write-once: when updateTag drops a node, the last child is a\n // previously completed sibling whose endIndex must not be overwritten\n if (lastChild !== undefined && lastChild[METADATA_SYMBOL] !== undefined\n && lastChild[METADATA_SYMBOL].endIndex === undefined) {\n lastChild[METADATA_SYMBOL].endIndex = endIndex;\n }\n }\n /** symbol used for metadata */\n static getMetaDataSymbol() {\n return METADATA_SYMBOL;\n }\n}\n","/**\n * xml-naming\n * Validates XML Name productions as defined in the XML 1.0 and 1.1 specifications.\n * Covers: Name, NCName, QName, NMToken, NMTokens\n *\n * XML 1.0 spec: https://www.w3.org/TR/xml/#NT-Name\n * XML 1.1 spec: https://www.w3.org/TR/xml11/#NT-NameStartChar\n * XML NS spec: https://www.w3.org/TR/xml-names/#NT-NCName\n */\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.0\n//\n// NameStartChar ::= \":\" | [A-Z] | \"_\" | [a-z]\n// | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF]\n// | [#x370-#x37D] | [#x37F-#x1FFF] <- split to exclude #x0487\n// | [#x200C-#x200D]\n// | [#x2070-#x218F] | [#x2C00-#x2FEF]\n// | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD]\n//\n// NameChar ::= NameStartChar | \"-\" | \".\" | [0-9]\n// | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]\n//\n// Note: \\u0487 (Combining Cyrillic Millions Sign) was added in Unicode 4.0,\n// after XML 1.0 was defined against Unicode 2.0. It falls inside the range\n// \\u037F-\\u1FFF but must be excluded. We split that range into\n// \\u037F-\\u0486 and \\u0488-\\u1FFF to exclude it explicitly.\n// ---------------------------------------------------------------------------\n\nconst nameStartChar10 =\n ':A-Za-z_' +\n '\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF' +\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD';\n\nconst nameChar10 =\n nameStartChar10 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Character class strings — XML 1.1\n//\n// Differences from XML 1.0:\n//\n// NameStartChar:\n// 1.0 has split ranges: \\u00C0-\\u00D6, \\u00D8-\\u00F6, \\u00F8-\\u02FF\n// 1.1 merges them into: \\u00C0-\\u02FF\n// (\\u00D7 x and \\u00F7 / are division symbols, excluded in both versions)\n//\n// 1.0 tops out at \\uFFFD (BMP only)\n// 1.1 adds \\u{10000}-\\u{EFFFF} (supplementary planes)\n// These require the /u flag on the RegExp — see buildRegexes below.\n//\n// NameChar:\n// 1.1 adds \\u0487 (Combining Cyrillic Millions Sign, added in Unicode 4.0)\n// ---------------------------------------------------------------------------\n\nconst nameStartChar11 =\n ':A-Za-z_' +\n '\\u00C0-\\u02FF' + // merged — 1.0 had three split ranges here\n '\\u0370-\\u037D' +\n '\\u037F-\\u0486\\u0488-\\u1FFF' + // split to exclude \\u0487 (combining mark, never a NameStartChar)\n '\\u200C-\\u200D' +\n '\\u2070-\\u218F' +\n '\\u2C00-\\u2FEF' +\n '\\u3001-\\uD7FF' +\n '\\uF900-\\uFDCF' +\n '\\uFDF0-\\uFFFD' +\n '\\u{10000}-\\u{EFFFF}'; // supplementary planes — REQUIRES /u flag on RegExp\n\nconst nameChar11 =\n nameStartChar11 +\n '\\\\-\\\\.\\\\d' +\n '\\u00B7' +\n '\\u0300-\\u036F' +\n '\\u0487' + // Combining Cyrillic Millions Sign — valid in 1.1, not 1.0\n '\\u203F-\\u2040';\n\n// ---------------------------------------------------------------------------\n// Regex builders\n//\n// XML 1.0 regexes: no flags — BMP only, standard JS regex behaviour.\n// XML 1.1 regexes: /u flag — required for \\u{10000}-\\u{EFFFF} to match actual\n// supplementary code points rather than lone surrogates (which are illegal XML).\n// ---------------------------------------------------------------------------\n\nconst buildRegexes = (startChar, char, flags = '') => {\n const ncStart = startChar.replace(':', '');\n const ncChar = char.replace(':', '');\n const ncNamePat = `[${ncStart}][${ncChar}]*`;\n\n return {\n name: new RegExp(`^[${startChar}][${char}]*$`, flags),\n ncName: new RegExp(`^${ncNamePat}$`, flags),\n qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),\n nmToken: new RegExp(`^[${char}]+$`, flags),\n nmTokens: new RegExp(`^[${char}]+(?:\\\\s+[${char}]+)*$`, flags),\n };\n};\n\nconst regexes10 = buildRegexes(nameStartChar10, nameChar10); // no /u — BMP only\nconst regexes11 = buildRegexes(nameStartChar11, nameChar11, 'u'); // /u — enables \\u{10000}-\\u{EFFFF}\n\n// ---------------------------------------------------------------------------\n// ASCII-only fast path (opt-in, off by default)\n//\n// The XML 1.0 vs 1.1 NameStartChar/NameChar productions differ *only* in\n// their non-ASCII ranges (merged vs split Latin-1 ranges, \\u0487, and\n// supplementary planes). Restricted to ASCII, both versions collapse to the\n// same character classes, so a single regex pair covers both xmlVersion\n// values — no /u flag needed.\n//\n// Rationale: unicode-aware regexes (the /u flag, required for XML 1.1's\n// supplementary-plane range) are measurably slower in V8 than plain\n// non-unicode regexes on the same input, even when the input is pure ASCII.\n// For the common case — HTML/SVG ids, XML tags — names are ASCII, so callers\n// who know this can opt in to skip the unicode-aware matching path entirely.\n// This is a real but *conditional* win: mainly for XML 1.1 input (avoids /u),\n// or at scale where the larger unicode character classes add engine\n// overhead. It also changes behaviour (rejects legitimate non-ASCII XML\n// 1.0/1.1 names), so it must never be silently enabled — hence off by\n// default.\n// ---------------------------------------------------------------------------\n\nconst nameStartCharAscii = ':A-Za-z_';\nconst nameCharAscii = nameStartCharAscii + '\\\\-\\\\.\\\\d';\n\nconst regexesAscii = buildRegexes(nameStartCharAscii, nameCharAscii); // no /u — ASCII only\n\nconst getRegexes = (xmlVersion = '1.0', asciiOnly = false) => {\n if (asciiOnly) return regexesAscii;\n return xmlVersion === '1.1' ? regexes11 : regexes10;\n};\n\n// ---------------------------------------------------------------------------\n// Boolean validators\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if the string is a valid XML Name.\n * Colons are allowed anywhere (Name production).\n * Used for: DOCTYPE entity names, notation names, DTD element declarations.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const name = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).name.test(str);\n\n/**\n * Returns true if the string is a valid NCName (Non-Colonized Name).\n * Colons are not permitted.\n * Used for: namespace prefixes, local names, SVG id attributes.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const ncName = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).ncName.test(str);\n\n/**\n * Returns true if the string is a valid QName (Qualified Name).\n * Allows exactly one colon as a prefix separator: prefix:localName.\n * Used for: element and attribute names in namespace-aware XML/SVG.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const qName = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).qName.test(str);\n\n/**\n * Returns true if the string is a valid NMToken.\n * Like Name but no restriction on the first character.\n * Used for: DTD NMTOKEN attribute values.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const nmToken = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).nmToken.test(str);\n\n/**\n * Returns true if the string is a valid NMTokens value.\n * A whitespace-separated list of NMToken values.\n * Used for: DTD NMTOKENS attribute values.\n *\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * asciiOnly: skip unicode-aware matching, ASCII names only (default false).\n */\nexport const nmTokens = (str, { xmlVersion = '1.0', asciiOnly = false } = {}) =>\n getRegexes(xmlVersion, asciiOnly).nmTokens.test(str);\n\n// ---------------------------------------------------------------------------\n// Memoized validator factory\n//\n// Real documents reuse a small vocabulary of tag/attribute names across many\n// siblings (e.g. `id`, `class`, `href` repeated across hundreds of elements).\n// The plain boolean validators above re-run the regex on every call\n// regardless of repeats. `createValidator` returns a closure with a private\n// string -> boolean cache, so repeated names after the first become O(1)\n// lookups instead of regex tests.\n//\n// - opts (xmlVersion, asciiOnly) are fixed at creation time, so the regex is\n// resolved once, not on every call.\n// - The cache is private to the returned closure — no shared/global state,\n// no cross-caller pollution.\n// - `maxCacheSize` bounds memory: once the cache reaches this many entries,\n// it stops accepting new ones (existing entries keep serving hits; new\n// misses just fall through to the regex, uncached). This avoids unbounded\n// growth against adversarial/high-cardinality input (e.g. validating\n// attacker-supplied names with no repeats) without the cost/complexity of\n// a full LRU, and without the perf cliff of reset-and-refill thrashing.\n// - Call `.reset()` on the returned function to clear the cache manually\n// (e.g. between unrelated parse calls).\n// ---------------------------------------------------------------------------\n\nconst PRODUCTIONS = ['name', 'ncName', 'qName', 'nmToken', 'nmTokens'];\n\n/**\n * Returns a memoized boolean validator function for a single production,\n * with opts fixed at creation time.\n *\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean, maxCacheSize?: number }} [opts]\n * maxCacheSize: max number of distinct strings to cache (default 2048).\n * Once reached, new strings are validated but not cached; existing cached\n * entries keep being served.\n * @returns {((str: string) => boolean) & { reset: () => void }}\n */\nexport const createValidator = (production, { xmlVersion = '1.0', asciiOnly = false, maxCacheSize = 2048 } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const regex = getRegexes(xmlVersion, asciiOnly)[production];\n let cache = new Map();\n\n const validator = (str) => {\n const cached = cache.get(str);\n if (cached !== undefined) return cached;\n\n const result = regex.test(str);\n if (cache.size < maxCacheSize) cache.set(str, result);\n return result;\n };\n\n validator.reset = () => { cache = new Map(); };\n\n return validator;\n};\n\n// ---------------------------------------------------------------------------\n// Diagnostic validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates a string against a named production and returns a detailed result.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * @returns {{ valid: boolean, production: string, input: string, reason?: string, position?: number }}\n */\nexport const validate = (str, production, { xmlVersion = '1.0', asciiOnly = false } = {}) => {\n if (!PRODUCTIONS.includes(production)) {\n throw new TypeError(\n `Unknown production \"${production}\". Must be one of: ${PRODUCTIONS.join(', ')}`\n );\n }\n\n const validators = { name, ncName, qName, nmToken, nmTokens };\n const isValid = validators[production](str, { xmlVersion, asciiOnly });\n\n if (isValid) return { valid: true, production, input: str };\n\n let reason = 'Does not match the production rules';\n let position;\n\n // Diagnostic fallback char checks must mirror the same character set the\n // boolean validator above used, or the reported reason/position could\n // contradict the `valid: false` result (e.g. flagging a char as illegal\n // that the unicode-aware check would have accepted).\n const startCharPattern = asciiOnly ? /^[:A-Za-z_]/ : /^[:A-Za-z_\\u00C0-\\uFFFD]/;\n const namePattern = asciiOnly ? /[\\w\\-\\\\.:]/ : /[\\w\\-\\\\.:\\u00B7\\u00C0-\\uFFFD]/;\n\n if (str.length === 0) {\n reason = 'Input is empty';\n } else if (production === 'ncName' && str.includes(':')) {\n position = str.indexOf(':');\n reason = 'Colon is not allowed in NCName';\n } else if (production === 'qName' && str.startsWith(':')) {\n reason = 'QName cannot start with a colon';\n position = 0;\n } else if (production === 'qName' && str.endsWith(':')) {\n reason = 'QName cannot end with a colon';\n position = str.length - 1;\n } else if (production === 'qName' && (str.match(/:/g) || []).length > 1) {\n reason = 'QName can have at most one colon';\n position = str.lastIndexOf(':');\n } else if (\n ['name', 'ncName', 'qName'].includes(production) &&\n !startCharPattern.test(str[0])\n ) {\n reason = `First character \"${str[0]}\" is not a valid NameStartChar`;\n position = 0;\n } else {\n for (let i = 0; i < str.length; i++) {\n if (!namePattern.test(str[i])) {\n reason = `Character \"${str[i]}\" at position ${i} is not a valid NameChar`;\n position = i;\n break;\n }\n }\n }\n\n return { valid: false, production, input: str, reason, position };\n};\n\n// ---------------------------------------------------------------------------\n// Batch validator\n// ---------------------------------------------------------------------------\n\n/**\n * Validates an array of strings against a named production.\n *\n * @param {string[]} strings\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ xmlVersion?: '1.0'|'1.1', asciiOnly?: boolean }} [opts]\n * @returns {Array<{ valid: boolean, production: string, input: string, reason?: string, position?: number }>}\n */\nexport const validateAll = (strings, production, opts = {}) =>\n strings.map(str => validate(str, production, opts));\n\n// ---------------------------------------------------------------------------\n// Sanitizer\n// ---------------------------------------------------------------------------\n\n/**\n * Transforms an invalid string into the nearest valid XML name for the given production.\n *\n * @param {string} str\n * @param {'name'|'ncName'|'qName'|'nmToken'|'nmTokens'} production\n * @param {{ replacement?: string, asciiOnly?: boolean }} [opts]\n * asciiOnly: also replace any non-ASCII character, not just XML-illegal\n * ones (default false).\n * @returns {string}\n */\nexport const sanitize = (str, production = 'name', { replacement = '_', asciiOnly = false } = {}) => {\n if (!str) return replacement;\n\n let result = str;\n\n // Strip colons for NCName\n if (production === 'ncName') {\n result = result.replace(/:/g, '');\n }\n\n // Replace illegal characters\n const allowedCharPattern = asciiOnly ? /[^\\w\\-\\.:]/g : /[^\\w\\-\\.:\\u00B7\\u00C0-\\uFFFD]/g;\n result = result.replace(allowedCharPattern, replacement);\n\n // Fix invalid start character for Name / NCName / QName\n if (production !== 'nmToken' && production !== 'nmTokens') {\n if (/^[\\-\\.\\d]/.test(result)) {\n result = replacement + result;\n }\n }\n\n return result || replacement;\n};","import { qName as isName } from 'xml-naming';\n\nexport default class DocTypeReader {\n constructor(options, xmlVersion) {\n this.suppressValidationErr = !options;\n this.options = options;\n this.xmlVersion = xmlVersion || 1.0;\n }\n\n setXmlVersion(xmlVersion = 1.0) {\n this.xmlVersion = xmlVersion;\n }\n readDocType(xmlData, i) {\n const entities = Object.create(null);\n let entityCount = 0;\n\n if (xmlData[i + 3] === 'O' &&\n xmlData[i + 4] === 'C' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'Y' &&\n xmlData[i + 7] === 'P' &&\n xmlData[i + 8] === 'E') {\n i = i + 9;\n let angleBracketsCount = 1;\n let hasBody = false, comment = false;\n let quoteChar = null; // tracks an open SYSTEM/PUBLIC literal before the '[' body\n let exp = \"\";\n for (; i < xmlData.length; i++) {\n // Inside a quoted external-identifier literal — XML allows '<'\n // and '>' as plain data here, so they must not be interpreted\n // as DOCTYPE structure until the matching quote closes.\n if (quoteChar !== null) {\n if (xmlData[i] === quoteChar) quoteChar = null;\n exp += xmlData[i];\n continue;\n }\n if (!hasBody && !comment && (xmlData[i] === '\"' || xmlData[i] === \"'\")) {\n quoteChar = xmlData[i];\n exp += xmlData[i];\n continue;\n }\n\n if (xmlData[i] === '<' && !comment) { //Determine the tag type\n if (hasBody && hasSeq(xmlData, \"!ENTITY\", i)) {\n i += 7;\n let entityName, val;\n [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);\n if (val.indexOf(\"&\") === -1) { //Parameter entities are not supported\n if (this.options.enabled !== false &&\n this.options.maxEntityCount != null &&\n entityCount >= this.options.maxEntityCount) {\n throw new Error(\n `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`\n );\n }\n //const escaped = entityName.replace(/[.\\-+*:]/g, '\\\\.');\n //const escaped = entityName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n entities[entityName] = val;\n entityCount++;\n }\n }\n else if (hasBody && hasSeq(xmlData, \"!ELEMENT\", i)) {\n i += 8;//Not supported\n const { index } = this.readElementExp(xmlData, i + 1);\n i = index;\n } else if (hasBody && hasSeq(xmlData, \"!ATTLIST\", i)) {\n i += 8;//Not supported\n // const {index} = this.readAttlistExp(xmlData,i+1);\n // i = index;\n } else if (hasBody && hasSeq(xmlData, \"!NOTATION\", i)) {\n i += 9;//Not supported\n const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);\n i = index;\n } else if (hasSeq(xmlData, \"!--\", i)) comment = true;\n else throw new Error(`Invalid DOCTYPE`);\n\n angleBracketsCount++;\n exp = \"\";\n } else if (xmlData[i] === '>') { //Read tag content\n if (comment) {\n if (xmlData[i - 1] === \"-\" && xmlData[i - 2] === \"-\") {\n comment = false;\n angleBracketsCount--;\n }\n } else {\n angleBracketsCount--;\n }\n if (angleBracketsCount === 0) {\n break;\n }\n } else if (xmlData[i] === '[') {\n hasBody = true;\n } else {\n exp += xmlData[i];\n }\n }\n if (quoteChar !== null || angleBracketsCount !== 0) {\n throw new Error(`Unclosed DOCTYPE`);\n }\n } else {\n throw new Error(`Invalid Tag instead of DOCTYPE`);\n }\n return { entities, i };\n }\n readEntityExp(xmlData, i) {\n //External entities are not supported\n // \n\n //Parameter entities are not supported\n // \n\n //Internal entities are supported\n // \n\n // Skip leading whitespace after this.options.maxEntitySize) {\n throw new Error(\n `Entity \"${entityName}\" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`\n );\n }\n\n i--;\n return [entityName, entityValue, i];\n }\n\n readNotationExp(xmlData, i) {\n // Skip leading whitespace after \n // \n // \n // \n // \n\n // Skip leading whitespace after {\n while (index < data.length && /\\s/.test(data[index])) {\n index++;\n }\n return index;\n};\n\n\n\nfunction hasSeq(data, seq, i) {\n for (let j = 0; j < seq.length; j++) {\n if (seq[j] !== data[i + j + 1]) return false;\n }\n return true;\n}\n\nfunction validateEntityName(name, xmlVersion) {\n if (isName(name, { xmlVersion: xmlVersion }))\n return name;\n else\n throw new Error(`Invalid entity name ${name}`);\n}","/**\n * Flat lookup table: maps Unicode code point → ASCII digit (0-9).\n * Only decimal digit characters (Unicode category Nd) are included.\n *\n * Strategy: Int32Array of size (maxCodePoint - minCodePoint + 1).\n * Value 0xFF means \"not a digit\". Value 0-9 is the ASCII digit value.\n * This gives O(1) lookup with no branching, no bisect, no loop.\n *\n * Memory: range is 0x0660 to 0x1FBF0 → ~129,936 entries × 1 byte = ~127 KB.\n * Acceptable for a one-time init; lookup is a single array index.\n */\n\n// All known Unicode Nd (decimal digit) script zero code points.\n// Each script has exactly 10 consecutive digits: zero+0 .. zero+9.\nconst SCRIPT_ZEROS = [\n // Basic Latin (ASCII) — included for completeness / pass-through\n 0x0030, // 0-9\n\n // Arabic scripts\n 0x0660, // Arabic-Indic ٠١٢٣٤٥٦٧٨٩\n 0x06F0, // Extended Arabic-Indic (Urdu/Persian/Sindhi) ۰۱۲۳\n\n // Indic scripts\n 0x0966, // Devanagari ०१२३४५६७८९\n 0x09E6, // Bengali ০১২৩৪৫৬৭৮৯\n 0x0A66, // Gurmukhi ੦੧੨੩੪੫੬੭੮੯\n 0x0AE6, // Gujarati ૦૧૨૩૪૫૬૭૮૯\n 0x0B66, // Odia ୦୧୨୩୪୫୬୭୮୯\n 0x0BE6, // Tamil ௦௧௨௩௪௫௬௭௮௯\n 0x0C66, // Telugu ౦౧౨౩౪౫౬౭౮౯\n 0x0CE6, // Kannada ೦೧೨೩೪೫೬೭೮೯\n 0x0D66, // Malayalam ൦൧൨൩൪൫൬൭൮൯\n 0x0DE6, // Sinhala Archaic ෦෧෨෩෪෫෬෭෮෯\n\n // Southeast Asian scripts\n 0x0E50, // Thai ๐๑๒๓๔๕๖๗๘๙\n 0x0ED0, // Lao ໐໑໒໓໔໕໖໗໘໙\n 0x0F20, // Tibetan ༠༡༢༣༤༥༦༧༨༩\n 0x1040, // Myanmar ၀၁၂၃၄၅၆၇၈၉\n 0x1090, // Myanmar Shan ႐႑႒႓႔႕႖႗႘႙\n 0x17E0, // Khmer ០១២៣៤៥៦៧៨៩\n 0x1810, // Mongolian ᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙\n 0x1946, // Limbu ᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏\n 0x19D0, // New Tai Lue ᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙\n 0x1A80, // Tai Tham Hora ᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉\n 0x1A90, // Tai Tham Tham ᪐᪑᪒᪓᪔᪕᪖᪗᪘᪙\n 0x1B50, // Balinese ᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙\n 0x1BB0, // Sundanese ᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹\n 0x1C40, // Lepcha ᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉\n 0x1C50, // Ol Chiki ᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙\n\n // Fullwidth (CJK context)\n 0xFF10, // Fullwidth 0123456789\n\n // Mathematical digit variants (Unicode math block)\n 0x1D7CE, // Mathematical Bold\n 0x1D7D8, // Mathematical Double-Struck\n 0x1D7E2, // Mathematical Sans-Serif\n 0x1D7EC, // Mathematical Sans-Serif Bold\n 0x1D7F6, // Mathematical Monospace\n\n // Other scripts\n 0x104A0, // Osmanya 𐒠𐒡𐒢𐒣𐒤𐒥𐒦𐒧𐒨𐒩\n 0x10D30, // Hanifi Rohingya 𐴰𐴱𐴲𐴳𐴴𐴵𐴶𐴷𐴸𐴹\n 0x11066, // Brahmi 𑁦𑁧𑁨𑁩𑁪𑁫𑁬𑁭𑁮𑁯\n 0x110F0, // Sora Sompeng 𑃰𑃱𑃲𑃳𑃴𑃵𑃶𑃷𑃸𑃹\n 0x11136, // Chakma 𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿\n 0x111D0, // Sharada 𑇐𑇑𑇒𑇓𑇔𑇕𑇖𑇗𑇘𑇙\n 0x112F0, // Khudawadi 𑋰𑋱𑋲𑋳𑋴𑋵𑋶𑋷𑋸𑋹\n 0x11450, // Newa 𑑐𑑑𑑒𑑓𑑔𑑕𑑖𑑗𑑘𑑙\n 0x114D0, // Tirhuta 𑓐𑓑𑓒𑓓𑓔𑓕𑓖𑓗𑓘𑓙\n 0x11650, // Modi 𑙐𑙑𑙒𑙓𑙔𑙕𑙖𑙗𑙘𑙙\n 0x116C0, // Takri 𑛀𑛁𑛂𑛃𑛄𑛅𑛆𑛇𑛈𑛉\n 0x11730, // Ahom 𑜰𑜱𑜲𑜳𑜴𑜵𑜶𑜷𑜸𑜹\n 0x118E0, // Warang Citi 𑣠𑣡𑣢𑣣𑣤𑣥𑣦𑣧𑣨𑣩\n 0x11950, // Dives Akuru 𑥐𑥑𑥒𑥓𑥔𑥕𑥖𑥗𑥘𑥙\n 0x11BF0, // Khitan Small Script 𑯰𑯱𑯲𑯳𑯴𑯵𑯶𑯷𑯸𑯹\n 0x11C50, // Bhaiksuki 𑱐𑱑𑱒𑱓𑱔𑱕𑱖𑱗𑱘𑱙\n 0x11D50, // Masaram Gondi 𑵐𑵑𑵒𑵓𑵔𑵕𑵖𑵗𑵘𑵙\n 0x11DA0, // Gunjala Gondi 𑶠𑶡𑶢𑶣𑶤𑶥𑶦𑶧𑶨𑶩\n 0x11F50, // Kawi 𑽐𑽑𑽒𑽓𑽔𑽕𑽖𑽗𑽘𑽙\n 0x16A60, // Mro 𖩠𖩡𖩢𖩣𖩤𖩥𖩦𖩧𖩨𖩩\n 0x16AC0, // Tangsa 𖫀𖫁𖫂𖫃𖫄𖫅𖫆𖫇𖫈𖫉\n 0x16B50, // Pahawh Hmong 𖭐𖭑𖭒𖭓𖭔𖭕𖭖𖭗𖭘𖭙\n 0x1E140, // Nyiakeng Puachue Hmong 𞅀𞅁𞅂𞅃𞅄𞅅𞅆𞅇𞅈𞅉\n 0x1E2F0, // Wancho 𞋰𞋱𞋲𞋳𞋴𞋵𞋶𞋷𞋸𞋹\n 0x1E4F0, // Nag Mundari 𞓰𞓱𞓲𞓳𞓴𞓵𞓶𞓷𞓸𞓹\n 0x1E950, // Adlam 𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘𞥙\n 0x1FBF0, // Segmented digit symbols 🯰🯱🯲🯳🯴🯵🯶🯷🯸🯹\n];\n\n// Build a sparse Map for scripts above 0xFFFF (surrogate-pair range).\n// These can't go into a flat Uint8Array indexed by code point efficiently.\nconst NOT_DIGIT = 0xFF;\nconst HIGH_MAP = new Map(); // codePoint → digit value (0-9)\n\nconst LOW_MAX = 0xFFFF;\nconst LOW_MIN = 0x0660; // first non-ASCII digit script\n\n// Flat Uint8Array covering 0x0660 .. 0xFFFF\nconst TABLE_OFFSET = LOW_MIN;\nconst TABLE_SIZE = LOW_MAX - LOW_MIN + 1;\nconst TABLE = new Uint8Array(TABLE_SIZE).fill(NOT_DIGIT);\n\nfor (const zero of SCRIPT_ZEROS) {\n for (let d = 0; d < 10; d++) {\n const cp = zero + d;\n if (cp <= LOW_MAX) {\n TABLE[cp - TABLE_OFFSET] = d;\n } else {\n HIGH_MAP.set(cp, d);\n }\n }\n}\n\nexport { TABLE, TABLE_OFFSET, HIGH_MAP, NOT_DIGIT };\n","'use strict';\n\nimport { TABLE, TABLE_OFFSET, HIGH_MAP, NOT_DIGIT } from './digitTable.js';\n\nconst CHAR_0 = 48; // '0'.charCodeAt(0)\nconst CHAR_9 = 57; // '9'.charCodeAt(0)\nconst CHAR_MINUS = 45; // '-'.charCodeAt(0)\n\n// Unicode minus/hyphen variants worth normalizing to ASCII '-' in numeric context:\n// U+2212 MINUS SIGN − (mathematically correct minus)\n// U+FF0D FULLWIDTH HYPHEN-MINUS - (Japanese fullwidth context)\n// U+FE63 SMALL HYPHEN-MINUS ﹣ (small form variant)\n//\n// NOT normalized (deliberate):\n// U+2013 EN DASH – (punctuation, not a numeric sign)\n// U+2014 EM DASH — (punctuation)\n// U+2010 HYPHEN ‐ (typographic hyphen)\n//\n// Rationale: only characters a human or locale formatter would plausibly use\n// as a numeric minus sign are normalized. Dashes used for punctuation are left\n// alone to avoid mangling non-numeric strings.\nconst MINUS_SET = new Set([0x2212, 0xFF0D, 0xFE63]);\n\n/**\n * Normalize all Unicode decimal digit characters in a string to ASCII (0-9),\n * and normalize Unicode minus variants to ASCII '-' (U+002D).\n *\n * Non-digit, non-minus characters are passed through unchanged.\n *\n * Performance design:\n * - Fast path: if the string has no convertible characters, return it unchanged\n * (zero allocation).\n * - BMP digits (0x0660..0xFFFF excl. surrogates): flat Uint8Array lookup (O(1)).\n * - Supplementary plane digits (> 0xFFFF, encoded as surrogate pairs): Map lookup.\n * - Minus variants: checked inline with a small fixed Set.\n *\n * @param {string} str\n * @returns {string}\n */\nfunction anynum(str) {\n if (typeof str !== 'string') return str;\n\n const len = str.length;\n if (len === 0) return str;\n\n // Scan for first character needing conversion.\n // If none found, return original string (zero allocation).\n let firstHit = -1;\n\n for (let i = 0; i < len; i++) {\n const cc = str.charCodeAt(i);\n\n // ASCII digit or ASCII minus — already normalized, skip fast\n if ((cc >= CHAR_0 && cc <= CHAR_9) || cc === CHAR_MINUS) continue;\n\n // Below first unicode digit script — check minus variants only\n if (cc < TABLE_OFFSET) {\n if (MINUS_SET.has(cc)) { firstHit = i; break; }\n continue;\n }\n\n // Surrogate pairs live in BMP range 0xD800-0xDFFF — check before TABLE\n if (cc >= 0xD800 && cc <= 0xDBFF) {\n if (i + 1 < len) {\n const low = str.charCodeAt(i + 1);\n if (low >= 0xDC00 && low <= 0xDFFF) {\n const cp = 0x10000 + ((cc - 0xD800) << 10) + (low - 0xDC00);\n if (HIGH_MAP.has(cp)) { firstHit = i; break; }\n }\n }\n continue;\n }\n\n // BMP non-surrogate: flat table lookup; also check minus variants in this range\n if (TABLE[cc - TABLE_OFFSET] !== NOT_DIGIT || MINUS_SET.has(cc)) {\n firstHit = i;\n break;\n }\n }\n\n // Nothing to replace — return original, zero allocation\n if (firstHit === -1) return str;\n\n // Build result: copy unchanged prefix, then convert from firstHit onward\n const chars = [];\n\n if (firstHit > 0) chars.push(str.slice(0, firstHit));\n\n for (let i = firstHit; i < len; i++) {\n const cc = str.charCodeAt(i);\n\n // ASCII digit or ASCII minus — pass through\n if ((cc >= CHAR_0 && cc <= CHAR_9) || cc === CHAR_MINUS) {\n chars.push(str[i]);\n continue;\n }\n\n // Below TABLE_OFFSET — check minus variants, else pass through\n if (cc < TABLE_OFFSET) {\n chars.push(MINUS_SET.has(cc) ? '-' : str[i]);\n continue;\n }\n\n // Surrogate pairs\n if (cc >= 0xD800 && cc <= 0xDBFF) {\n if (i + 1 < len) {\n const low = str.charCodeAt(i + 1);\n if (low >= 0xDC00 && low <= 0xDFFF) {\n const cp = 0x10000 + ((cc - 0xD800) << 10) + (low - 0xDC00);\n const d = HIGH_MAP.get(cp);\n if (d !== undefined) {\n chars.push(String.fromCharCode(d + 48));\n i++; // consume low surrogate\n continue;\n }\n }\n }\n chars.push(str[i]);\n continue;\n }\n\n // BMP non-surrogate: flat table lookup + minus variants\n if (MINUS_SET.has(cc)) {\n chars.push('-');\n continue;\n }\n const d = TABLE[cc - TABLE_OFFSET];\n chars.push(d !== NOT_DIGIT ? String.fromCharCode(d + 48) : str[i]);\n }\n\n return chars.join('');\n}\n\nexport { anynum };\nexport default anynum;","const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;\nconst binRegex = /^0b[01]+$/;\nconst octRegex = /^0o[0-7]+$/;\nconst numRegex = /^([\\-\\+])?(0*)([0-9]*(\\.[0-9]*)?)$/;\n\nimport anynum from \"anynum\";\n\nconst consider = {\n hex: true,\n binary: false,\n octal: false,\n leadingZeros: true,\n decimalPoint: \"\\.\",\n eNotation: true,\n //skipLike: /regex/,\n infinity: \"original\", // \"null\", \"infinity\" (Infinity type), \"string\" (\"Infinity\" (the string literal))\n unicode: false,\n};\n\nexport default function toNumber(str, options = {}) {\n options = Object.assign({}, consider, options);\n if (!str || typeof str !== \"string\") return str;\n\n let trimmedStr = str.trim();\n\n if (trimmedStr.length === 0) return str;\n else if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;\n else if (trimmedStr === \"0\") return 0;\n\n if (options.unicode) {\n trimmedStr = anynum(trimmedStr);\n if (trimmedStr === \"0\") return 0; // re-check after normalization\n }\n if (options.hex && hexRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 16);\n } else if (options.binary && binRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 2);\n } else if (options.octal && octRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 8);\n } else if (!isFinite(trimmedStr)) { //Infinity\n return handleInfinity(str, Number(trimmedStr), options);\n } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation\n return resolveEnotation(str, trimmedStr, options);\n } else {\n //separate negative sign, leading zeros, and rest number\n const match = numRegex.exec(trimmedStr);\n // +00.123 => [ , '+', '00', '.123', ..\n if (match) {\n const sign = match[1] || \"\";\n const leadingZeros = match[2];\n let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros\n const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.\n str[leadingZeros.length + 1] === \".\"\n : str[leadingZeros.length] === \".\";\n\n //trim ending zeros for floating number\n if (!options.leadingZeros //leading zeros are not allowed\n && (leadingZeros.length > 1\n || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {\n // 00, 00.3, +03.24, 03, 03.24\n return str;\n }\n else {//no leading zeros or leading zeros are allowed\n const num = Number(trimmedStr);\n const parsedStr = String(num);\n\n if (num === 0) return num;\n if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation\n if (options.eNotation) return num;\n else return str;\n } else if (trimmedStr.indexOf(\".\") !== -1) { //floating number\n if (parsedStr === \"0\") return num; //0.0\n else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000\n else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;\n else return str;\n }\n\n let n = leadingZeros ? numTrimmedByZeros : trimmedStr;\n if (leadingZeros) {\n // -009 => -9\n return (n === parsedStr) || (sign + n === parsedStr) ? num : str\n } else {\n // +9\n return (n === parsedStr) || (n === sign + parsedStr) ? num : str\n }\n }\n } else { //non-numeric string\n return str;\n }\n }\n}\n\nconst eNotationRegx = /^([-+])?(0*)(\\d*(\\.\\d*)?[eE][-\\+]?\\d+)$/;\nfunction resolveEnotation(str, trimmedStr, options) {\n if (!options.eNotation) return str;\n const notation = trimmedStr.match(eNotationRegx);\n if (notation) {\n let sign = notation[1] || \"\";\n const eChar = notation[3].indexOf(\"e\") === -1 ? \"E\" : \"e\";\n const leadingZeros = notation[2];\n const eAdjacentToLeadingZeros = sign ? // 0E.\n str[leadingZeros.length + 1] === eChar\n : str[leadingZeros.length] === eChar;\n\n if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;\n else if (leadingZeros.length === 1\n && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {\n return Number(trimmedStr);\n } else if (leadingZeros.length > 0) {\n // Has leading zeros — only accept if leadingZeros option allows it\n if (options.leadingZeros && !eAdjacentToLeadingZeros) {\n trimmedStr = (notation[1] || \"\") + notation[3];\n return Number(trimmedStr);\n } else return str;\n } else {\n // No leading zeros — always valid e-notation, parse it\n return Number(trimmedStr);\n }\n } else {\n return str;\n }\n}\n\n/**\n * \n * @param {string} numStr without leading zeros\n * @returns \n */\nfunction trimZeros(numStr) {\n if (numStr && numStr.indexOf(\".\") !== -1) {//float\n //remove ending zeros without the O(n^2) backtracking that /0+$/ hits\n //when the string doesn't end in 0 but has a long internal zero-run\n let end = numStr.length;\n while (end > 0 && numStr.charCodeAt(end - 1) === 48 /* '0' */) end--;\n numStr = numStr.slice(0, end);\n if (numStr === \".\") numStr = \"0\";\n else if (numStr[0] === \".\") numStr = \"0\" + numStr;\n else if (numStr[numStr.length - 1] === \".\") numStr = numStr.substring(0, numStr.length - 1);\n return numStr;\n }\n return numStr;\n}\n\nfunction parse_int(numStr, base) {\n const str = numStr.trim();\n if (base === 2 || base === 8) numStr = str.substring(2);\n\n if (parseInt) return parseInt(numStr, base);\n else if (Number.parseInt) return Number.parseInt(numStr, base);\n else if (window && window.parseInt) return window.parseInt(numStr, base);\n else throw new Error(\"parseInt, Number.parseInt, window.parseInt are not supported\");\n}\n\n/**\n * Handle infinite values based on user option\n * @param {string} str - original input string\n * @param {number} num - parsed number (Infinity or -Infinity)\n * @param {object} options - user options\n * @returns {string|number|null} based on infinity option\n */\nfunction handleInfinity(str, num, options) {\n const isPositive = num === Infinity;\n\n switch (options.infinity.toLowerCase()) {\n case \"null\":\n return null;\n case \"infinity\":\n return num; // Return Infinity or -Infinity\n case \"string\":\n return isPositive ? \"Infinity\" : \"-Infinity\";\n case \"original\":\n default:\n return str; // Return original string like \"1e1000\"\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get the value of a \"kept\" attribute from the nearest ancestor (or\n * current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {*}\n */\n getAnyParentAttr(attrName) {\n return this._matcher.getAnyParentAttr(attrName);\n }\n\n /**\n * Check whether any ancestor (or the current node) kept the given\n * attribute via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAnyParentAttr(attrName) {\n return this._matcher.hasAnyParentAttr(attrName);\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n\n // Kept-attribute stack: only populated when push() is called with options.keep.\n this._keptAttrs = [];\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n * @param {Object|null} [options=null]\n * @param {string[]} [options.keep] - Names of attributes (from attrValues)\n */\n push(tagName, attrValues = null, namespace = null, options = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n let level = this.siblingStacks[currentLevel];\n if (!level) {\n // `counts` tells same-name siblings apart (the \"counter\" — nth \n // among other s). `total` is every child seen at this level so\n // far, kept as a running number instead of re-added from `counts` on\n // every push — a parent with many differently-named children would\n // otherwise cost more per child the more distinct names it has.\n level = { counts: new Map(), total: 0 };\n this.siblingStacks[currentLevel] = level;\n }\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = level.counts.get(siblingKey) || 0;\n\n // Position = total children at this level seen before this one.\n const position = level.total;\n\n // Update sibling count for this tag, and the level's running total.\n level.counts.set(siblingKey, counter + 1);\n level.total++;\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n\n // Depth of the node we just pushed (1-based, matches this.path.length)\n const depth = this.path.length;\n\n // Copy only the requested attributes into the kept-attrs stack. This is\n // the one part of push() whose cost scales with input (O(keep.length))\n // rather than being O(1) — by design, since the caller is explicitly\n // opting in for specific attribute names. No options/keep => zero added\n // cost beyond the two property reads below.\n const keep = options !== null ? options.keep : null;\n if (keep !== null && keep !== undefined && keep.length > 0 && attrValues) {\n for (let i = 0; i < keep.length; i++) {\n const name = keep[i];\n if (attrValues[name] !== undefined) {\n this._keptAttrs.push({ depth, name, value: attrValues[name] });\n }\n }\n }\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n // Drop any kept attributes that belonged to the popped node (or deeper).\n // _keptAttrs is depth-ordered (push only ever appends increasing depths),\n // so this is a backward scan that stops at the first surviving entry —\n // typically O(1) since kept attrs are rare by design.\n const poppedDepth = this.path.length + 1;\n while (\n this._keptAttrs.length > 0 &&\n this._keptAttrs[this._keptAttrs.length - 1].depth >= poppedDepth\n ) {\n this._keptAttrs.pop();\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get the value of a \"kept\" attribute from the nearest ancestor (or\n * current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.\n * Unlike getAttrValue(), this works regardless of how deep the path has\n * gone since the attribute was pushed — but only for attribute names that\n * were explicitly marked with `keep` at push time. Cost is proportional to\n * the number of currently-kept attributes (typically 0-3), not path depth.\n * @param {string} attrName\n * @returns {*} the value, or undefined if no ancestor kept this attribute\n */\n getAnyParentAttr(attrName) {\n const kept = this._keptAttrs;\n for (let i = kept.length - 1; i >= 0; i--) {\n if (kept[i].name === attrName) return kept[i].value;\n }\n return undefined;\n }\n\n /**\n * Check whether any ancestor (or the current node) kept the given\n * attribute via `push(tag, attrs, ns, { keep: [...] })`.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAnyParentAttr(attrName) {\n const kept = this._keptAttrs;\n for (let i = kept.length - 1; i >= 0; i--) {\n if (kept[i].name === attrName) return true;\n }\n return false;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n this._keptAttrs = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(level => level ? { counts: new Map(level.counts), total: level.total } : level),\n keptAttrs: this._keptAttrs.map(entry => ({ ...entry }))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(level => level ? { counts: new Map(level.counts), total: level.total } : level);\n this._keptAttrs = (snapshot.keptAttrs || []).map(entry => ({ ...entry }));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}\n","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","/**\n * ExpressionSet - An indexed collection of Expressions for efficient bulk matching\n *\n * Instead of iterating all expressions on every tag, ExpressionSet pre-indexes\n * them at insertion time by depth and terminal tag name. At match time, only\n * the relevant bucket is evaluated — typically reducing checks from O(E) to O(1)\n * lookup plus O(small bucket) matches.\n *\n * Three buckets are maintained:\n * - `_byDepthAndTag` — exact depth + exact tag name (tightest, used first)\n * - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only)\n * - `_deepWildcards` — expressions containing `..` (cannot be depth-indexed)\n *\n * @example\n * import { Expression, ExpressionSet } from 'fast-xml-tagger';\n *\n * // Build once at config time\n * const stopNodes = new ExpressionSet();\n * stopNodes.add(new Expression('root.users.user'));\n * stopNodes.add(new Expression('root.config.setting'));\n * stopNodes.add(new Expression('..script'));\n *\n * // Query on every tag — hot path\n * if (stopNodes.matchesAny(matcher)) { ... }\n */\nexport default class ExpressionSet {\n constructor() {\n /** @type {Map} depth:tag → expressions */\n this._byDepthAndTag = new Map();\n\n /** @type {Map} depth → wildcard-tag expressions */\n this._wildcardByDepth = new Map();\n\n /** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */\n this._deepWildcards = [];\n\n /** @type {Map} terminalTag → deep wildcard expressions */\n this._deepByTerminalTag = new Map();\n\n /** @type {Set} pattern strings already added — used for deduplication */\n this._patterns = new Set();\n\n /** @type {boolean} whether the set is sealed against further additions */\n this._sealed = false;\n }\n\n /**\n * Add an Expression to the set.\n * Duplicate patterns (same pattern string) are silently ignored.\n *\n * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance\n * @returns {this} for chaining\n * @throws {TypeError} if called after seal()\n *\n * @example\n * set.add(new Expression('root.users.user'));\n * set.add(new Expression('..script'));\n */\n add(expression) {\n if (this._sealed) {\n throw new TypeError(\n 'ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.'\n );\n }\n\n // Deduplicate by pattern string\n if (this._patterns.has(expression.pattern)) return this;\n this._patterns.add(expression.pattern);\n\n if (expression.hasDeepWildcard()) {\n const lastSeg = expression.segments[expression.segments.length - 1];\n if (lastSeg && lastSeg.type !== 'deep-wildcard' && lastSeg.tag !== '*') {\n const tag = lastSeg.tag;\n if (!this._deepByTerminalTag.has(tag)) this._deepByTerminalTag.set(tag, []);\n this._deepByTerminalTag.get(tag).push(expression);\n } else {\n this._deepWildcards.push(expression);\n }\n return this;\n }\n\n const depth = expression.length;\n const lastSeg = expression.segments[expression.segments.length - 1];\n const tag = lastSeg?.tag;\n\n if (!tag || tag === '*') {\n // Can index by depth but not by tag\n if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);\n this._wildcardByDepth.get(depth).push(expression);\n } else {\n // Tightest bucket: depth + tag\n const key = `${depth}:${tag}`;\n if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);\n this._byDepthAndTag.get(key).push(expression);\n }\n\n return this;\n }\n\n /**\n * Add multiple expressions at once.\n *\n * @param {import('./Expression.js').default[]} expressions - Array of Expression instances\n * @returns {this} for chaining\n *\n * @example\n * set.addAll([\n * new Expression('root.users.user'),\n * new Expression('root.config.setting'),\n * ]);\n */\n addAll(expressions) {\n for (const expr of expressions) this.add(expr);\n return this;\n }\n\n /**\n * Check whether a pattern string is already present in the set.\n *\n * @param {import('./Expression.js').default} expression\n * @returns {boolean}\n */\n has(expression) {\n return this._patterns.has(expression.pattern);\n }\n\n /**\n * Number of expressions in the set.\n * @type {number}\n */\n get size() {\n return this._patterns.size;\n }\n\n /**\n * Seal the set against further modifications.\n * Useful to prevent accidental mutations after config is built.\n * Calling add() or addAll() on a sealed set throws a TypeError.\n *\n * @returns {this}\n */\n seal() {\n this._sealed = true;\n return this;\n }\n\n /**\n * Whether the set has been sealed.\n * @type {boolean}\n */\n get isSealed() {\n return this._sealed;\n }\n\n /**\n * Test whether the matcher's current path matches any expression in the set.\n *\n * Evaluation order (cheapest → most expensive):\n * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions\n * 2. Depth-only wildcard bucket — O(1) lookup, rare\n * 3. Deep-wildcard list — always checked, but usually small\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {boolean} true if any expression matches the current path\n *\n * @example\n * if (stopNodes.matchesAny(matcher)) {\n * // handle stop node\n * }\n */\n matchesAny(matcher) {\n return this.findMatch(matcher) !== null;\n }\n /**\n * Find and return the first Expression that matches the matcher's current path.\n *\n * Uses the same evaluation order as matchesAny (cheapest → most expensive):\n * 1. Exact depth + tag bucket\n * 2. Depth-only wildcard bucket\n * 3. Deep-wildcard list\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {import('./Expression.js').default | null} the first matching Expression, or null\n *\n * @example\n * const expr = stopNodes.findMatch(matcher);\n * if (expr) {\n * // access expr.config, expr.pattern, etc.\n * }\n */\n findMatch(matcher) {\n const depth = matcher.getDepth();\n const tag = matcher.getCurrentTag();\n\n // 1. Tightest bucket — most expressions live here\n const exactKey = `${depth}:${tag}`;\n const exactBucket = this._byDepthAndTag.get(exactKey);\n if (exactBucket) {\n for (let i = 0; i < exactBucket.length; i++) {\n if (matcher.matches(exactBucket[i])) return exactBucket[i];\n }\n }\n\n // 2. Depth-matched wildcard-tag expressions\n const wildcardBucket = this._wildcardByDepth.get(depth);\n if (wildcardBucket) {\n for (let i = 0; i < wildcardBucket.length; i++) {\n if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];\n }\n }\n\n // 3. Deep wildcards — indexed by terminal tag, then unindexed fallback\n const deepBucket = this._deepByTerminalTag.get(tag);\n if (deepBucket) {\n for (let i = 0; i < deepBucket.length; i++) {\n if (matcher.matches(deepBucket[i])) return deepBucket[i];\n }\n }\n for (let i = 0; i < this._deepWildcards.length; i++) {\n if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];\n }\n\n return null;\n }\n}\n","// ---------------------------------------------------------------------------\n// Complete HTML5 named entity reference\n// Organized by logical categories for easy maintenance and selective importing\n// ---------------------------------------------------------------------------\n\n/**\n * Basic Latin & Special Characters\n * @type {Record}\n */\nexport const BASIC_LATIN = {\n amp: '&',\n AMP: '&',\n lt: '<',\n LT: '<',\n gt: '>',\n GT: '>',\n quot: '\"',\n QUOT: '\"',\n apos: \"'\",\n lsquo: '‘',\n rsquo: '’',\n ldquo: '“',\n rdquo: '”',\n lsquor: '‚',\n rsquor: '’',\n ldquor: '„',\n bdquo: '„',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n excl: '!',\n quest: '?',\n num: '#',\n dollar: '$',\n percent: '%',\n ast: '*',\n commat: '@',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n sol: '/',\n bsol: '\\\\',\n lbrace: '{',\n rbrace: '}',\n lbrack: '[',\n rbrack: ']',\n lpar: '(',\n rpar: ')',\n nbsp: '\\u00a0',\n iexcl: '¡',\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n COPY: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n REG: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n half: '½',\n frac34: '¾',\n iquest: '¿',\n times: '×',\n div: '÷',\n divide: '÷',\n};\n\n/**\n * Latin Extended & Accented Letters (A-Z)\n * @type {Record}\n */\nexport const LATIN_ACCENTS = {\n Agrave: 'À',\n agrave: 'à',\n Aacute: 'Á',\n aacute: 'á',\n Acirc: 'Â',\n acirc: 'â',\n Atilde: 'Ã',\n atilde: 'ã',\n Auml: 'Ä',\n auml: 'ä',\n Aring: 'Å',\n aring: 'å',\n AElig: 'Æ',\n aelig: 'æ',\n Ccedil: 'Ç',\n ccedil: 'ç',\n Egrave: 'È',\n egrave: 'è',\n Eacute: 'É',\n eacute: 'é',\n Ecirc: 'Ê',\n ecirc: 'ê',\n Euml: 'Ë',\n euml: 'ë',\n Igrave: 'Ì',\n igrave: 'ì',\n Iacute: 'Í',\n iacute: 'í',\n Icirc: 'Î',\n icirc: 'î',\n Iuml: 'Ï',\n iuml: 'ï',\n ETH: 'Ð',\n eth: 'ð',\n Ntilde: 'Ñ',\n ntilde: 'ñ',\n Ograve: 'Ò',\n ograve: 'ò',\n Oacute: 'Ó',\n oacute: 'ó',\n Ocirc: 'Ô',\n ocirc: 'ô',\n Otilde: 'Õ',\n otilde: 'õ',\n Ouml: 'Ö',\n ouml: 'ö',\n Oslash: 'Ø',\n oslash: 'ø',\n Ugrave: 'Ù',\n ugrave: 'ù',\n Uacute: 'Ú',\n uacute: 'ú',\n Ucirc: 'Û',\n ucirc: 'û',\n Uuml: 'Ü',\n uuml: 'ü',\n Yacute: 'Ý',\n yacute: 'ý',\n THORN: 'Þ',\n thorn: 'þ',\n szlig: 'ß',\n yuml: 'ÿ',\n Yuml: 'Ÿ',\n};\n\n/**\n * Latin Extended (Letters with diacritics)\n * @type {Record}\n */\nexport const LATIN_EXTENDED = {\n Amacr: 'Ā',\n amacr: 'ā',\n Abreve: 'Ă',\n abreve: 'ă',\n Aogon: 'Ą',\n aogon: 'ą',\n Cacute: 'Ć',\n cacute: 'ć',\n Ccirc: 'Ĉ',\n ccirc: 'ĉ',\n Cdot: 'Ċ',\n cdot: 'ċ',\n Ccaron: 'Č',\n ccaron: 'č',\n Dcaron: 'Ď',\n dcaron: 'ď',\n Dstrok: 'Đ',\n dstrok: 'đ',\n Emacr: 'Ē',\n emacr: 'ē',\n Ecaron: 'Ě',\n ecaron: 'ě',\n Edot: 'Ė',\n edot: 'ė',\n Eogon: 'Ę',\n eogon: 'ę',\n Gcirc: 'Ĝ',\n gcirc: 'ĝ',\n Gbreve: 'Ğ',\n gbreve: 'ğ',\n Gdot: 'Ġ',\n gdot: 'ġ',\n Gcedil: 'Ģ',\n Hcirc: 'Ĥ',\n hcirc: 'ĥ',\n Hstrok: 'Ħ',\n hstrok: 'ħ',\n Itilde: 'Ĩ',\n itilde: 'ĩ',\n Imacr: 'Ī',\n imacr: 'ī',\n Iogon: 'Į',\n iogon: 'į',\n Idot: 'İ',\n IJlig: 'IJ',\n ijlig: 'ij',\n Jcirc: 'Ĵ',\n jcirc: 'ĵ',\n Kcedil: 'Ķ',\n kcedil: 'ķ',\n kgreen: 'ĸ',\n Lacute: 'Ĺ',\n lacute: 'ĺ',\n Lcedil: 'Ļ',\n lcedil: 'ļ',\n Lcaron: 'Ľ',\n lcaron: 'ľ',\n Lmidot: 'Ŀ',\n lmidot: 'ŀ',\n Lstrok: 'Ł',\n lstrok: 'ł',\n Nacute: 'Ń',\n nacute: 'ń',\n Ncaron: 'Ň',\n ncaron: 'ň',\n Ncedil: 'Ņ',\n ncedil: 'ņ',\n ENG: 'Ŋ',\n eng: 'ŋ',\n Omacr: 'Ō',\n omacr: 'ō',\n Odblac: 'Ő',\n odblac: 'ő',\n OElig: 'Œ',\n oelig: 'œ',\n Racute: 'Ŕ',\n racute: 'ŕ',\n Rcaron: 'Ř',\n rcaron: 'ř',\n Rcedil: 'Ŗ',\n rcedil: 'ŗ',\n Sacute: 'Ś',\n sacute: 'ś',\n Scirc: 'Ŝ',\n scirc: 'ŝ',\n Scedil: 'Ş',\n scedil: 'ş',\n Scaron: 'Š',\n scaron: 'š',\n Tcedil: 'Ţ',\n tcedil: 'ţ',\n Tcaron: 'Ť',\n tcaron: 'ť',\n Tstrok: 'Ŧ',\n tstrok: 'ŧ',\n Utilde: 'Ũ',\n utilde: 'ũ',\n Umacr: 'Ū',\n umacr: 'ū',\n Ubreve: 'Ŭ',\n ubreve: 'ŭ',\n Uring: 'Ů',\n uring: 'ů',\n Udblac: 'Ű',\n udblac: 'ű',\n Uogon: 'Ų',\n uogon: 'ų',\n Wcirc: 'Ŵ',\n wcirc: 'ŵ',\n Ycirc: 'Ŷ',\n ycirc: 'ŷ',\n Zacute: 'Ź',\n zacute: 'ź',\n Zdot: 'Ż',\n zdot: 'ż',\n Zcaron: 'Ž',\n zcaron: 'ž',\n};\n\n/**\n * Greek Letters\n * @type {Record}\n */\nexport const GREEK = {\n Alpha: 'Α',\n alpha: 'α',\n Beta: 'Β',\n beta: 'β',\n Gamma: 'Γ',\n gamma: 'γ',\n Delta: 'Δ',\n delta: 'δ',\n Epsilon: 'Ε',\n epsilon: 'ε',\n epsiv: 'ϵ',\n varepsilon: 'ϵ',\n Zeta: 'Ζ',\n zeta: 'ζ',\n Eta: 'Η',\n eta: 'η',\n Theta: 'Θ',\n theta: 'θ',\n thetasym: 'ϑ',\n vartheta: 'ϑ',\n Iota: 'Ι',\n iota: 'ι',\n Kappa: 'Κ',\n kappa: 'κ',\n kappav: 'ϰ',\n varkappa: 'ϰ',\n Lambda: 'Λ',\n lambda: 'λ',\n Mu: 'Μ',\n mu: 'μ',\n Nu: 'Ν',\n nu: 'ν',\n Xi: 'Ξ',\n xi: 'ξ',\n Omicron: 'Ο',\n omicron: 'ο',\n Pi: 'Π',\n pi: 'π',\n piv: 'ϖ',\n varpi: 'ϖ',\n Rho: 'Ρ',\n rho: 'ρ',\n rhov: 'ϱ',\n varrho: 'ϱ',\n Sigma: 'Σ',\n sigma: 'σ',\n sigmaf: 'ς',\n sigmav: 'ς',\n varsigma: 'ς',\n Tau: 'Τ',\n tau: 'τ',\n Upsilon: 'Υ',\n upsilon: 'υ',\n upsi: 'υ',\n Upsi: 'ϒ',\n upsih: 'ϒ',\n Phi: 'Φ',\n phi: 'φ',\n phiv: 'ϕ',\n varphi: 'ϕ',\n Chi: 'Χ',\n chi: 'χ',\n Psi: 'Ψ',\n psi: 'ψ',\n Omega: 'Ω',\n omega: 'ω',\n ohm: 'Ω',\n Gammad: 'Ϝ',\n gammad: 'ϝ',\n digamma: 'ϝ',\n};\n\n/**\n * Cyrillic Letters\n * @type {Record}\n */\nexport const CYRILLIC = {\n Afr: '𝔄',\n afr: '𝔞',\n Acy: 'А',\n acy: 'а',\n Bcy: 'Б',\n bcy: 'б',\n Vcy: 'В',\n vcy: 'в',\n Gcy: 'Г',\n gcy: 'г',\n Dcy: 'Д',\n dcy: 'д',\n IEcy: 'Е',\n iecy: 'е',\n IOcy: 'Ё',\n iocy: 'ё',\n ZHcy: 'Ж',\n zhcy: 'ж',\n Zcy: 'З',\n zcy: 'з',\n Icy: 'И',\n icy: 'и',\n Jcy: 'Й',\n jcy: 'й',\n Kcy: 'К',\n kcy: 'к',\n Lcy: 'Л',\n lcy: 'л',\n Mcy: 'М',\n mcy: 'м',\n Ncy: 'Н',\n ncy: 'н',\n Ocy: 'О',\n ocy: 'о',\n Pcy: 'П',\n pcy: 'п',\n Rcy: 'Р',\n rcy: 'р',\n Scy: 'С',\n scy: 'с',\n Tcy: 'Т',\n tcy: 'т',\n Ucy: 'У',\n ucy: 'у',\n Fcy: 'Ф',\n fcy: 'ф',\n KHcy: 'Х',\n khcy: 'х',\n TScy: 'Ц',\n tscy: 'ц',\n CHcy: 'Ч',\n chcy: 'ч',\n SHcy: 'Ш',\n shcy: 'ш',\n SHCHcy: 'Щ',\n shchcy: 'щ',\n HARDcy: 'Ъ',\n hardcy: 'ъ',\n Ycy: 'Ы',\n ycy: 'ы',\n SOFTcy: 'Ь',\n softcy: 'ь',\n Ecy: 'Э',\n ecy: 'э',\n YUcy: 'Ю',\n yucy: 'ю',\n YAcy: 'Я',\n yacy: 'я',\n DJcy: 'Ђ',\n djcy: 'ђ',\n GJcy: 'Ѓ',\n gjcy: 'ѓ',\n Jukcy: 'Є',\n jukcy: 'є',\n DScy: 'Ѕ',\n dscy: 'ѕ',\n Iukcy: 'І',\n iukcy: 'і',\n YIcy: 'Ї',\n yicy: 'ї',\n Jsercy: 'Ј',\n jsercy: 'ј',\n LJcy: 'Љ',\n ljcy: 'љ',\n NJcy: 'Њ',\n njcy: 'њ',\n TSHcy: 'Ћ',\n tshcy: 'ћ',\n KJcy: 'Ќ',\n kjcy: 'ќ',\n Ubrcy: 'Ў',\n ubrcy: 'ў',\n DZcy: 'Џ',\n dzcy: 'џ',\n};\n\n/**\n * Mathematical Operators & Relations\n * @type {Record}\n */\nexport const MATH = {\n plus: '+',\n pm: '±',\n times: '×',\n div: '÷',\n divide: '÷',\n sdot: '⋅',\n star: '☆',\n starf: '★',\n bigstar: '★',\n lowast: '∗',\n ast: '*',\n midast: '*',\n compfn: '∘',\n smallcircle: '∘',\n bullet: '•',\n bull: '•',\n nbsp: '\\u00a0',\n hellip: '…',\n mldr: '…',\n prime: '′',\n Prime: '″',\n tprime: '‴',\n bprime: '‵',\n backprime: '‵',\n minus: '−',\n minusd: '∸',\n dotminus: '∸',\n plusdo: '∔',\n dotplus: '∔',\n plusmn: '±',\n minusplus: '∓',\n mnplus: '∓',\n mp: '∓',\n setminus: '∖',\n smallsetminus: '∖',\n Backslash: '∖',\n setmn: '∖',\n ssetmn: '∖',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n VerticalLine: '|',\n colon: ':',\n Colon: '∷',\n Proportion: '∷',\n ratio: '∶',\n equals: '=',\n ne: '≠',\n nequiv: '≢',\n equiv: '≡',\n Congruent: '≡',\n sim: '∼',\n thicksim: '∼',\n thksim: '∼',\n sime: '≃',\n simeq: '≃',\n TildeEqual: '≃',\n asymp: '≈',\n approx: '≈',\n thickapprox: '≈',\n thkap: '≈',\n TildeTilde: '≈',\n ncong: '≇',\n cong: '≅',\n TildeFullEqual: '≅',\n asympeq: '≍',\n CupCap: '≍',\n bump: '≎',\n Bumpeq: '≎',\n HumpDownHump: '≎',\n bumpe: '≏',\n bumpeq: '≏',\n HumpEqual: '≏',\n le: '≤',\n LessEqual: '≤',\n ge: '≥',\n GreaterEqual: '≥',\n lesseqgtr: '⋚',\n lesseqqgtr: '⪋',\n greater: '>',\n less: '<',\n};\n\n/**\n * Mathematical Operators (Advanced)\n * @type {Record}\n */\nexport const MATH_ADVANCED = {\n alefsym: 'ℵ',\n aleph: 'ℵ',\n beth: 'ℶ',\n gimel: 'ℷ',\n daleth: 'ℸ',\n forall: '∀',\n ForAll: '∀',\n part: '∂',\n PartialD: '∂',\n exist: '∃',\n Exists: '∃',\n nexist: '∄',\n nexists: '∄',\n empty: '∅',\n emptyset: '∅',\n emptyv: '∅',\n varnothing: '∅',\n nabla: '∇',\n Del: '∇',\n isin: '∈',\n isinv: '∈',\n in: '∈',\n Element: '∈',\n notin: '∉',\n notinva: '∉',\n ni: '∋',\n niv: '∋',\n SuchThat: '∋',\n ReverseElement: '∋',\n notni: '∌',\n notniva: '∌',\n prod: '∏',\n Product: '∏',\n coprod: '∐',\n Coproduct: '∐',\n sum: '∑',\n Sum: '∑',\n minus: '−',\n mp: '∓',\n plusdo: '∔',\n dotplus: '∔',\n setminus: '∖',\n lowast: '∗',\n radic: '√',\n Sqrt: '√',\n prop: '∝',\n propto: '∝',\n Proportional: '∝',\n varpropto: '∝',\n infin: '∞',\n infintie: '⧝',\n ang: '∠',\n angle: '∠',\n angmsd: '∡',\n measuredangle: '∡',\n angsph: '∢',\n mid: '∣',\n VerticalBar: '∣',\n nmid: '∤',\n nsmid: '∤',\n npar: '∦',\n parallel: '∥',\n spar: '∥',\n nparallel: '∦',\n nspar: '∦',\n and: '∧',\n wedge: '∧',\n or: '∨',\n vee: '∨',\n cap: '∩',\n cup: '∪',\n int: '∫',\n Integral: '∫',\n conint: '∮',\n ContourIntegral: '∮',\n Conint: '∯',\n DoubleContourIntegral: '∯',\n Cconint: '∰',\n there4: '∴',\n therefore: '∴',\n Therefore: '∴',\n becaus: '∵',\n because: '∵',\n Because: '∵',\n ratio: '∶',\n Proportion: '∷',\n minusd: '∸',\n dotminus: '∸',\n mDDot: '∺',\n homtht: '∻',\n sim: '∼',\n bsimg: '∽',\n backsim: '∽',\n ac: '∾',\n mstpos: '∾',\n acd: '∿',\n VerticalTilde: '≀',\n wr: '≀',\n wreath: '≀',\n nsime: '≄',\n nsimeq: '≄',\n ncong: '≇',\n simne: '≆',\n ncongdot: '⩭̸',\n ngsim: '≵',\n nsim: '≁',\n napprox: '≉',\n nap: '≉',\n ngeq: '≱',\n nge: '≱',\n nleq: '≰',\n nle: '≰',\n ngtr: '≯',\n ngt: '≯',\n nless: '≮',\n nlt: '≮',\n nprec: '⊀',\n npr: '⊀',\n nsucc: '⊁',\n nsc: '⊁',\n};\n\n/**\n * Arrows\n * @type {Record}\n */\nexport const ARROWS = {\n larr: '←',\n leftarrow: '←',\n LeftArrow: '←',\n uarr: '↑',\n uparrow: '↑',\n UpArrow: '↑',\n rarr: '→',\n rightarrow: '→',\n RightArrow: '→',\n darr: '↓',\n downarrow: '↓',\n DownArrow: '↓',\n harr: '↔',\n leftrightarrow: '↔',\n LeftRightArrow: '↔',\n varr: '↕',\n updownarrow: '↕',\n UpDownArrow: '↕',\n nwarr: '↖',\n nwarrow: '↖',\n UpperLeftArrow: '↖',\n nearr: '↗',\n nearrow: '↗',\n UpperRightArrow: '↗',\n searr: '↘',\n searrow: '↘',\n LowerRightArrow: '↘',\n swarr: '↙',\n swarrow: '↙',\n LowerLeftArrow: '↙',\n lArr: '⇐',\n Leftarrow: '⇐',\n uArr: '⇑',\n Uparrow: '⇑',\n rArr: '⇒',\n Rightarrow: '⇒',\n dArr: '⇓',\n Downarrow: '⇓',\n hArr: '⇔',\n Leftrightarrow: '⇔',\n iff: '⇔',\n vArr: '⇕',\n Updownarrow: '⇕',\n lAarr: '⇚',\n Lleftarrow: '⇚',\n rAarr: '⇛',\n Rrightarrow: '⇛',\n lrarr: '⇆',\n leftrightarrows: '⇆',\n rlarr: '⇄',\n rightleftarrows: '⇄',\n lrhar: '⇋',\n leftrightharpoons: '⇋',\n ReverseEquilibrium: '⇋',\n rlhar: '⇌',\n rightleftharpoons: '⇌',\n Equilibrium: '⇌',\n udarr: '⇅',\n UpArrowDownArrow: '⇅',\n duarr: '⇵',\n DownArrowUpArrow: '⇵',\n llarr: '⇇',\n leftleftarrows: '⇇',\n rrarr: '⇉',\n rightrightarrows: '⇉',\n ddarr: '⇊',\n downdownarrows: '⇊',\n har: '↽',\n lhard: '↽',\n leftharpoondown: '↽',\n lharu: '↼',\n leftharpoonup: '↼',\n rhard: '⇁',\n rightharpoondown: '⇁',\n rharu: '⇀',\n rightharpoonup: '⇀',\n lsh: '↰',\n Lsh: '↰',\n rsh: '↱',\n Rsh: '↱',\n ldsh: '↲',\n rdsh: '↳',\n hookleftarrow: '↩',\n hookrightarrow: '↪',\n mapstoleft: '↤',\n mapstoup: '↥',\n map: '↦',\n mapsto: '↦',\n mapstodown: '↧',\n crarr: '↵',\n nleftarrow: '↚',\n nleftrightarrow: '↮',\n nrightarrow: '↛',\n nrarr: '↛',\n larrtl: '↢',\n rarrtl: '↣',\n leftarrowtail: '↢',\n rightarrowtail: '↣',\n twoheadleftarrow: '↞',\n twoheadrightarrow: '↠',\n Larr: '↞',\n Rarr: '↠',\n larrhk: '↩',\n rarrhk: '↪',\n larrlp: '↫',\n looparrowleft: '↫',\n rarrlp: '↬',\n looparrowright: '↬',\n harrw: '↭',\n leftrightsquigarrow: '↭',\n nrarrw: '↝̸',\n rarrw: '↝',\n rightsquigarrow: '↝',\n larrbfs: '⤟',\n rarrbfs: '⤠',\n nvHarr: '⤄',\n nvlArr: '⤂',\n nvrArr: '⤃',\n larrfs: '⤝',\n rarrfs: '⤞',\n Map: '⤅',\n larrsim: '⥳',\n rarrsim: '⥴',\n harrcir: '⥈',\n Uarrocir: '⥉',\n lurdshar: '⥊',\n ldrdhar: '⥧',\n ldrushar: '⥋',\n rdldhar: '⥩',\n lrhard: '⥭',\n uharr: '↾',\n uharl: '↿',\n dharr: '⇂',\n dharl: '⇃',\n Uarr: '↟',\n Darr: '↡',\n zigrarr: '⇝',\n nwArr: '⇖',\n neArr: '⇗',\n seArr: '⇘',\n swArr: '⇙',\n nharr: '↮',\n nhArr: '⇎',\n nlarr: '↚',\n nlArr: '⇍',\n nrArr: '⇏',\n larrb: '⇤',\n LeftArrowBar: '⇤',\n rarrb: '⇥',\n RightArrowBar: '⇥',\n};\n\n/**\n * Geometric Shapes\n * @type {Record}\n */\nexport const SHAPES = {\n square: '□',\n Square: '□',\n squ: '□',\n squf: '▪',\n squarf: '▪',\n blacksquar: '▪',\n blacksquare: '▪',\n FilledVerySmallSquare: '▪',\n blk34: '▓',\n blk12: '▒',\n blk14: '░',\n block: '█',\n srect: '▭',\n rect: '▭',\n sdot: '⋅',\n sdotb: '⊡',\n dotsquare: '⊡',\n triangle: '▵',\n tri: '▵',\n trine: '▵',\n utri: '▵',\n triangledown: '▿',\n dtri: '▿',\n tridown: '▿',\n triangleleft: '◃',\n ltri: '◃',\n triangleright: '▹',\n rtri: '▹',\n blacktriangle: '▴',\n utrif: '▴',\n blacktriangledown: '▾',\n dtrif: '▾',\n blacktriangleleft: '◂',\n ltrif: '◂',\n blacktriangleright: '▸',\n rtrif: '▸',\n loz: '◊',\n lozenge: '◊',\n blacklozenge: '⧫',\n lozf: '⧫',\n bigcirc: '◯',\n xcirc: '◯',\n circ: 'ˆ',\n Circle: '○',\n cir: '○',\n o: '○',\n bullet: '•',\n bull: '•',\n hellip: '…',\n mldr: '…',\n nldr: '‥',\n boxh: '─',\n HorizontalLine: '─',\n boxv: '│',\n boxdr: '┌',\n boxdl: '┐',\n boxur: '└',\n boxul: '┘',\n boxvr: '├',\n boxvl: '┤',\n boxhd: '┬',\n boxhu: '┴',\n boxvh: '┼',\n boxH: '═',\n boxV: '║',\n boxdR: '╒',\n boxDr: '╓',\n boxDR: '╔',\n boxDl: '╕',\n boxdL: '╖',\n boxDL: '╗',\n boxuR: '╘',\n boxUr: '╙',\n boxUR: '╚',\n boxUl: '╜',\n boxuL: '╛',\n boxUL: '╝',\n boxvR: '╞',\n boxVr: '╟',\n boxVR: '╠',\n boxVl: '╢',\n boxvL: '╡',\n boxVL: '╣',\n boxHd: '╤',\n boxhD: '╥',\n boxHD: '╦',\n boxHu: '╧',\n boxhU: '╨',\n boxHU: '╩',\n boxvH: '╪',\n boxVh: '╫',\n boxVH: '╬',\n};\n\n/**\n * Punctuation & Diacritics\n * @type {Record}\n */\nexport const PUNCTUATION = {\n excl: '!',\n iexcl: '¡',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n frac34: '¾',\n iquest: '¿',\n nbsp: '\\u00a0',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n vert: '|',\n Verbar: '‖',\n verbar: '|',\n dblac: '˝',\n circ: 'ˆ',\n caron: 'ˇ',\n breve: '˘',\n dot: '˙',\n ring: '˚',\n ogon: '˛',\n tilde: '˜',\n DiacriticalGrave: '`',\n DiacriticalAcute: '´',\n DiacriticalTilde: '˜',\n DiacriticalDot: '˙',\n DiacriticalDoubleAcute: '˝',\n grave: '`',\n};\n\n/**\n * Currency Symbols\n * @type {Record}\n */\nexport const CURRENCY = {\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n euro: '€',\n dollar: '$',\n fnof: 'ƒ',\n inr: '₹',\n af: '؋',\n birr: 'ብር',\n peso: '₱',\n rub: '₽',\n won: '₩',\n yuan: '¥',\n cedil: '¸',\n};\n\n/**\n * Fractions\n * @type {Record}\n */\nexport const FRACTIONS = {\n frac12: '½',\n half: '½',\n frac13: '⅓',\n frac14: '¼',\n frac15: '⅕',\n frac16: '⅙',\n frac18: '⅛',\n frac23: '⅔',\n frac25: '⅖',\n frac34: '¾',\n frac35: '⅗',\n frac38: '⅜',\n frac45: '⅘',\n frac56: '⅚',\n frac58: '⅝',\n frac78: '⅞',\n frasl: '⁄',\n};\n\n/**\n * Miscellaneous Symbols\n * @type {Record}\n */\nexport const MISC_SYMBOLS = {\n trade: '™',\n TRADE: '™',\n telrec: '⌕',\n target: '⌖',\n ulcorn: '⌜',\n ulcorner: '⌜',\n urcorn: '⌝',\n urcorner: '⌝',\n dlcorn: '⌞',\n llcorner: '⌞',\n drcorn: '⌟',\n lrcorner: '⌟',\n intercal: '⊺',\n intcal: '⊺',\n oplus: '⊕',\n CirclePlus: '⊕',\n ominus: '⊖',\n CircleMinus: '⊖',\n otimes: '⊗',\n CircleTimes: '⊗',\n osol: '⊘',\n odot: '⊙',\n CircleDot: '⊙',\n oast: '⊛',\n circledast: '⊛',\n odash: '⊝',\n circleddash: '⊝',\n ocirc: '⊚',\n circledcirc: '⊚',\n boxplus: '⊞',\n plusb: '⊞',\n boxminus: '⊟',\n minusb: '⊟',\n boxtimes: '⊠',\n timesb: '⊠',\n boxdot: '⊡',\n sdotb: '⊡',\n veebar: '⊻',\n vee: '∨',\n barvee: '⊽',\n and: '∧',\n wedge: '∧',\n Cap: '⋒',\n Cup: '⋓',\n Fork: '⋔',\n pitchfork: '⋔',\n epar: '⋕',\n ltlarr: '⥶',\n nvap: '≍⃒',\n nvsim: '∼⃒',\n nvge: '≥⃒',\n nvle: '≤⃒',\n nvlt: '<⃒',\n nvgt: '>⃒',\n nvltrie: '⊴⃒',\n nvrtrie: '⊵⃒',\n Vdash: '⊩',\n dashv: '⊣',\n vDash: '⊨',\n Vvdash: '⊪',\n nvdash: '⊬',\n nvDash: '⊭',\n nVdash: '⊮',\n nVDash: '⊯',\n};\n\nexport const XML = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: \"\\\"\"\n}\nexport const COMMON_HTML = {\n nbsp: '\\u00a0',\n copy: '\\u00a9',\n reg: '\\u00ae',\n trade: '\\u2122',\n mdash: '\\u2014',\n ndash: '\\u2013',\n hellip: '\\u2026',\n laquo: '\\u00ab',\n raquo: '\\u00bb',\n lsquo: '\\u2018',\n rsquo: '\\u2019',\n ldquo: '\\u201c',\n rdquo: '\\u201d',\n bull: '\\u2022',\n para: '\\u00b6',\n sect: '\\u00a7',\n deg: '\\u00b0',\n frac12: '\\u00bd',\n frac14: '\\u00bc',\n frac34: '\\u00be',\n}\n// ---------------------------------------------------------------------------\n// Note: NUMERIC_ENTITIES (&#NNN; / &#xHH;) are handled by the scanner directly\n// via String.fromCodePoint() without any map lookup.\n// ---------------------------------------------------------------------------","// ---------------------------------------------------------------------------\n// Built-in named entity map (name → replacement string)\n// No regex, no {regex,val} objects — just flat key/value pairs.\n// ---------------------------------------------------------------------------\n\nimport { XML as DEFAULT_XML_ENTITIES } from \"./entities.js\"\n\n// ---------------------------------------------------------------------------\n// Entity hook action constants\n// ---------------------------------------------------------------------------\n\n/**\n * Action constants for `onExternalEntity` and `onInputEntity` hooks.\n *\n * Use these instead of raw strings to avoid typos:\n *\n * @example\n * import EntityDecoder, { ENTITY_ACTION } from './EntityDecoder.js';\n * const dec = new EntityDecoder({\n * onInputEntity: (name, value) => ENTITY_ACTION.BLOCK,\n * });\n */\nexport const ENTITY_ACTION = Object.freeze({\n /** Resolve and expand the entity normally. */\n ALLOW: 'allow',\n /** Silently skip this entity — it will not be registered. */\n BLOCK: 'block',\n /** Throw an error, aborting entity registration entirely. */\n THROW: 'throw',\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst SPECIAL_CHARS = new Set('!?\\\\\\\\/[]$%{}^&*()<>|+');\n\n/**\n * Validate that an entity name contains no dangerous characters.\n * @param {string} name\n * @returns {string} the name, unchanged\n * @throws {Error} on invalid characters\n */\nfunction validateEntityName(name) {\n if (name[0] === '#') {\n throw new Error(`[EntityReplacer] Invalid character '#' in entity name: \"${name}\"`);\n }\n for (const ch of name) {\n if (SPECIAL_CHARS.has(ch)) {\n throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: \"${name}\"`);\n }\n }\n return name;\n}\n\n/**\n * Merge one or more entity maps into a flat name→string map.\n * Accepts either:\n * - plain string values: { amp: '&' }\n * - legacy {regex,val} / {regx,val}: { lt: { regex: /.../, val: '<' } }\n *\n * Values containing '&' are skipped (recursive expansion risk).\n *\n * @param {...object} maps\n * @returns {Record}\n */\nfunction mergeEntityMaps(...maps) {\n const out = Object.create(null);\n for (const map of maps) {\n if (!map) continue;\n for (const key of Object.keys(map)) {\n const raw = map[key];\n if (typeof raw === 'string') {\n out[key] = raw;\n } else if (raw && typeof raw === 'object' && raw.val !== undefined) {\n // Legacy {regex,val} or {regx,val} — extract the string val only\n const val = raw.val;\n if (typeof val === 'string') {\n out[key] = val;\n }\n // function vals are not supported in the scanner — skip\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// applyLimitsTo helpers\n// ---------------------------------------------------------------------------\n\nconst LIMIT_TIER_EXTERNAL = 'external'; // input/runtime + persistent external maps\nconst LIMIT_TIER_BASE = 'base'; // DEFAULT_XML_ENTITIES + namedEntities (system) maps\nconst LIMIT_TIER_ALL = 'all'; // every entity regardless of tier\n\n/**\n * Resolve `applyLimitsTo` option into a normalised Set of tier strings.\n * Accepted values: 'external' | 'base' | 'all' | string[]\n * Default: 'external' (only untrusted injected entities are counted).\n * @param {string|string[]|undefined} raw\n * @returns {Set}\n */\nfunction parseLimitTiers(raw) {\n if (!raw || raw === LIMIT_TIER_EXTERNAL) return new Set([LIMIT_TIER_EXTERNAL]);\n if (raw === LIMIT_TIER_ALL) return new Set([LIMIT_TIER_ALL]);\n if (raw === LIMIT_TIER_BASE) return new Set([LIMIT_TIER_BASE]);\n if (Array.isArray(raw)) return new Set(raw);\n return new Set([LIMIT_TIER_EXTERNAL]); // safe default for unrecognised values\n}\n\n// ---------------------------------------------------------------------------\n// NCR (Numeric Character Reference) classification\n// ---------------------------------------------------------------------------\n\n// Severity order — higher number = stricter action.\n// Used to enforce minimum action levels for specific codepoint ranges.\nconst NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 });\n\n// XML 1.0 §2.2: allowed chars are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n// Restricted C0: U+0001–U+001F excluding U+0009, U+000A, U+000D\nconst XML10_ALLOWED_C0 = new Set([0x09, 0x0A, 0x0D]);\n\n/**\n * Parse the `ncr` constructor option into flat, hot-path-friendly fields.\n * @param {object|undefined} ncr\n * @returns {{ xmlVersion: number, onLevel: number, nullLevel: number }}\n */\nfunction parseNCRConfig(ncr) {\n if (!ncr) {\n return { xmlVersion: 1.0, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove };\n }\n const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1.0;\n const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow;\n const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove;\n // 'allow' is not meaningful for null — clamp to at least 'remove'\n const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove);\n return { xmlVersion, onLevel, nullLevel: clampedNull };\n}\n\n// ---------------------------------------------------------------------------\n// EntityReplacer\n// ---------------------------------------------------------------------------\n\n/**\n * Single-pass, zero-regex entity replacer for XML/HTML content.\n *\n * Algorithm: scan the string once for '&', read to ';', resolve via map\n * or direct codepoint conversion, build output chunks, join once at the end.\n *\n * Entity lookup priority (highest → lowest):\n * 1. input / runtime (DOCTYPE entities for current document)\n * 2. persistent external (survive across documents)\n * 3. base named map (DEFAULT_XML_ENTITIES + user-supplied namedEntities)\n *\n * Both input and external resolve as the 'external' tier for limit purposes.\n * Base map entities resolve as the 'base' tier.\n *\n * Numeric / hex references (&#NNN; / &#xHH;) are resolved directly via\n * String.fromCodePoint() — no map needed. They count as 'base' tier.\n *\n * @example\n * const replacer = new EntityReplacer({ namedEntities: COMMON_HTML });\n * replacer.setExternalEntities({ brand: 'Acme' });\n *\n * const instance = replacer.reset();\n * instance.addInputEntities({ version: '1.0' });\n * instance.encode('&brand; v&version; <'); // 'Acme v1.0 <'\n */\nexport default class EntityDecoder {\n /**\n * @param {object} [options]\n * @param {object|null} [options.namedEntities] — extra named entities merged into base map\n * @param {object} [options.limit] — security limits\n * @param {number} [options.limit.maxTotalExpansions=0] — 0 = unlimited\n * @param {number} [options.limit.maxExpandedLength=0] — 0 = unlimited\n * @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external']\n * Which entity tiers count against the security limits:\n * - 'external' (default) — only input/runtime + persistent external entities\n * - 'base' — only DEFAULT_XML_ENTITIES + namedEntities\n * - 'all' — every entity regardless of tier\n * - string[] — explicit combination, e.g. ['external', 'base']\n * @param {((resolved: string, original: string) => string)|null} [options.postCheck=null]\n * @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string)\n * @param {string[]} [options.leave=[]] — entity names to keep as literal (unchanged in output)\n * @param {object} [options.ncr] — Numeric Character Reference controls\n * @param {1.0|1.1} [options.ncr.xmlVersion=1.0]\n * XML version governing which codepoint ranges are restricted:\n * - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited\n * - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is\n * @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow']\n * Base action for numeric references. Severity order: allow < leave < remove < throw.\n * For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove),\n * the effective action is max(onNCR, rangeMinimum).\n * @param {'remove'|'throw'} [options.ncr.nullNCR='remove']\n * Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe.\n * @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onExternalEntity=null]\n * Hook called when an external entity is registered via `setExternalEntities()` or\n * `addExternalEntity()`. Return `ENTITY_ACTION.ALLOW` to accept the entity,\n * `ENTITY_ACTION.BLOCK` to silently skip it, or `ENTITY_ACTION.THROW` to abort with an error.\n * @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onInputEntity=null]\n * Hook called when an input entity is registered via `addInputEntities()`. Return\n * `ENTITY_ACTION.ALLOW` to accept, `ENTITY_ACTION.BLOCK` to silently skip, or\n * `ENTITY_ACTION.THROW` to abort with an error.\n */\n constructor(options = {}) {\n this._limit = options.limit || {};\n this._maxTotalExpansions = this._limit.maxTotalExpansions || 0;\n this._maxExpandedLength = this._limit.maxExpandedLength || 0;\n this._postCheck = typeof options.postCheck === 'function' ? options.postCheck : r => r;\n this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL);\n this._numericAllowed = options.numericAllowed ?? true;\n // Base map: DEFAULT_XML_ENTITIES + user-supplied extras. Immutable after construction.\n this._baseMap = mergeEntityMaps(DEFAULT_XML_ENTITIES, options.namedEntities || null);\n\n // Persistent external entities — survive across documents.\n // Stored as a separate map so reset() never touches them.\n /** @type {Record} */\n this._externalMap = Object.create(null);\n\n // Input / runtime entities — current document only, wiped on reset().\n /** @type {Record} */\n this._inputMap = Object.create(null);\n\n // Per-document counters\n this._totalExpansions = 0;\n this._expandedLength = 0;\n\n // --- New: remove / leave sets ---\n /** @type {Set} */\n this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []);\n /** @type {Set} */\n this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []);\n\n // --- NCR config (parsed into flat fields for hot-path speed) ---\n const ncrCfg = parseNCRConfig(options.ncr);\n this._ncrXmlVersion = ncrCfg.xmlVersion;\n this._ncrOnLevel = ncrCfg.onLevel;\n this._ncrNullLevel = ncrCfg.nullLevel;\n\n // --- Registration hooks ---\n /** @type {((name: string, value: string) => 'allow'|'block'|'throw')|null} */\n this._onExternalEntity = typeof options.onExternalEntity === 'function'\n ? options.onExternalEntity\n : null;\n /** @type {((name: string, value: string) => 'allow'|'block'|'throw')|null} */\n this._onInputEntity = typeof options.onInputEntity === 'function'\n ? options.onInputEntity\n : null;\n }\n\n // -------------------------------------------------------------------------\n // Private: registration hook dispatch\n // -------------------------------------------------------------------------\n\n /**\n * Invoke a registration hook for a single entity name/value pair.\n * Returns true when the entity should be accepted, false when it should be\n * silently skipped (BLOCK), and throws when the hook returns THROW.\n *\n * @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} hook\n * @param {string} name\n * @param {string} value\n * @param {string} context — used in error messages ('external' | 'input')\n * @returns {boolean} true = accept, false = skip\n */\n _applyRegistrationHook(hook, name, value, context) {\n if (!hook) return true; // no hook → always accept\n const action = hook(name, value);\n if (action === ENTITY_ACTION.BLOCK) return false;\n if (action === ENTITY_ACTION.THROW) {\n throw new Error(\n `[EntityDecoder] Registration of ${context} entity \"&${name};\" was rejected by hook`\n );\n }\n return true; // ALLOW or any unknown return value → accept\n }\n\n // -------------------------------------------------------------------------\n // Persistent external entity registration\n // -------------------------------------------------------------------------\n\n /**\n * Replace the full set of persistent external entities.\n * All keys are validated — throws on invalid characters.\n * If `onExternalEntity` is set, it is called once per entry; entries that\n * return `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW`\n * aborts the whole call.\n * @param {Record} map\n */\n setExternalEntities(map) {\n if (map) {\n for (const key of Object.keys(map)) {\n validateEntityName(key);\n }\n }\n if (!this._onExternalEntity) {\n this._externalMap = mergeEntityMaps(map);\n return;\n }\n // Hook present — resolve values first, then filter\n const flat = mergeEntityMaps(map);\n const filtered = Object.create(null);\n for (const [name, value] of Object.entries(flat)) {\n if (this._applyRegistrationHook(this._onExternalEntity, name, value, 'external')) {\n filtered[name] = value;\n }\n }\n this._externalMap = filtered;\n }\n\n /**\n * Add a single persistent external entity.\n * If `onExternalEntity` is set it is called before the entity is stored;\n * `ENTITY_ACTION.BLOCK` silently skips storage, `ENTITY_ACTION.THROW` raises.\n * @param {string} key\n * @param {string} value\n */\n addExternalEntity(key, value) {\n validateEntityName(key);\n if (typeof value === 'string' && value.indexOf('&') === -1) {\n if (this._applyRegistrationHook(this._onExternalEntity, key, value, 'external')) {\n this._externalMap[key] = value;\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Input / runtime entity registration (per document)\n // -------------------------------------------------------------------------\n\n /**\n * Inject DOCTYPE entities for the current document.\n * Also resets per-document expansion counters.\n * If `onInputEntity` is set it is called once per entry; entries returning\n * `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW` aborts.\n * @param {Record} map\n */\n addInputEntities(map) {\n this._totalExpansions = 0;\n this._expandedLength = 0;\n if (!this._onInputEntity) {\n this._inputMap = mergeEntityMaps(map);\n return;\n }\n const flat = mergeEntityMaps(map);\n const filtered = Object.create(null);\n for (const [name, value] of Object.entries(flat)) {\n if (this._applyRegistrationHook(this._onInputEntity, name, value, 'input')) {\n filtered[name] = value;\n }\n }\n this._inputMap = filtered;\n }\n\n // -------------------------------------------------------------------------\n // Per-document reset\n // -------------------------------------------------------------------------\n\n /**\n * Wipe input/runtime entities and reset counters.\n * Call this before processing each new document.\n * @returns {this}\n */\n reset() {\n this._inputMap = Object.create(null);\n this._totalExpansions = 0;\n this._expandedLength = 0;\n return this;\n }\n\n // -------------------------------------------------------------------------\n // XML version (can be set after construction, e.g. once parser reads )\n // -------------------------------------------------------------------------\n\n /**\n * Update the XML version used for NCR classification.\n * Call this as soon as the document's `` declaration is parsed.\n * @param {1.0|1.1|number} version\n */\n setXmlVersion(version) {\n this._ncrXmlVersion = version === 1.1 ? 1.1 : 1.0;\n }\n\n // -------------------------------------------------------------------------\n // Primary API\n // -------------------------------------------------------------------------\n\n /**\n * Replace all entity references in `str` in a single pass.\n *\n * @param {string} str\n * @returns {string}\n */\n decode(str) {\n if (typeof str !== 'string' || str.length === 0) return str;\n //TODO: check if needed\n if (str.indexOf('&') === -1) return str; // fast path — no entities at all\n\n const original = str;\n const chunks = [];\n const len = str.length;\n let last = 0; // start of next unprocessed literal chunk\n let i = 0;\n\n const limitExpansions = this._maxTotalExpansions > 0;\n const limitLength = this._maxExpandedLength > 0;\n const checkLimits = limitExpansions || limitLength;\n\n while (i < len) {\n // Scan forward to next '&'\n if (str.charCodeAt(i) !== 38 /* '&' */) { i++; continue; }\n\n // --- Found '&' at position i ---\n\n // Scan forward to ';'\n let j = i + 1;\n while (j < len && str.charCodeAt(j) !== 59 /* ';' */ && (j - i) <= 32) j++;\n\n if (j >= len || str.charCodeAt(j) !== 59) {\n // No closing ';' within window — treat '&' as literal\n i++;\n continue;\n }\n\n // Raw token between '&' and ';' (exclusive)\n const token = str.slice(i + 1, j);\n if (token.length === 0) { i++; continue; }\n\n let replacement;\n let tier; // which limit tier this entity belongs to\n\n if (this._removeSet.has(token)) {\n // Remove entity: replace with empty string\n replacement = '';\n // If entity was unknown (replacement undefined), we still need a tier for limits.\n // Treat as external tier because it's user-directed removal of an unknown reference.\n if (tier === undefined) {\n tier = LIMIT_TIER_EXTERNAL;\n }\n } else if (this._leaveSet.has(token)) {\n // Do not replace — keep original &token; as literal\n i++;\n continue;\n } else if (token.charCodeAt(0) === 35 /* '#' */) {\n // ---- Numeric / NCR reference ----\n // NCR classification always runs first — prohibited codepoints must be\n // caught regardless of numericAllowed.\n const ncrResult = this._resolveNCR(token);\n if (ncrResult === undefined) {\n // 'leave' action — keep original &token; as-is\n i++;\n continue;\n }\n replacement = ncrResult; // '' for remove, char string for allow\n tier = LIMIT_TIER_BASE;\n } else {\n // ---- Named reference ----\n const resolved = this._resolveName(token);\n replacement = resolved?.value;\n tier = resolved?.tier;\n }\n\n if (replacement === undefined) {\n // Unknown entity — leave as-is, advance past '&' only\n i++;\n continue;\n }\n\n // Flush literal chunk before this entity\n if (i > last) chunks.push(str.slice(last, i));\n chunks.push(replacement);\n last = j + 1; // skip past ';'\n i = last;\n\n // Apply expansion limits only if this tier is being tracked\n if (checkLimits && this._tierCounts(tier)) {\n if (limitExpansions) {\n this._totalExpansions++;\n if (this._totalExpansions > this._maxTotalExpansions) {\n throw new Error(\n `[EntityReplacer] Entity expansion count limit exceeded: ` +\n `${this._totalExpansions} > ${this._maxTotalExpansions}`\n );\n }\n }\n if (limitLength) {\n // delta: replacement.length minus the raw &token; length (token.length + 2 for '&' and ';')\n const delta = replacement.length - (token.length + 2);\n if (delta > 0) {\n this._expandedLength += delta;\n if (this._expandedLength > this._maxExpandedLength) {\n throw new Error(\n `[EntityReplacer] Expanded content length limit exceeded: ` +\n `${this._expandedLength} > ${this._maxExpandedLength}`\n );\n }\n }\n }\n }\n }\n\n // Flush trailing literal\n if (last < len) chunks.push(str.slice(last));\n\n // If nothing was replaced, chunks is empty — return original\n const result = chunks.length === 0 ? str : chunks.join('');\n\n return this._postCheck(result, original);\n }\n\n // -------------------------------------------------------------------------\n // Private: limit tier check\n // -------------------------------------------------------------------------\n\n /**\n * Returns true if a resolved entity of the given tier should count\n * against the expansion/length limits.\n * @param {string} tier — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE\n * @returns {boolean}\n */\n _tierCounts(tier) {\n if (this._limitTiers.has(LIMIT_TIER_ALL)) return true;\n return this._limitTiers.has(tier);\n }\n\n // -------------------------------------------------------------------------\n // Private: entity resolution\n // -------------------------------------------------------------------------\n\n /**\n * Resolve a named entity token (without & and ;).\n * Priority: inputMap > externalMap > baseMap\n * Returns the resolved value tagged with its limit tier.\n *\n * @param {string} name\n * @returns {{ value: string, tier: string }|undefined}\n */\n _resolveName(name) {\n // input and external both count as 'external' tier for limit purposes —\n // they are injected at runtime and are the untrusted surface.\n if (name in this._inputMap) return { value: this._inputMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._externalMap) return { value: this._externalMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._baseMap) return { value: this._baseMap[name], tier: LIMIT_TIER_BASE };\n return undefined;\n }\n\n /**\n * Classify a codepoint and return the minimum action level that must be applied.\n * Returns -1 when no minimum is imposed (normal allow path).\n *\n * Ranges checked (in priority order):\n * 1. U+0000 — null, governed by nullNCR (always ≥ remove)\n * 2. U+D800–U+DFFF — surrogates, always prohibited (min: remove)\n * 3. U+0001–U+001F \\ {0x09,0x0A,0x0D} — XML 1.0 restricted C0 (min: remove)\n * (skipped in XML 1.1 — C0 controls are allowed when written as NCRs)\n *\n * @param {number} cp — codepoint\n * @returns {number} — minimum NCR_LEVEL value, or -1 for no restriction\n */\n _classifyNCR(cp) {\n // 1. Null\n if (cp === 0) return this._ncrNullLevel;\n\n // 2. Surrogates — always prohibited, minimum 'remove'\n if (cp >= 0xD800 && cp <= 0xDFFF) return NCR_LEVEL.remove;\n\n // 3. XML 1.0 restricted C0 controls\n if (this._ncrXmlVersion === 1.0) {\n if (cp >= 0x01 && cp <= 0x1F && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove;\n }\n\n return -1; // no restriction\n }\n\n /**\n * Execute a resolved NCR action.\n *\n * @param {number} action — NCR_LEVEL value\n * @param {string} token — raw token (e.g. '#38') for error messages\n * @param {number} cp — codepoint, used only for error messages\n * @returns {string|undefined}\n * - decoded character string → 'allow'\n * - '' → 'remove'\n * - undefined → 'leave' (caller must skip past '&' only)\n * - throws Error → 'throw'\n */\n _applyNCRAction(action, token, cp) {\n switch (action) {\n case NCR_LEVEL.allow: return String.fromCodePoint(cp);\n case NCR_LEVEL.remove: return '';\n case NCR_LEVEL.leave: return undefined; // signal: keep literal\n case NCR_LEVEL.throw:\n throw new Error(\n `[EntityDecoder] Prohibited numeric character reference ` +\n `&${token}; (U+${cp.toString(16).toUpperCase().padStart(4, '0')})`\n );\n default: return String.fromCodePoint(cp);\n }\n }\n\n /**\n * Full NCR resolution pipeline for a numeric token.\n *\n * Steps:\n * 1. Parse the codepoint (decimal or hex).\n * 2. Validate the raw codepoint range (NaN, <0, >0x10FFFF).\n * 3. If numericAllowed is false and no minimum restriction applies → leave as-is.\n * 4. Classify the codepoint to find the minimum required action level.\n * 5. Resolve effective action = max(onNCR, minimum).\n * 6. Apply and return.\n *\n * @param {string} token — e.g. '#38', '#x26', '#X26'\n * @returns {string|undefined}\n * - string (incl. '') — replacement ('' = remove)\n * - undefined — leave original &token; as-is\n */\n _resolveNCR(token) {\n // Step 1: parse codepoint\n const second = token.charCodeAt(1);\n let cp;\n if (second === 120 /* x */ || second === 88 /* X */) {\n cp = parseInt(token.slice(2), 16);\n } else {\n cp = parseInt(token.slice(1), 10);\n }\n\n // Step 2: out-of-range → leave as-is unconditionally\n if (Number.isNaN(cp) || cp < 0 || cp > 0x10FFFF) return undefined;\n\n // Step 3: classify to get minimum action level\n const minimum = this._classifyNCR(cp);\n\n // Step 4: if numericAllowed is false and no hard minimum → leave\n if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return undefined;\n\n // Step 5: effective action = max(configured onNCR, range minimum)\n const effective = minimum === -1\n ? this._ncrOnLevel\n : Math.max(this._ncrOnLevel, minimum);\n\n // Step 6: apply\n return this._applyNCRAction(effective, token, cp);\n }\n}","/**\n * SQL context patterns — high-precision rules only.\n *\n * These rules have very low false-positive risk and are safe to apply to\n * general user text (names, descriptions, search queries, etc.).\n * All patterns are ReDoS-safe — unlike the `sql-injection` npm package\n * which has an active CVE on its own detection regexes.\n *\n * For exhaustive coverage including noisier heuristics (comment sequences,\n * hex literals, stacked queries with semicolons), use 'SQL-STRICT' instead.\n * Apply 'SQL-STRICT' only to strings that are specifically SQL fragments,\n * not to general free-text fields.\n */\n\nconst SQL_PATTERNS = [\n {\n id: 'sql-block-comment-open',\n description: 'SQL block comment open: /* ... */ — unusual in legitimate user text',\n pattern: /\\/\\*/,\n },\n {\n id: 'sql-union-select',\n description: 'UNION SELECT — most common SQL injection aggregation attack',\n pattern: /\\bUNION\\s{1,20}(?:ALL\\s{1,20})?SELECT\\b/i,\n },\n {\n id: 'sql-drop-table',\n description: 'DROP TABLE — destructive DDL injection',\n pattern: /\\bDROP\\s{1,20}TABLE\\b/i,\n },\n {\n id: 'sql-drop-database',\n description: 'DROP DATABASE — destructive DDL injection',\n pattern: /\\bDROP\\s{1,20}DATABASE\\b/i,\n },\n {\n id: 'sql-insert-into',\n description: 'INSERT INTO — data injection',\n pattern: /\\bINSERT\\s{1,20}INTO\\b/i,\n },\n {\n id: 'sql-delete-from',\n description: 'DELETE FROM — data deletion injection',\n pattern: /\\bDELETE\\s{1,20}FROM\\b/i,\n },\n {\n id: 'sql-update-set',\n description: 'UPDATE ... SET — data modification injection',\n // Allows arbitrary content between UPDATE and SET (table name, alias, etc.)\n pattern: /\\bUPDATE\\b[\\s\\S]{1,60}\\bSET\\b/i,\n },\n {\n id: 'sql-exec-xp',\n description: 'EXEC xp_ — MSSQL extended stored procedure execution',\n pattern: /\\bEXEC(?:UTE)?\\s{1,20}xp_/i,\n },\n {\n id: 'sql-tautology-string',\n description: \"Classic string tautology: ' OR '1'='1 or \\\" OR \\\"1\\\"=\\\"1\\\"\",\n // Last quote is optional — injection may truncate it: ' OR '1'='1--\n pattern: /'\\s{0,10}OR\\s{0,10}'[^']{0,20}'\\s*=\\s*'[^']{0,20}/i,\n },\n {\n id: 'sql-tautology-numeric',\n description: 'Numeric tautology: OR 1=1',\n pattern: /\\bOR\\s{1,10}1\\s*=\\s*1\\b/i,\n },\n {\n id: 'sql-always-true-zero',\n description: 'Numeric tautology: OR 0=0',\n pattern: /\\bOR\\s{1,10}0\\s*=\\s*0\\b/i,\n },\n {\n id: 'sql-sleep-benchmark',\n description: 'Time-based blind injection: SLEEP() or BENCHMARK()',\n pattern: /\\b(?:SLEEP|BENCHMARK)\\s*\\(/i,\n },\n {\n id: 'sql-waitfor-delay',\n description: 'MSSQL time-based blind injection: WAITFOR DELAY',\n pattern: /\\bWAITFOR\\s{1,20}DELAY\\b/i,\n },\n {\n id: 'sql-char-function',\n description: 'CHAR() function — used to obfuscate injected strings',\n pattern: /\\bCHAR\\s*\\(\\s*\\d{1,3}/i,\n },\n {\n id: 'sql-information-schema',\n description: 'INFORMATION_SCHEMA — reconnaissance query for table/column enumeration',\n pattern: /\\bINFORMATION_SCHEMA\\b/i,\n },\n];\n\nexport default SQL_PATTERNS;\n","/**\n * SQL-STRICT context patterns.\n *\n * Extends the base 'SQL' context with three additional rules that are\n * effective at detecting real injections but carry a higher false-positive\n * risk on general free-text input.\n *\n * Use 'SQL-STRICT' when:\n * - The string is specifically a SQL fragment or database identifier\n * - You control the input domain (e.g. a dedicated SQL search field)\n * - You can tolerate occasional false positives in exchange for broader coverage\n *\n * Use 'SQL' (not STRICT) when:\n * - The field is general user text (names, descriptions, comments)\n * - False positives would block legitimate content (e.g. \"see note -- above\")\n *\n * Rules moved here from 'SQL' due to false-positive risk:\n *\n * sql-line-comment — \"--\" fires on \"see note -- above\", \"value--\", CSS var(--primary)\n * sql-stacked-query — \"; SELECT\" fires on legitimate prose with semicolons + SQL words\n * sql-hex-encoding — \"0xDEAD\" fires on hex values in technical docs and log output\n */\n\nimport SQL_PATTERNS from './sql.js';\n\nconst SQL_STRICT_EXTRA = [\n {\n id: 'sql-line-comment',\n description: 'SQL line comment: -- followed by whitespace or end of string',\n pattern: /--(?:\\s|$)/,\n },\n {\n id: 'sql-stacked-query',\n description: 'Stacked queries: semicolon immediately followed by a SQL keyword',\n pattern: /;\\s{0,10}(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|EXEC)\\b/i,\n },\n {\n id: 'sql-hex-encoding',\n description: 'Hex-encoded string injection: 0x41414141 style (MySQL)',\n pattern: /\\b0x[0-9a-f]{4,}/i,\n },\n];\n\n// SQL-STRICT = all base SQL rules + the three noisy extras\nconst SQL_STRICT_PATTERNS = [...SQL_PATTERNS, ...SQL_STRICT_EXTRA];\n\nexport default SQL_STRICT_PATTERNS;\n","/**\n * HTML context patterns.\n *\n * Detects XSS vectors that are dangerous when a string ends up rendered as HTML.\n * All patterns use bounded quantifiers to ensure linear-time matching (ReDoS-safe).\n *\n * Each entry is { pattern: RegExp, id: string, description: string }\n * so callers can inspect which rule fired if they need to.\n */\n\nconst HTML_PATTERNS = [\n {\n id: 'html-script-open',\n description: ']/i,\n },\n {\n id: 'html-javascript-protocol',\n description: 'javascript: URI scheme (with optional whitespace/encoding)',\n // Handles javascript:, j\\u0061vascript:, and whitespace variants\n pattern: /j[\\t\\n\\r ]*a[\\t\\n\\r ]*v[\\t\\n\\r ]*a[\\t\\n\\r ]*s[\\t\\n\\r ]*c[\\t\\n\\r ]*r[\\t\\n\\r ]*i[\\t\\n\\r ]*p[\\t\\n\\r ]*t[\\t\\n\\r ]*:/i,\n },\n {\n id: 'html-vbscript-protocol',\n description: 'vbscript: URI scheme',\n pattern: /vbscript[\\t\\n\\r ]*:/i,\n },\n {\n id: 'html-data-html',\n description: 'data:text/html URI — can execute scripts in browsers',\n pattern: /data[\\t\\n\\r ]*:[\\t\\n\\r ]*text\\/html/i,\n },\n {\n id: 'html-data-xhtml',\n description: 'data:application/xhtml+xml URI',\n pattern: /data[\\t\\n\\r ]*:[\\t\\n\\r ]*application\\/xhtml/i,\n },\n {\n id: 'html-data-svg',\n description: 'data:image/svg+xml URI — can execute scripts',\n pattern: /data[\\t\\n\\r ]*:[\\t\\n\\r ]*image\\/svg\\+xml/i,\n },\n {\n id: 'html-inline-event-handler',\n description: 'Inline event handler attributes: onclick=, onerror=, onload=, etc.',\n // \\bon ensures we match a word boundary so \"phonetic=\" is not caught\n pattern: /\\bon\\w{1,30}\\s*=/i,\n },\n {\n id: 'html-entity-obfuscated-script',\n description: 'HTML-entity-encoded ', HTML) // true\n * isUnsafe('hello world', HTML) // false\n * isUnsafe('value', [HTML, SQL]) // false\n * isUnsafe('value', /my-pattern/i) // false\n */\nfunction isUnsafe(value, context) {\n assertString(value);\n assertContext(context);\n\n const { lists, regex } = normalise(context);\n\n if (regex) return regex.test(value);\n\n for (const list of lists) {\n if (matchList(value, list) !== null) return true;\n }\n return false;\n}\n\n/**\n * Like `isUnsafe`, but returns the first `MatchResult` describing **why**\n * the value was flagged, or `null` if it is safe.\n *\n * @param {string} value\n * @param {PatternList | PatternList[] | RegExp} context\n * @returns {MatchResult|null}\n *\n * @example\n * import { whyUnsafe, HTML } from 'is-unsafe';\n *\n * whyUnsafe('', HTML)\n * // { context: 'HTML', id: 'html-script-open', description: '...', pattern: /.../ }\n */\nfunction whyUnsafe(value, context) {\n assertString(value);\n assertContext(context);\n\n const { lists, regex } = normalise(context);\n\n if (regex) {\n return regex.test(value)\n ? { context: 'CUSTOM', id: 'custom-regex', description: 'Matched caller-supplied pattern', pattern: regex }\n : null;\n }\n\n for (const list of lists) {\n const result = matchList(value, list);\n if (result !== null) return result;\n }\n return null;\n}\n\n/**\n * Returns **all** matching rules across the given context(s), or an empty\n * array if the value is safe. Useful for comprehensive auditing.\n *\n * @param {string} value\n * @param {PatternList | PatternList[] | RegExp} context\n * @returns {MatchResult[]}\n */\nfunction allUnsafe(value, context) {\n assertString(value);\n assertContext(context);\n\n const { lists, regex } = normalise(context);\n const results = [];\n\n if (regex) {\n if (regex.test(value)) {\n results.push({ context: 'CUSTOM', id: 'custom-regex', description: 'Matched caller-supplied pattern', pattern: regex });\n }\n return results;\n }\n\n for (const list of lists) {\n const label = list.label ?? 'CUSTOM';\n for (const rule of list) {\n if (rule.pattern.test(value)) {\n results.push({ context: label, id: rule.id, description: rule.description, pattern: rule.pattern });\n }\n }\n }\n\n return results;\n}\n\nexport { isUnsafe, whyUnsafe, allUnsafe };\nexport default isUnsafe;\n","'use strict';\n///@ts-check\n\nimport { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';\nimport xmlNode from './xmlNode.js';\nimport DocTypeReader from './DocTypeReader.js';\nimport toNumber from \"strnum\";\nimport getIgnoreAttributesFn from \"../ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\nimport { ExpressionSet } from 'path-expression-matcher';\nimport { EntityDecoder, XML, CURRENCY, COMMON_HTML, ENTITY_ACTION } from '@nodable/entities';\nimport { isUnsafe, HTML as HTML_CONTEXT, XML as XML_CONTEXT } from \"is-unsafe\"\n\n\n// const regx =\n// '<((!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\\\/)(NAME)\\\\s*>))([^<]*)'\n// .replace(/NAME/g, util.nameRegexp);\n\n//const tagsRegx = new RegExp(\"<(\\\\/?[\\\\w:\\\\-\\._]+)([^>]*)>(\\\\s*\"+cdataRegx+\")*([^<]+)?\",\"g\");\n//const tagsRegx = new RegExp(\"<(\\\\/?)((\\\\w*:)?([\\\\w:\\\\-\\._]+))([^>]*)>([^<]*)(\"+cdataRegx+\"([^<]*))*([^<]+)?\",\"g\");\n\n// Helper functions for attribute and namespace handling\n\n/**\n * Extract raw attributes (without prefix) from prefixed attribute map\n * @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap\n * @param {object} options - Parser options containing attributeNamePrefix\n * @returns {object} Raw attributes for matcher\n */\nfunction extractRawAttributes(prefixedAttrs, options) {\n if (!prefixedAttrs) return {};\n\n // Handle attributesGroupName option\n const attrs = options.attributesGroupName\n ? prefixedAttrs[options.attributesGroupName]\n : prefixedAttrs;\n\n if (!attrs) return {};\n\n const rawAttrs = {};\n for (const key in attrs) {\n // Remove the attribute prefix to get raw name\n if (key.startsWith(options.attributeNamePrefix)) {\n const rawName = key.substring(options.attributeNamePrefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * Extract namespace from raw tag name\n * @param {string} rawTagName - Tag name possibly with namespace (e.g., \"soap:Envelope\")\n * @returns {string|undefined} Namespace or undefined\n */\nfunction extractNamespace(rawTagName) {\n if (!rawTagName || typeof rawTagName !== 'string') return undefined;\n\n const colonIndex = rawTagName.indexOf(':');\n if (colonIndex !== -1 && colonIndex > 0) {\n const ns = rawTagName.substring(0, colonIndex);\n // Don't treat xmlns as a namespace\n if (ns !== 'xmlns') {\n return ns;\n }\n }\n return undefined;\n}\n\nexport default class OrderedObjParser {\n constructor(options, externalEntities) {\n this.options = options;\n this.currentNode = null;\n this.tagsNodeStack = [];\n this.parseXml = parseXml;\n this.parseTextData = parseTextData;\n this.resolveNameSpace = resolveNameSpace;\n this.buildAttributesMap = buildAttributesMap;\n this.isItStopNode = isItStopNode;\n this.replaceEntitiesValue = replaceEntitiesValue;\n this.readStopNodeData = readStopNodeData;\n this.saveTextToParentTag = saveTextToParentTag;\n this.addChild = addChild;\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n this.doctypefound = false;\n let namedEntities = { ...XML };\n if (this.options.entityDecoder) {\n this.entityDecoder = this.options.entityDecoder\n } else {\n if (typeof this.options.htmlEntities === \"object\") namedEntities = this.options.htmlEntities;\n else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };\n this.entityDecoder = new EntityDecoder({\n namedEntities: { ...namedEntities, ...externalEntities },\n numericAllowed: this.options.htmlEntities,\n limit: {\n maxTotalExpansions: this.options.processEntities.maxTotalExpansions,\n maxExpandedLength: this.options.processEntities.maxExpandedLength,\n applyLimitsTo: this.options.processEntities.appliesTo,\n },\n // onExternalEntity: (name, value) => isUnsafe(value) ? 'block' : 'allow',\n onInputEntity: (name, value) =>\n //TODO: VALID_CONTEXTS.HTML should be set only if this.options.htmlEntities\n isUnsafe(value, [HTML_CONTEXT, XML_CONTEXT]) ? ENTITY_ACTION.BLOCK : ENTITY_ACTION.ALLOW,\n\n //postCheck: resolved => resolved\n });\n }\n\n // Initialize path matcher for path-expression-matcher\n this.matcher = new Matcher();\n this.readonlyMatcher = this.matcher.readOnly();\n\n // Flag to track if current node is a stop node (optimization)\n this.isCurrentNodeStopNode = false;\n\n // Pre-compile stopNodes expressions\n this.stopNodeExpressionsSet = new ExpressionSet();\n const stopNodesOpts = this.options.stopNodes;\n if (stopNodesOpts && stopNodesOpts.length > 0) {\n for (let i = 0; i < stopNodesOpts.length; i++) {\n const stopNodeExp = stopNodesOpts[i];\n if (typeof stopNodeExp === 'string') {\n // Convert string to Expression object\n this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));\n } else if (stopNodeExp instanceof Expression) {\n // Already an Expression object\n this.stopNodeExpressionsSet.add(stopNodeExp);\n }\n }\n this.stopNodeExpressionsSet.seal();\n }\n }\n\n}\n\n\n/**\n * @param {string} val\n * @param {string} tagName\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n * @param {boolean} dontTrim\n * @param {boolean} hasAttributes\n * @param {boolean} isLeafNode\n * @param {boolean} escapeEntities\n */\nfunction parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {\n const options = this.options;\n if (val !== undefined) {\n if (options.trimValues && !dontTrim) {\n val = val.trim();\n }\n if (val.length > 0) {\n if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;\n const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);\n if (newval === null || newval === undefined) {\n //don't parse\n return val;\n } else if (typeof newval !== typeof val || newval !== val) {\n //overwrite\n return newval;\n } else if (options.trimValues) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n const trimmedVal = val.trim();\n if (trimmedVal === val) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n return val;\n }\n }\n }\n }\n}\n\nfunction resolveNameSpace(tagname) {\n if (this.options.removeNSPrefix) {\n const tags = tagname.split(':');\n const prefix = tagname.charAt(0) === '/' ? '/' : '';\n if (tags[0] === 'xmlns') {\n return '';\n }\n if (tags.length === 2) {\n tagname = prefix + tags[1];\n }\n }\n return tagname;\n}\n\n//TODO: change regex to capture NS\n//const attrsRegx = new RegExp(\"([\\\\w\\\\-\\\\.\\\\:]+)\\\\s*=\\\\s*(['\\\"])((.|\\n)*?)\\\\2\",\"gm\");\nconst attrsRegx = new RegExp('([^\\\\s=]+)\\\\s*(=\\\\s*([\\'\"])([\\\\s\\\\S]*?)\\\\3)?', 'gm');\n\nfunction buildAttributesMap(attrStr, jPath, tagName, force = false) {\n const options = this.options;\n if (force === true || (options.ignoreAttributes !== true && typeof attrStr === 'string')) {\n // attrStr = attrStr.replace(/\\r?\\n/g, ' ');\n //attrStr = attrStr || attrStr.trim();\n\n const matches = getAllMatches(attrStr, attrsRegx);\n const len = matches.length; //don't make it inline\n const attrs = {};\n\n // Pre-process values once: trim + entity replacement\n // Reused in both matcher update and second pass\n const processedVals = new Array(len);\n let hasRawAttrs = false;\n const rawAttrsForMatcher = {};\n\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n const oldVal = matches[i][4];\n\n if (attrName.length && oldVal !== undefined) {\n let val = oldVal;\n if (options.trimValues) val = val.trim();\n val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);\n processedVals[i] = val;\n\n rawAttrsForMatcher[attrName] = val;\n hasRawAttrs = true;\n }\n }\n\n // Update matcher ONCE before second pass, if applicable\n if (hasRawAttrs && typeof jPath === 'object' && jPath.updateCurrent) {\n jPath.updateCurrent(rawAttrsForMatcher);\n }\n\n // Hoist toString() once — path doesn't change during attribute processing\n const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;\n\n // Second pass: apply processors, build final attrs\n let hasAttrs = false;\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n\n if (this.ignoreAttributesFn(attrName, jPathStr)) continue;\n\n let aName = options.attributeNamePrefix + attrName;\n\n if (attrName.length) {\n if (options.transformAttributeName) {\n aName = options.transformAttributeName(aName);\n }\n aName = sanitizeName(aName, options);\n\n if (matches[i][4] !== undefined) {\n // Reuse already-processed value — no double entity replacement\n const oldVal = processedVals[i];\n\n const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);\n if (newVal === null || newVal === undefined) {\n attrs[aName] = oldVal;\n } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {\n attrs[aName] = newVal;\n } else {\n attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);\n }\n hasAttrs = true;\n } else if (options.allowBooleanAttributes) {\n attrs[aName] = true;\n hasAttrs = true;\n }\n }\n }\n\n if (!hasAttrs) return;\n\n if (options.attributesGroupName && !options.preserveOrder) {\n const attrCollection = {};\n attrCollection[options.attributesGroupName] = attrs;\n return attrCollection;\n }\n return attrs;\n }\n}\nconst parseXml = function (xmlData) {\n xmlData = xmlData.replace(/\\r\\n?/g, \"\\n\"); //TODO: remove this line\n const xmlObj = new xmlNode('!xml');\n let currentNode = xmlObj;\n let textData = \"\";\n\n // Reset matcher for new document\n this.matcher.reset();\n this.entityDecoder.reset();\n\n // Reset entity expansion counters for this document\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n this.doctypefound = false;\n const options = this.options;\n const docTypeReader = new DocTypeReader(options.processEntities);\n const xmlLen = xmlData.length;\n for (let i = 0; i < xmlLen; i++) {//for each char in XML data\n const ch = xmlData[i];\n if (ch === '<') {\n // const nextIndex = i+1;\n // const _2ndChar = xmlData[nextIndex];\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//Closing Tag '/'\n const closeIndex = findClosingIndex(xmlData, \">\", i, \"Closing Tag is not closed.\")\n let tagName = xmlData.substring(i + 2, closeIndex).trim();\n\n if (options.removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n }\n }\n\n tagName = transformTagName(options.transformTagName, tagName, \"\", options).tagName;\n\n if (currentNode) {\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n }\n\n //check if last tag of nested tag was unpaired tag\n const lastTagName = this.matcher.getCurrentTag();\n if (tagName && options.unpairedTagsSet.has(tagName)) {\n throw new Error(`Unpaired tag can not be used as closing tag: `);\n }\n if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {\n // Pop the unpaired tag\n this.matcher.pop();\n this.tagsNodeStack.pop();\n }\n // Pop the closing tag\n this.matcher.pop();\n this.isCurrentNodeStopNode = false; // Reset flag when closing tag\n\n //a closing tag with no matching opening tag leaves the stack empty\n currentNode = this.tagsNodeStack.pop() || xmlObj;//avoid recursion, set the parent tag scope\n\n if (options.captureMetaData && currentNode) {\n currentNode.addEndIndex(closeIndex + 1);\n }\n textData = \"\";\n i = closeIndex;\n } else if (c1 === 63) { //'?'\n\n let tagData = readTagExp(xmlData, i, false, \"?>\");\n if (!tagData) throw new Error(\"Pi Tag is not closed.\");\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);\n if (attsMap) {\n const ver = attsMap[this.options.attributeNamePrefix + \"version\"];\n this.entityDecoder.setXmlVersion(Number(ver) || 1.0);\n docTypeReader.setXmlVersion(Number(ver) || 1.0);\n }\n if ((options.ignoreDeclaration && tagData.tagName === \"?xml\") || options.ignorePiTags) {\n //do nothing\n } else {\n\n const childNode = new xmlNode(tagData.tagName);\n childNode.add(options.textNodeName, \"\");\n\n if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) {\n childNode[\":@\"] = attsMap\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, i);\n\n if (options.captureMetaData) {\n // closeIndex points at '?' of the closing '?>'\n currentNode.addEndIndex(tagData.closeIndex + 2);\n }\n }\n\n\n i = tagData.closeIndex + 1;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { //'!--'\n const endIndex = findClosingIndex(xmlData, \"-->\", i + 4, \"Comment is not closed.\")\n if (options.commentPropName) {\n const comment = xmlData.substring(i + 4, endIndex - 2);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);\n }\n i = endIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 68) { //'!D'\n if (this.doctypefound) throw new Error(\"Multiple DOCTYPE declarations found.\");\n this.doctypefound = true;\n const result = docTypeReader.readDocType(xmlData, i);\n this.entityDecoder.addInputEntities(result.entities);\n i = result.i;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"CDATA is not closed.\") - 2;\n const tagExp = xmlData.substring(i + 9, closeIndex);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);\n if (val == undefined) val = \"\";\n\n //cdata should be set even if it is 0 length string\n if (options.cdataPropName) {\n currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);\n } else {\n currentNode.add(options.textNodeName, val);\n }\n\n i = closeIndex + 2;\n } else {//Opening tag\n let result = readTagExp(xmlData, i, options.removeNSPrefix);\n\n // Safety check: readTagExp can return undefined\n if (!result) {\n // Log context for debugging\n const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));\n throw new Error(`readTagExp returned undefined at position ${i}. Context: \"${context}\"`);\n }\n\n let tagName = result.tagName;\n const rawTagName = result.rawTagName;\n let tagExp = result.tagExp;\n let attrExpPresent = result.attrExpPresent;\n let closeIndex = result.closeIndex;\n\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n if (options.strictReservedNames &&\n (tagName === options.commentPropName\n || tagName === options.cdataPropName\n || tagName === options.textNodeName\n || tagName === options.attributesGroupName\n )) {\n throw new Error(`Invalid tag name: ${tagName}`);\n }\n\n //save text as child node\n if (currentNode && textData) {\n if (currentNode.tagname !== '!xml') {\n //when nested tag is found\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);\n }\n }\n\n //check if last tag was unpaired tag\n const lastTag = currentNode;\n if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {\n currentNode = this.tagsNodeStack.pop();\n this.matcher.pop();\n }\n\n // Clean up self-closing syntax BEFORE processing attributes\n // This is where tagExp gets the trailing / removed\n let isSelfClosing = false;\n if (tagExp.length > 0 && tagExp.lastIndexOf(\"/\") === tagExp.length - 1) {\n isSelfClosing = true;\n if (tagName[tagName.length - 1] === \"/\") {\n tagName = tagName.substr(0, tagName.length - 1);\n tagExp = tagName;\n } else {\n tagExp = tagExp.substr(0, tagExp.length - 1);\n }\n\n // Re-check attrExpPresent after cleaning\n attrExpPresent = (tagName !== tagExp);\n }\n\n // Now process attributes with CLEAN tagExp (no trailing /)\n let prefixedAttrs = null;\n let rawAttrs = {};\n let namespace = undefined;\n\n // Extract namespace from rawTagName\n namespace = extractNamespace(rawTagName);\n\n // Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path\n if (tagName !== xmlObj.tagname) {\n this.matcher.push(tagName, {}, namespace);\n }\n\n // Now build attributes - callbacks will see correct matcher state\n if (tagName !== tagExp && attrExpPresent) {\n // Build attributes (returns prefixed attributes for the tree)\n // Note: buildAttributesMap now internally updates the matcher with raw attributes\n prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);\n\n if (prefixedAttrs) {\n // Extract raw attributes (without prefix) for our use\n //TODO: seems a performance overhead\n rawAttrs = extractRawAttributes(prefixedAttrs, options);\n }\n }\n\n // Now check if this is a stop node (after attributes are set)\n if (tagName !== xmlObj.tagname) {\n this.isCurrentNodeStopNode = this.isItStopNode();\n }\n\n const startIndex = i;\n if (this.isCurrentNodeStopNode) {\n let tagContent = \"\";\n\n // For self-closing tags, content is empty\n if (isSelfClosing) {\n i = result.closeIndex;\n }\n //unpaired tag\n else if (options.unpairedTagsSet.has(tagName)) {\n i = result.closeIndex;\n }\n //normal tag\n else {\n //read until closing tag is found\n const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);\n if (!result) throw new Error(`Unexpected end of ${rawTagName}`);\n i = result.i;\n tagContent = result.tagContent;\n }\n\n const childNode = new xmlNode(tagName);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n\n // For stop nodes, store raw content as-is without any processing\n childNode.add(options.textNodeName, tagContent);\n\n this.matcher.pop(); // Pop the stop node tag\n this.isCurrentNodeStopNode = false; // Reset flag\n\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n\n if (options.captureMetaData) {\n currentNode.addEndIndex(i + 1);\n }\n } else {\n //selfClosing tag\n if (isSelfClosing) {\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n\n if (options.captureMetaData) {\n currentNode.addEndIndex(closeIndex + 1);\n }\n this.matcher.pop(); // Pop self-closing tag\n this.isCurrentNodeStopNode = false; // Reset flag\n }\n else if (options.unpairedTagsSet.has(tagName)) {//unpaired tag\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n\n if (options.captureMetaData) {\n currentNode.addEndIndex(result.closeIndex + 1);\n }\n this.matcher.pop(); // Pop unpaired tag\n this.isCurrentNodeStopNode = false; // Reset flag\n i = result.closeIndex;\n // Continue to next iteration without changing currentNode\n continue;\n }\n //opening tag\n else {\n const childNode = new xmlNode(tagName);\n if (this.tagsNodeStack.length > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n this.tagsNodeStack.push(currentNode);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n currentNode = childNode;\n }\n textData = \"\";\n i = closeIndex;\n }\n }\n } else {\n textData += xmlData[i];\n }\n }\n return xmlObj.child;\n}\n\nfunction addChild(currentNode, childNode, matcher, startIndex) {\n // unset startIndex if not requested\n if (!this.options.captureMetaData) startIndex = undefined;\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;\n const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[\":@\"])\n if (result === false) {\n //do nothing\n } else if (typeof result === \"string\") {\n childNode.tagname = result\n currentNode.addChild(childNode, startIndex);\n } else {\n currentNode.addChild(childNode, startIndex);\n }\n}\n\n/**\n * @param {object} val - Entity object with regex and val properties\n * @param {string} tagName - Tag name\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n */\nfunction replaceEntitiesValue(val, tagName, jPath) {\n const entityConfig = this.options.processEntities;\n\n if (!entityConfig || !entityConfig.enabled) {\n return val;\n }\n\n // Check if tag is allowed to contain entities\n if (entityConfig.allowedTags) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const allowed = Array.isArray(entityConfig.allowedTags)\n ? entityConfig.allowedTags.includes(tagName)\n : entityConfig.allowedTags(tagName, jPathOrMatcher);\n\n if (!allowed) {\n return val;\n }\n }\n\n // Apply custom tag filter if provided\n if (entityConfig.tagFilter) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {\n return val; // Skip based on custom filter\n }\n }\n\n return this.entityDecoder.decode(val);\n}\n\n\nfunction saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {\n if (textData) { //store previously collected data as textNode\n if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0\n\n textData = this.parseTextData(textData,\n parentNode.tagname,\n matcher,\n false,\n parentNode[\":@\"] ? Object.keys(parentNode[\":@\"]).length !== 0 : false,\n isLeafNode);\n\n if (textData !== undefined && textData !== \"\")\n parentNode.add(this.options.textNodeName, textData);\n textData = \"\";\n }\n return textData;\n}\n\n/**\n * @param {Array} stopNodeExpressions - Array of compiled Expression objects\n * @param {Matcher} matcher - Current path matcher\n */\nfunction isItStopNode() {\n if (this.stopNodeExpressionsSet.size === 0) return false;\n\n return this.matcher.matchesAny(this.stopNodeExpressionsSet);\n}\n\n/**\n * Returns the tag Expression and where it is ending handling single-double quotes situation\n * @param {string} xmlData \n * @param {number} i starting index\n * @returns \n */\nfunction tagExpWithClosingIndex(xmlData, i, closingChar = \">\") {\n //TODO: ignore boolean attributes in tag expression\n //TODO: if ignore attributes, dont read full attribute expression but the end. But read for xml declaration\n let attrBoundary = 0;\n const len = xmlData.length;\n const closeCode0 = closingChar.charCodeAt(0);\n const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;\n\n let result = '';\n let segmentStart = i;\n\n for (let index = i; index < len; index++) {\n const code = xmlData.charCodeAt(index);\n\n if (attrBoundary) {\n if (code === attrBoundary) attrBoundary = 0;\n } else if (code === 34 || code === 39) { // \" or '\n attrBoundary = code;\n } else if (code === closeCode0) {\n if (closeCode1 !== -1) {\n if (xmlData.charCodeAt(index + 1) === closeCode1) {\n result += xmlData.substring(segmentStart, index);\n return { data: result, index };\n }\n } else {\n result += xmlData.substring(segmentStart, index);\n return { data: result, index };\n }\n } else if (code === 9 && !attrBoundary) { // \\t - only replace with space outside attribute values\n // Flush accumulated segment, add space, start new segment\n result += xmlData.substring(segmentStart, index) + ' ';\n segmentStart = index + 1;\n }\n }\n}\n\nfunction findClosingIndex(xmlData, str, i, errMsg) {\n const closingIndex = xmlData.indexOf(str, i);\n if (closingIndex === -1) {\n throw new Error(errMsg)\n } else {\n return closingIndex + str.length - 1;\n }\n}\n\nfunction findClosingChar(xmlData, char, i, errMsg) {\n const closingIndex = xmlData.indexOf(char, i);\n if (closingIndex === -1) throw new Error(errMsg);\n return closingIndex; // no offset needed\n}\n\nfunction readTagExp(xmlData, i, removeNSPrefix, closingChar = \">\") {\n const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);\n if (!result) return;\n let tagExp = result.data;\n const closeIndex = result.index;\n const separatorIndex = tagExp.search(/\\s/);\n let tagName = tagExp;\n let attrExpPresent = true;\n if (separatorIndex !== -1) {//separate tag name and attributes expression\n tagName = tagExp.substring(0, separatorIndex);\n tagExp = tagExp.substring(separatorIndex + 1).trimStart();\n }\n\n const rawTagName = tagName;\n if (removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n attrExpPresent = tagName !== result.data.substr(colonIndex + 1);\n }\n }\n\n return {\n tagName: tagName,\n tagExp: tagExp,\n closeIndex: closeIndex,\n attrExpPresent: attrExpPresent,\n rawTagName: rawTagName,\n }\n}\n/**\n * find paired tag for a stop node\n * @param {string} xmlData \n * @param {string} tagName \n * @param {number} i \n */\nfunction readStopNodeData(xmlData, tagName, i) {\n const startIndex = i;\n // Starting at 1 since we already have an open tag\n let openTagCount = 1;\n\n const xmllen = xmlData.length;\n for (; i < xmllen; i++) {\n if (xmlData[i] === \"<\") {\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//close tag '/'\n const closeIndex = findClosingChar(xmlData, \">\", i, `${tagName} is not closed`);\n let closeTagName = xmlData.substring(i + 2, closeIndex).trim();\n if (closeTagName === tagName) {\n openTagCount--;\n if (openTagCount === 0) {\n return {\n tagContent: xmlData.substring(startIndex, i),\n i: closeIndex\n }\n }\n }\n i = closeIndex;\n } else if (c1 === 63) { //?\n const closeIndex = findClosingIndex(xmlData, \"?>\", i + 1, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { // '!--'\n const closeIndex = findClosingIndex(xmlData, \"-->\", i + 3, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"StopNode is not closed.\") - 2;\n i = closeIndex;\n } else {\n const tagData = readTagExp(xmlData, i, false)\n\n if (tagData) {\n const openTagName = tagData && tagData.tagName;\n if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== \"/\") {\n openTagCount++;\n }\n i = tagData.closeIndex;\n }\n }\n }\n }//end for loop\n}\n\nfunction parseValue(val, shouldParse, options) {\n if (shouldParse && typeof val === 'string') {\n //console.log(options)\n const newval = val.trim();\n if (newval === 'true') return true;\n else if (newval === 'false') return false;\n else return toNumber(val, options);\n } else {\n if (isExist(val)) {\n return val;\n } else {\n return '';\n }\n }\n}\n\nfunction fromCodePoint(str, base, prefix) {\n const codePoint = Number.parseInt(str, base);\n\n if (codePoint >= 0 && codePoint <= 0x10FFFF) {\n return String.fromCodePoint(codePoint);\n } else {\n return prefix + str + \";\";\n }\n}\n\nfunction transformTagName(fn, tagName, tagExp, options) {\n if (fn) {\n const newTagName = fn(tagName);\n if (tagExp === tagName) {\n tagExp = newTagName\n }\n tagName = newTagName;\n }\n tagName = sanitizeName(tagName, options);\n return { tagName, tagExp };\n}\n\n\n\nfunction sanitizeName(name, options) {\n if (criticalProperties.includes(name)) {\n throw new Error(`[SECURITY] Invalid name: \"${name}\" is a reserved JavaScript keyword that could cause prototype pollution`);\n } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return options.onDangerousProperty(name);\n }\n return name;\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","'use strict';\n\nimport XmlNode from './xmlNode.js';\nimport { Matcher } from 'path-expression-matcher';\n\nconst METADATA_SYMBOL = XmlNode.getMetaDataSymbol();\n\n/**\n * Helper function to strip attribute prefix from attribute map\n * @param {object} attrs - Attributes with prefix (e.g., {\"@_class\": \"code\"})\n * @param {string} prefix - Attribute prefix to remove (e.g., \"@_\")\n * @returns {object} Attributes without prefix (e.g., {\"class\": \"code\"})\n */\nfunction stripAttributePrefix(attrs, prefix) {\n if (!attrs || typeof attrs !== 'object') return {};\n if (!prefix) return attrs;\n\n const rawAttrs = {};\n for (const key in attrs) {\n if (key.startsWith(prefix)) {\n const rawName = key.substring(prefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * \n * @param {array} node \n * @param {any} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns \n */\nexport default function prettify(node, options, matcher, readonlyMatcher) {\n return compress(node, options, matcher, readonlyMatcher);\n}\n\n/**\n * @param {array} arr \n * @param {object} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns object\n */\nfunction compress(arr, options, matcher, readonlyMatcher) {\n let text;\n const compressedObj = {}; //This is intended to be a plain object\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const property = propName(tagObj);\n\n // Push current property to matcher WITH RAW ATTRIBUTES (no prefix)\n if (property !== undefined && property !== options.textNodeName) {\n const rawAttrs = stripAttributePrefix(\n tagObj[\":@\"] || {},\n options.attributeNamePrefix\n );\n matcher.push(property, rawAttrs);\n }\n\n if (property === options.textNodeName) {\n if (text === undefined) text = tagObj[property];\n else text += \"\" + tagObj[property];\n } else if (property === undefined) {\n continue;\n } else if (tagObj[property]) {\n\n let val = compress(tagObj[property], options, matcher, readonlyMatcher);\n const isLeaf = isLeafTag(val, options);\n\n if (Object.keys(val).length === 0 && options.alwaysCreateTextNode) {\n val[options.textNodeName] = \"\";\n }\n\n if (tagObj[\":@\"]) {\n assignAttributes(val, tagObj[\":@\"], readonlyMatcher, options);\n } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {\n val = val[options.textNodeName];\n } else if (Object.keys(val).length === 0) {\n if (options.alwaysCreateTextNode) val[options.textNodeName] = \"\";\n else val = \"\";\n }\n\n if (tagObj[METADATA_SYMBOL] !== undefined && typeof val === \"object\" && val !== null) {\n val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata\n }\n\n\n if (compressedObj[property] !== undefined && Object.prototype.hasOwnProperty.call(compressedObj, property)) {\n if (!Array.isArray(compressedObj[property])) {\n compressedObj[property] = [compressedObj[property]];\n }\n compressedObj[property].push(val);\n } else {\n //TODO: if a node is not an array, then check if it should be an array\n //also determine if it is a leaf node\n\n // Pass jPath string or readonlyMatcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;\n if (options.isArray(property, jPathOrMatcher, isLeaf)) {\n compressedObj[property] = [val];\n } else {\n compressedObj[property] = val;\n }\n }\n\n // Pop property from matcher after processing\n if (property !== undefined && property !== options.textNodeName) {\n matcher.pop();\n }\n }\n\n }\n // if(text && text.length > 0) compressedObj[options.textNodeName] = text;\n if (typeof text === \"string\") {\n if (text.length > 0) compressedObj[options.textNodeName] = text;\n } else if (text !== undefined) compressedObj[options.textNodeName] = text;\n\n\n return compressedObj;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== \":@\") return key;\n }\n}\n\nfunction assignAttributes(obj, attrMap, readonlyMatcher, options) {\n if (attrMap) {\n const keys = Object.keys(attrMap);\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n const atrrName = keys[i]; // This is the PREFIXED name (e.g., \"@_class\")\n\n // Strip prefix for matcher path (for isArray callback)\n const rawAttrName = atrrName.startsWith(options.attributeNamePrefix)\n ? atrrName.substring(options.attributeNamePrefix.length)\n : atrrName;\n\n // For attributes, we need to create a temporary path\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath\n ? readonlyMatcher.toString() + \".\" + rawAttrName\n : readonlyMatcher;\n\n if (options.isArray(atrrName, jPathOrMatcher, true, true)) {\n obj[atrrName] = [attrMap[atrrName]];\n } else {\n obj[atrrName] = attrMap[atrrName];\n }\n }\n }\n}\n\nfunction isLeafTag(obj, options) {\n const { textNodeName } = options;\n const propCount = Object.keys(obj).length;\n\n if (propCount === 0) {\n return true;\n }\n\n if (\n propCount === 1 &&\n (obj[textNodeName] || typeof obj[textNodeName] === \"boolean\" || obj[textNodeName] === 0)\n ) {\n return true;\n }\n\n return false;\n}","'use strict';\n\nimport { isName } from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/()/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n\n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i + 1] === '?') {\n i += 2;\n i = readPI(xmlData, i);\n if (i.err) return i;\n } else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n\n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\" + tagName + \"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\" + tagName + \"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\" + otg.tagName + \"' (opened in line \" + openPos.line + \", col \" + openPos.col + \") instead of closing tag '\" + tagName + \"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if (options.unpairedTags.indexOf(tagName) !== -1) {\n //don't push into stack\n } else {\n tags.push({ tagName, tagStartPos });\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i + 1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else {\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n } else {\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if (isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\" + xmlData[i] + \"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n } else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\" + tags[0].tagName + \"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n } else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\" +\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '') +\n \"' found.\", { line: 1, col: 1 });\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char) {\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Walk `attrStr` once, left to right, splitting it into attribute tokens.\n *\n * This replaces a regex that used to do the same job\n * (`(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?`). That regex led with an\n * optional whitespace group followed by a required \"non-whitespace\" group.\n * On a long run of whitespace that never resolves into an attribute name\n * (e.g. a tag with thousands of trailing spaces before `>`), the engine\n * backtracks the whitespace group one character at a time before giving up\n * and moving to the next starting position — one full backtrack per\n * position, which is quadratic in the length of the run.\n *\n * A single forward-only scan can never backtrack, so it can't be made slow\n * this way no matter how much whitespace the input contains — it's always\n * proportional to the length of the string, once.\n *\n * Each returned token mirrors the shape the old regex match array had, so\n * the validation logic below (which reads token[1]..token[6]) didn't need\n * to change:\n * token.startIndex - where this token begins in attrStr\n * token[1] - leading whitespace before the name\n * token[2] - the attribute name\n * token[3] - whitespace + '=' if present, else undefined\n * token[4] - marker (any defined value) if a quoted value was found\n * token[5] - the quote character used ('\"' or \"'\")\n * token[6] - the value's text, without the surrounding quotes\n *\n * A malformed leading character (e.g. a stray '=' with no name before it)\n * is simply skipped over, one character at a time — the same outcome the\n * old regex produced by failing to match at that position and retrying at\n * the next one.\n */\nfunction scanAttributeTokens(attrStr) {\n const tokens = [];\n const len = attrStr.length;\n let i = 0;\n\n while (i < len) {\n const tokenStart = i;\n\n // Leading whitespace before the name.\n while (i < len && isWhiteSpace(attrStr[i])) i++;\n if (i >= len) break; // trailing whitespace only — nothing left to read\n\n if (attrStr[i] === '=') {\n // No name before this '=' — not a valid attribute start. Move past\n // just this one character and try again from the next position.\n i = tokenStart + 1;\n continue;\n }\n\n const leadingWs = attrStr.slice(tokenStart, i);\n\n // Attribute name — everything up to the next whitespace or '='.\n const nameStart = i;\n while (i < len && !isWhiteSpace(attrStr[i]) && attrStr[i] !== '=') i++;\n const name = attrStr.slice(nameStart, i);\n\n // Optional whitespace + '='.\n let equalsGroup; // whitespace + '=' text, or undefined if absent\n let j = i;\n while (j < len && isWhiteSpace(attrStr[j])) j++;\n if (j < len && attrStr[j] === '=') {\n equalsGroup = attrStr.slice(i, j + 1);\n i = j + 1;\n }\n\n // Optional whitespace + quoted value.\n let quoteChar;\n let value;\n let k = i;\n while (k < len && isWhiteSpace(attrStr[k])) k++;\n if (k < len && (attrStr[k] === '\"' || attrStr[k] === \"'\")) {\n const valueStart = k + 1;\n const closeIdx = attrStr.indexOf(attrStr[k], valueStart);\n if (closeIdx !== -1) {\n quoteChar = attrStr[k];\n value = attrStr.slice(valueStart, closeIdx);\n i = closeIdx + 1;\n }\n // No closing quote found anywhere in the rest of the string — leave\n // quoteChar/value undefined, same as the old regex's group failing\n // to match a backreference-less run.\n }\n\n const token = { startIndex: tokenStart };\n token[1] = leadingWs;\n token[2] = name;\n token[3] = equalsGroup;\n token[4] = quoteChar !== undefined ? true : undefined;\n token[5] = quoteChar;\n token[6] = value;\n tokens.push(token);\n }\n\n return tokens;\n}\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = scanAttributeTokens(attrStr);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\" + matches[i][2] + \"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}","/* global Uint8Array */\nimport { buildOptions } from './OptionsBuilder.js';\nimport OrderedObjParser from './OrderedObjParser.js';\nimport prettify from './node2json.js';\nimport { validate } from \"../validator.js\";\nimport XmlNode from './xmlNode.js';\n\nexport default class XMLParser {\n\n constructor(options) {\n this.externalEntities = {};\n this.options = buildOptions(options);\n\n }\n /**\n * Parse XML dats to JS object \n * @param {string|Uint8Array} xmlData \n * @param {boolean|Object} validationOption \n */\n parse(xmlData, validationOption) {\n if (typeof xmlData !== \"string\" && xmlData.toString) {\n if (xmlData instanceof Uint8Array &&\n !(typeof Buffer !== \"undefined\" && Buffer.isBuffer(xmlData))) {\n xmlData = new TextDecoder(\"utf-8\", { ignoreBOM: true }).decode(xmlData);\n } else {\n xmlData = xmlData.toString();\n }\n } else if (typeof xmlData !== \"string\") {\n throw new Error(\"XML data is accepted in String or Bytes[] form.\")\n }\n\n if (validationOption) {\n if (validationOption === true) validationOption = {}; //validate with default options\n\n const result = validate(xmlData, validationOption);\n if (result !== true) {\n throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)\n }\n }\n const orderedObjParser = new OrderedObjParser(this.options, this.externalEntities);\n // orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities);\n const orderedResult = orderedObjParser.parseXml(xmlData);\n if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;\n else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);\n }\n\n /**\n * Add Entity which is not by default supported by this library\n * @param {string} key \n * @param {string} value \n */\n addEntity(key, value) {\n if (value.indexOf(\"&\") !== -1) {\n throw new Error(\"Entity value can't have '&'\")\n } else if (key.indexOf(\"&\") !== -1 || key.indexOf(\";\") !== -1) {\n throw new Error(\"An entity must be set without '&' and ';'. Eg. use '#xD' for ' '\")\n } else if (value === \"&\") {\n throw new Error(\"An entity with value '&' is not permitted\");\n } else {\n this.externalEntities[key] = value;\n }\n }\n\n /**\n * Returns a Symbol that can be used to access the metadata\n * property on a node.\n * \n * If Symbol is not available in the environment, an ordinary property is used\n * and the name of the property is here returned.\n * \n * The XMLMetaData property is only present when `captureMetaData`\n * is true in the options.\n */\n static getMetaDataSymbol() {\n return XmlNode.getMetaDataSymbol();\n }\n}"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","isName","string","exec","DANGEROUS_PROPERTY_NAMES","criticalProperties","defaultOnDangerousProperty","name","includes","defaultOptions","preserveOrder","attributeNamePrefix","attributesGroupName","textNodeName","ignoreAttributes","removeNSPrefix","allowBooleanAttributes","parseTagValue","parseAttributeValue","trimValues","cdataPropName","numberParseOptions","hex","leadingZeros","eNotation","unicode","tagValueProcessor","tagName","val","attributeValueProcessor","attrName","stopNodes","alwaysCreateTextNode","isArray","commentPropName","unpairedTags","processEntities","htmlEntities","entityDecoder","ignoreDeclaration","ignorePiTags","transformTagName","transformAttributeName","updateTag","jPath","attrs","captureMetaData","maxNestedTags","strictReservedNames","onDangerousProperty","validatePropertyName","propertyName","optionName","normalized","toLowerCase","some","dangerous","Error","normalizeProcessEntities","enabled","maxEntitySize","maxExpansionDepth","maxTotalExpansions","Infinity","maxExpandedLength","maxEntityCount","allowedTags","tagFilter","appliesTo","Math","max","_value$maxEntitySize","_value$maxExpansionDe","_value$maxTotalExpans","_value$maxExpandedLen","_value$maxEntityCount","_value$allowedTags","_value$tagFilter","_value$appliesTo","METADATA_SYMBOL","buildOptions","options","built","assign","_i","_propertyNameOptions","length","_propertyNameOptions$","unpairedTagsSet","Set","Array","map","node","startsWith","substring","XmlNode","tagname","child","create","_proto","add","_this$child$push","push","addChild","startIndex","_this$child$push2","_this$child$push3","keys","addStartIndex","undefined","addEndIndex","endIndex","lastChild","getMetaDataSymbol","nameStartChar10","nameStartChar11","nameChar11","buildRegexes","startChar","char","flags","ncNamePat","replace","ncName","qName","nmToken","nmTokens","regexes10","regexes11","nameStartCharAscii","regexesAscii","str","xmlVersion","asciiOnly","getRegexes","test","DocTypeReader","suppressValidationErr","setXmlVersion","readDocType","xmlData","i","entities","entityCount","angleBracketsCount","hasBody","comment","quoteChar","hasSeq","entityName","_this$readEntityExp","readEntityExp","indexOf","readElementExp","index","readNotationExp","skipWhitespace","validateEntityName","toUpperCase","entityValue","_this$readIdentifierV","readIdentifierVal","notationName","identifierType","publicIdentifier","systemIdentifier","_this$readIdentifierV2","_this$readIdentifierV3","_this$readIdentifierV4","type","identifierVal","elementName","contentModel","trim","readAttlistExp","attributeName","attributeType","allowedNotations","notation","join","defaultValue","_this$readIdentifierV5","data","seq","j","SCRIPT_ZEROS","HIGH_MAP","Map","TABLE_OFFSET","TABLE","Uint8Array","LOW_MAX","fill","zero","d","cp","set","MINUS_SET","hexRegex","binRegex","octRegex","numRegex","consider","binary","octal","decimalPoint","infinity","toNumber","trimmedStr","skipLike","len","firstHit","cc","charCodeAt","has","low","chars","slice","String","fromCharCode","anynum","parse_int","isFinite","match","eNotationRegx","sign","eChar","eAdjacentToLeadingZeros","Number","resolveEnotation","numTrimmedByZeros","numStr","end","trimZeros","decimalAdjacentToLeadingZeros","num","parsedStr","search","n","isPositive","handleInfinity","base","parseInt","window","MatcherView","constructor","matcher","_matcher","separator","getCurrentTag","path","tag","getCurrentNamespace","namespace","getAttrValue","values","hasAttr","current","getAnyParentAttr","hasAnyParentAttr","getPosition","position","getCounter","counter","getIndex","getDepth","toString","includeNamespace","toArray","matches","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","_keptAttrs","attrValues","currentLevel","level","counts","total","siblingKey","depth","keep","pop","poppedDepth","updateCurrent","kept","sep","result","reset","segments","hasDeepWildcard","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","segment","nextSeg","found","isCurrentNode","attrValue","positionValue","snapshot","keptAttrs","entry","restore","readOnly","Expression","pattern","_parse","_hasDeepWildcard","seg","_hasAttributeCondition","_hasPositionSelector","currentPart","_parseSegment","part","bracketContent","withoutBrackets","bracketMatch","content","tagAndPosition","nsIndex","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","eqIndex","nthMatch","hasAttributeCondition","hasPositionSelector","ExpressionSet","_byDepthAndTag","_wildcardByDepth","_deepWildcards","_deepByTerminalTag","_patterns","_sealed","TypeError","lastSeg","addAll","expressions","expr","size","seal","isSealed","findMatch","exactKey","exactBucket","wildcardBucket","deepBucket","CURRENCY","cent","pound","curren","yen","euro","dollar","fnof","inr","af","birr","peso","rub","won","yuan","cedil","XML","amp","apos","gt","lt","quot","COMMON_HTML","nbsp","copy","reg","trade","mdash","ndash","hellip","laquo","raquo","lsquo","rsquo","ldquo","rdquo","bull","para","sect","deg","frac12","frac14","frac34","ENTITY_ACTION","freeze","ALLOW","BLOCK","THROW","SPECIAL_CHARS","ch","mergeEntityMaps","maps","out","raw","LIMIT_TIER_EXTERNAL","LIMIT_TIER_BASE","LIMIT_TIER_ALL","NCR_LEVEL","allow","leave","remove","throw","XML10_ALLOWED_C0","EntityDecoder","_limit","limit","_maxTotalExpansions","_maxExpandedLength","_postCheck","postCheck","r","_limitTiers","applyLimitsTo","_numericAllowed","numericAllowed","_baseMap","DEFAULT_XML_ENTITIES","namedEntities","_externalMap","_inputMap","_totalExpansions","_expandedLength","_removeSet","_leaveSet","ncrCfg","ncr","onLevel","nullLevel","onNCR","nullNCR","parseNCRConfig","_ncrXmlVersion","_ncrOnLevel","_ncrNullLevel","_onExternalEntity","onExternalEntity","_onInputEntity","onInputEntity","_applyRegistrationHook","hook","context","action","setExternalEntities","flat","filtered","entries","addExternalEntity","addInputEntities","version","decode","original","chunks","last","limitExpansions","limitLength","checkLimits","token","replacement","tier","ncrResult","_resolveNCR","resolved","_resolveName","_tierCounts","delta","_classifyNCR","_applyNCRAction","fromCodePoint","padStart","second","isNaN","minimum","effective","id","description","SQL_PATTERNS","matchList","list","label","rule","isUnsafe","assertString","assertContext","lists","regex","normalise","_extends","bind","e","arguments","t","apply","extractRawAttributes","prefixedAttrs","rawAttrs","extractNamespace","rawTagName","ns","HTML","SVG","SQL","SQL_STRICT","SHELL","REDOS","NOSQL","LOG","OrderedObjParser","externalEntities","currentNode","tagsNodeStack","parseXml","parseTextData","resolveNameSpace","buildAttributesMap","isItStopNode","replaceEntitiesValue","readStopNodeData","saveTextToParentTag","ignoreAttributesFn","_step","_iterator","_createForOfIteratorHelperLoose","done","entityExpansionCount","currentExpandedLength","doctypefound","HTML_CONTEXT","XML_CONTEXT","readonlyMatcher","isCurrentNodeStopNode","stopNodeExpressionsSet","stopNodesOpts","stopNodeExp","dontTrim","hasAttributes","isLeafNode","escapeEntities","jPathOrMatcher","newval","parseValue","tags","split","prefix","charAt","attrsRegx","attrStr","force","allmatches","lastIndex","getAllMatches","processedVals","hasRawAttrs","rawAttrsForMatcher","oldVal","jPathStr","hasAttrs","aName","sanitizeName","newVal","attrCollection","xmlObj","xmlNode","textData","docTypeReader","xmlLen","c1","closeIndex","findClosingIndex","substr","lastTagName","tagData","readTagExp","attsMap","tagExp","ver","childNode","attrExpPresent","_ref","_ref2","min","_transformTagName","lastTag","isSelfClosing","tagContent","_transformTagName2","entityConfig","parentNode","errMsg","closingIndex","findClosingChar","closingChar","attrBoundary","closeCode0","closeCode1","segmentStart","code","tagExpWithClosingIndex","separatorIndex","trimStart","openTagCount","xmllen","shouldParse","fn","newTagName","stripAttributePrefix","prettify","compress","arr","text","compressedObj","tagObj","property","propName","isLeaf","isLeafTag","assignAttributes","attrMap","atrrName","rawAttrName","propCount","isWhiteSpace","readPI","start","getErrorObject","getLineNumberForPosition","readCommentAndCDATA","readAttributeStr","tagClosed","validateAttributeString","tokens","tokenStart","leadingWs","nameStart","equalsGroup","k","valueStart","closeIdx","scanAttributeTokens","attrNames","getPositionFromMatch","validateAttrName","validateAmpersand","re","validateNumberAmpersand","count","message","lineNumber","err","msg","line","col","validateTagName","lines","XMLParser","parse","validationOption","Buffer","isBuffer","TextDecoder","ignoreBOM","tagFound","reachedRoot","tagStartPos","closingTag","attrStrStart","isValid","otg","openPos","afterAmp","JSON","stringify","validate","orderedObjParser","orderedResult","addEntity"],"sourceRoot":""}