diff --git a/.github/utils/update_metadata.ts b/.github/utils/update_metadata.ts index 03c0aa03..6fb07b56 100644 --- a/.github/utils/update_metadata.ts +++ b/.github/utils/update_metadata.ts @@ -135,7 +135,7 @@ export async function currentData(): Promise { res.on('end', () => { try { const parsedData = JSON.parse(rawData) as SwiftorgMetadata - core.debug(`Recieved swift.org metadata: "${rawData}"`) + core.debug(`Received swift.org metadata: "${rawData}"`) resolve(parsedData) } catch (e) { core.error(`Parsing swift.org metadata error: '${e}'`) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 897ed5e8..06c980ea 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ _See also: [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md)_ ## Submitting Pull Requests -You can contribute by fixing bugs or adding new features, you can go through out [GitHub issues](https://github.com/SwiftyLab/setup-swift/issues) to start contributing. For larger code changes, we first recommend discussing them in our [GitHub dicussions](https://github.com/SwiftyLab/setup-swift/discussions). When submitting a pull request, please do the followings: +You can contribute by fixing bugs or adding new features, you can go through out [GitHub issues](https://github.com/SwiftyLab/setup-swift/issues) to start contributing. For larger code changes, we first recommend discussing them in our [GitHub discussions](https://github.com/SwiftyLab/setup-swift/discussions). When submitting a pull request, please do the followings: 1. Apply standard formatting with `npm run format`, and verify added code with lint rules by `npm run lint`. 1. Add relevant tests and ensure your changes don't break any existing tests (see [Automated Tests](#automated-tests) below). diff --git a/dist/index.js b/dist/index.js index 85852c22..6da3062a 100644 --- a/dist/index.js +++ b/dist/index.js @@ -35072,9 +35072,10 @@ var require_dom = __commonJS({ item: function(index) { return index >= 0 && index < this.length ? this[index] : null; }, - toString: function(isHTML, nodeFilter) { + toString: function(isHTML, nodeFilter, options) { + var requireWellFormed = !!options && !!options.requireWellFormed; for (var buf = [], i = 0; i < this.length; i++) { - serializeToString(this[i], buf, isHTML, nodeFilter); + serializeToString(this[i], buf, isHTML, nodeFilter, null, requireWellFormed); } return buf.join(""); }, @@ -35280,13 +35281,28 @@ var require_dom = __commonJS({ /** * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. * - * __This behavior is slightly different from the in the specs__: + * __This implementation differs from the specification:__ * - this implementation is not validating names or qualified names * (when parsing XML strings, the SAX parser takes care of that) * + * Note: `internalSubset` can only be introduced via a direct property write to `node.internalSubset` after creation. + * Creation-time validation of `publicId`, `systemId` is not enforced. + * The serializer-level check covers all mutation vectors, including direct property writes. + * `internalSubset` is only serialized as `[ ... ]` when both `publicId` and `systemId` are + * absent (empty or `'.'`) — if either external identifier is present, `internalSubset` is + * silently omitted from the serialized output. + * * @param {string} qualifiedName * @param {string} [publicId] + * The external subset public identifier. Stored verbatim including surrounding quotes. + * When serialized with `requireWellFormed: true` (via the 4th-parameter options object), + * throws `DOMException` with code `INVALID_STATE_ERR` if the value is non-empty and does + * not match the XML `PubidLiteral` production (W3C DOM Parsing §3.2.1.3; XML 1.0 [12]). * @param {string} [systemId] + * The external subset system identifier. Stored verbatim including surrounding quotes. + * When serialized with `requireWellFormed: true`, throws `DOMException` with code + * `INVALID_STATE_ERR` if the value is non-empty and does not match the XML `SystemLiteral` + * production (W3C DOM Parsing §3.2.1.3; XML 1.0 [11]). * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()` * @@ -35345,18 +35361,40 @@ var require_dom = __commonJS({ return cloneNode(this.ownerDocument || this, this, deep); }, // Modified in DOM Level 2: + /** + * Puts the specified node and all of its subtree into a "normalized" form. In a normalized + * subtree, no text nodes in the subtree are empty and there are no adjacent text nodes. + * + * Specifically, this method merges any adjacent text nodes (i.e., nodes for which `nodeType` + * is `TEXT_NODE`) into a single node with the combined data. It also removes any empty text + * nodes. + * + * This method iteratively traverses all child nodes to normalize all descendant nodes within + * the subtree. + * + * @throws {DOMException} + * May throw a DOMException if operations within removeChild or appendData (which are + * potentially invoked in this method) do not meet their specific constraints. + * @see {@link Node.removeChild} + * @see {@link CharacterData.appendData} + * @see ../docs/walk-dom.md. + */ normalize: function() { - var child2 = this.firstChild; - while (child2) { - var next = child2.nextSibling; - if (next && next.nodeType == TEXT_NODE && child2.nodeType == TEXT_NODE) { - this.removeChild(next); - child2.appendData(next.data); - } else { - child2.normalize(); - child2 = next; + walkDOM(this, null, { + enter: function(node) { + var child2 = node.firstChild; + while (child2) { + var next = child2.nextSibling; + if (next !== null && next.nodeType === TEXT_NODE && child2.nodeType === TEXT_NODE) { + node.removeChild(next); + child2.appendData(next.data); + } else { + child2 = next; + } + } + return true; } - } + }); }, // Introduced in DOM Level 2: isSupported: function(feature, version3) { @@ -35421,17 +35459,38 @@ var require_dom = __commonJS({ copy(NodeType, Node); copy(NodeType, Node.prototype); function _visitNode(node, callback) { - if (callback(node)) { - return true; - } - if (node = node.firstChild) { - do { - if (_visitNode(node, callback)) { - return true; + return walkDOM(node, null, { enter: function(n7) { + return callback(n7) ? walkDOM.STOP : true; + } }) === walkDOM.STOP; + } + function walkDOM(node, context3, callbacks) { + var stack = [{ node, context: context3, phase: walkDOM.ENTER }]; + while (stack.length > 0) { + var frame = stack.pop(); + if (frame.phase === walkDOM.ENTER) { + var childContext = callbacks.enter(frame.node, frame.context); + if (childContext === walkDOM.STOP) { + return walkDOM.STOP; + } + stack.push({ node: frame.node, context: childContext, phase: walkDOM.EXIT }); + if (childContext === null || childContext === void 0) { + continue; } - } while (node = node.nextSibling); + var child2 = frame.node.lastChild; + while (child2) { + stack.push({ node: child2, context: childContext, phase: walkDOM.ENTER }); + child2 = child2.previousSibling; + } + } else { + if (callbacks.exit) { + callbacks.exit(frame.node, frame.context); + } + } } } + walkDOM.STOP = /* @__PURE__ */ Symbol("walkDOM.STOP"); + walkDOM.ENTER = 0; + walkDOM.EXIT = 1; function Document() { this.ownerDocument = this; } @@ -35836,6 +35895,23 @@ var require_dom = __commonJS({ node.appendData(data); return node; }, + /** + * Returns a ProcessingInstruction node whose target is target and data is data. + * + * __This implementation differs from the specification:__ + * - it does not do any input validation on the arguments and doesn't throw "InvalidCharacterError". + * + * Note: When the resulting document is serialized with `requireWellFormed: true`, the + * serializer throws with code `INVALID_STATE_ERR` if `.data` contains `?>` (W3C DOM Parsing + * §3.2.1.7). Without that option the data is emitted verbatim. + * + * @param {string} target + * @param {string} data + * @returns {ProcessingInstruction} + * @see https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction + * @see https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction + * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.7 + */ createProcessingInstruction: function(target, data) { var node = new ProcessingInstruction(); node.ownerDocument = this; @@ -36077,11 +36153,12 @@ var require_dom = __commonJS({ _extends(ProcessingInstruction, Node); function XMLSerializer() { } - XMLSerializer.prototype.serializeToString = function(node, isHtml, nodeFilter) { - return nodeSerializeToString.call(node, isHtml, nodeFilter); + XMLSerializer.prototype.serializeToString = function(node, isHtml, nodeFilter, options) { + return nodeSerializeToString.call(node, isHtml, nodeFilter, options); }; Node.prototype.toString = nodeSerializeToString; - function nodeSerializeToString(isHtml, nodeFilter) { + function nodeSerializeToString(isHtml, nodeFilter, options) { + var requireWellFormed = !!options && !!options.requireWellFormed; var buf = []; var refNode = this.nodeType == 9 && this.documentElement || this; var prefix2 = refNode.prefix; @@ -36095,7 +36172,7 @@ var require_dom = __commonJS({ ]; } } - serializeToString(this, buf, isHtml, nodeFilter, visibleNamespaces); + serializeToString(this, buf, isHtml, nodeFilter, visibleNamespaces, requireWellFormed); return buf.join(""); } function needNamespaceDefine(node, isHTML, visibleNamespaces) { @@ -36119,246 +36196,255 @@ var require_dom = __commonJS({ function addSerializedAttribute(buf, qualifiedName, value) { buf.push(" ", qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"'); } - function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces) { + function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces, requireWellFormed) { if (!visibleNamespaces) { visibleNamespaces = []; } - if (nodeFilter) { - node = nodeFilter(node); - if (node) { - if (typeof node == "string") { - buf.push(node); - return; - } - } else { - return; - } - } - switch (node.nodeType) { - case ELEMENT_NODE: - var attrs = node.attributes; - var len = attrs.length; - var child2 = node.firstChild; - var nodeName = node.tagName; - isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML; - var prefixedNodeName = nodeName; - if (!isHTML && !node.prefix && node.namespaceURI) { - var defaultNS; - for (var ai2 = 0; ai2 < attrs.length; ai2++) { - if (attrs.item(ai2).name === "xmlns") { - defaultNS = attrs.item(ai2).value; - break; + walkDOM(node, { ns: visibleNamespaces, isHTML }, { + enter: function(n7, ctx) { + var ns2 = ctx.ns; + var html = ctx.isHTML; + if (nodeFilter) { + n7 = nodeFilter(n7); + if (n7) { + if (typeof n7 == "string") { + buf.push(n7); + return null; } + } else { + return null; } - if (!defaultNS) { - for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { - var namespace = visibleNamespaces[nsi]; - if (namespace.prefix === "" && namespace.namespace === node.namespaceURI) { - defaultNS = namespace.namespace; - break; + } + switch (n7.nodeType) { + case ELEMENT_NODE: + var attrs = n7.attributes; + var len = attrs.length; + var nodeName = n7.tagName; + html = NAMESPACE.isHTML(n7.namespaceURI) || html; + var prefixedNodeName = nodeName; + if (!html && !n7.prefix && n7.namespaceURI) { + var defaultNS; + for (var ai2 = 0; ai2 < attrs.length; ai2++) { + if (attrs.item(ai2).name === "xmlns") { + defaultNS = attrs.item(ai2).value; + break; + } + } + if (!defaultNS) { + for (var nsi = ns2.length - 1; nsi >= 0; nsi--) { + var nsEntry = ns2[nsi]; + if (nsEntry.prefix === "" && nsEntry.namespace === n7.namespaceURI) { + defaultNS = nsEntry.namespace; + break; + } + } + } + if (defaultNS !== n7.namespaceURI) { + for (var nsi = ns2.length - 1; nsi >= 0; nsi--) { + var nsEntry = ns2[nsi]; + if (nsEntry.namespace === n7.namespaceURI) { + if (nsEntry.prefix) { + prefixedNodeName = nsEntry.prefix + ":" + nodeName; + } + break; + } + } } } - } - if (defaultNS !== node.namespaceURI) { - for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { - var namespace = visibleNamespaces[nsi]; - if (namespace.namespace === node.namespaceURI) { - if (namespace.prefix) { - prefixedNodeName = namespace.prefix + ":" + nodeName; + buf.push("<", prefixedNodeName); + var childNs = ns2.slice(); + for (var i = 0; i < len; i++) { + var attr = attrs.item(i); + if (attr.prefix == "xmlns") { + childNs.push({ prefix: attr.localName, namespace: attr.value }); + } else if (attr.nodeName == "xmlns") { + childNs.push({ prefix: "", namespace: attr.value }); + } + } + for (var i = 0; i < len; i++) { + var attr = attrs.item(i); + if (needNamespaceDefine(attr, html, childNs)) { + var attrPrefix = attr.prefix || ""; + var uri = attr.namespaceURI; + addSerializedAttribute(buf, attrPrefix ? "xmlns:" + attrPrefix : "xmlns", uri); + childNs.push({ prefix: attrPrefix, namespace: uri }); + } + var filteredAttr = nodeFilter ? nodeFilter(attr) : attr; + if (filteredAttr) { + if (typeof filteredAttr === "string") { + buf.push(filteredAttr); + } else { + addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value); } - break; } } - } - } - buf.push("<", prefixedNodeName); - for (var i = 0; i < len; i++) { - var attr = attrs.item(i); - if (attr.prefix == "xmlns") { - visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value }); - } else if (attr.nodeName == "xmlns") { - visibleNamespaces.push({ prefix: "", namespace: attr.value }); - } - } - for (var i = 0; i < len; i++) { - var attr = attrs.item(i); - if (needNamespaceDefine(attr, isHTML, visibleNamespaces)) { - var prefix2 = attr.prefix || ""; - var uri = attr.namespaceURI; - addSerializedAttribute(buf, prefix2 ? "xmlns:" + prefix2 : "xmlns", uri); - visibleNamespaces.push({ prefix: prefix2, namespace: uri }); - } - serializeToString(attr, buf, isHTML, nodeFilter, visibleNamespaces); - } - if (nodeName === prefixedNodeName && needNamespaceDefine(node, isHTML, visibleNamespaces)) { - var prefix2 = node.prefix || ""; - var uri = node.namespaceURI; - addSerializedAttribute(buf, prefix2 ? "xmlns:" + prefix2 : "xmlns", uri); - visibleNamespaces.push({ prefix: prefix2, namespace: uri }); - } - if (child2 || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)) { - buf.push(">"); - if (isHTML && /^script$/i.test(nodeName)) { - while (child2) { - if (child2.data) { - buf.push(child2.data); - } else { - serializeToString(child2, buf, isHTML, nodeFilter, visibleNamespaces.slice()); + if (nodeName === prefixedNodeName && needNamespaceDefine(n7, html, childNs)) { + var nodePrefix = n7.prefix || ""; + var uri = n7.namespaceURI; + addSerializedAttribute(buf, nodePrefix ? "xmlns:" + nodePrefix : "xmlns", uri); + childNs.push({ prefix: nodePrefix, namespace: uri }); + } + var child2 = n7.firstChild; + if (child2 || html && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)) { + buf.push(">"); + if (html && /^script$/i.test(nodeName)) { + while (child2) { + if (child2.data) { + buf.push(child2.data); + } else { + serializeToString(child2, buf, html, nodeFilter, childNs.slice(), requireWellFormed); + } + child2 = child2.nextSibling; + } + buf.push(""); + return null; } - child2 = child2.nextSibling; + return { ns: childNs, isHTML: html, tag: prefixedNodeName }; + } else { + buf.push("/>"); + return null; } - } else { - while (child2) { - serializeToString(child2, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - child2 = child2.nextSibling; + case DOCUMENT_NODE: + case DOCUMENT_FRAGMENT_NODE: + return { ns: ns2.slice(), isHTML: html, tag: null }; + case ATTRIBUTE_NODE: + addSerializedAttribute(buf, n7.name, n7.value); + return null; + case TEXT_NODE: + buf.push(n7.data.replace(/[<&>]/g, _xmlEncoder)); + return null; + case CDATA_SECTION_NODE: + if (requireWellFormed && n7.data.indexOf("]]>") !== -1) { + throw new DOMException2(INVALID_STATE_ERR, 'The CDATASection data contains "]]>"'); } - } - buf.push(""); - } else { - buf.push("/>"); - } - return; - case DOCUMENT_NODE: - case DOCUMENT_FRAGMENT_NODE: - var child2 = node.firstChild; - while (child2) { - serializeToString(child2, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - child2 = child2.nextSibling; + buf.push("/g, "]]]]>"), "]]>"); + return null; + case COMMENT_NODE: + if (requireWellFormed && n7.data.indexOf("-->") !== -1) { + throw new DOMException2(INVALID_STATE_ERR, 'The comment node data contains "-->"'); + } + buf.push(""); + return null; + case DOCUMENT_TYPE_NODE: + if (requireWellFormed) { + if (n7.publicId && !/^("[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%']*"|'[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%'"]*')$/.test(n7.publicId)) { + throw new DOMException2(INVALID_STATE_ERR, "DocumentType publicId is not a valid PubidLiteral"); + } + if (n7.systemId && !/^("[^"]*"|'[^']*')$/.test(n7.systemId)) { + throw new DOMException2(INVALID_STATE_ERR, "DocumentType systemId is not a valid SystemLiteral"); + } + if (n7.internalSubset && n7.internalSubset.indexOf("]>") !== -1) { + throw new DOMException2(INVALID_STATE_ERR, 'DocumentType internalSubset contains "]>"'); + } + } + var pubid = n7.publicId; + var sysid = n7.systemId; + buf.push(""); + } else if (sysid && sysid != ".") { + buf.push(" SYSTEM ", sysid, ">"); + } else { + var sub = n7.internalSubset; + if (sub) { + buf.push(" [", sub, "]"); + } + buf.push(">"); + } + return null; + case PROCESSING_INSTRUCTION_NODE: + if (requireWellFormed && n7.data.indexOf("?>") !== -1) { + throw new DOMException2(INVALID_STATE_ERR, 'The ProcessingInstruction data contains "?>"'); + } + buf.push(""); + return null; + case ENTITY_REFERENCE_NODE: + buf.push("&", n7.nodeName, ";"); + return null; + //case ENTITY_NODE: + //case NOTATION_NODE: + default: + buf.push("??", n7.nodeName); + return null; } - return; - case ATTRIBUTE_NODE: - return addSerializedAttribute(buf, node.name, node.value); - case TEXT_NODE: - return buf.push( - node.data.replace(/[<&>]/g, _xmlEncoder) - ); - case CDATA_SECTION_NODE: - return buf.push("/g, "]]]]>"), "]]>"); - case COMMENT_NODE: - return buf.push(""); - case DOCUMENT_TYPE_NODE: - var pubid = node.publicId; - var sysid = node.systemId; - buf.push(""); - } else if (sysid && sysid != ".") { - buf.push(" SYSTEM ", sysid, ">"); - } else { - var sub = node.internalSubset; - if (sub) { - buf.push(" [", sub, "]"); - } - buf.push(">"); + }, + exit: function(n7, childCtx) { + if (childCtx && childCtx.tag) { + buf.push(""); } - return; - case PROCESSING_INSTRUCTION_NODE: - return buf.push(""); - case ENTITY_REFERENCE_NODE: - return buf.push("&", node.nodeName, ";"); - //case ENTITY_NODE: - //case NOTATION_NODE: - default: - buf.push("??", node.nodeName); - } + } + }); } function importNode(doc, node, deep) { - var node2; - switch (node.nodeType) { - case ELEMENT_NODE: - node2 = node.cloneNode(false); - node2.ownerDocument = doc; - //var attrs = node2.attributes; - //var len = attrs.length; - //for(var i=0;i { try { const parsedData = JSON.parse(rawData); - debug(`Recieved swift.org metadata: "${rawData}"`); + debug(`Received swift.org metadata: "${rawData}"`); _Swiftorg.commitFromMetadata(parsedData).then((commit) => resolve2({ commit }), (e) => reject(e)); } catch (e) { error(`Parsing swift.org metadata error: '${e}'`); @@ -59003,6 +59104,1475 @@ function getPositionFromMatch(match2) { return match2.startIndex + match2[1].length; } +// node_modules/@nodable/entities/src/entities.js +var BASIC_LATIN = { + amp: "&", + AMP: "&", + lt: "<", + LT: "<", + gt: ">", + GT: ">", + quot: '"', + QUOT: '"', + apos: "'", + lsquo: "\u2018", + rsquo: "\u2019", + ldquo: "\u201C", + rdquo: "\u201D", + lsquor: "\u201A", + rsquor: "\u2019", + ldquor: "\u201E", + bdquo: "\u201E", + comma: ",", + period: ".", + colon: ":", + semi: ";", + excl: "!", + quest: "?", + num: "#", + dollar: "$", + percent: "%", + amp: "&", + ast: "*", + commat: "@", + lowbar: "_", + verbar: "|", + vert: "|", + sol: "/", + bsol: "\\", + lbrace: "{", + rbrace: "}", + lbrack: "[", + rbrack: "]", + lpar: "(", + rpar: ")", + nbsp: "\xA0", + iexcl: "\xA1", + cent: "\xA2", + pound: "\xA3", + curren: "\xA4", + yen: "\xA5", + brvbar: "\xA6", + sect: "\xA7", + uml: "\xA8", + copy: "\xA9", + COPY: "\xA9", + ordf: "\xAA", + laquo: "\xAB", + not: "\xAC", + shy: "\xAD", + reg: "\xAE", + REG: "\xAE", + macr: "\xAF", + deg: "\xB0", + plusmn: "\xB1", + sup2: "\xB2", + sup3: "\xB3", + acute: "\xB4", + micro: "\xB5", + para: "\xB6", + middot: "\xB7", + cedil: "\xB8", + sup1: "\xB9", + ordm: "\xBA", + raquo: "\xBB", + frac14: "\xBC", + frac12: "\xBD", + half: "\xBD", + frac34: "\xBE", + iquest: "\xBF", + times: "\xD7", + div: "\xF7", + divide: "\xF7" +}; +var LATIN_ACCENTS = { + Agrave: "\xC0", + agrave: "\xE0", + Aacute: "\xC1", + aacute: "\xE1", + Acirc: "\xC2", + acirc: "\xE2", + Atilde: "\xC3", + atilde: "\xE3", + Auml: "\xC4", + auml: "\xE4", + Aring: "\xC5", + aring: "\xE5", + AElig: "\xC6", + aelig: "\xE6", + Ccedil: "\xC7", + ccedil: "\xE7", + Egrave: "\xC8", + egrave: "\xE8", + Eacute: "\xC9", + eacute: "\xE9", + Ecirc: "\xCA", + ecirc: "\xEA", + Euml: "\xCB", + euml: "\xEB", + Igrave: "\xCC", + igrave: "\xEC", + Iacute: "\xCD", + iacute: "\xED", + Icirc: "\xCE", + icirc: "\xEE", + Iuml: "\xCF", + iuml: "\xEF", + ETH: "\xD0", + eth: "\xF0", + Ntilde: "\xD1", + ntilde: "\xF1", + Ograve: "\xD2", + ograve: "\xF2", + Oacute: "\xD3", + oacute: "\xF3", + Ocirc: "\xD4", + ocirc: "\xF4", + Otilde: "\xD5", + otilde: "\xF5", + Ouml: "\xD6", + ouml: "\xF6", + Oslash: "\xD8", + oslash: "\xF8", + Ugrave: "\xD9", + ugrave: "\xF9", + Uacute: "\xDA", + uacute: "\xFA", + Ucirc: "\xDB", + ucirc: "\xFB", + Uuml: "\xDC", + uuml: "\xFC", + Yacute: "\xDD", + yacute: "\xFD", + THORN: "\xDE", + thorn: "\xFE", + szlig: "\xDF", + yuml: "\xFF", + Yuml: "\u0178" +}; +var LATIN_EXTENDED = { + Amacr: "\u0100", + amacr: "\u0101", + Abreve: "\u0102", + abreve: "\u0103", + Aogon: "\u0104", + aogon: "\u0105", + Cacute: "\u0106", + cacute: "\u0107", + Ccirc: "\u0108", + ccirc: "\u0109", + Cdot: "\u010A", + cdot: "\u010B", + Ccaron: "\u010C", + ccaron: "\u010D", + Dcaron: "\u010E", + dcaron: "\u010F", + Dstrok: "\u0110", + dstrok: "\u0111", + Emacr: "\u0112", + emacr: "\u0113", + Ecaron: "\u011A", + ecaron: "\u011B", + Edot: "\u0116", + edot: "\u0117", + Eogon: "\u0118", + eogon: "\u0119", + Gcirc: "\u011C", + gcirc: "\u011D", + Gbreve: "\u011E", + gbreve: "\u011F", + Gdot: "\u0120", + gdot: "\u0121", + Gcedil: "\u0122", + Hcirc: "\u0124", + hcirc: "\u0125", + Hstrok: "\u0126", + hstrok: "\u0127", + Itilde: "\u0128", + itilde: "\u0129", + Imacr: "\u012A", + imacr: "\u012B", + Iogon: "\u012E", + iogon: "\u012F", + Idot: "\u0130", + IJlig: "\u0132", + ijlig: "\u0133", + Jcirc: "\u0134", + jcirc: "\u0135", + Kcedil: "\u0136", + kcedil: "\u0137", + kgreen: "\u0138", + Lacute: "\u0139", + lacute: "\u013A", + Lcedil: "\u013B", + lcedil: "\u013C", + Lcaron: "\u013D", + lcaron: "\u013E", + Lmidot: "\u013F", + lmidot: "\u0140", + Lstrok: "\u0141", + lstrok: "\u0142", + Nacute: "\u0143", + nacute: "\u0144", + Ncaron: "\u0147", + ncaron: "\u0148", + Ncedil: "\u0145", + ncedil: "\u0146", + ENG: "\u014A", + eng: "\u014B", + Omacr: "\u014C", + omacr: "\u014D", + Odblac: "\u0150", + odblac: "\u0151", + OElig: "\u0152", + oelig: "\u0153", + Racute: "\u0154", + racute: "\u0155", + Rcaron: "\u0158", + rcaron: "\u0159", + Rcedil: "\u0156", + rcedil: "\u0157", + Sacute: "\u015A", + sacute: "\u015B", + Scirc: "\u015C", + scirc: "\u015D", + Scedil: "\u015E", + scedil: "\u015F", + Scaron: "\u0160", + scaron: "\u0161", + Tcedil: "\u0162", + tcedil: "\u0163", + Tcaron: "\u0164", + tcaron: "\u0165", + Tstrok: "\u0166", + tstrok: "\u0167", + Utilde: "\u0168", + utilde: "\u0169", + Umacr: "\u016A", + umacr: "\u016B", + Ubreve: "\u016C", + ubreve: "\u016D", + Uring: "\u016E", + uring: "\u016F", + Udblac: "\u0170", + udblac: "\u0171", + Uogon: "\u0172", + uogon: "\u0173", + Wcirc: "\u0174", + wcirc: "\u0175", + Ycirc: "\u0176", + ycirc: "\u0177", + Zacute: "\u0179", + zacute: "\u017A", + Zdot: "\u017B", + zdot: "\u017C", + Zcaron: "\u017D", + zcaron: "\u017E" +}; +var GREEK = { + Alpha: "\u0391", + alpha: "\u03B1", + Beta: "\u0392", + beta: "\u03B2", + Gamma: "\u0393", + gamma: "\u03B3", + Delta: "\u0394", + delta: "\u03B4", + Epsilon: "\u0395", + epsilon: "\u03B5", + epsiv: "\u03F5", + varepsilon: "\u03F5", + Zeta: "\u0396", + zeta: "\u03B6", + Eta: "\u0397", + eta: "\u03B7", + Theta: "\u0398", + theta: "\u03B8", + thetasym: "\u03D1", + vartheta: "\u03D1", + Iota: "\u0399", + iota: "\u03B9", + Kappa: "\u039A", + kappa: "\u03BA", + kappav: "\u03F0", + varkappa: "\u03F0", + Lambda: "\u039B", + lambda: "\u03BB", + Mu: "\u039C", + mu: "\u03BC", + Nu: "\u039D", + nu: "\u03BD", + Xi: "\u039E", + xi: "\u03BE", + Omicron: "\u039F", + omicron: "\u03BF", + Pi: "\u03A0", + pi: "\u03C0", + piv: "\u03D6", + varpi: "\u03D6", + Rho: "\u03A1", + rho: "\u03C1", + rhov: "\u03F1", + varrho: "\u03F1", + Sigma: "\u03A3", + sigma: "\u03C3", + sigmaf: "\u03C2", + sigmav: "\u03C2", + varsigma: "\u03C2", + Tau: "\u03A4", + tau: "\u03C4", + Upsilon: "\u03A5", + upsilon: "\u03C5", + upsi: "\u03C5", + Upsi: "\u03D2", + upsih: "\u03D2", + Phi: "\u03A6", + phi: "\u03C6", + phiv: "\u03D5", + varphi: "\u03D5", + Chi: "\u03A7", + chi: "\u03C7", + Psi: "\u03A8", + psi: "\u03C8", + Omega: "\u03A9", + omega: "\u03C9", + ohm: "\u03A9", + Gammad: "\u03DC", + gammad: "\u03DD", + digamma: "\u03DD" +}; +var CYRILLIC = { + Afr: "\u{1D504}", + afr: "\u{1D51E}", + Acy: "\u0410", + acy: "\u0430", + Bcy: "\u0411", + bcy: "\u0431", + Vcy: "\u0412", + vcy: "\u0432", + Gcy: "\u0413", + gcy: "\u0433", + Dcy: "\u0414", + dcy: "\u0434", + IEcy: "\u0415", + iecy: "\u0435", + IOcy: "\u0401", + iocy: "\u0451", + ZHcy: "\u0416", + zhcy: "\u0436", + Zcy: "\u0417", + zcy: "\u0437", + Icy: "\u0418", + icy: "\u0438", + Jcy: "\u0419", + jcy: "\u0439", + Kcy: "\u041A", + kcy: "\u043A", + Lcy: "\u041B", + lcy: "\u043B", + Mcy: "\u041C", + mcy: "\u043C", + Ncy: "\u041D", + ncy: "\u043D", + Ocy: "\u041E", + ocy: "\u043E", + Pcy: "\u041F", + pcy: "\u043F", + Rcy: "\u0420", + rcy: "\u0440", + Scy: "\u0421", + scy: "\u0441", + Tcy: "\u0422", + tcy: "\u0442", + Ucy: "\u0423", + ucy: "\u0443", + Fcy: "\u0424", + fcy: "\u0444", + KHcy: "\u0425", + khcy: "\u0445", + TScy: "\u0426", + tscy: "\u0446", + CHcy: "\u0427", + chcy: "\u0447", + SHcy: "\u0428", + shcy: "\u0448", + SHCHcy: "\u0429", + shchcy: "\u0449", + HARDcy: "\u042A", + hardcy: "\u044A", + Ycy: "\u042B", + ycy: "\u044B", + SOFTcy: "\u042C", + softcy: "\u044C", + Ecy: "\u042D", + ecy: "\u044D", + YUcy: "\u042E", + yucy: "\u044E", + YAcy: "\u042F", + yacy: "\u044F", + DJcy: "\u0402", + djcy: "\u0452", + GJcy: "\u0403", + gjcy: "\u0453", + Jukcy: "\u0404", + jukcy: "\u0454", + DScy: "\u0405", + dscy: "\u0455", + Iukcy: "\u0406", + iukcy: "\u0456", + YIcy: "\u0407", + yicy: "\u0457", + Jsercy: "\u0408", + jsercy: "\u0458", + LJcy: "\u0409", + ljcy: "\u0459", + NJcy: "\u040A", + njcy: "\u045A", + TSHcy: "\u040B", + tshcy: "\u045B", + KJcy: "\u040C", + kjcy: "\u045C", + Ubrcy: "\u040E", + ubrcy: "\u045E", + DZcy: "\u040F", + dzcy: "\u045F" +}; +var MATH = { + plus: "+", + minus: "\u2212", + mnplus: "\u2213", + mp: "\u2213", + pm: "\xB1", + times: "\xD7", + div: "\xF7", + divide: "\xF7", + sdot: "\u22C5", + star: "\u2606", + starf: "\u2605", + bigstar: "\u2605", + lowast: "\u2217", + ast: "*", + midast: "*", + compfn: "\u2218", + smallcircle: "\u2218", + bullet: "\u2022", + bull: "\u2022", + nbsp: "\xA0", + hellip: "\u2026", + mldr: "\u2026", + prime: "\u2032", + Prime: "\u2033", + tprime: "\u2034", + bprime: "\u2035", + backprime: "\u2035", + minus: "\u2212", + minusd: "\u2238", + dotminus: "\u2238", + plusdo: "\u2214", + dotplus: "\u2214", + plusmn: "\xB1", + minusplus: "\u2213", + mnplus: "\u2213", + mp: "\u2213", + setminus: "\u2216", + smallsetminus: "\u2216", + Backslash: "\u2216", + setmn: "\u2216", + ssetmn: "\u2216", + lowbar: "_", + verbar: "|", + vert: "|", + VerticalLine: "|", + colon: ":", + Colon: "\u2237", + Proportion: "\u2237", + ratio: "\u2236", + equals: "=", + ne: "\u2260", + nequiv: "\u2262", + equiv: "\u2261", + Congruent: "\u2261", + sim: "\u223C", + thicksim: "\u223C", + thksim: "\u223C", + sime: "\u2243", + simeq: "\u2243", + TildeEqual: "\u2243", + asymp: "\u2248", + approx: "\u2248", + thickapprox: "\u2248", + thkap: "\u2248", + TildeTilde: "\u2248", + ncong: "\u2247", + cong: "\u2245", + TildeFullEqual: "\u2245", + asympeq: "\u224D", + CupCap: "\u224D", + bump: "\u224E", + Bumpeq: "\u224E", + HumpDownHump: "\u224E", + bumpe: "\u224F", + bumpeq: "\u224F", + HumpEqual: "\u224F", + dotminus: "\u2238", + minusd: "\u2238", + plusdo: "\u2214", + dotplus: "\u2214", + le: "\u2264", + LessEqual: "\u2264", + ge: "\u2265", + GreaterEqual: "\u2265", + lesseqgtr: "\u22DA", + lesseqqgtr: "\u2A8B", + greater: ">", + less: "<" +}; +var MATH_ADVANCED = { + alefsym: "\u2135", + aleph: "\u2135", + beth: "\u2136", + gimel: "\u2137", + daleth: "\u2138", + forall: "\u2200", + ForAll: "\u2200", + part: "\u2202", + PartialD: "\u2202", + exist: "\u2203", + Exists: "\u2203", + nexist: "\u2204", + nexists: "\u2204", + empty: "\u2205", + emptyset: "\u2205", + emptyv: "\u2205", + varnothing: "\u2205", + nabla: "\u2207", + Del: "\u2207", + isin: "\u2208", + isinv: "\u2208", + in: "\u2208", + Element: "\u2208", + notin: "\u2209", + notinva: "\u2209", + ni: "\u220B", + niv: "\u220B", + SuchThat: "\u220B", + ReverseElement: "\u220B", + notni: "\u220C", + notniva: "\u220C", + prod: "\u220F", + Product: "\u220F", + coprod: "\u2210", + Coproduct: "\u2210", + sum: "\u2211", + Sum: "\u2211", + minus: "\u2212", + mp: "\u2213", + plusdo: "\u2214", + dotplus: "\u2214", + setminus: "\u2216", + lowast: "\u2217", + radic: "\u221A", + Sqrt: "\u221A", + prop: "\u221D", + propto: "\u221D", + Proportional: "\u221D", + varpropto: "\u221D", + infin: "\u221E", + infintie: "\u29DD", + ang: "\u2220", + angle: "\u2220", + angmsd: "\u2221", + measuredangle: "\u2221", + angsph: "\u2222", + mid: "\u2223", + VerticalBar: "\u2223", + nmid: "\u2224", + nsmid: "\u2224", + npar: "\u2226", + parallel: "\u2225", + spar: "\u2225", + nparallel: "\u2226", + nspar: "\u2226", + and: "\u2227", + wedge: "\u2227", + or: "\u2228", + vee: "\u2228", + cap: "\u2229", + cup: "\u222A", + int: "\u222B", + Integral: "\u222B", + conint: "\u222E", + ContourIntegral: "\u222E", + Conint: "\u222F", + DoubleContourIntegral: "\u222F", + Cconint: "\u2230", + there4: "\u2234", + therefore: "\u2234", + Therefore: "\u2234", + becaus: "\u2235", + because: "\u2235", + Because: "\u2235", + ratio: "\u2236", + Proportion: "\u2237", + minusd: "\u2238", + dotminus: "\u2238", + mDDot: "\u223A", + homtht: "\u223B", + sim: "\u223C", + bsimg: "\u223D", + backsim: "\u223D", + ac: "\u223E", + mstpos: "\u223E", + acd: "\u223F", + VerticalTilde: "\u2240", + wr: "\u2240", + wreath: "\u2240", + nsime: "\u2244", + nsimeq: "\u2244", + nsimeq: "\u2244", + ncong: "\u2247", + simne: "\u2246", + ncongdot: "\u2A6D\u0338", + ngsim: "\u2275", + nsim: "\u2241", + napprox: "\u2249", + nap: "\u2249", + ngeq: "\u2271", + nge: "\u2271", + nleq: "\u2270", + nle: "\u2270", + ngtr: "\u226F", + ngt: "\u226F", + nless: "\u226E", + nlt: "\u226E", + nprec: "\u2280", + npr: "\u2280", + nsucc: "\u2281", + nsc: "\u2281" +}; +var ARROWS = { + larr: "\u2190", + leftarrow: "\u2190", + LeftArrow: "\u2190", + uarr: "\u2191", + uparrow: "\u2191", + UpArrow: "\u2191", + rarr: "\u2192", + rightarrow: "\u2192", + RightArrow: "\u2192", + darr: "\u2193", + downarrow: "\u2193", + DownArrow: "\u2193", + harr: "\u2194", + leftrightarrow: "\u2194", + LeftRightArrow: "\u2194", + varr: "\u2195", + updownarrow: "\u2195", + UpDownArrow: "\u2195", + nwarr: "\u2196", + nwarrow: "\u2196", + UpperLeftArrow: "\u2196", + nearr: "\u2197", + nearrow: "\u2197", + UpperRightArrow: "\u2197", + searr: "\u2198", + searrow: "\u2198", + LowerRightArrow: "\u2198", + swarr: "\u2199", + swarrow: "\u2199", + LowerLeftArrow: "\u2199", + lArr: "\u21D0", + Leftarrow: "\u21D0", + uArr: "\u21D1", + Uparrow: "\u21D1", + rArr: "\u21D2", + Rightarrow: "\u21D2", + dArr: "\u21D3", + Downarrow: "\u21D3", + hArr: "\u21D4", + Leftrightarrow: "\u21D4", + iff: "\u21D4", + vArr: "\u21D5", + Updownarrow: "\u21D5", + lAarr: "\u21DA", + Lleftarrow: "\u21DA", + rAarr: "\u21DB", + Rrightarrow: "\u21DB", + lrarr: "\u21C6", + leftrightarrows: "\u21C6", + rlarr: "\u21C4", + rightleftarrows: "\u21C4", + lrhar: "\u21CB", + leftrightharpoons: "\u21CB", + ReverseEquilibrium: "\u21CB", + rlhar: "\u21CC", + rightleftharpoons: "\u21CC", + Equilibrium: "\u21CC", + udarr: "\u21C5", + UpArrowDownArrow: "\u21C5", + duarr: "\u21F5", + DownArrowUpArrow: "\u21F5", + llarr: "\u21C7", + leftleftarrows: "\u21C7", + rrarr: "\u21C9", + rightrightarrows: "\u21C9", + ddarr: "\u21CA", + downdownarrows: "\u21CA", + har: "\u21BD", + lhard: "\u21BD", + leftharpoondown: "\u21BD", + lharu: "\u21BC", + leftharpoonup: "\u21BC", + rhard: "\u21C1", + rightharpoondown: "\u21C1", + rharu: "\u21C0", + rightharpoonup: "\u21C0", + lsh: "\u21B0", + Lsh: "\u21B0", + rsh: "\u21B1", + Rsh: "\u21B1", + ldsh: "\u21B2", + rdsh: "\u21B3", + hookleftarrow: "\u21A9", + hookrightarrow: "\u21AA", + mapstoleft: "\u21A4", + mapstoup: "\u21A5", + map: "\u21A6", + mapsto: "\u21A6", + mapstodown: "\u21A7", + crarr: "\u21B5", + nwarrow: "\u2196", + nearrow: "\u2197", + searrow: "\u2198", + swarrow: "\u2199", + nleftarrow: "\u219A", + nleftrightarrow: "\u21AE", + nrightarrow: "\u219B", + nrarr: "\u219B", + larrtl: "\u21A2", + rarrtl: "\u21A3", + leftarrowtail: "\u21A2", + rightarrowtail: "\u21A3", + twoheadleftarrow: "\u219E", + twoheadrightarrow: "\u21A0", + Larr: "\u219E", + Rarr: "\u21A0", + larrhk: "\u21A9", + rarrhk: "\u21AA", + larrlp: "\u21AB", + looparrowleft: "\u21AB", + rarrlp: "\u21AC", + looparrowright: "\u21AC", + harrw: "\u21AD", + leftrightsquigarrow: "\u21AD", + nrarrw: "\u219D\u0338", + rarrw: "\u219D", + rightsquigarrow: "\u219D", + larrbfs: "\u291F", + rarrbfs: "\u2920", + nvHarr: "\u2904", + nvlArr: "\u2902", + nvrArr: "\u2903", + larrfs: "\u291D", + rarrfs: "\u291E", + Map: "\u2905", + larrsim: "\u2973", + rarrsim: "\u2974", + harrcir: "\u2948", + Uarrocir: "\u2949", + lurdshar: "\u294A", + ldrdhar: "\u2967", + ldrushar: "\u294B", + rdldhar: "\u2969", + lrhard: "\u296D", + rlhar: "\u21CC", + uharr: "\u21BE", + uharl: "\u21BF", + dharr: "\u21C2", + dharl: "\u21C3", + Uarr: "\u219F", + Darr: "\u21A1", + zigrarr: "\u21DD", + nwArr: "\u21D6", + neArr: "\u21D7", + seArr: "\u21D8", + swArr: "\u21D9", + nharr: "\u21AE", + nhArr: "\u21CE", + nlarr: "\u219A", + nlArr: "\u21CD", + nrarr: "\u219B", + nrArr: "\u21CF", + larrb: "\u21E4", + LeftArrowBar: "\u21E4", + rarrb: "\u21E5", + RightArrowBar: "\u21E5" +}; +var SHAPES = { + square: "\u25A1", + Square: "\u25A1", + squ: "\u25A1", + squf: "\u25AA", + squarf: "\u25AA", + blacksquar: "\u25AA", + blacksquare: "\u25AA", + FilledVerySmallSquare: "\u25AA", + blk34: "\u2593", + blk12: "\u2592", + blk14: "\u2591", + block: "\u2588", + srect: "\u25AD", + rect: "\u25AD", + sdot: "\u22C5", + sdotb: "\u22A1", + dotsquare: "\u22A1", + triangle: "\u25B5", + tri: "\u25B5", + trine: "\u25B5", + utri: "\u25B5", + triangledown: "\u25BF", + dtri: "\u25BF", + tridown: "\u25BF", + triangleleft: "\u25C3", + ltri: "\u25C3", + triangleright: "\u25B9", + rtri: "\u25B9", + blacktriangle: "\u25B4", + utrif: "\u25B4", + blacktriangledown: "\u25BE", + dtrif: "\u25BE", + blacktriangleleft: "\u25C2", + ltrif: "\u25C2", + blacktriangleright: "\u25B8", + rtrif: "\u25B8", + loz: "\u25CA", + lozenge: "\u25CA", + blacklozenge: "\u29EB", + lozf: "\u29EB", + bigcirc: "\u25EF", + xcirc: "\u25EF", + circ: "\u02C6", + Circle: "\u25CB", + cir: "\u25CB", + o: "\u25CB", + bullet: "\u2022", + bull: "\u2022", + hellip: "\u2026", + mldr: "\u2026", + nldr: "\u2025", + boxh: "\u2500", + HorizontalLine: "\u2500", + boxv: "\u2502", + boxdr: "\u250C", + boxdl: "\u2510", + boxur: "\u2514", + boxul: "\u2518", + boxvr: "\u251C", + boxvl: "\u2524", + boxhd: "\u252C", + boxhu: "\u2534", + boxvh: "\u253C", + boxH: "\u2550", + boxV: "\u2551", + boxdR: "\u2552", + boxDr: "\u2553", + boxDR: "\u2554", + boxDl: "\u2555", + boxdL: "\u2556", + boxDL: "\u2557", + boxuR: "\u2558", + boxUr: "\u2559", + boxUR: "\u255A", + boxUl: "\u255C", + boxuL: "\u255B", + boxUL: "\u255D", + boxvR: "\u255E", + boxVr: "\u255F", + boxVR: "\u2560", + boxVl: "\u2562", + boxvL: "\u2561", + boxVL: "\u2563", + boxHd: "\u2564", + boxhD: "\u2565", + boxHD: "\u2566", + boxHu: "\u2567", + boxhU: "\u2568", + boxHU: "\u2569", + boxvH: "\u256A", + boxVh: "\u256B", + boxVH: "\u256C" +}; +var PUNCTUATION = { + excl: "!", + iexcl: "\xA1", + brvbar: "\xA6", + sect: "\xA7", + uml: "\xA8", + copy: "\xA9", + ordf: "\xAA", + laquo: "\xAB", + not: "\xAC", + shy: "\xAD", + reg: "\xAE", + macr: "\xAF", + deg: "\xB0", + plusmn: "\xB1", + sup2: "\xB2", + sup3: "\xB3", + acute: "\xB4", + micro: "\xB5", + para: "\xB6", + middot: "\xB7", + cedil: "\xB8", + sup1: "\xB9", + ordm: "\xBA", + raquo: "\xBB", + frac14: "\xBC", + frac12: "\xBD", + frac34: "\xBE", + iquest: "\xBF", + nbsp: "\xA0", + comma: ",", + period: ".", + colon: ":", + semi: ";", + vert: "|", + Verbar: "\u2016", + verbar: "|", + dblac: "\u02DD", + circ: "\u02C6", + caron: "\u02C7", + breve: "\u02D8", + dot: "\u02D9", + ring: "\u02DA", + ogon: "\u02DB", + tilde: "\u02DC", + DiacriticalGrave: "`", + DiacriticalAcute: "\xB4", + DiacriticalTilde: "\u02DC", + DiacriticalDot: "\u02D9", + DiacriticalDoubleAcute: "\u02DD", + grave: "`", + acute: "\xB4" +}; +var CURRENCY = { + cent: "\xA2", + pound: "\xA3", + curren: "\xA4", + yen: "\xA5", + euro: "\u20AC", + dollar: "$", + euro: "\u20AC", + fnof: "\u0192", + inr: "\u20B9", + af: "\u060B", + birr: "\u1265\u122D", + peso: "\u20B1", + rub: "\u20BD", + won: "\u20A9", + yuan: "\xA5", + cedil: "\xB8" +}; +var FRACTIONS = { + frac12: "\xBD", + half: "\xBD", + frac13: "\u2153", + frac14: "\xBC", + frac15: "\u2155", + frac16: "\u2159", + frac18: "\u215B", + frac23: "\u2154", + frac25: "\u2156", + frac34: "\xBE", + frac35: "\u2157", + frac38: "\u215C", + frac45: "\u2158", + frac56: "\u215A", + frac58: "\u215D", + frac78: "\u215E", + frasl: "\u2044" +}; +var MISC_SYMBOLS = { + trade: "\u2122", + TRADE: "\u2122", + telrec: "\u2315", + target: "\u2316", + ulcorn: "\u231C", + ulcorner: "\u231C", + urcorn: "\u231D", + urcorner: "\u231D", + dlcorn: "\u231E", + llcorner: "\u231E", + drcorn: "\u231F", + lrcorner: "\u231F", + intercal: "\u22BA", + intcal: "\u22BA", + oplus: "\u2295", + CirclePlus: "\u2295", + ominus: "\u2296", + CircleMinus: "\u2296", + otimes: "\u2297", + CircleTimes: "\u2297", + osol: "\u2298", + odot: "\u2299", + CircleDot: "\u2299", + oast: "\u229B", + circledast: "\u229B", + odash: "\u229D", + circleddash: "\u229D", + ocirc: "\u229A", + circledcirc: "\u229A", + boxplus: "\u229E", + plusb: "\u229E", + boxminus: "\u229F", + minusb: "\u229F", + boxtimes: "\u22A0", + timesb: "\u22A0", + boxdot: "\u22A1", + sdotb: "\u22A1", + veebar: "\u22BB", + vee: "\u2228", + barvee: "\u22BD", + and: "\u2227", + wedge: "\u2227", + Cap: "\u22D2", + Cup: "\u22D3", + Fork: "\u22D4", + pitchfork: "\u22D4", + epar: "\u22D5", + ltlarr: "\u2976", + nvap: "\u224D\u20D2", + nvsim: "\u223C\u20D2", + nvge: "\u2265\u20D2", + nvle: "\u2264\u20D2", + nvlt: "<\u20D2", + nvgt: ">\u20D2", + nvltrie: "\u22B4\u20D2", + nvrtrie: "\u22B5\u20D2", + Vdash: "\u22A9", + dashv: "\u22A3", + vDash: "\u22A8", + Vdash: "\u22A9", + Vvdash: "\u22AA", + nvdash: "\u22AC", + nvDash: "\u22AD", + nVdash: "\u22AE", + nVDash: "\u22AF" +}; +var ALL_ENTITIES = { + ...BASIC_LATIN, + ...LATIN_ACCENTS, + ...LATIN_EXTENDED, + ...GREEK, + ...CYRILLIC, + ...MATH, + ...MATH_ADVANCED, + ...ARROWS, + ...SHAPES, + ...PUNCTUATION, + ...CURRENCY, + ...FRACTIONS, + ...MISC_SYMBOLS +}; +var XML = { + amp: "&", + apos: "'", + gt: ">", + lt: "<", + quot: '"' +}; +var COMMON_HTML = { + nbsp: "\xA0", + copy: "\xA9", + reg: "\xAE", + trade: "\u2122", + mdash: "\u2014", + ndash: "\u2013", + hellip: "\u2026", + laquo: "\xAB", + raquo: "\xBB", + lsquo: "\u2018", + rsquo: "\u2019", + ldquo: "\u201C", + rdquo: "\u201D", + bull: "\u2022", + para: "\xB6", + sect: "\xA7", + deg: "\xB0", + frac12: "\xBD", + frac14: "\xBC", + frac34: "\xBE" +}; + +// node_modules/@nodable/entities/src/EntityDecoder.js +var SPECIAL_CHARS = new Set("!?\\\\/[]$%{}^&*()<>|+"); +function validateEntityName(name) { + if (name[0] === "#") { + throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${name}"`); + } + for (const ch of name) { + if (SPECIAL_CHARS.has(ch)) { + throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: "${name}"`); + } + } + return name; +} +function mergeEntityMaps(...maps) { + const out = /* @__PURE__ */ Object.create(null); + for (const map2 of maps) { + if (!map2) continue; + for (const key of Object.keys(map2)) { + const raw = map2[key]; + if (typeof raw === "string") { + out[key] = raw; + } else if (raw && typeof raw === "object" && raw.val !== void 0) { + const val = raw.val; + if (typeof val === "string") { + out[key] = val; + } + } + } + } + return out; +} +var LIMIT_TIER_EXTERNAL = "external"; +var LIMIT_TIER_BASE = "base"; +var LIMIT_TIER_ALL = "all"; +function parseLimitTiers(raw) { + if (!raw || raw === LIMIT_TIER_EXTERNAL) return /* @__PURE__ */ new Set([LIMIT_TIER_EXTERNAL]); + if (raw === LIMIT_TIER_ALL) return /* @__PURE__ */ new Set([LIMIT_TIER_ALL]); + if (raw === LIMIT_TIER_BASE) return /* @__PURE__ */ new Set([LIMIT_TIER_BASE]); + if (Array.isArray(raw)) return new Set(raw); + return /* @__PURE__ */ new Set([LIMIT_TIER_EXTERNAL]); +} +var NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 }); +var XML10_ALLOWED_C0 = /* @__PURE__ */ new Set([9, 10, 13]); +function parseNCRConfig(ncr) { + if (!ncr) { + return { xmlVersion: 1, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove }; + } + const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1; + const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow; + const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove; + const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove); + return { xmlVersion, onLevel, nullLevel: clampedNull }; +} +var EntityDecoder = class { + /** + * @param {object} [options] + * @param {object|null} [options.namedEntities] — extra named entities merged into base map + * @param {object} [options.limit] — security limits + * @param {number} [options.limit.maxTotalExpansions=0] — 0 = unlimited + * @param {number} [options.limit.maxExpandedLength=0] — 0 = unlimited + * @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external'] + * Which entity tiers count against the security limits: + * - 'external' (default) — only input/runtime + persistent external entities + * - 'base' — only DEFAULT_XML_ENTITIES + namedEntities + * - 'all' — every entity regardless of tier + * - string[] — explicit combination, e.g. ['external', 'base'] + * @param {((resolved: string, original: string) => string)|null} [options.postCheck=null] + * @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string) + * @param {string[]} [options.leave=[]] — entity names to keep as literal (unchanged in output) + * @param {object} [options.ncr] — Numeric Character Reference controls + * @param {1.0|1.1} [options.ncr.xmlVersion=1.0] + * XML version governing which codepoint ranges are restricted: + * - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited + * - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is + * @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow'] + * Base action for numeric references. Severity order: allow < leave < remove < throw. + * For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove), + * the effective action is max(onNCR, rangeMinimum). + * @param {'remove'|'throw'} [options.ncr.nullNCR='remove'] + * Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe. + */ + constructor(options = {}) { + this._limit = options.limit || {}; + this._maxTotalExpansions = this._limit.maxTotalExpansions || 0; + this._maxExpandedLength = this._limit.maxExpandedLength || 0; + this._postCheck = typeof options.postCheck === "function" ? options.postCheck : (r) => r; + this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL); + this._numericAllowed = options.numericAllowed ?? true; + this._baseMap = mergeEntityMaps(XML, options.namedEntities || null); + this._externalMap = /* @__PURE__ */ Object.create(null); + this._inputMap = /* @__PURE__ */ Object.create(null); + this._totalExpansions = 0; + this._expandedLength = 0; + this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []); + this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []); + const ncrCfg = parseNCRConfig(options.ncr); + this._ncrXmlVersion = ncrCfg.xmlVersion; + this._ncrOnLevel = ncrCfg.onLevel; + this._ncrNullLevel = ncrCfg.nullLevel; + } + // ------------------------------------------------------------------------- + // Persistent external entity registration + // ------------------------------------------------------------------------- + /** + * Replace the full set of persistent external entities. + * All keys are validated — throws on invalid characters. + * @param {Record} map + */ + setExternalEntities(map2) { + if (map2) { + for (const key of Object.keys(map2)) { + validateEntityName(key); + } + } + this._externalMap = mergeEntityMaps(map2); + } + /** + * Add a single persistent external entity. + * @param {string} key + * @param {string} value + */ + addExternalEntity(key, value) { + validateEntityName(key); + if (typeof value === "string" && value.indexOf("&") === -1) { + this._externalMap[key] = value; + } + } + // ------------------------------------------------------------------------- + // Input / runtime entity registration (per document) + // ------------------------------------------------------------------------- + /** + * Inject DOCTYPE entities for the current document. + * Also resets per-document expansion counters. + * @param {Record} map + */ + addInputEntities(map2) { + this._totalExpansions = 0; + this._expandedLength = 0; + this._inputMap = mergeEntityMaps(map2); + } + // ------------------------------------------------------------------------- + // Per-document reset + // ------------------------------------------------------------------------- + /** + * Wipe input/runtime entities and reset counters. + * Call this before processing each new document. + * @returns {this} + */ + reset() { + this._inputMap = /* @__PURE__ */ Object.create(null); + this._totalExpansions = 0; + this._expandedLength = 0; + return this; + } + // ------------------------------------------------------------------------- + // XML version (can be set after construction, e.g. once parser reads ) + // ------------------------------------------------------------------------- + /** + * Update the XML version used for NCR classification. + * Call this as soon as the document's `` declaration is parsed. + * @param {1.0|1.1|number} version + */ + setXmlVersion(version3) { + this._ncrXmlVersion = version3 === 1.1 ? 1.1 : 1; + } + // ------------------------------------------------------------------------- + // Primary API + // ------------------------------------------------------------------------- + /** + * Replace all entity references in `str` in a single pass. + * + * @param {string} str + * @returns {string} + */ + decode(str2) { + if (typeof str2 !== "string" || str2.length === 0) return str2; + const original = str2; + const chunks = []; + const len = str2.length; + let last = 0; + let i = 0; + const limitExpansions = this._maxTotalExpansions > 0; + const limitLength = this._maxExpandedLength > 0; + const checkLimits = limitExpansions || limitLength; + while (i < len) { + if (str2.charCodeAt(i) !== 38) { + i++; + continue; + } + let j2 = i + 1; + while (j2 < len && str2.charCodeAt(j2) !== 59 && j2 - i <= 32) j2++; + if (j2 >= len || str2.charCodeAt(j2) !== 59) { + i++; + continue; + } + const token = str2.slice(i + 1, j2); + if (token.length === 0) { + i++; + continue; + } + let replacement; + let tier2; + if (this._removeSet.has(token)) { + replacement = ""; + if (tier2 === void 0) { + tier2 = LIMIT_TIER_EXTERNAL; + } + } else if (this._leaveSet.has(token)) { + i++; + continue; + } else if (token.charCodeAt(0) === 35) { + const ncrResult = this._resolveNCR(token); + if (ncrResult === void 0) { + i++; + continue; + } + replacement = ncrResult; + tier2 = LIMIT_TIER_BASE; + } else { + const resolved = this._resolveName(token); + replacement = resolved?.value; + tier2 = resolved?.tier; + } + if (replacement === void 0) { + i++; + continue; + } + if (i > last) chunks.push(str2.slice(last, i)); + chunks.push(replacement); + last = j2 + 1; + i = last; + if (checkLimits && this._tierCounts(tier2)) { + if (limitExpansions) { + this._totalExpansions++; + if (this._totalExpansions > this._maxTotalExpansions) { + throw new Error( + `[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}` + ); + } + } + if (limitLength) { + const delta = replacement.length - (token.length + 2); + if (delta > 0) { + this._expandedLength += delta; + if (this._expandedLength > this._maxExpandedLength) { + throw new Error( + `[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}` + ); + } + } + } + } + } + if (last < len) chunks.push(str2.slice(last)); + const result = chunks.length === 0 ? str2 : chunks.join(""); + return this._postCheck(result, original); + } + // ------------------------------------------------------------------------- + // Private: limit tier check + // ------------------------------------------------------------------------- + /** + * Returns true if a resolved entity of the given tier should count + * against the expansion/length limits. + * @param {string} tier — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE + * @returns {boolean} + */ + _tierCounts(tier2) { + if (this._limitTiers.has(LIMIT_TIER_ALL)) return true; + return this._limitTiers.has(tier2); + } + // ------------------------------------------------------------------------- + // Private: entity resolution + // ------------------------------------------------------------------------- + /** + * Resolve a named entity token (without & and ;). + * Priority: inputMap > externalMap > baseMap + * Returns the resolved value tagged with its limit tier. + * + * @param {string} name + * @returns {{ value: string, tier: string }|undefined} + */ + _resolveName(name) { + if (name in this._inputMap) return { value: this._inputMap[name], tier: LIMIT_TIER_EXTERNAL }; + if (name in this._externalMap) return { value: this._externalMap[name], tier: LIMIT_TIER_EXTERNAL }; + if (name in this._baseMap) return { value: this._baseMap[name], tier: LIMIT_TIER_BASE }; + return void 0; + } + /** + * Classify a codepoint and return the minimum action level that must be applied. + * Returns -1 when no minimum is imposed (normal allow path). + * + * Ranges checked (in priority order): + * 1. U+0000 — null, governed by nullNCR (always ≥ remove) + * 2. U+D800–U+DFFF — surrogates, always prohibited (min: remove) + * 3. U+0001–U+001F \ {0x09,0x0A,0x0D} — XML 1.0 restricted C0 (min: remove) + * (skipped in XML 1.1 — C0 controls are allowed when written as NCRs) + * + * @param {number} cp — codepoint + * @returns {number} — minimum NCR_LEVEL value, or -1 for no restriction + */ + _classifyNCR(cp2) { + if (cp2 === 0) return this._ncrNullLevel; + if (cp2 >= 55296 && cp2 <= 57343) return NCR_LEVEL.remove; + if (this._ncrXmlVersion === 1) { + if (cp2 >= 1 && cp2 <= 31 && !XML10_ALLOWED_C0.has(cp2)) return NCR_LEVEL.remove; + } + return -1; + } + /** + * Execute a resolved NCR action. + * + * @param {number} action — NCR_LEVEL value + * @param {string} token — raw token (e.g. '#38') for error messages + * @param {number} cp — codepoint, used only for error messages + * @returns {string|undefined} + * - decoded character string → 'allow' + * - '' → 'remove' + * - undefined → 'leave' (caller must skip past '&' only) + * - throws Error → 'throw' + */ + _applyNCRAction(action5, token, cp2) { + switch (action5) { + case NCR_LEVEL.allow: + return String.fromCodePoint(cp2); + case NCR_LEVEL.remove: + return ""; + case NCR_LEVEL.leave: + return void 0; + // signal: keep literal + case NCR_LEVEL.throw: + throw new Error( + `[EntityDecoder] Prohibited numeric character reference &${token}; (U+${cp2.toString(16).toUpperCase().padStart(4, "0")})` + ); + default: + return String.fromCodePoint(cp2); + } + } + /** + * Full NCR resolution pipeline for a numeric token. + * + * Steps: + * 1. Parse the codepoint (decimal or hex). + * 2. Validate the raw codepoint range (NaN, <0, >0x10FFFF). + * 3. If numericAllowed is false and no minimum restriction applies → leave as-is. + * 4. Classify the codepoint to find the minimum required action level. + * 5. Resolve effective action = max(onNCR, minimum). + * 6. Apply and return. + * + * @param {string} token — e.g. '#38', '#x26', '#X26' + * @returns {string|undefined} + * - string (incl. '') — replacement ('' = remove) + * - undefined — leave original &token; as-is + */ + _resolveNCR(token) { + const second = token.charCodeAt(1); + let cp2; + if (second === 120 || second === 88) { + cp2 = parseInt(token.slice(2), 16); + } else { + cp2 = parseInt(token.slice(1), 10); + } + if (Number.isNaN(cp2) || cp2 < 0 || cp2 > 1114111) return void 0; + const minimum = this._classifyNCR(cp2); + if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return void 0; + const effective = minimum === -1 ? this._ncrOnLevel : Math.max(this._ncrOnLevel, minimum); + return this._applyNCRAction(effective, token, cp2); + } +}; + // node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js var defaultOnDangerousProperty = (name) => { if (DANGEROUS_PROPERTY_NAMES.includes(name)) { @@ -59045,6 +60615,7 @@ var defaultOptions2 = { unpairedTags: [], processEntities: true, htmlEntities: false, + entityDecoder: null, ignoreDeclaration: false, ignorePiTags: false, transformTagName: false, @@ -59076,18 +60647,19 @@ function validatePropertyName(propertyName, optionName) { ); } } -function normalizeProcessEntities(value) { +function normalizeProcessEntities(value, htmlEntities) { if (typeof value === "boolean") { return { enabled: value, // true or false maxEntitySize: 1e4, - maxExpansionDepth: 10, - maxTotalExpansions: 1e3, + maxExpansionDepth: 1e4, + maxTotalExpansions: Infinity, maxExpandedLength: 1e5, - maxEntityCount: 100, + maxEntityCount: 1e3, allowedTags: null, - tagFilter: null + tagFilter: null, + appliesTo: "all" }; } if (typeof value === "object" && value !== null) { @@ -59099,7 +60671,8 @@ function normalizeProcessEntities(value) { maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 1e5), maxEntityCount: Math.max(1, value.maxEntityCount ?? 1e3), allowedTags: value.allowedTags ?? null, - tagFilter: value.tagFilter ?? null + tagFilter: value.tagFilter ?? null, + appliesTo: value.appliesTo ?? "all" }; } return normalizeProcessEntities(true); @@ -59121,7 +60694,8 @@ var buildOptions = function(options) { if (built.onDangerousProperty === null) { built.onDangerousProperty = defaultOnDangerousProperty; } - built.processEntities = normalizeProcessEntities(built.processEntities); + built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities); + built.unpairedTagsSet = new Set(built.unpairedTags); if (built.stopNodes && Array.isArray(built.stopNodes)) { built.stopNodes = built.stopNodes.map((node) => { if (typeof node === "string" && node.startsWith("*.")) { @@ -59193,11 +60767,7 @@ var DocTypeReader = class { `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})` ); } - const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); - entities[entityName] = { - regx: RegExp(`&${escaped};`, "g"), - val - }; + entities[entityName] = val; entityCount++; } } else if (hasBody && hasSeq(xmlData, "!ELEMENT", i)) { @@ -59247,7 +60817,7 @@ var DocTypeReader = class { i++; } let entityName = xmlData.substring(startIndex, i); - validateEntityName(entityName); + validateEntityName2(entityName); i = skipWhitespace(xmlData, i); if (!this.suppressValidationErr) { if (xmlData.substring(i, i + 6).toUpperCase() === "SYSTEM") { @@ -59273,7 +60843,7 @@ var DocTypeReader = class { i++; } let notationName = xmlData.substring(startIndex, i); - !this.suppressValidationErr && validateEntityName(notationName); + !this.suppressValidationErr && validateEntityName2(notationName); i = skipWhitespace(xmlData, i); const identifierType = xmlData.substring(i, i + 6).toUpperCase(); if (!this.suppressValidationErr && identifierType !== "SYSTEM" && identifierType !== "PUBLIC") { @@ -59355,14 +60925,14 @@ var DocTypeReader = class { i++; } let elementName = xmlData.substring(startIndex, i); - validateEntityName(elementName); + validateEntityName2(elementName); i = skipWhitespace(xmlData, i); startIndex = i; while (i < xmlData.length && !/\s/.test(xmlData[i])) { i++; } let attributeName = xmlData.substring(startIndex, i); - if (!validateEntityName(attributeName)) { + if (!validateEntityName2(attributeName)) { throw new Error(`Invalid attribute name: "${attributeName}"`); } i = skipWhitespace(xmlData, i); @@ -59383,7 +60953,7 @@ var DocTypeReader = class { } let notation = xmlData.substring(startIndex2, i); notation = notation.trim(); - if (!validateEntityName(notation)) { + if (!validateEntityName2(notation)) { throw new Error(`Invalid notation name: "${notation}"`); } allowedNotations.push(notation); @@ -59440,7 +61010,7 @@ function hasSeq(data, seq2, i) { } return true; } -function validateEntityName(name) { +function validateEntityName2(name) { if (isName(name)) return name; else @@ -59597,10 +61167,11 @@ var Expression = class { * @param {Object} options - Configuration options * @param {string} options.separator - Path separator (default: '.') */ - constructor(pattern, options = {}) { + constructor(pattern, options = {}, data) { this.pattern = pattern; this.separator = options.separator || "."; this.segments = this._parse(pattern); + this.data = data; this._hasDeepWildcard = this.segments.some((seg) => seg.type === "deep-wildcard"); this._hasAttributeCondition = this.segments.some((seg) => seg.attrName !== void 0); this._hasPositionSelector = this.segments.some((seg) => seg.position !== void 0); @@ -59751,30 +61322,302 @@ var Expression = class { } }; +// node_modules/path-expression-matcher/src/ExpressionSet.js +var ExpressionSet = class { + constructor() { + this._byDepthAndTag = /* @__PURE__ */ new Map(); + this._wildcardByDepth = /* @__PURE__ */ new Map(); + this._deepWildcards = []; + this._patterns = /* @__PURE__ */ new Set(); + this._sealed = false; + } + /** + * Add an Expression to the set. + * Duplicate patterns (same pattern string) are silently ignored. + * + * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance + * @returns {this} for chaining + * @throws {TypeError} if called after seal() + * + * @example + * set.add(new Expression('root.users.user')); + * set.add(new Expression('..script')); + */ + add(expression) { + if (this._sealed) { + throw new TypeError( + "ExpressionSet is sealed. Create a new ExpressionSet to add more expressions." + ); + } + if (this._patterns.has(expression.pattern)) return this; + this._patterns.add(expression.pattern); + if (expression.hasDeepWildcard()) { + this._deepWildcards.push(expression); + return this; + } + const depth = expression.length; + const lastSeg = expression.segments[expression.segments.length - 1]; + const tag = lastSeg?.tag; + if (!tag || tag === "*") { + if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []); + this._wildcardByDepth.get(depth).push(expression); + } else { + const key = `${depth}:${tag}`; + if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []); + this._byDepthAndTag.get(key).push(expression); + } + return this; + } + /** + * Add multiple expressions at once. + * + * @param {import('./Expression.js').default[]} expressions - Array of Expression instances + * @returns {this} for chaining + * + * @example + * set.addAll([ + * new Expression('root.users.user'), + * new Expression('root.config.setting'), + * ]); + */ + addAll(expressions) { + for (const expr of expressions) this.add(expr); + return this; + } + /** + * Check whether a pattern string is already present in the set. + * + * @param {import('./Expression.js').default} expression + * @returns {boolean} + */ + has(expression) { + return this._patterns.has(expression.pattern); + } + /** + * Number of expressions in the set. + * @type {number} + */ + get size() { + return this._patterns.size; + } + /** + * Seal the set against further modifications. + * Useful to prevent accidental mutations after config is built. + * Calling add() or addAll() on a sealed set throws a TypeError. + * + * @returns {this} + */ + seal() { + this._sealed = true; + return this; + } + /** + * Whether the set has been sealed. + * @type {boolean} + */ + get isSealed() { + return this._sealed; + } + /** + * Test whether the matcher's current path matches any expression in the set. + * + * Evaluation order (cheapest → most expensive): + * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions + * 2. Depth-only wildcard bucket — O(1) lookup, rare + * 3. Deep-wildcard list — always checked, but usually small + * + * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view) + * @returns {boolean} true if any expression matches the current path + * + * @example + * if (stopNodes.matchesAny(matcher)) { + * // handle stop node + * } + */ + matchesAny(matcher) { + return this.findMatch(matcher) !== null; + } + /** + * Find and return the first Expression that matches the matcher's current path. + * + * Uses the same evaluation order as matchesAny (cheapest → most expensive): + * 1. Exact depth + tag bucket + * 2. Depth-only wildcard bucket + * 3. Deep-wildcard list + * + * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view) + * @returns {import('./Expression.js').default | null} the first matching Expression, or null + * + * @example + * const expr = stopNodes.findMatch(matcher); + * if (expr) { + * // access expr.config, expr.pattern, etc. + * } + */ + findMatch(matcher) { + const depth = matcher.getDepth(); + const tag = matcher.getCurrentTag(); + const exactKey = `${depth}:${tag}`; + const exactBucket = this._byDepthAndTag.get(exactKey); + if (exactBucket) { + for (let i = 0; i < exactBucket.length; i++) { + if (matcher.matches(exactBucket[i])) return exactBucket[i]; + } + } + const wildcardBucket = this._wildcardByDepth.get(depth); + if (wildcardBucket) { + for (let i = 0; i < wildcardBucket.length; i++) { + if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i]; + } + } + for (let i = 0; i < this._deepWildcards.length; i++) { + if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i]; + } + return null; + } +}; + // node_modules/path-expression-matcher/src/Matcher.js -var MUTATING_METHODS = /* @__PURE__ */ new Set(["push", "pop", "reset", "updateCurrent", "restore"]); +var MatcherView = class { + /** + * @param {Matcher} matcher - The parent Matcher instance to read from. + */ + constructor(matcher) { + this._matcher = matcher; + } + /** + * Get the path separator used by the parent matcher. + * @returns {string} + */ + get separator() { + return this._matcher.separator; + } + /** + * Get current tag name. + * @returns {string|undefined} + */ + getCurrentTag() { + const path36 = this._matcher.path; + return path36.length > 0 ? path36[path36.length - 1].tag : void 0; + } + /** + * Get current namespace. + * @returns {string|undefined} + */ + getCurrentNamespace() { + const path36 = this._matcher.path; + return path36.length > 0 ? path36[path36.length - 1].namespace : void 0; + } + /** + * Get current node's attribute value. + * @param {string} attrName + * @returns {*} + */ + getAttrValue(attrName) { + const path36 = this._matcher.path; + if (path36.length === 0) return void 0; + return path36[path36.length - 1].values?.[attrName]; + } + /** + * Check if current node has an attribute. + * @param {string} attrName + * @returns {boolean} + */ + hasAttr(attrName) { + const path36 = this._matcher.path; + if (path36.length === 0) return false; + const current = path36[path36.length - 1]; + return current.values !== void 0 && attrName in current.values; + } + /** + * Get current node's sibling position (child index in parent). + * @returns {number} + */ + getPosition() { + const path36 = this._matcher.path; + if (path36.length === 0) return -1; + return path36[path36.length - 1].position ?? 0; + } + /** + * Get current node's repeat counter (occurrence count of this tag name). + * @returns {number} + */ + getCounter() { + const path36 = this._matcher.path; + if (path36.length === 0) return -1; + return path36[path36.length - 1].counter ?? 0; + } + /** + * Get current node's sibling index (alias for getPosition). + * @returns {number} + * @deprecated Use getPosition() or getCounter() instead + */ + getIndex() { + return this.getPosition(); + } + /** + * Get current path depth. + * @returns {number} + */ + getDepth() { + return this._matcher.path.length; + } + /** + * Get path as string. + * @param {string} [separator] - Optional separator (uses default if not provided) + * @param {boolean} [includeNamespace=true] + * @returns {string} + */ + toString(separator, includeNamespace = true) { + return this._matcher.toString(separator, includeNamespace); + } + /** + * Get path as array of tag names. + * @returns {string[]} + */ + toArray() { + return this._matcher.path.map((n7) => n7.tag); + } + /** + * Match current path against an Expression. + * @param {Expression} expression + * @returns {boolean} + */ + matches(expression) { + return this._matcher.matches(expression); + } + /** + * Match any expression in the given set against the current path. + * @param {ExpressionSet} exprSet + * @returns {boolean} + */ + matchesAny(exprSet) { + return exprSet.matchesAny(this._matcher); + } +}; var Matcher = class { /** - * Create a new Matcher - * @param {Object} options - Configuration options - * @param {string} options.separator - Default path separator (default: '.') + * Create a new Matcher. + * @param {Object} [options={}] + * @param {string} [options.separator='.'] - Default path separator */ constructor(options = {}) { this.separator = options.separator || "."; this.path = []; this.siblingStacks = []; + this._pathStringCache = null; + this._view = new MatcherView(this); } /** - * Push a new tag onto the path - * @param {string} tagName - Name of the tag - * @param {Object} attrValues - Attribute key-value pairs for current node (optional) - * @param {string} namespace - Namespace for the tag (optional) + * Push a new tag onto the path. + * @param {string} tagName + * @param {Object|null} [attrValues=null] + * @param {string|null} [namespace=null] */ push(tagName, attrValues = null, namespace = null) { this._pathStringCache = null; if (this.path.length > 0) { - const prev = this.path[this.path.length - 1]; - prev.values = void 0; + this.path[this.path.length - 1].values = void 0; } const currentLevel = this.path.length; if (!this.siblingStacks[currentLevel]) { @@ -59802,13 +61645,11 @@ var Matcher = class { this.path.push(node); } /** - * Pop the last tag from the path + * Pop the last tag from the path. * @returns {Object|undefined} The popped node */ pop() { - if (this.path.length === 0) { - return void 0; - } + if (this.path.length === 0) return void 0; this._pathStringCache = null; const node = this.path.pop(); if (this.siblingStacks.length > this.path.length + 1) { @@ -59817,9 +61658,9 @@ var Matcher = class { return node; } /** - * Update current node's attribute values - * Useful when attributes are parsed after push - * @param {Object} attrValues - Attribute values + * Update current node's attribute values. + * Useful when attributes are parsed after push. + * @param {Object} attrValues */ updateCurrent(attrValues) { if (this.path.length > 0) { @@ -59830,32 +61671,31 @@ var Matcher = class { } } /** - * Get current tag name + * Get current tag name. * @returns {string|undefined} */ getCurrentTag() { return this.path.length > 0 ? this.path[this.path.length - 1].tag : void 0; } /** - * Get current namespace + * Get current namespace. * @returns {string|undefined} */ getCurrentNamespace() { return this.path.length > 0 ? this.path[this.path.length - 1].namespace : void 0; } /** - * Get current node's attribute value - * @param {string} attrName - Attribute name - * @returns {*} Attribute value or undefined + * Get current node's attribute value. + * @param {string} attrName + * @returns {*} */ getAttrValue(attrName) { if (this.path.length === 0) return void 0; - const current = this.path[this.path.length - 1]; - return current.values?.[attrName]; + return this.path[this.path.length - 1].values?.[attrName]; } /** - * Check if current node has an attribute - * @param {string} attrName - Attribute name + * Check if current node has an attribute. + * @param {string} attrName * @returns {boolean} */ hasAttr(attrName) { @@ -59864,7 +61704,7 @@ var Matcher = class { return current.values !== void 0 && attrName in current.values; } /** - * Get current node's sibling position (child index in parent) + * Get current node's sibling position (child index in parent). * @returns {number} */ getPosition() { @@ -59872,7 +61712,7 @@ var Matcher = class { return this.path[this.path.length - 1].position ?? 0; } /** - * Get current node's repeat counter (occurrence count of this tag name) + * Get current node's repeat counter (occurrence count of this tag name). * @returns {number} */ getCounter() { @@ -59880,7 +61720,7 @@ var Matcher = class { return this.path[this.path.length - 1].counter ?? 0; } /** - * Get current node's sibling index (alias for getPosition for backward compatibility) + * Get current node's sibling index (alias for getPosition). * @returns {number} * @deprecated Use getPosition() or getCounter() instead */ @@ -59888,27 +61728,27 @@ var Matcher = class { return this.getPosition(); } /** - * Get current path depth + * Get current path depth. * @returns {number} */ getDepth() { return this.path.length; } /** - * Get path as string - * @param {string} separator - Optional separator (uses default if not provided) - * @param {boolean} includeNamespace - Whether to include namespace in output (default: true) + * Get path as string. + * @param {string} [separator] - Optional separator (uses default if not provided) + * @param {boolean} [includeNamespace=true] * @returns {string} */ toString(separator, includeNamespace = true) { const sep8 = separator || this.separator; const isDefault = sep8 === this.separator && includeNamespace === true; if (isDefault) { - if (this._pathStringCache !== null && this._pathStringCache !== void 0) { + if (this._pathStringCache !== null) { return this._pathStringCache; } const result = this.path.map( - (n7) => includeNamespace && n7.namespace ? `${n7.namespace}:${n7.tag}` : n7.tag + (n7) => n7.namespace ? `${n7.namespace}:${n7.tag}` : n7.tag ).join(sep8); this._pathStringCache = result; return result; @@ -59918,14 +61758,14 @@ var Matcher = class { ).join(sep8); } /** - * Get path as array of tag names + * Get path as array of tag names. * @returns {string[]} */ toArray() { return this.path.map((n7) => n7.tag); } /** - * Reset the path to empty + * Reset the path to empty. */ reset() { this._pathStringCache = null; @@ -59933,9 +61773,9 @@ var Matcher = class { this.siblingStacks = []; } /** - * Match current path against an Expression - * @param {Expression} expression - The expression to match against - * @returns {boolean} True if current path matches the expression + * Match current path against an Expression. + * @param {Expression} expression + * @returns {boolean} */ matches(expression) { const segments = expression.segments; @@ -59948,7 +61788,6 @@ var Matcher = class { return this._matchSimple(segments); } /** - * Match simple path (no deep wildcards) * @private */ _matchSimple(segments) { @@ -59956,17 +61795,13 @@ var Matcher = class { return false; } for (let i = 0; i < segments.length; i++) { - const segment = segments[i]; - const node = this.path[i]; - const isCurrentNode = i === this.path.length - 1; - if (!this._matchSegment(segment, node, isCurrentNode)) { + if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) { return false; } } return true; } /** - * Match path with deep wildcards * @private */ _matchWithDeepWildcard(segments) { @@ -59982,8 +61817,7 @@ var Matcher = class { const nextSeg = segments[segIdx]; let found = false; for (let i = pathIdx; i >= 0; i--) { - const isCurrentNode = i === this.path.length - 1; - if (this._matchSegment(nextSeg, this.path[i], isCurrentNode)) { + if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) { pathIdx = i - 1; segIdx--; found = true; @@ -59994,8 +61828,7 @@ var Matcher = class { return false; } } else { - const isCurrentNode = pathIdx === this.path.length - 1; - if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) { + if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) { return false; } pathIdx--; @@ -60005,12 +61838,7 @@ var Matcher = class { return segIdx < 0; } /** - * Match a single segment against a node * @private - * @param {Object} segment - Segment from Expression - * @param {Object} node - Node from path - * @param {boolean} isCurrentNode - Whether this is the current (last) node - * @returns {boolean} */ _matchSegment(segment, node, isCurrentNode) { if (segment.tag !== "*" && segment.tag !== node.tag) { @@ -60029,8 +61857,7 @@ var Matcher = class { return false; } if (segment.attrValue !== void 0) { - const actualValue = node.values[segment.attrName]; - if (String(actualValue) !== String(segment.attrValue)) { + if (String(node.values[segment.attrName]) !== String(segment.attrValue)) { return false; } } @@ -60046,17 +61873,23 @@ var Matcher = class { return false; } else if (segment.position === "even" && counter % 2 !== 0) { return false; - } else if (segment.position === "nth") { - if (counter !== segment.positionValue) { - return false; - } + } else if (segment.position === "nth" && counter !== segment.positionValue) { + return false; } } return true; } /** - * Create a snapshot of current state - * @returns {Object} State snapshot + * Match any expression in the given set against the current path. + * @param {ExpressionSet} exprSet + * @returns {boolean} + */ + matchesAny(exprSet) { + return exprSet.matchesAny(this); + } + /** + * Create a snapshot of current state. + * @returns {Object} */ snapshot() { return { @@ -60065,8 +61898,8 @@ var Matcher = class { }; } /** - * Restore state from snapshot - * @param {Object} snapshot - State snapshot + * Restore state from snapshot. + * @param {Object} snapshot */ restore(snapshot2) { this._pathStringCache = null; @@ -60074,64 +61907,23 @@ var Matcher = class { this.siblingStacks = snapshot2.siblingStacks.map((map2) => new Map(map2)); } /** - * Return a read-only view of this matcher. + * Return the read-only {@link MatcherView} for this matcher. * - * The returned object exposes all query/inspection methods but throws a - * TypeError if any state-mutating method is called (`push`, `pop`, `reset`, - * `updateCurrent`, `restore`). Property reads (e.g. `.path`, `.separator`) - * are allowed but the returned arrays/objects are frozen so callers cannot - * mutate internal state through them either. + * The same instance is returned on every call — no allocation occurs. + * It always reflects the current parser state and is safe to pass to + * user callbacks without risk of accidental mutation. * - * @returns {ReadOnlyMatcher} A proxy that forwards read operations and blocks writes. + * @returns {MatcherView} * * @example - * const matcher = new Matcher(); - * matcher.push("root", {}); - * - * const ro = matcher.readOnly(); - * ro.matches(expr); // ✓ works - * ro.getCurrentTag(); // ✓ works - * ro.push("child", {}); // ✗ throws TypeError - * ro.reset(); // ✗ throws TypeError + * const view = matcher.readOnly(); + * // pass view to callbacks — it stays in sync automatically + * view.matches(expr); // ✓ + * view.getCurrentTag(); // ✓ + * // view.push(...) // ✗ method does not exist — caught by TypeScript */ readOnly() { - const self2 = this; - return new Proxy(self2, { - get(target, prop, receiver) { - if (MUTATING_METHODS.has(prop)) { - return () => { - throw new TypeError( - `Cannot call '${prop}' on a read-only Matcher. Obtain a writable instance to mutate state.` - ); - }; - } - const value = Reflect.get(target, prop, receiver); - if (prop === "path" || prop === "siblingStacks") { - return Object.freeze( - Array.isArray(value) ? value.map( - (item) => item instanceof Map ? Object.freeze(new Map(item)) : Object.freeze({ ...item }) - // freeze a copy of each node - ) : value - ); - } - if (typeof value === "function") { - return value.bind(target); - } - return value; - }, - // Prevent any property assignment on the read-only view - set(_target, prop) { - throw new TypeError( - `Cannot set property '${String(prop)}' on a read-only Matcher.` - ); - }, - // Prevent property deletion - deleteProperty(_target, prop) { - throw new TypeError( - `Cannot delete property '${String(prop)}' from a read-only Matcher.` - ); - } - }); + return this._view; } }; @@ -60167,32 +61959,6 @@ var OrderedObjParser = class { this.options = options; this.currentNode = null; this.tagsNodeStack = []; - this.docTypeEntities = {}; - this.lastEntities = { - "apos": { regex: /&(apos|#39|#x27);/g, val: "'" }, - "gt": { regex: /&(gt|#62|#x3E);/g, val: ">" }, - "lt": { regex: /&(lt|#60|#x3C);/g, val: "<" }, - "quot": { regex: /&(quot|#34|#x22);/g, val: '"' } - }; - this.ampEntity = { regex: /&(amp|#38|#x26);/g, val: "&" }; - this.htmlEntities = { - "space": { regex: /&(nbsp|#160);/g, val: " " }, - // "lt" : { regex: /&(lt|#60);/g, val: "<" }, - // "gt" : { regex: /&(gt|#62);/g, val: ">" }, - // "amp" : { regex: /&(amp|#38);/g, val: "&" }, - // "quot" : { regex: /&(quot|#34);/g, val: "\"" }, - // "apos" : { regex: /&(apos|#39);/g, val: "'" }, - "cent": { regex: /&(cent|#162);/g, val: "\xA2" }, - "pound": { regex: /&(pound|#163);/g, val: "\xA3" }, - "yen": { regex: /&(yen|#165);/g, val: "\xA5" }, - "euro": { regex: /&(euro|#8364);/g, val: "\u20AC" }, - "copyright": { regex: /&(copy|#169);/g, val: "\xA9" }, - "reg": { regex: /&(reg|#174);/g, val: "\xAE" }, - "inr": { regex: /&(inr|#8377);/g, val: "\u20B9" }, - "num_dec": { regex: /&#([0-9]{1,7});/g, val: (_2, str2) => fromCodePoint(str2, 10, "&#") }, - "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (_2, str2) => fromCodePoint(str2, 16, "&#x") } - }; - this.addExternalEntities = addExternalEntities; this.parseXml = parseXml; this.parseTextData = parseTextData; this.resolveNameSpace = resolveNameSpace; @@ -60205,52 +61971,61 @@ var OrderedObjParser = class { this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes); this.entityExpansionCount = 0; this.currentExpandedLength = 0; + let namedEntities = { ...XML }; + if (this.options.entityDecoder) { + this.entityDecoder = this.options.entityDecoder; + } else { + if (typeof this.options.htmlEntities === "object") namedEntities = this.options.htmlEntities; + else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY }; + this.entityDecoder = new EntityDecoder({ + namedEntities, + numericAllowed: this.options.htmlEntities, + limit: { + maxTotalExpansions: this.options.processEntities.maxTotalExpansions, + maxExpandedLength: this.options.processEntities.maxExpandedLength, + applyLimitsTo: this.options.processEntities.appliesTo + } + //postCheck: resolved => resolved + }); + } this.matcher = new Matcher(); this.readonlyMatcher = this.matcher.readOnly(); this.isCurrentNodeStopNode = false; - if (this.options.stopNodes && this.options.stopNodes.length > 0) { - this.stopNodeExpressions = []; - for (let i = 0; i < this.options.stopNodes.length; i++) { - const stopNodeExp = this.options.stopNodes[i]; + this.stopNodeExpressionsSet = new ExpressionSet(); + const stopNodesOpts = this.options.stopNodes; + if (stopNodesOpts && stopNodesOpts.length > 0) { + for (let i = 0; i < stopNodesOpts.length; i++) { + const stopNodeExp = stopNodesOpts[i]; if (typeof stopNodeExp === "string") { - this.stopNodeExpressions.push(new Expression(stopNodeExp)); + this.stopNodeExpressionsSet.add(new Expression(stopNodeExp)); } else if (stopNodeExp instanceof Expression) { - this.stopNodeExpressions.push(stopNodeExp); + this.stopNodeExpressionsSet.add(stopNodeExp); } } + this.stopNodeExpressionsSet.seal(); } } }; -function addExternalEntities(externalEntities) { - const entKeys = Object.keys(externalEntities); - for (let i = 0; i < entKeys.length; i++) { - const ent = entKeys[i]; - const escaped = ent.replace(/[.\-+*:]/g, "\\."); - this.lastEntities[ent] = { - regex: new RegExp("&" + escaped + ";", "g"), - val: externalEntities[ent] - }; - } -} function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) { + const options = this.options; if (val !== void 0) { - if (this.options.trimValues && !dontTrim) { + if (options.trimValues && !dontTrim) { val = val.trim(); } if (val.length > 0) { if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath); - const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath; - const newval = this.options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode); + const jPathOrMatcher = options.jPath ? jPath.toString() : jPath; + const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode); if (newval === null || newval === void 0) { return val; } else if (typeof newval !== typeof val || newval !== val) { return newval; - } else if (this.options.trimValues) { - return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions); + } else if (options.trimValues) { + return parseValue(val, options.parseTagValue, options.numberParseOptions); } else { const trimmedVal = val.trim(); if (trimmedVal === val) { - return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions); + return parseValue(val, options.parseTagValue, options.numberParseOptions); } else { return val; } @@ -60272,8 +62047,9 @@ function resolveNameSpace(tagname) { return tagname; } var attrsRegx = new RegExp(`([^\\s=]+)\\s*(=\\s*(['"])([\\s\\S]*?)\\3)?`, "gm"); -function buildAttributesMap(attrStr, jPath, tagName) { - if (this.options.ignoreAttributes !== true && typeof attrStr === "string") { +function buildAttributesMap(attrStr, jPath, tagName, force = false) { + const options = this.options; + if (force === true || options.ignoreAttributes !== true && typeof attrStr === "string") { const matches = getAllMatches(attrStr, attrsRegx); const len = matches.length; const attrs = {}; @@ -60285,7 +62061,7 @@ function buildAttributesMap(attrStr, jPath, tagName) { const oldVal = matches[i][4]; if (attrName.length && oldVal !== void 0) { let val = oldVal; - if (this.options.trimValues) val = val.trim(); + if (options.trimValues) val = val.trim(); val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher); processedVals[i] = val; rawAttrsForMatcher[attrName] = val; @@ -60295,38 +62071,38 @@ function buildAttributesMap(attrStr, jPath, tagName) { if (hasRawAttrs && typeof jPath === "object" && jPath.updateCurrent) { jPath.updateCurrent(rawAttrsForMatcher); } - const jPathStr = this.options.jPath ? jPath.toString() : this.readonlyMatcher; + const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher; let hasAttrs = false; for (let i = 0; i < len; i++) { const attrName = this.resolveNameSpace(matches[i][1]); if (this.ignoreAttributesFn(attrName, jPathStr)) continue; - let aName = this.options.attributeNamePrefix + attrName; + let aName = options.attributeNamePrefix + attrName; if (attrName.length) { - if (this.options.transformAttributeName) { - aName = this.options.transformAttributeName(aName); + if (options.transformAttributeName) { + aName = options.transformAttributeName(aName); } - aName = sanitizeName(aName, this.options); + aName = sanitizeName(aName, options); if (matches[i][4] !== void 0) { const oldVal = processedVals[i]; - const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPathStr); + const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr); if (newVal === null || newVal === void 0) { attrs[aName] = oldVal; } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) { attrs[aName] = newVal; } else { - attrs[aName] = parseValue(oldVal, this.options.parseAttributeValue, this.options.numberParseOptions); + attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions); } hasAttrs = true; - } else if (this.options.allowBooleanAttributes) { + } else if (options.allowBooleanAttributes) { attrs[aName] = true; hasAttrs = true; } } } if (!hasAttrs) return; - if (this.options.attributesGroupName) { + if (options.attributesGroupName) { const attrCollection = {}; - attrCollection[this.options.attributesGroupName] = attrs; + attrCollection[options.attributesGroupName] = attrs; return attrCollection; } return attrs; @@ -60338,30 +62114,34 @@ var parseXml = function(xmlData) { let currentNode = xmlObj; let textData = ""; this.matcher.reset(); + this.entityDecoder.reset(); this.entityExpansionCount = 0; this.currentExpandedLength = 0; - const docTypeReader = new DocTypeReader(this.options.processEntities); - for (let i = 0; i < xmlData.length; i++) { + const options = this.options; + const docTypeReader = new DocTypeReader(options.processEntities); + const xmlLen = xmlData.length; + for (let i = 0; i < xmlLen; i++) { const ch = xmlData[i]; if (ch === "<") { - if (xmlData[i + 1] === "/") { + const c1 = xmlData.charCodeAt(i + 1); + if (c1 === 47) { const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed."); let tagName = xmlData.substring(i + 2, closeIndex).trim(); - if (this.options.removeNSPrefix) { + if (options.removeNSPrefix) { const colonIndex = tagName.indexOf(":"); if (colonIndex !== -1) { tagName = tagName.substr(colonIndex + 1); } } - tagName = transformTagName(this.options.transformTagName, tagName, "", this.options).tagName; + tagName = transformTagName(options.transformTagName, tagName, "", options).tagName; if (currentNode) { textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); } const lastTagName = this.matcher.getCurrentTag(); - if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) { + if (tagName && options.unpairedTagsSet.has(tagName)) { throw new Error(`Unpaired tag can not be used as closing tag: `); } - if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) { + if (lastTagName && options.unpairedTagsSet.has(lastTagName)) { this.matcher.pop(); this.tagsNodeStack.pop(); } @@ -60370,48 +62150,53 @@ var parseXml = function(xmlData) { currentNode = this.tagsNodeStack.pop(); textData = ""; i = closeIndex; - } else if (xmlData[i + 1] === "?") { + } else if (c1 === 63) { let tagData = readTagExp(xmlData, i, false, "?>"); if (!tagData) throw new Error("Pi Tag is not closed."); textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); - if (this.options.ignoreDeclaration && tagData.tagName === "?xml" || this.options.ignorePiTags) { + const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true); + if (attsMap) { + const ver = attsMap[this.options.attributeNamePrefix + "version"]; + this.entityDecoder.setXmlVersion(Number(ver) || 1); + } + if (options.ignoreDeclaration && tagData.tagName === "?xml" || options.ignorePiTags) { } else { const childNode = new XmlNode(tagData.tagName); - childNode.add(this.options.textNodeName, ""); - if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) { - childNode[":@"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName); + childNode.add(options.textNodeName, ""); + if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) { + childNode[":@"] = attsMap; } this.addChild(currentNode, childNode, this.readonlyMatcher, i); } i = tagData.closeIndex + 1; - } else if (xmlData.substr(i + 1, 3) === "!--") { + } else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) { const endIndex = findClosingIndex(xmlData, "-->", i + 4, "Comment is not closed."); - if (this.options.commentPropName) { + if (options.commentPropName) { const comment = xmlData.substring(i + 4, endIndex - 2); textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); - currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]); + currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]); } i = endIndex; - } else if (xmlData.substr(i + 1, 2) === "!D") { + } else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 68) { const result = docTypeReader.readDocType(xmlData, i); - this.docTypeEntities = result.entities; + this.entityDecoder.addInputEntities(result.entities); i = result.i; - } else if (xmlData.substr(i + 1, 2) === "![") { + } else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) { const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2; const tagExp = xmlData.substring(i + 9, closeIndex); textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true); if (val == void 0) val = ""; - if (this.options.cdataPropName) { - currentNode.add(this.options.cdataPropName, [{ [this.options.textNodeName]: tagExp }]); + if (options.cdataPropName) { + currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]); } else { - currentNode.add(this.options.textNodeName, val); + currentNode.add(options.textNodeName, val); } i = closeIndex + 2; } else { - let result = readTagExp(xmlData, i, this.options.removeNSPrefix); + let result = readTagExp(xmlData, i, options.removeNSPrefix); if (!result) { - const context3 = xmlData.substring(Math.max(0, i - 50), Math.min(xmlData.length, i + 50)); + const context3 = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50)); throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context3}"`); } let tagName = result.tagName; @@ -60419,8 +62204,8 @@ var parseXml = function(xmlData) { let tagExp = result.tagExp; let attrExpPresent = result.attrExpPresent; let closeIndex = result.closeIndex; - ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options)); - if (this.options.strictReservedNames && (tagName === this.options.commentPropName || tagName === this.options.cdataPropName || tagName === this.options.textNodeName || tagName === this.options.attributesGroupName)) { + ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options)); + if (options.strictReservedNames && (tagName === options.commentPropName || tagName === options.cdataPropName || tagName === options.textNodeName || tagName === options.attributesGroupName)) { throw new Error(`Invalid tag name: ${tagName}`); } if (currentNode && textData) { @@ -60429,7 +62214,7 @@ var parseXml = function(xmlData) { } } const lastTag = currentNode; - if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) { + if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) { currentNode = this.tagsNodeStack.pop(); this.matcher.pop(); } @@ -60454,18 +62239,18 @@ var parseXml = function(xmlData) { if (tagName !== tagExp && attrExpPresent) { prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName); if (prefixedAttrs) { - rawAttrs = extractRawAttributes(prefixedAttrs, this.options); + rawAttrs = extractRawAttributes(prefixedAttrs, options); } } if (tagName !== xmlObj.tagname) { - this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher); + this.isCurrentNodeStopNode = this.isItStopNode(); } const startIndex = i; if (this.isCurrentNodeStopNode) { let tagContent = ""; if (isSelfClosing) { i = result.closeIndex; - } else if (this.options.unpairedTags.indexOf(tagName) !== -1) { + } else if (options.unpairedTagsSet.has(tagName)) { i = result.closeIndex; } else { const result2 = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1); @@ -60477,13 +62262,13 @@ var parseXml = function(xmlData) { if (prefixedAttrs) { childNode[":@"] = prefixedAttrs; } - childNode.add(this.options.textNodeName, tagContent); + childNode.add(options.textNodeName, tagContent); this.matcher.pop(); this.isCurrentNodeStopNode = false; this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex); } else { if (isSelfClosing) { - ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options)); + ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options)); const childNode = new XmlNode(tagName); if (prefixedAttrs) { childNode[":@"] = prefixedAttrs; @@ -60491,7 +62276,7 @@ var parseXml = function(xmlData) { this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex); this.matcher.pop(); this.isCurrentNodeStopNode = false; - } else if (this.options.unpairedTags.indexOf(tagName) !== -1) { + } else if (options.unpairedTagsSet.has(tagName)) { const childNode = new XmlNode(tagName); if (prefixedAttrs) { childNode[":@"] = prefixedAttrs; @@ -60503,7 +62288,7 @@ var parseXml = function(xmlData) { continue; } else { const childNode = new XmlNode(tagName); - if (this.tagsNodeStack.length > this.options.maxNestedTags) { + if (this.tagsNodeStack.length > options.maxNestedTags) { throw new Error("Maximum nested tags exceeded"); } this.tagsNodeStack.push(currentNode); @@ -60553,60 +62338,7 @@ function replaceEntitiesValue(val, tagName, jPath) { return val; } } - for (const entityName of Object.keys(this.docTypeEntities)) { - const entity = this.docTypeEntities[entityName]; - const matches = val.match(entity.regx); - if (matches) { - this.entityExpansionCount += matches.length; - if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) { - throw new Error( - `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}` - ); - } - const lengthBefore = val.length; - val = val.replace(entity.regx, entity.val); - if (entityConfig.maxExpandedLength) { - this.currentExpandedLength += val.length - lengthBefore; - if (this.currentExpandedLength > entityConfig.maxExpandedLength) { - throw new Error( - `Total expanded content size exceeded: ${this.currentExpandedLength} > ${entityConfig.maxExpandedLength}` - ); - } - } - } - } - if (val.indexOf("&") === -1) return val; - for (const entityName of Object.keys(this.lastEntities)) { - const entity = this.lastEntities[entityName]; - const matches = val.match(entity.regex); - if (matches) { - this.entityExpansionCount += matches.length; - if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) { - throw new Error( - `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}` - ); - } - } - val = val.replace(entity.regex, entity.val); - } - if (val.indexOf("&") === -1) return val; - if (this.options.htmlEntities) { - for (const entityName of Object.keys(this.htmlEntities)) { - const entity = this.htmlEntities[entityName]; - const matches = val.match(entity.regex); - if (matches) { - this.entityExpansionCount += matches.length; - if (entityConfig.maxTotalExpansions && this.entityExpansionCount > entityConfig.maxTotalExpansions) { - throw new Error( - `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}` - ); - } - } - val = val.replace(entity.regex, entity.val); - } - } - val = val.replace(this.ampEntity.regex, this.ampEntity.val); - return val; + return this.entityDecoder.decode(val); } function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) { if (textData) { @@ -60625,42 +62357,35 @@ function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) { } return textData; } -function isItStopNode(stopNodeExpressions, matcher) { - if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false; - for (let i = 0; i < stopNodeExpressions.length; i++) { - if (matcher.matches(stopNodeExpressions[i])) { - return true; - } - } - return false; +function isItStopNode() { + if (this.stopNodeExpressionsSet.size === 0) return false; + return this.matcher.matchesAny(this.stopNodeExpressionsSet); } function tagExpWithClosingIndex(xmlData, i, closingChar = ">") { - let attrBoundary; - let tagExp = ""; - for (let index = i; index < xmlData.length; index++) { - let ch = xmlData[index]; + let attrBoundary = 0; + const chars = []; + const len = xmlData.length; + const closeCode0 = closingChar.charCodeAt(0); + const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1; + for (let index = i; index < len; index++) { + const code = xmlData.charCodeAt(index); if (attrBoundary) { - if (ch === attrBoundary) attrBoundary = ""; - } else if (ch === '"' || ch === "'") { - attrBoundary = ch; - } else if (ch === closingChar[0]) { - if (closingChar[1]) { - if (xmlData[index + 1] === closingChar[1]) { - return { - data: tagExp, - index - }; + if (code === attrBoundary) attrBoundary = 0; + } else if (code === 34 || code === 39) { + attrBoundary = code; + } else if (code === closeCode0) { + if (closeCode1 !== -1) { + if (xmlData.charCodeAt(index + 1) === closeCode1) { + return { data: String.fromCharCode(...chars), index }; } } else { - return { - data: tagExp, - index - }; + return { data: String.fromCharCode(...chars), index }; } - } else if (ch === " ") { - ch = " "; + } else if (code === 9) { + chars.push(32); + continue; } - tagExp += ch; + chars.push(code); } } function findClosingIndex(xmlData, str2, i, errMsg) { @@ -60671,6 +62396,11 @@ function findClosingIndex(xmlData, str2, i, errMsg) { return closingIndex + str2.length - 1; } } +function findClosingChar(xmlData, char, i, errMsg) { + const closingIndex = xmlData.indexOf(char, i); + if (closingIndex === -1) throw new Error(errMsg); + return closingIndex; +} function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") { const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar); if (!result) return; @@ -60702,10 +62432,12 @@ function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") { function readStopNodeData(xmlData, tagName, i) { const startIndex = i; let openTagCount = 1; - for (; i < xmlData.length; i++) { + const xmllen = xmlData.length; + for (; i < xmllen; i++) { if (xmlData[i] === "<") { - if (xmlData[i + 1] === "/") { - const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`); + const c1 = xmlData.charCodeAt(i + 1); + if (c1 === 47) { + const closeIndex = findClosingChar(xmlData, ">", i, `${tagName} is not closed`); let closeTagName = xmlData.substring(i + 2, closeIndex).trim(); if (closeTagName === tagName) { openTagCount--; @@ -60717,13 +62449,13 @@ function readStopNodeData(xmlData, tagName, i) { } } i = closeIndex; - } else if (xmlData[i + 1] === "?") { + } else if (c1 === 63) { const closeIndex = findClosingIndex(xmlData, "?>", i + 1, "StopNode is not closed."); i = closeIndex; - } else if (xmlData.substr(i + 1, 3) === "!--") { + } else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) { const closeIndex = findClosingIndex(xmlData, "-->", i + 3, "StopNode is not closed."); i = closeIndex; - } else if (xmlData.substr(i + 1, 2) === "![") { + } else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) { const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2; i = closeIndex; } else { @@ -60753,14 +62485,6 @@ function parseValue(val, shouldParse, options) { } } } -function fromCodePoint(str2, base, prefix2) { - const codePoint = Number.parseInt(str2, base); - if (codePoint >= 0 && codePoint <= 1114111) { - return String.fromCodePoint(codePoint); - } else { - return prefix2 + str2 + ";"; - } -} function transformTagName(fn, tagName, tagExp, options) { if (fn) { const newTagName = fn(tagName); @@ -60915,7 +62639,7 @@ var XMLParser = class { } } const orderedObjParser = new OrderedObjParser(this.options); - orderedObjParser.addExternalEntities(this.externalEntities); + orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities); const orderedResult = orderedObjParser.parseXml(xmlData); if (this.options.preserveOrder || orderedResult === void 0) return orderedResult; else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher); @@ -61010,12 +62734,16 @@ function arrToStr(arr, options, indentation, matcher, stopNodeExpressions) { if (isPreviousElementTag) { xmlStr += indentation; } - xmlStr += ``; + const val = tagObj[tagName][0][options.textNodeName]; + const safeVal = String(val).replace(/\]\]>/g, "]]]]>"); + xmlStr += ``; isPreviousElementTag = false; matcher.pop(); continue; } else if (tagName === options.commentPropName) { - xmlStr += indentation + ``; + const val = tagObj[tagName][0][options.textNodeName]; + const safeVal = String(val).replace(/--/g, "- -").replace(/-$/, "- "); + xmlStr += indentation + ``; isPreviousElementTag = true; matcher.pop(); continue; @@ -61566,9 +63294,11 @@ Builder.prototype.checkStopNode = function(matcher) { }; Builder.prototype.buildTextValNode = function(val, key, attrStr, level, matcher) { if (this.options.cdataPropName !== false && key === this.options.cdataPropName) { - return this.indentate(level) + `` + this.newLine; + const safeVal = String(val).replace(/\]\]>/g, "]]]]>"); + return this.indentate(level) + `` + this.newLine; } else if (this.options.commentPropName !== false && key === this.options.commentPropName) { - return this.indentate(level) + `` + this.newLine; + const safeVal = String(val).replace(/--/g, "- -").replace(/-$/, "- "); + return this.indentate(level) + `` + this.newLine; } else if (key[0] === "?") { return this.indentate(level) + "<" + key + attrStr + "?" + this.tagEndChar; } else { @@ -86916,7 +88646,7 @@ async function env() { }, Promise.resolve({})); } async function fallback(oldEnv, newEnv) { - warning("Procceding with fallback installation approach"); + warning("Proceeding with fallback installation approach"); const data = Object.entries(newEnv).reduce((previous, current) => { return { ...previous, @@ -87060,7 +88790,7 @@ async function updateSdkModules(sdkRoot) { rawData += chunk; }); res.on("end", () => { - debug(`Recieved ${name} module definition: "${rawData}"`); + debug(`Received ${name} module definition: "${rawData}"`); resolve2(rawData); }); }); @@ -87091,15 +88821,15 @@ var WindowsToolchainInstaller = class extends VerifyingToolchainInstaller { const recommended = semver5.gte(this.version ?? "6.2.0", "6.2.0") ? win11Semver : "10.0.17763"; const current = os14.release(); let version3 = semver5.gte(current, recommended) ? current : recommended; - const insatlled = await this.insatlledSdks(); - if (insatlled.length && !insatlled.includes(version3)) { - version3 = insatlled[0]; + const installed = await this.installedSdks(); + if (installed.length && !installed.includes(version3)) { + version3 = installed[0]; } const major2 = semver5.lt(version3, win11Semver) ? semver5.major(version3) : 11; const minor = semver5.patch(version3); return `Microsoft.VisualStudio.Component.Windows${major2}SDK.${minor}`; } - async insatlledSdks() { + async installedSdks() { const sdksPath = path30.join(program86(), "Windows Kits", "10", "Include"); try { const dirs = await fs21.readdir(sdksPath, { withFileTypes: true }); @@ -87196,7 +88926,7 @@ var WindowsToolchainInstaller = class extends VerifyingToolchainInstaller { sdkroot = installation.variables[sdkrootKey]; } if (!sdkroot) { - warning(`Failed VS enviroment after installation ${installLocation}`); + warning(`Failed VS environment after installation ${installLocation}`); return; } const version3 = await this.installedSwiftVersion(); diff --git a/package-lock.json b/package-lock.json index ff166efa..e4fd2d46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -605,31 +605,6 @@ "node": ">=6.9.0" } }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@emnapi/wasi-threads": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", diff --git a/src/installer/windows/index.ts b/src/installer/windows/index.ts index b41113bd..02bbcce1 100644 --- a/src/installer/windows/index.ts +++ b/src/installer/windows/index.ts @@ -23,9 +23,9 @@ export class WindowsToolchainInstaller extends VerifyingToolchainInstaller, newEnv: Record ) { - core.warning('Procceding with fallback installation approach') + core.warning('Proceeding with fallback installation approach') const data = Object.entries(newEnv).reduce( (previous, current) => { return { diff --git a/src/installer/windows/modules/index.ts b/src/installer/windows/modules/index.ts index c02a1a55..04b959ea 100644 --- a/src/installer/windows/modules/index.ts +++ b/src/installer/windows/modules/index.ts @@ -116,7 +116,7 @@ export async function updateSdkModules(sdkRoot: string): Promise { }) res.on('end', () => { - core.debug(`Recieved ${name} module definition: "${rawData}"`) + core.debug(`Received ${name} module definition: "${rawData}"`) resolve(rawData) }) }) diff --git a/src/swiftorg.ts b/src/swiftorg.ts index 2eb95d92..92eb8e9b 100644 --- a/src/swiftorg.ts +++ b/src/swiftorg.ts @@ -89,7 +89,7 @@ export class Swiftorg { res.on('end', () => { try { const parsedData = JSON.parse(rawData) - core.debug(`Recieved swift.org metadata: "${rawData}"`) + core.debug(`Received swift.org metadata: "${rawData}"`) Swiftorg.commitFromMetadata(parsedData).then( commit => resolve({commit}), e => reject(e)