From 09d0677378d50fef230b7cd4c0dea6dfe8883938 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 10:48:24 +0200 Subject: [PATCH 1/8] build(deps): bump @actions/github from 9.0.0 to 9.1.0 (#396) Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 9.0.0 to 9.1.0. - [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github) --- updated-dependencies: - dependency-name: "@actions/github" dependency-version: 9.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6904a46b..4b56f1ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "dependencies": { "@actions/artifact": "^6.2.1", "@actions/core": "^3.0.0", - "@actions/github": "^9.0.0", + "@actions/github": "^9.1.0", "adm-zip": "^0.5.17", "filesize": "^11.0.15" } @@ -75,9 +75,9 @@ } }, "node_modules/@actions/github": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.0.0.tgz", - "integrity": "sha512-yJ0RoswsAaKcvkmpCE4XxBRiy/whH2SdTBHWzs0gi4wkqTDhXMChjSdqBz/F4AeiDlP28rQqL33iHb+kjAMX6w==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.0.tgz", + "integrity": "sha512-u0hDGQeCS+7VNoLA8hYG65RLdPLMaPGfka0sZ0up7P0AiShqfX6xcuXNteGkQ7X7Tod7AMNwHd4p7DS63i8zzA==", "license": "MIT", "dependencies": { "@actions/http-client": "^3.0.2", diff --git a/package.json b/package.json index ee2e7298..436b6d7b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dependencies": { "@actions/artifact": "^6.2.1", "@actions/core": "^3.0.0", - "@actions/github": "^9.0.0", + "@actions/github": "^9.1.0", "adm-zip": "^0.5.17", "filesize": "^11.0.15" } From 026702ee85894c7c9a8b25fff9783448656079fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 22:59:08 +0200 Subject: [PATCH 2/8] build(deps): bump filesize from 11.0.15 to 11.0.16 (#399) Bumps [filesize](https://github.com/avoidwork/filesize.js) from 11.0.15 to 11.0.16. - [Changelog](https://github.com/avoidwork/filesize.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/avoidwork/filesize.js/compare/11.0.15...11.0.16) --- updated-dependencies: - dependency-name: filesize dependency-version: 11.0.16 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b56f1ed..025301ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@actions/core": "^3.0.0", "@actions/github": "^9.1.0", "adm-zip": "^0.5.17", - "filesize": "^11.0.15" + "filesize": "^11.0.16" } }, "node_modules/@actions/artifact": { @@ -992,9 +992,9 @@ } }, "node_modules/filesize": { - "version": "11.0.15", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.15.tgz", - "integrity": "sha512-30TpbYxQxCpi4XdVjkwXYQ37CzZltV38+P7MYroQ+4NK/Dmx9mxixFNrolzcmEIBsjT/uowC9T7kiy2+C12r1A==", + "version": "11.0.16", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.16.tgz", + "integrity": "sha512-XMcUu0Zxnh0L8rY5b5vrdKKs0H3l3osTp9vNEBulRmwLqYfuQe5SJCagpA0/sGMJx2KHbD+IWOyd6QsJQuYEkQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 10.8.0" diff --git a/package.json b/package.json index 436b6d7b..69aef9da 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,6 @@ "@actions/core": "^3.0.0", "@actions/github": "^9.1.0", "adm-zip": "^0.5.17", - "filesize": "^11.0.15" + "filesize": "^11.0.16" } } From ef0669122ea62d17c71dcb14c4063378e3f76a3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 16:29:39 +0200 Subject: [PATCH 3/8] build(deps): bump fast-xml-parser from 5.5.7 to 5.7.1 (#402) Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.5.7 to 5.7.1. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v5.5.7...v5.7.1) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.7.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 025301ec..fbe4b7b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -352,6 +352,18 @@ "node": ">=12" } }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@octokit/auth-token": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", @@ -957,9 +969,9 @@ "license": "MIT" }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", "funding": [ { "type": "github", @@ -972,9 +984,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.5.7", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.7.tgz", - "integrity": "sha512-LteOsISQ2GEiDHZch6L9hB0+MLoYVLToR7xotrzU0opCICBkxOPgHAy1HxAvtxfJNXDJpgAsQN30mkrfpO2Prg==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.1.tgz", + "integrity": "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==", "funding": [ { "type": "github", @@ -983,9 +995,10 @@ ], "license": "MIT", "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.1.3", - "strnum": "^2.2.0" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" @@ -1293,9 +1306,9 @@ "license": "BlueOak-1.0.0" }, "node_modules/path-expression-matcher": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz", - "integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -1556,9 +1569,9 @@ } }, "node_modules/strnum": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz", - "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", "funding": [ { "type": "github", From c802aad8eeef2832e9a5d902eb86d4f112d1f001 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 16:30:40 +0200 Subject: [PATCH 4/8] build(deps): bump @actions/github from 9.1.0 to 9.1.1 (#400) Bumps [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github) from 9.1.0 to 9.1.1. - [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github) --- updated-dependencies: - dependency-name: "@actions/github" dependency-version: 9.1.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index fbe4b7b1..ea38f69b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "dependencies": { "@actions/artifact": "^6.2.1", "@actions/core": "^3.0.0", - "@actions/github": "^9.1.0", + "@actions/github": "^9.1.1", "adm-zip": "^0.5.17", "filesize": "^11.0.16" } @@ -75,9 +75,9 @@ } }, "node_modules/@actions/github": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.0.tgz", - "integrity": "sha512-u0hDGQeCS+7VNoLA8hYG65RLdPLMaPGfka0sZ0up7P0AiShqfX6xcuXNteGkQ7X7Tod7AMNwHd4p7DS63i8zzA==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.1.tgz", + "integrity": "sha512-tL5JbYOBZHc0ngEnCsaDcryUizIUIlQyIMwy1Wkx93H5HzbBJ7TbiPx2PnFjBwZW0Vh05JmfFZhecE6gglYegA==", "license": "MIT", "dependencies": { "@actions/http-client": "^3.0.2", diff --git a/package.json b/package.json index 69aef9da..36a92c24 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "dependencies": { "@actions/artifact": "^6.2.1", "@actions/core": "^3.0.0", - "@actions/github": "^9.1.0", + "@actions/github": "^9.1.1", "adm-zip": "^0.5.17", "filesize": "^11.0.16" } From 0414c42ca96cdcf3c0bb79a6dfc99de30b1fa48d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 16:33:20 +0200 Subject: [PATCH 5/8] build(deps): bump @actions/core from 3.0.0 to 3.0.1 (#401) Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 3.0.0 to 3.0.1. - [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md) - [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core) --- updated-dependencies: - dependency-name: "@actions/core" dependency-version: 3.0.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea38f69b..038ce9c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,7 @@ "name": "action-download-artifact", "dependencies": { "@actions/artifact": "^6.2.1", - "@actions/core": "^3.0.0", + "@actions/core": "^3.0.1", "@actions/github": "^9.1.1", "adm-zip": "^0.5.17", "filesize": "^11.0.16" @@ -46,9 +46,9 @@ } }, "node_modules/@actions/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", - "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", "license": "MIT", "dependencies": { "@actions/exec": "^3.0.0", diff --git a/package.json b/package.json index 36a92c24..e2126e2e 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "main": "main.js", "dependencies": { "@actions/artifact": "^6.2.1", - "@actions/core": "^3.0.0", + "@actions/core": "^3.0.1", "@actions/github": "^9.1.1", "adm-zip": "^0.5.17", "filesize": "^11.0.16" From 00b585a7f596b6d2fe2349f6a75dc47dc7f5ee03 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 12:20:53 +0200 Subject: [PATCH 6/8] build(deps): bump filesize from 11.0.16 to 11.0.17 (#404) Bumps [filesize](https://github.com/avoidwork/filesize.js) from 11.0.16 to 11.0.17. - [Changelog](https://github.com/avoidwork/filesize.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/avoidwork/filesize.js/commits) --- updated-dependencies: - dependency-name: filesize dependency-version: 11.0.17 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 038ce9c6..e538be6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "@actions/core": "^3.0.1", "@actions/github": "^9.1.1", "adm-zip": "^0.5.17", - "filesize": "^11.0.16" + "filesize": "^11.0.17" } }, "node_modules/@actions/artifact": { @@ -1005,9 +1005,9 @@ } }, "node_modules/filesize": { - "version": "11.0.16", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.16.tgz", - "integrity": "sha512-XMcUu0Zxnh0L8rY5b5vrdKKs0H3l3osTp9vNEBulRmwLqYfuQe5SJCagpA0/sGMJx2KHbD+IWOyd6QsJQuYEkQ==", + "version": "11.0.17", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.17.tgz", + "integrity": "sha512-oHLTvMLw6imZUl1se/RBQrFlyy50nXce4sU7yGR6Qc0JgCwqnfiFsAnEwotdGmfKLD7SArGUk2/5STU0k8LOBQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 10.8.0" diff --git a/package.json b/package.json index e2126e2e..31abd0fb 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,6 @@ "@actions/core": "^3.0.1", "@actions/github": "^9.1.1", "adm-zip": "^0.5.17", - "filesize": "^11.0.16" + "filesize": "^11.0.17" } } From 1708cb364f3b2d67c7981023b5cbc75815c2b95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Drobni=C4=8D?= Date: Tue, 28 Apr 2026 12:23:45 +0200 Subject: [PATCH 7/8] Download artifacts in creation order (#398) --- main.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.js b/main.js index a9a385c5..12c5d3c3 100644 --- a/main.js +++ b/main.js @@ -229,6 +229,8 @@ async function main() { artifacts = filtered } + artifacts.sort((a, b) => a.created_at.localeCompare(b.created_at)) + core.setOutput("artifacts", artifacts) if (dryRun) { From b6e2e70617bc3265edd6dab6c906732b2f1ae151 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Tue, 28 Apr 2026 12:34:21 +0200 Subject: [PATCH 8/8] node_modules: update (#405) Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com> --- node_modules/.package-lock.json | 61 +- node_modules/@actions/core/package.json | 2 +- .../@actions/github/lib/internal/utils.d.ts | 1 + .../@actions/github/lib/internal/utils.js | 13 + .../@actions/github/lib/internal/utils.js.map | 2 +- node_modules/@actions/github/lib/utils.d.ts | 1 + node_modules/@actions/github/lib/utils.js | 6 + node_modules/@actions/github/lib/utils.js.map | 2 +- node_modules/@actions/github/package.json | 2 +- node_modules/@nodable/entities/README.md | 41 + node_modules/@nodable/entities/package.json | 54 + .../@nodable/entities/src/EntityDecoder.js | 543 ++++++++ .../@nodable/entities/src/EntityEncoder.js | 194 +++ .../@nodable/entities/src/entities.js | 1177 +++++++++++++++++ .../@nodable/entities/src/entityTries.js | 49 + node_modules/@nodable/entities/src/index.d.ts | 264 ++++ node_modules/@nodable/entities/src/index.js | 29 + node_modules/fast-xml-builder/package.json | 2 +- node_modules/fast-xml-builder/src/fxb.js | 8 +- .../fast-xml-builder/src/orderedJs2Xml.js | 18 +- node_modules/fast-xml-parser/CHANGELOG.md | 56 + node_modules/fast-xml-parser/README.md | 36 +- .../fast-xml-parser/lib/fxbuilder.min.js | 2 +- .../fast-xml-parser/lib/fxbuilder.min.js.map | 2 +- node_modules/fast-xml-parser/lib/fxp.cjs | 2 +- node_modules/fast-xml-parser/lib/fxp.d.cts | 200 ++- node_modules/fast-xml-parser/lib/fxp.min.js | 2 +- .../fast-xml-parser/lib/fxp.min.js.map | 2 +- .../fast-xml-parser/lib/fxparser.min.js | 2 +- .../fast-xml-parser/lib/fxparser.min.js.map | 2 +- node_modules/fast-xml-parser/package.json | 9 +- node_modules/fast-xml-parser/src/fxp.d.ts | 183 ++- .../src/xmlparser/DocTypeReader.js | 7 +- .../src/xmlparser/OptionsBuilder.js | 26 +- .../src/xmlparser/OrderedObjParser.js | 438 +++--- .../src/xmlparser/XMLParser.js | 6 +- .../src/xmlparser/node2json.js | 21 +- node_modules/filesize/README.md | 9 - node_modules/filesize/dist/filesize.cjs | 383 ++++-- node_modules/filesize/dist/filesize.js | 383 ++++-- node_modules/filesize/package.json | 6 +- .../path-expression-matcher/README.md | 287 +++- .../path-expression-matcher/lib/pem.cjs | 2 +- .../path-expression-matcher/lib/pem.d.cts | 299 +++++ .../path-expression-matcher/lib/pem.min.js | 2 +- .../lib/pem.min.js.map | 2 +- .../path-expression-matcher/package.json | 4 +- .../path-expression-matcher/src/Expression.js | 4 +- .../src/ExpressionSet.js | 209 +++ .../path-expression-matcher/src/Matcher.js | 356 +++-- .../path-expression-matcher/src/index.d.ts | 301 ++++- .../path-expression-matcher/src/index.js | 5 +- node_modules/strnum/.github/SECURITY.md | 5 - node_modules/strnum/.vscode/launch.json | 25 - node_modules/strnum/CHANGELOG.md | 4 + node_modules/strnum/algo.stflow | 84 -- node_modules/strnum/package.json | 2 +- node_modules/strnum/strnum.js | 5 +- node_modules/strnum/tests/infinity_test.js | 18 - node_modules/strnum/tests/strnum_test.js | 174 --- node_modules/strnum/tests/temp.js | 8 - 61 files changed, 4948 insertions(+), 1094 deletions(-) create mode 100644 node_modules/@nodable/entities/README.md create mode 100644 node_modules/@nodable/entities/package.json create mode 100644 node_modules/@nodable/entities/src/EntityDecoder.js create mode 100644 node_modules/@nodable/entities/src/EntityEncoder.js create mode 100644 node_modules/@nodable/entities/src/entities.js create mode 100644 node_modules/@nodable/entities/src/entityTries.js create mode 100644 node_modules/@nodable/entities/src/index.d.ts create mode 100644 node_modules/@nodable/entities/src/index.js create mode 100644 node_modules/path-expression-matcher/src/ExpressionSet.js delete mode 100644 node_modules/strnum/.github/SECURITY.md delete mode 100644 node_modules/strnum/.vscode/launch.json delete mode 100644 node_modules/strnum/algo.stflow delete mode 100644 node_modules/strnum/tests/infinity_test.js delete mode 100644 node_modules/strnum/tests/strnum_test.js delete mode 100644 node_modules/strnum/tests/temp.js diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 6daeb27d..2d15f6fc 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -36,9 +36,9 @@ } }, "node_modules/@actions/core": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.0.tgz", - "integrity": "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-3.0.1.tgz", + "integrity": "sha512-a6d/Nwahm9fliVGRhdhofo40HjHQasUPusmc7vBfyky+7Z+P2A1J68zyFVaNcEclc/Se+eO595oAr5nwEIoIUA==", "license": "MIT", "dependencies": { "@actions/exec": "^3.0.0", @@ -65,9 +65,9 @@ } }, "node_modules/@actions/github": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.0.0.tgz", - "integrity": "sha512-yJ0RoswsAaKcvkmpCE4XxBRiy/whH2SdTBHWzs0gi4wkqTDhXMChjSdqBz/F4AeiDlP28rQqL33iHb+kjAMX6w==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-9.1.1.tgz", + "integrity": "sha512-tL5JbYOBZHc0ngEnCsaDcryUizIUIlQyIMwy1Wkx93H5HzbBJ7TbiPx2PnFjBwZW0Vh05JmfFZhecE6gglYegA==", "license": "MIT", "dependencies": { "@actions/http-client": "^3.0.2", @@ -342,6 +342,18 @@ "node": ">=12" } }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, "node_modules/@octokit/auth-token": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", @@ -947,9 +959,9 @@ "license": "MIT" }, "node_modules/fast-xml-builder": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", - "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", "funding": [ { "type": "github", @@ -962,9 +974,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "5.5.7", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.7.tgz", - "integrity": "sha512-LteOsISQ2GEiDHZch6L9hB0+MLoYVLToR7xotrzU0opCICBkxOPgHAy1HxAvtxfJNXDJpgAsQN30mkrfpO2Prg==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.1.tgz", + "integrity": "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==", "funding": [ { "type": "github", @@ -973,18 +985,19 @@ ], "license": "MIT", "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.1.3", - "strnum": "^2.2.0" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "node_modules/filesize": { - "version": "11.0.15", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.15.tgz", - "integrity": "sha512-30TpbYxQxCpi4XdVjkwXYQ37CzZltV38+P7MYroQ+4NK/Dmx9mxixFNrolzcmEIBsjT/uowC9T7kiy2+C12r1A==", + "version": "11.0.17", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.17.tgz", + "integrity": "sha512-oHLTvMLw6imZUl1se/RBQrFlyy50nXce4sU7yGR6Qc0JgCwqnfiFsAnEwotdGmfKLD7SArGUk2/5STU0k8LOBQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 10.8.0" @@ -1283,9 +1296,9 @@ "license": "BlueOak-1.0.0" }, "node_modules/path-expression-matcher": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.1.3.tgz", - "integrity": "sha512-qdVgY8KXmVdJZRSS1JdEPOKPdTiEK/pi0RkcT2sw1RhXxohdujUlJFPuS1TSkevZ9vzd3ZlL7ULl1MHGTApKzQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", "funding": [ { "type": "github", @@ -1546,9 +1559,9 @@ } }, "node_modules/strnum": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.1.tgz", - "integrity": "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", "funding": [ { "type": "github", diff --git a/node_modules/@actions/core/package.json b/node_modules/@actions/core/package.json index 3088d9d7..01f93cd7 100644 --- a/node_modules/@actions/core/package.json +++ b/node_modules/@actions/core/package.json @@ -1,6 +1,6 @@ { "name": "@actions/core", - "version": "3.0.0", + "version": "3.0.1", "description": "Actions core lib", "keywords": [ "github", diff --git a/node_modules/@actions/github/lib/internal/utils.d.ts b/node_modules/@actions/github/lib/internal/utils.d.ts index b0b206f2..4a379069 100644 --- a/node_modules/@actions/github/lib/internal/utils.d.ts +++ b/node_modules/@actions/github/lib/internal/utils.d.ts @@ -6,3 +6,4 @@ export declare function getProxyAgent(destinationUrl: string): http.Agent; export declare function getProxyAgentDispatcher(destinationUrl: string): ProxyAgent | undefined; export declare function getProxyFetch(destinationUrl: any): typeof fetch; export declare function getApiBaseUrl(): string; +export declare function getUserAgentWithOrchestrationId(baseUserAgent?: string): string | undefined; diff --git a/node_modules/@actions/github/lib/internal/utils.js b/node_modules/@actions/github/lib/internal/utils.js index 07b7974a..af52111a 100644 --- a/node_modules/@actions/github/lib/internal/utils.js +++ b/node_modules/@actions/github/lib/internal/utils.js @@ -36,4 +36,17 @@ export function getProxyFetch(destinationUrl) { export function getApiBaseUrl() { return process.env['GITHUB_API_URL'] || 'https://api.github.com'; } +export function getUserAgentWithOrchestrationId(baseUserAgent) { + var _a; + const orchId = (_a = process.env['ACTIONS_ORCHESTRATION_ID']) === null || _a === void 0 ? void 0 : _a.trim(); + if (orchId) { + const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_'); + const tag = `actions_orchestration_id/${sanitizedId}`; + if (baseUserAgent === null || baseUserAgent === void 0 ? void 0 : baseUserAgent.includes(tag)) + return baseUserAgent; + const ua = baseUserAgent ? `${baseUserAgent} ` : ''; + return `${ua}${tag}`; + } + return baseUserAgent; +} //# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/node_modules/@actions/github/lib/internal/utils.js.map b/node_modules/@actions/github/lib/internal/utils.js.map index 05e2442a..56c8f1f8 100644 --- a/node_modules/@actions/github/lib/internal/utils.js.map +++ b/node_modules/@actions/github/lib/internal/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/internal/utils.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,KAAK,UAAU,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAa,KAAK,EAAC,MAAM,QAAQ,CAAA;AAExC,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,OAAuB;IAEvB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;SAAM,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAA;AAC3E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,cAAsB;IAClD,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,CAAA;IACtC,OAAO,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,cAAsB;IAEtB,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,CAAA;IACtC,OAAO,EAAE,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,cAAc;IAC1C,MAAM,cAAc,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAA;IAC9D,MAAM,UAAU,GAAiB,CAAO,GAAG,EAAE,IAAI,EAAE,EAAE;QACnD,OAAO,KAAK,CAAC,GAAG,kCACX,IAAI,KACP,UAAU,EAAE,cAAc,IAC1B,CAAA;IACJ,CAAC,CAAA,CAAA;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,wBAAwB,CAAA;AAClE,CAAC"} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/internal/utils.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAO,KAAK,UAAU,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAa,KAAK,EAAC,MAAM,QAAQ,CAAA;AAExC,MAAM,UAAU,aAAa,CAC3B,KAAa,EACb,OAAuB;IAEvB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IAC7D,CAAC;SAAM,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAA;AAC3E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,cAAsB;IAClD,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,CAAA;IACtC,OAAO,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,cAAsB;IAEtB,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,CAAA;IACtC,OAAO,EAAE,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,cAAc;IAC1C,MAAM,cAAc,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAA;IAC9D,MAAM,UAAU,GAAiB,CAAO,GAAG,EAAE,IAAI,EAAE,EAAE;QACnD,OAAO,KAAK,CAAC,GAAG,kCACX,IAAI,KACP,UAAU,EAAE,cAAc,IAC1B,CAAA;IACJ,CAAC,CAAA,CAAA;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,wBAAwB,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,aAAsB;;IAEtB,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,0CAAE,IAAI,EAAE,CAAA;IAC9D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;QACzD,MAAM,GAAG,GAAG,4BAA4B,WAAW,EAAE,CAAA;QACrD,IAAI,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,aAAa,CAAA;QACtD,MAAM,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QACnD,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAA;IACtB,CAAC;IACD,OAAO,aAAa,CAAA;AACtB,CAAC"} \ No newline at end of file diff --git a/node_modules/@actions/github/lib/utils.d.ts b/node_modules/@actions/github/lib/utils.d.ts index 4912067d..ea50d2e7 100644 --- a/node_modules/@actions/github/lib/utils.d.ts +++ b/node_modules/@actions/github/lib/utils.d.ts @@ -6,6 +6,7 @@ export declare const defaults: OctokitOptions; export declare const GitHub: typeof Octokit & import("@octokit/core/types").Constructor; +export { getUserAgentWithOrchestrationId } from './internal/utils.js'; /** * Convience function to correctly format Octokit Options to pass into the constructor. * diff --git a/node_modules/@actions/github/lib/utils.js b/node_modules/@actions/github/lib/utils.js index 72e0c9ef..53c41896 100644 --- a/node_modules/@actions/github/lib/utils.js +++ b/node_modules/@actions/github/lib/utils.js @@ -14,6 +14,7 @@ export const defaults = { } }; export const GitHub = Octokit.plugin(restEndpointMethods, paginateRest).defaults(defaults); +export { getUserAgentWithOrchestrationId } from './internal/utils.js'; /** * Convience function to correctly format Octokit Options to pass into the constructor. * @@ -27,6 +28,11 @@ export function getOctokitOptions(token, options) { if (auth) { opts.auth = auth; } + // Orchestration ID + const userAgent = Utils.getUserAgentWithOrchestrationId(opts.userAgent); + if (userAgent) { + opts.userAgent = userAgent; + } return opts; } //# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/node_modules/@actions/github/lib/utils.js.map b/node_modules/@actions/github/lib/utils.js.map index 781a9120..12f4a409 100644 --- a/node_modules/@actions/github/lib/utils.js.map +++ b/node_modules/@actions/github/lib/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA;AAG5C,oBAAoB;AACpB,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AACrC,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAA;AACzE,OAAO,EAAC,YAAY,EAAC,MAAM,+BAA+B,CAAA;AAE1D,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;AAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,EAAE,CAAA;AACrC,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC,OAAO;IACP,OAAO,EAAE;QACP,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;QACnC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;KACpC;CACF,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAClC,mBAAmB,EACnB,YAAY,CACb,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAEpB;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,OAAwB;IAExB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA,CAAC,iEAAiE;IAE/G,OAAO;IACP,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7C,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA;AAG5C,oBAAoB;AACpB,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AACrC,OAAO,EAAC,mBAAmB,EAAC,MAAM,uCAAuC,CAAA;AACzE,OAAO,EAAC,YAAY,EAAC,MAAM,+BAA+B,CAAA;AAE1D,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAA;AAE5C,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,EAAE,CAAA;AACrC,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC,OAAO;IACP,OAAO,EAAE;QACP,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;QACnC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC;KACpC;CACF,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAClC,mBAAmB,EACnB,YAAY,CACb,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAEpB,OAAO,EAAC,+BAA+B,EAAC,MAAM,qBAAqB,CAAA;AAEnE;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,OAAwB;IAExB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA,CAAC,iEAAiE;IAE/G,OAAO;IACP,MAAM,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IAC7C,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,mBAAmB;IACnB,MAAM,SAAS,GAAG,KAAK,CAAC,+BAA+B,CACrD,IAAI,CAAC,SAA+B,CACrC,CAAA;IACD,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC"} \ No newline at end of file diff --git a/node_modules/@actions/github/package.json b/node_modules/@actions/github/package.json index 21345966..7395c981 100644 --- a/node_modules/@actions/github/package.json +++ b/node_modules/@actions/github/package.json @@ -1,6 +1,6 @@ { "name": "@actions/github", - "version": "9.0.0", + "version": "9.1.1", "description": "Actions github lib", "keywords": [ "github", diff --git a/node_modules/@nodable/entities/README.md b/node_modules/@nodable/entities/README.md new file mode 100644 index 00000000..18a7fb6b --- /dev/null +++ b/node_modules/@nodable/entities/README.md @@ -0,0 +1,41 @@ +# @nodable/entities + +Fast, zero-dependency XML/HTML entity encoder and decoder for Node.js. + +## Install + +```bash +npm install @nodable/entities +``` + +## Quick start + +```js +import { EntityEncoder, EntityDecoder, ALL_ENTITIES } from '@nodable/entities'; + +// Encode: plain text → entity references +const enc = new EntityEncoder(); +enc.encode('Hello © 2024 & '); +// → 'Hello © 2024 & <stuff>' + +// Decode: entity references → plain text +const dec = new EntityDecoder({ namedEntities: ALL_ENTITIES }); +dec.decode('Hello © 2024 & <stuff>'); +// → 'Hello © 2024 & ' +``` + +## Performance + +| | encode | decode | +|---|---|---| +| `entities` (npm) | 3.65 M req/s | 1.76 M req/s | +| `@nodable/entities` | 3.33 M req/s | **5.19 M req/s** | + +## Documentation + +- [EntityEncoder](docs/EntityEncoder.md) — options, API, recipes +- [EntityDecoder](docs/EntityDecoder.md) — options, API, security limits, entity sets + +## License + +MIT \ No newline at end of file diff --git a/node_modules/@nodable/entities/package.json b/node_modules/@nodable/entities/package.json new file mode 100644 index 00000000..b47e2600 --- /dev/null +++ b/node_modules/@nodable/entities/package.json @@ -0,0 +1,54 @@ +{ + "name": "@nodable/entities", + "version": "2.1.0", + "description": "Entity parser for XML, HTML, External entites with security and NCR control", + "main": "./src/index.js", + "type": "module", + "sideEffects": false, + "types": "./src/index.d.ts", + "scripts": { + "test": "node --experimental-vm-modules node_modules/.bin/jest", + "test:watch": "node --experimental-vm-modules node_modules/.bin/jest --watch", + "test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage", + "lint": "eslint src/ test/" + }, + "files": [ + "src", + "README.md" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/nodable/val-parsers.git" + }, + "keywords": [ + "fast", + "xml", + "html", + "entity", + "encode", + "decode", + "ncr", + "security", + "performance" + ], + "author": "Amit Gupta (https://solothought.com)", + "license": "MIT", + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "jest": "^29.7.0" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "jest": { + "testMatch": [ + "**/?(*.)+(spec|test).[jt]s?(x)", + "**/*_spec.[jt]s?(x)" + ] + } +} \ No newline at end of file diff --git a/node_modules/@nodable/entities/src/EntityDecoder.js b/node_modules/@nodable/entities/src/EntityDecoder.js new file mode 100644 index 00000000..c2aa270a --- /dev/null +++ b/node_modules/@nodable/entities/src/EntityDecoder.js @@ -0,0 +1,543 @@ +// --------------------------------------------------------------------------- +// Built-in named entity map (name → replacement string) +// No regex, no {regex,val} objects — just flat key/value pairs. +// --------------------------------------------------------------------------- + +import { XML as DEFAULT_XML_ENTITIES } from "./entities.js" + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +const SPECIAL_CHARS = new Set('!?\\\\/[]$%{}^&*()<>|+'); + +/** + * Validate that an entity name contains no dangerous characters. + * @param {string} name + * @returns {string} the name, unchanged + * @throws {Error} on invalid characters + */ +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; +} + +/** + * Merge one or more entity maps into a flat name→string map. + * Accepts either: + * - plain string values: { amp: '&' } + * - legacy {regex,val} / {regx,val}: { lt: { regex: /.../, val: '<' } } + * + * Values containing '&' are skipped (recursive expansion risk). + * + * @param {...object} maps + * @returns {Record} + */ +function mergeEntityMaps(...maps) { + const out = Object.create(null); + for (const map of maps) { + if (!map) continue; + for (const key of Object.keys(map)) { + const raw = map[key]; + if (typeof raw === 'string') { + out[key] = raw; + } else if (raw && typeof raw === 'object' && raw.val !== undefined) { + // Legacy {regex,val} or {regx,val} — extract the string val only + const val = raw.val; + if (typeof val === 'string') { + out[key] = val; + } + // function vals are not supported in the scanner — skip + } + } + } + return out; +} + +// --------------------------------------------------------------------------- +// applyLimitsTo helpers +// --------------------------------------------------------------------------- + +const LIMIT_TIER_EXTERNAL = 'external'; // input/runtime + persistent external maps +const LIMIT_TIER_BASE = 'base'; // DEFAULT_XML_ENTITIES + namedEntities (system) maps +const LIMIT_TIER_ALL = 'all'; // every entity regardless of tier + +/** + * Resolve `applyLimitsTo` option into a normalised Set of tier strings. + * Accepted values: 'external' | 'base' | 'all' | string[] + * Default: 'external' (only untrusted injected entities are counted). + * @param {string|string[]|undefined} raw + * @returns {Set} + */ +function parseLimitTiers(raw) { + if (!raw || raw === LIMIT_TIER_EXTERNAL) return new Set([LIMIT_TIER_EXTERNAL]); + if (raw === LIMIT_TIER_ALL) return new Set([LIMIT_TIER_ALL]); + if (raw === LIMIT_TIER_BASE) return new Set([LIMIT_TIER_BASE]); + if (Array.isArray(raw)) return new Set(raw); + return new Set([LIMIT_TIER_EXTERNAL]); // safe default for unrecognised values +} + +// --------------------------------------------------------------------------- +// NCR (Numeric Character Reference) classification +// --------------------------------------------------------------------------- + +// Severity order — higher number = stricter action. +// Used to enforce minimum action levels for specific codepoint ranges. +const NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 }); + +// XML 1.0 §2.2: allowed chars are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] +// Restricted C0: U+0001–U+001F excluding U+0009, U+000A, U+000D +const XML10_ALLOWED_C0 = new Set([0x09, 0x0A, 0x0D]); + +/** + * Parse the `ncr` constructor option into flat, hot-path-friendly fields. + * @param {object|undefined} ncr + * @returns {{ xmlVersion: number, onLevel: number, nullLevel: number }} + */ +function parseNCRConfig(ncr) { + if (!ncr) { + return { xmlVersion: 1.0, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove }; + } + const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1.0; + const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow; + const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove; + // 'allow' is not meaningful for null — clamp to at least 'remove' + const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove); + return { xmlVersion, onLevel, nullLevel: clampedNull }; +} + +// --------------------------------------------------------------------------- +// EntityReplacer +// --------------------------------------------------------------------------- + +/** + * Single-pass, zero-regex entity replacer for XML/HTML content. + * + * Algorithm: scan the string once for '&', read to ';', resolve via map + * or direct codepoint conversion, build output chunks, join once at the end. + * + * Entity lookup priority (highest → lowest): + * 1. input / runtime (DOCTYPE entities for current document) + * 2. persistent external (survive across documents) + * 3. base named map (DEFAULT_XML_ENTITIES + user-supplied namedEntities) + * + * Both input and external resolve as the 'external' tier for limit purposes. + * Base map entities resolve as the 'base' tier. + * + * Numeric / hex references (&#NNN; / &#xHH;) are resolved directly via + * String.fromCodePoint() — no map needed. They count as 'base' tier. + * + * @example + * const replacer = new EntityReplacer({ namedEntities: COMMON_HTML }); + * replacer.setExternalEntities({ brand: 'Acme' }); + * + * const instance = replacer.reset(); + * instance.addInputEntities({ version: '1.0' }); + * instance.encode('&brand; v&version; <'); // 'Acme v1.0 <' + */ +export default class EntityDecoder { + /** + * @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; + // Base map: DEFAULT_XML_ENTITIES + user-supplied extras. Immutable after construction. + this._baseMap = mergeEntityMaps(DEFAULT_XML_ENTITIES, options.namedEntities || null); + + // Persistent external entities — survive across documents. + // Stored as a separate map so reset() never touches them. + /** @type {Record} */ + this._externalMap = Object.create(null); + + // Input / runtime entities — current document only, wiped on reset(). + /** @type {Record} */ + this._inputMap = Object.create(null); + + // Per-document counters + this._totalExpansions = 0; + this._expandedLength = 0; + + // --- New: remove / leave sets --- + /** @type {Set} */ + this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []); + /** @type {Set} */ + this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []); + + // --- NCR config (parsed into flat fields for hot-path speed) --- + 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(map) { + if (map) { + for (const key of Object.keys(map)) { + validateEntityName(key); + } + } + this._externalMap = mergeEntityMaps(map); + } + + /** + * 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(map) { + this._totalExpansions = 0; + this._expandedLength = 0; + this._inputMap = mergeEntityMaps(map); + } + + // ------------------------------------------------------------------------- + // Per-document reset + // ------------------------------------------------------------------------- + + /** + * Wipe input/runtime entities and reset counters. + * Call this before processing each new document. + * @returns {this} + */ + reset() { + this._inputMap = 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(version) { + this._ncrXmlVersion = version === 1.1 ? 1.1 : 1.0; + } + + // ------------------------------------------------------------------------- + // Primary API + // ------------------------------------------------------------------------- + + /** + * Replace all entity references in `str` in a single pass. + * + * @param {string} str + * @returns {string} + */ + decode(str) { + if (typeof str !== 'string' || str.length === 0) return str; + //TODO: check if needed + //if (str.indexOf('&') === -1) return str; // fast path — no entities at all + + const original = str; + const chunks = []; + const len = str.length; + let last = 0; // start of next unprocessed literal chunk + let i = 0; + + const limitExpansions = this._maxTotalExpansions > 0; + const limitLength = this._maxExpandedLength > 0; + const checkLimits = limitExpansions || limitLength; + + while (i < len) { + // Scan forward to next '&' + if (str.charCodeAt(i) !== 38 /* '&' */) { i++; continue; } + + // --- Found '&' at position i --- + + // Scan forward to ';' + let j = i + 1; + while (j < len && str.charCodeAt(j) !== 59 /* ';' */ && (j - i) <= 32) j++; + + if (j >= len || str.charCodeAt(j) !== 59) { + // No closing ';' within window — treat '&' as literal + i++; + continue; + } + + // Raw token between '&' and ';' (exclusive) + const token = str.slice(i + 1, j); + if (token.length === 0) { i++; continue; } + + let replacement; + let tier; // which limit tier this entity belongs to + + if (this._removeSet.has(token)) { + // Remove entity: replace with empty string + replacement = ''; + // If entity was unknown (replacement undefined), we still need a tier for limits. + // Treat as external tier because it's user-directed removal of an unknown reference. + if (tier === undefined) { + tier = LIMIT_TIER_EXTERNAL; + } + } else if (this._leaveSet.has(token)) { + // Do not replace — keep original &token; as literal + i++; + continue; + } else if (token.charCodeAt(0) === 35 /* '#' */) { + // ---- Numeric / NCR reference ---- + // NCR classification always runs first — prohibited codepoints must be + // caught regardless of numericAllowed. + const ncrResult = this._resolveNCR(token); + if (ncrResult === undefined) { + // 'leave' action — keep original &token; as-is + i++; + continue; + } + replacement = ncrResult; // '' for remove, char string for allow + tier = LIMIT_TIER_BASE; + } else { + // ---- Named reference ---- + const resolved = this._resolveName(token); + replacement = resolved?.value; + tier = resolved?.tier; + } + + if (replacement === undefined) { + // Unknown entity — leave as-is, advance past '&' only + i++; + continue; + } + + // Flush literal chunk before this entity + if (i > last) chunks.push(str.slice(last, i)); + chunks.push(replacement); + last = j + 1; // skip past ';' + i = last; + + // Apply expansion limits only if this tier is being tracked + if (checkLimits && this._tierCounts(tier)) { + if (limitExpansions) { + this._totalExpansions++; + if (this._totalExpansions > this._maxTotalExpansions) { + throw new Error( + `[EntityReplacer] Entity expansion count limit exceeded: ` + + `${this._totalExpansions} > ${this._maxTotalExpansions}` + ); + } + } + if (limitLength) { + // delta: replacement.length minus the raw &token; length (token.length + 2 for '&' and ';') + 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}` + ); + } + } + } + } + } + + // Flush trailing literal + if (last < len) chunks.push(str.slice(last)); + + // If nothing was replaced, chunks is empty — return original + const result = chunks.length === 0 ? str : 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(tier) { + if (this._limitTiers.has(LIMIT_TIER_ALL)) return true; + return this._limitTiers.has(tier); + } + + // ------------------------------------------------------------------------- + // 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) { + // input and external both count as 'external' tier for limit purposes — + // they are injected at runtime and are the untrusted surface. + 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 undefined; + } + + /** + * 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(cp) { + // 1. Null + if (cp === 0) return this._ncrNullLevel; + + // 2. Surrogates — always prohibited, minimum 'remove' + if (cp >= 0xD800 && cp <= 0xDFFF) return NCR_LEVEL.remove; + + // 3. XML 1.0 restricted C0 controls + if (this._ncrXmlVersion === 1.0) { + if (cp >= 0x01 && cp <= 0x1F && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove; + } + + return -1; // no restriction + } + + /** + * 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(action, token, cp) { + switch (action) { + case NCR_LEVEL.allow: return String.fromCodePoint(cp); + case NCR_LEVEL.remove: return ''; + case NCR_LEVEL.leave: return undefined; // signal: keep literal + case NCR_LEVEL.throw: + throw new Error( + `[EntityDecoder] Prohibited numeric character reference ` + + `&${token}; (U+${cp.toString(16).toUpperCase().padStart(4, '0')})` + ); + default: return String.fromCodePoint(cp); + } + } + + /** + * 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) { + // Step 1: parse codepoint + const second = token.charCodeAt(1); + let cp; + if (second === 120 /* x */ || second === 88 /* X */) { + cp = parseInt(token.slice(2), 16); + } else { + cp = parseInt(token.slice(1), 10); + } + + // Step 2: out-of-range → leave as-is unconditionally + if (Number.isNaN(cp) || cp < 0 || cp > 0x10FFFF) return undefined; + + // Step 3: classify to get minimum action level + const minimum = this._classifyNCR(cp); + + // Step 4: if numericAllowed is false and no hard minimum → leave + if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return undefined; + + // Step 5: effective action = max(configured onNCR, range minimum) + const effective = minimum === -1 + ? this._ncrOnLevel + : Math.max(this._ncrOnLevel, minimum); + + // Step 6: apply + return this._applyNCRAction(effective, token, cp); + } +} \ No newline at end of file diff --git a/node_modules/@nodable/entities/src/EntityEncoder.js b/node_modules/@nodable/entities/src/EntityEncoder.js new file mode 100644 index 00000000..a53f5a32 --- /dev/null +++ b/node_modules/@nodable/entities/src/EntityEncoder.js @@ -0,0 +1,194 @@ +// EntityDecoder.js +import { trie1, trie2, trie3 } from './entityTries.js'; + +// Replacement strings indexed by char code — direct array access, no hashing +const XML_UNSAFE_REPLACEMENT = new Array(128); +XML_UNSAFE_REPLACEMENT[38] = '&'; // & +XML_UNSAFE_REPLACEMENT[60] = '<'; // < +XML_UNSAFE_REPLACEMENT[62] = '>'; // > +XML_UNSAFE_REPLACEMENT[34] = '"'; // " +XML_UNSAFE_REPLACEMENT[39] = '''; // ' + +// Typed bitmask for O(1) "is this ASCII code XML-unsafe?" check +const IS_XML_UNSAFE = new Uint8Array(128); +IS_XML_UNSAFE[38] = 1; +IS_XML_UNSAFE[60] = 1; +IS_XML_UNSAFE[62] = 1; +IS_XML_UNSAFE[34] = 1; +IS_XML_UNSAFE[39] = 1; + +// Fast pre-scan: bail out immediately if nothing needs encoding +const NEEDS_PROCESSING = /[&<>"'\u0080-\uFFFF]/; + +export default class EntityEncoder { + constructor(options = {}) { + this.encodeXmlSafe = options.encodeXmlSafe !== false; + this.encodeAllNamed = options.encodeAllNamed !== false; + this.maxReplacements = options.maxReplacements || 0; + this.replacementsCount = 0; + } + + encode(str) { + if (typeof str !== 'string' || str.length === 0) return str; + if (!NEEDS_PROCESSING.test(str)) return str; + + const maxRep = this.maxReplacements; + if (maxRep > 0 && this.replacementsCount >= maxRep) return str; + + // Hoist to locals — avoids `this` property lookup inside the hot loop + const encodeXmlSafe = this.encodeXmlSafe; + const encodeAllNamed = this.encodeAllNamed; + + const len = str.length; + + let result = ''; + let last = 0; + let i = 0; + let limitReached = false; + + // ── Main loop: runs to len-2 so trie3 never needs a bounds check ──────── + // The last 2 characters are handled by the tail block below. + const mainEnd = len - 2; // i <= mainEnd guarantees i+1 and i+2 are valid + + while (i <= mainEnd && !limitReached) { + const c0 = str.charCodeAt(i); + + // ── ASCII branch ─────────────────────────────────────────────────── + if (c0 < 128) { + if (encodeXmlSafe && IS_XML_UNSAFE[c0] === 1) { + result += str.substring(last, i) + XML_UNSAFE_REPLACEMENT[c0]; + last = ++i; + if (maxRep > 0) { + this.replacementsCount++; + if (this.replacementsCount >= maxRep) { + limitReached = true; + break; + } + } + } else { + // Bulk-skip: advance to the next interesting position without + // touching the outer loop overhead on every safe character + i++; + while (i <= mainEnd && !limitReached) { + const c = str.charCodeAt(i); + if (c >= 128 || (encodeXmlSafe && IS_XML_UNSAFE[c] === 1)) break; + i++; + } + } + continue; + } + + // ── Non-ASCII: integer-keyed trie lookup ─────────────────────────── + // No bounds checks needed for c1/c2 because i <= mainEnd guarantees + // i+1 and i+2 are both within the string. + let matchedEntity = null; + let advance = 1; + + // Try 3-char match first (longest wins) + const mid3 = trie3.get(c0); + if (mid3 !== undefined) { + const c1 = str.charCodeAt(i + 1); + const inner3 = mid3.get(c1); + if (inner3 !== undefined) { + const c2 = str.charCodeAt(i + 2); + const candidate = inner3.get(c2); + if (candidate !== undefined) { matchedEntity = candidate; advance = 3; } + } + } + + // Try 2-char match + if (matchedEntity === null) { + const inner2 = trie2.get(c0); + if (inner2 !== undefined) { + const c1 = str.charCodeAt(i + 1); + const candidate = inner2.get(c1); + if (candidate !== undefined) { matchedEntity = candidate; advance = 2; } + } + } + + // Try 1-char match + if (matchedEntity === null && encodeAllNamed) { + const candidate = trie1.get(c0); + if (candidate !== undefined) { matchedEntity = candidate; } + } + + if (matchedEntity !== null) { + result += str.substring(last, i) + matchedEntity; + i += advance; + last = i; + if (maxRep > 0) { + this.replacementsCount++; + if (this.replacementsCount >= maxRep) { + limitReached = true; + break; + } + } + } else { + i++; + } + } + + // ── Tail: handle the last 1-2 characters (no 3-char match possible) ──── + while (i < len && !limitReached) { + const c0 = str.charCodeAt(i); + + if (c0 < 128) { + if (encodeXmlSafe && IS_XML_UNSAFE[c0] === 1) { + result += str.substring(last, i) + XML_UNSAFE_REPLACEMENT[c0]; + last = ++i; + if (maxRep > 0) { + this.replacementsCount++; + if (this.replacementsCount >= maxRep) { + limitReached = true; + break; + } + } + } else { + i++; + } + continue; + } + + // Non-ASCII tail — only 2-char and 1-char matches are possible here + let matchedEntity = null; + let advance = 1; + + if (i + 1 < len) { + const inner2 = trie2.get(c0); + if (inner2 !== undefined) { + const c1 = str.charCodeAt(i + 1); + const candidate = inner2.get(c1); + if (candidate !== undefined) { matchedEntity = candidate; advance = 2; } + } + } + + if (matchedEntity === null && encodeAllNamed) { + const candidate = trie1.get(c0); + if (candidate !== undefined) { matchedEntity = candidate; } + } + + if (matchedEntity !== null) { + result += str.substring(last, i) + matchedEntity; + i += advance; + last = i; + if (maxRep > 0) { + this.replacementsCount++; + if (this.replacementsCount >= maxRep) { + limitReached = true; + break; + } + } + } else { + i++; + } + } + + // ── Flush any remaining literal suffix ──────────────────────────────── + if (last < len) result += str.substring(last); + return result; + } + + reset() { + this.replacementsCount = 0; + } +} \ No newline at end of file diff --git a/node_modules/@nodable/entities/src/entities.js b/node_modules/@nodable/entities/src/entities.js new file mode 100644 index 00000000..46e8a883 --- /dev/null +++ b/node_modules/@nodable/entities/src/entities.js @@ -0,0 +1,1177 @@ +// --------------------------------------------------------------------------- +// Complete HTML5 named entity reference +// Organized by logical categories for easy maintenance and selective importing +// --------------------------------------------------------------------------- + +/** + * Basic Latin & Special Characters + * @type {Record} + */ +export const BASIC_LATIN = { + amp: '&', + AMP: '&', + lt: '<', + LT: '<', + gt: '>', + GT: '>', + quot: '"', + QUOT: '"', + apos: "'", + lsquo: '‘', + rsquo: '’', + ldquo: '“', + rdquo: '”', + lsquor: '‚', + rsquor: '’', + ldquor: '„', + bdquo: '„', + comma: ',', + period: '.', + colon: ':', + semi: ';', + excl: '!', + quest: '?', + num: '#', + dollar: '$', + percent: '%', + amp: '&', + ast: '*', + commat: '@', + lowbar: '_', + verbar: '|', + vert: '|', + sol: '/', + bsol: '\\', + lbrace: '{', + rbrace: '}', + lbrack: '[', + rbrack: ']', + lpar: '(', + rpar: ')', + nbsp: '\u00a0', + iexcl: '¡', + cent: '¢', + pound: '£', + curren: '¤', + yen: '¥', + brvbar: '¦', + sect: '§', + uml: '¨', + copy: '©', + COPY: '©', + ordf: 'ª', + laquo: '«', + not: '¬', + shy: '\u00ad', + reg: '®', + REG: '®', + macr: '¯', + deg: '°', + plusmn: '±', + sup2: '²', + sup3: '³', + acute: '´', + micro: 'µ', + para: '¶', + middot: '·', + cedil: '¸', + sup1: '¹', + ordm: 'º', + raquo: '»', + frac14: '¼', + frac12: '½', + half: '½', + frac34: '¾', + iquest: '¿', + times: '×', + div: '÷', + divide: '÷', +}; + +/** + * Latin Extended & Accented Letters (A-Z) + * @type {Record} + */ +export const LATIN_ACCENTS = { + Agrave: 'À', + agrave: 'à', + Aacute: 'Á', + aacute: 'á', + Acirc: 'Â', + acirc: 'â', + Atilde: 'Ã', + atilde: 'ã', + Auml: 'Ä', + auml: 'ä', + Aring: 'Å', + aring: 'å', + AElig: 'Æ', + aelig: 'æ', + Ccedil: 'Ç', + ccedil: 'ç', + Egrave: 'È', + egrave: 'è', + Eacute: 'É', + eacute: 'é', + Ecirc: 'Ê', + ecirc: 'ê', + Euml: 'Ë', + euml: 'ë', + Igrave: 'Ì', + igrave: 'ì', + Iacute: 'Í', + iacute: 'í', + Icirc: 'Î', + icirc: 'î', + Iuml: 'Ï', + iuml: 'ï', + ETH: 'Ð', + eth: 'ð', + Ntilde: 'Ñ', + ntilde: 'ñ', + Ograve: 'Ò', + ograve: 'ò', + Oacute: 'Ó', + oacute: 'ó', + Ocirc: 'Ô', + ocirc: 'ô', + Otilde: 'Õ', + otilde: 'õ', + Ouml: 'Ö', + ouml: 'ö', + Oslash: 'Ø', + oslash: 'ø', + Ugrave: 'Ù', + ugrave: 'ù', + Uacute: 'Ú', + uacute: 'ú', + Ucirc: 'Û', + ucirc: 'û', + Uuml: 'Ü', + uuml: 'ü', + Yacute: 'Ý', + yacute: 'ý', + THORN: 'Þ', + thorn: 'þ', + szlig: 'ß', + yuml: 'ÿ', + Yuml: 'Ÿ', +}; + +/** + * Latin Extended (Letters with diacritics) + * @type {Record} + */ +export const LATIN_EXTENDED = { + Amacr: 'Ā', + amacr: 'ā', + Abreve: 'Ă', + abreve: 'ă', + Aogon: 'Ą', + aogon: 'ą', + Cacute: 'Ć', + cacute: 'ć', + Ccirc: 'Ĉ', + ccirc: 'ĉ', + Cdot: 'Ċ', + cdot: 'ċ', + Ccaron: 'Č', + ccaron: 'č', + Dcaron: 'Ď', + dcaron: 'ď', + Dstrok: 'Đ', + dstrok: 'đ', + Emacr: 'Ē', + emacr: 'ē', + Ecaron: 'Ě', + ecaron: 'ě', + Edot: 'Ė', + edot: 'ė', + Eogon: 'Ę', + eogon: 'ę', + Gcirc: 'Ĝ', + gcirc: 'ĝ', + Gbreve: 'Ğ', + gbreve: 'ğ', + Gdot: 'Ġ', + gdot: 'ġ', + Gcedil: 'Ģ', + Hcirc: 'Ĥ', + hcirc: 'ĥ', + Hstrok: 'Ħ', + hstrok: 'ħ', + Itilde: 'Ĩ', + itilde: 'ĩ', + Imacr: 'Ī', + imacr: 'ī', + Iogon: 'Į', + iogon: 'į', + Idot: 'İ', + IJlig: 'IJ', + ijlig: 'ij', + Jcirc: 'Ĵ', + jcirc: 'ĵ', + Kcedil: 'Ķ', + kcedil: 'ķ', + kgreen: 'ĸ', + Lacute: 'Ĺ', + lacute: 'ĺ', + Lcedil: 'Ļ', + lcedil: 'ļ', + Lcaron: 'Ľ', + lcaron: 'ľ', + Lmidot: 'Ŀ', + lmidot: 'ŀ', + Lstrok: 'Ł', + lstrok: 'ł', + Nacute: 'Ń', + nacute: 'ń', + Ncaron: 'Ň', + ncaron: 'ň', + Ncedil: 'Ņ', + ncedil: 'ņ', + ENG: 'Ŋ', + eng: 'ŋ', + Omacr: 'Ō', + omacr: 'ō', + Odblac: 'Ő', + odblac: 'ő', + OElig: 'Œ', + oelig: 'œ', + Racute: 'Ŕ', + racute: 'ŕ', + Rcaron: 'Ř', + rcaron: 'ř', + Rcedil: 'Ŗ', + rcedil: 'ŗ', + Sacute: 'Ś', + sacute: 'ś', + Scirc: 'Ŝ', + scirc: 'ŝ', + Scedil: 'Ş', + scedil: 'ş', + Scaron: 'Š', + scaron: 'š', + Tcedil: 'Ţ', + tcedil: 'ţ', + Tcaron: 'Ť', + tcaron: 'ť', + Tstrok: 'Ŧ', + tstrok: 'ŧ', + Utilde: 'Ũ', + utilde: 'ũ', + Umacr: 'Ū', + umacr: 'ū', + Ubreve: 'Ŭ', + ubreve: 'ŭ', + Uring: 'Ů', + uring: 'ů', + Udblac: 'Ű', + udblac: 'ű', + Uogon: 'Ų', + uogon: 'ų', + Wcirc: 'Ŵ', + wcirc: 'ŵ', + Ycirc: 'Ŷ', + ycirc: 'ŷ', + Zacute: 'Ź', + zacute: 'ź', + Zdot: 'Ż', + zdot: 'ż', + Zcaron: 'Ž', + zcaron: 'ž', +}; + +/** + * Greek Letters + * @type {Record} + */ +export const GREEK = { + Alpha: 'Α', + alpha: 'α', + Beta: 'Β', + beta: 'β', + Gamma: 'Γ', + gamma: 'γ', + Delta: 'Δ', + delta: 'δ', + Epsilon: 'Ε', + epsilon: 'ε', + epsiv: 'ϵ', + varepsilon: 'ϵ', + Zeta: 'Ζ', + zeta: 'ζ', + Eta: 'Η', + eta: 'η', + Theta: 'Θ', + theta: 'θ', + thetasym: 'ϑ', + vartheta: 'ϑ', + Iota: 'Ι', + iota: 'ι', + Kappa: 'Κ', + kappa: 'κ', + kappav: 'ϰ', + varkappa: 'ϰ', + Lambda: 'Λ', + lambda: 'λ', + Mu: 'Μ', + mu: 'μ', + Nu: 'Ν', + nu: 'ν', + Xi: 'Ξ', + xi: 'ξ', + Omicron: 'Ο', + omicron: 'ο', + Pi: 'Π', + pi: 'π', + piv: 'ϖ', + varpi: 'ϖ', + Rho: 'Ρ', + rho: 'ρ', + rhov: 'ϱ', + varrho: 'ϱ', + Sigma: 'Σ', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + varsigma: 'ς', + Tau: 'Τ', + tau: 'τ', + Upsilon: 'Υ', + upsilon: 'υ', + upsi: 'υ', + Upsi: 'ϒ', + upsih: 'ϒ', + Phi: 'Φ', + phi: 'φ', + phiv: 'ϕ', + varphi: 'ϕ', + Chi: 'Χ', + chi: 'χ', + Psi: 'Ψ', + psi: 'ψ', + Omega: 'Ω', + omega: 'ω', + ohm: 'Ω', + Gammad: 'Ϝ', + gammad: 'ϝ', + digamma: 'ϝ', +}; + +/** + * Cyrillic Letters + * @type {Record} + */ +export const CYRILLIC = { + Afr: '𝔄', + afr: '𝔞', + Acy: 'А', + acy: 'а', + Bcy: 'Б', + bcy: 'б', + Vcy: 'В', + vcy: 'в', + Gcy: 'Г', + gcy: 'г', + Dcy: 'Д', + dcy: 'д', + IEcy: 'Е', + iecy: 'е', + IOcy: 'Ё', + iocy: 'ё', + ZHcy: 'Ж', + zhcy: 'ж', + Zcy: 'З', + zcy: 'з', + Icy: 'И', + icy: 'и', + Jcy: 'Й', + jcy: 'й', + Kcy: 'К', + kcy: 'к', + Lcy: 'Л', + lcy: 'л', + Mcy: 'М', + mcy: 'м', + Ncy: 'Н', + ncy: 'н', + Ocy: 'О', + ocy: 'о', + Pcy: 'П', + pcy: 'п', + Rcy: 'Р', + rcy: 'р', + Scy: 'С', + scy: 'с', + Tcy: 'Т', + tcy: 'т', + Ucy: 'У', + ucy: 'у', + Fcy: 'Ф', + fcy: 'ф', + KHcy: 'Х', + khcy: 'х', + TScy: 'Ц', + tscy: 'ц', + CHcy: 'Ч', + chcy: 'ч', + SHcy: 'Ш', + shcy: 'ш', + SHCHcy: 'Щ', + shchcy: 'щ', + HARDcy: 'Ъ', + hardcy: 'ъ', + Ycy: 'Ы', + ycy: 'ы', + SOFTcy: 'Ь', + softcy: 'ь', + Ecy: 'Э', + ecy: 'э', + YUcy: 'Ю', + yucy: 'ю', + YAcy: 'Я', + yacy: 'я', + DJcy: 'Ђ', + djcy: 'ђ', + GJcy: 'Ѓ', + gjcy: 'ѓ', + Jukcy: 'Є', + jukcy: 'є', + DScy: 'Ѕ', + dscy: 'ѕ', + Iukcy: 'І', + iukcy: 'і', + YIcy: 'Ї', + yicy: 'ї', + Jsercy: 'Ј', + jsercy: 'ј', + LJcy: 'Љ', + ljcy: 'љ', + NJcy: 'Њ', + njcy: 'њ', + TSHcy: 'Ћ', + tshcy: 'ћ', + KJcy: 'Ќ', + kjcy: 'ќ', + Ubrcy: 'Ў', + ubrcy: 'ў', + DZcy: 'Џ', + dzcy: 'џ', +}; + +/** + * Mathematical Operators & Relations + * @type {Record} + */ +export const MATH = { + plus: '+', + minus: '−', + mnplus: '∓', + mp: '∓', + pm: '±', + times: '×', + div: '÷', + divide: '÷', + sdot: '⋅', + star: '☆', + starf: '★', + bigstar: '★', + lowast: '∗', + ast: '*', + midast: '*', + compfn: '∘', + smallcircle: '∘', + bullet: '•', + bull: '•', + nbsp: '\u00a0', + hellip: '…', + mldr: '…', + prime: '′', + Prime: '″', + tprime: '‴', + bprime: '‵', + backprime: '‵', + minus: '−', + minusd: '∸', + dotminus: '∸', + plusdo: '∔', + dotplus: '∔', + plusmn: '±', + minusplus: '∓', + mnplus: '∓', + mp: '∓', + setminus: '∖', + smallsetminus: '∖', + Backslash: '∖', + setmn: '∖', + ssetmn: '∖', + lowbar: '_', + verbar: '|', + vert: '|', + VerticalLine: '|', + colon: ':', + Colon: '∷', + Proportion: '∷', + ratio: '∶', + equals: '=', + ne: '≠', + nequiv: '≢', + equiv: '≡', + Congruent: '≡', + sim: '∼', + thicksim: '∼', + thksim: '∼', + sime: '≃', + simeq: '≃', + TildeEqual: '≃', + asymp: '≈', + approx: '≈', + thickapprox: '≈', + thkap: '≈', + TildeTilde: '≈', + ncong: '≇', + cong: '≅', + TildeFullEqual: '≅', + asympeq: '≍', + CupCap: '≍', + bump: '≎', + Bumpeq: '≎', + HumpDownHump: '≎', + bumpe: '≏', + bumpeq: '≏', + HumpEqual: '≏', + dotminus: '∸', + minusd: '∸', + plusdo: '∔', + dotplus: '∔', + le: '≤', + LessEqual: '≤', + ge: '≥', + GreaterEqual: '≥', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + greater: '>', + less: '<', +}; + +/** + * Mathematical Operators (Advanced) + * @type {Record} + */ +export const MATH_ADVANCED = { + alefsym: 'ℵ', + aleph: 'ℵ', + beth: 'ℶ', + gimel: 'ℷ', + daleth: 'ℸ', + forall: '∀', + ForAll: '∀', + part: '∂', + PartialD: '∂', + exist: '∃', + Exists: '∃', + nexist: '∄', + nexists: '∄', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + varnothing: '∅', + nabla: '∇', + Del: '∇', + isin: '∈', + isinv: '∈', + in: '∈', + Element: '∈', + notin: '∉', + notinva: '∉', + ni: '∋', + niv: '∋', + SuchThat: '∋', + ReverseElement: '∋', + notni: '∌', + notniva: '∌', + prod: '∏', + Product: '∏', + coprod: '∐', + Coproduct: '∐', + sum: '∑', + Sum: '∑', + minus: '−', + mp: '∓', + plusdo: '∔', + dotplus: '∔', + setminus: '∖', + lowast: '∗', + radic: '√', + Sqrt: '√', + prop: '∝', + propto: '∝', + Proportional: '∝', + varpropto: '∝', + infin: '∞', + infintie: '⧝', + ang: '∠', + angle: '∠', + angmsd: '∡', + measuredangle: '∡', + angsph: '∢', + mid: '∣', + VerticalBar: '∣', + nmid: '∤', + nsmid: '∤', + npar: '∦', + parallel: '∥', + spar: '∥', + nparallel: '∦', + nspar: '∦', + and: '∧', + wedge: '∧', + or: '∨', + vee: '∨', + cap: '∩', + cup: '∪', + int: '∫', + Integral: '∫', + conint: '∮', + ContourIntegral: '∮', + Conint: '∯', + DoubleContourIntegral: '∯', + Cconint: '∰', + there4: '∴', + therefore: '∴', + Therefore: '∴', + becaus: '∵', + because: '∵', + Because: '∵', + ratio: '∶', + Proportion: '∷', + minusd: '∸', + dotminus: '∸', + mDDot: '∺', + homtht: '∻', + sim: '∼', + bsimg: '∽', + backsim: '∽', + ac: '∾', + mstpos: '∾', + acd: '∿', + VerticalTilde: '≀', + wr: '≀', + wreath: '≀', + nsime: '≄', + nsimeq: '≄', + nsimeq: '≄', + ncong: '≇', + simne: '≆', + ncongdot: '⩭̸', + ngsim: '≵', + nsim: '≁', + napprox: '≉', + nap: '≉', + ngeq: '≱', + nge: '≱', + nleq: '≰', + nle: '≰', + ngtr: '≯', + ngt: '≯', + nless: '≮', + nlt: '≮', + nprec: '⊀', + npr: '⊀', + nsucc: '⊁', + nsc: '⊁', +}; + +/** + * Arrows + * @type {Record} + */ +export const ARROWS = { + larr: '←', + leftarrow: '←', + LeftArrow: '←', + uarr: '↑', + uparrow: '↑', + UpArrow: '↑', + rarr: '→', + rightarrow: '→', + RightArrow: '→', + darr: '↓', + downarrow: '↓', + DownArrow: '↓', + harr: '↔', + leftrightarrow: '↔', + LeftRightArrow: '↔', + varr: '↕', + updownarrow: '↕', + UpDownArrow: '↕', + nwarr: '↖', + nwarrow: '↖', + UpperLeftArrow: '↖', + nearr: '↗', + nearrow: '↗', + UpperRightArrow: '↗', + searr: '↘', + searrow: '↘', + LowerRightArrow: '↘', + swarr: '↙', + swarrow: '↙', + LowerLeftArrow: '↙', + lArr: '⇐', + Leftarrow: '⇐', + uArr: '⇑', + Uparrow: '⇑', + rArr: '⇒', + Rightarrow: '⇒', + dArr: '⇓', + Downarrow: '⇓', + hArr: '⇔', + Leftrightarrow: '⇔', + iff: '⇔', + vArr: '⇕', + Updownarrow: '⇕', + lAarr: '⇚', + Lleftarrow: '⇚', + rAarr: '⇛', + Rrightarrow: '⇛', + lrarr: '⇆', + leftrightarrows: '⇆', + rlarr: '⇄', + rightleftarrows: '⇄', + lrhar: '⇋', + leftrightharpoons: '⇋', + ReverseEquilibrium: '⇋', + rlhar: '⇌', + rightleftharpoons: '⇌', + Equilibrium: '⇌', + udarr: '⇅', + UpArrowDownArrow: '⇅', + duarr: '⇵', + DownArrowUpArrow: '⇵', + llarr: '⇇', + leftleftarrows: '⇇', + rrarr: '⇉', + rightrightarrows: '⇉', + ddarr: '⇊', + downdownarrows: '⇊', + har: '↽', + lhard: '↽', + leftharpoondown: '↽', + lharu: '↼', + leftharpoonup: '↼', + rhard: '⇁', + rightharpoondown: '⇁', + rharu: '⇀', + rightharpoonup: '⇀', + lsh: '↰', + Lsh: '↰', + rsh: '↱', + Rsh: '↱', + ldsh: '↲', + rdsh: '↳', + hookleftarrow: '↩', + hookrightarrow: '↪', + mapstoleft: '↤', + mapstoup: '↥', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + crarr: '↵', + nwarrow: '↖', + nearrow: '↗', + searrow: '↘', + swarrow: '↙', + nleftarrow: '↚', + nleftrightarrow: '↮', + nrightarrow: '↛', + nrarr: '↛', + larrtl: '↢', + rarrtl: '↣', + leftarrowtail: '↢', + rightarrowtail: '↣', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + Larr: '↞', + Rarr: '↠', + larrhk: '↩', + rarrhk: '↪', + larrlp: '↫', + looparrowleft: '↫', + rarrlp: '↬', + looparrowright: '↬', + harrw: '↭', + leftrightsquigarrow: '↭', + nrarrw: '↝̸', + rarrw: '↝', + rightsquigarrow: '↝', + larrbfs: '⤟', + rarrbfs: '⤠', + nvHarr: '⤄', + nvlArr: '⤂', + nvrArr: '⤃', + larrfs: '⤝', + rarrfs: '⤞', + Map: '⤅', + larrsim: '⥳', + rarrsim: '⥴', + harrcir: '⥈', + Uarrocir: '⥉', + lurdshar: '⥊', + ldrdhar: '⥧', + ldrushar: '⥋', + rdldhar: '⥩', + lrhard: '⥭', + rlhar: '⇌', + uharr: '↾', + uharl: '↿', + dharr: '⇂', + dharl: '⇃', + Uarr: '↟', + Darr: '↡', + zigrarr: '⇝', + nwArr: '⇖', + neArr: '⇗', + seArr: '⇘', + swArr: '⇙', + nharr: '↮', + nhArr: '⇎', + nlarr: '↚', + nlArr: '⇍', + nrarr: '↛', + nrArr: '⇏', + larrb: '⇤', + LeftArrowBar: '⇤', + rarrb: '⇥', + RightArrowBar: '⇥', +}; + +/** + * Geometric Shapes + * @type {Record} + */ +export const SHAPES = { + square: '□', + Square: '□', + squ: '□', + squf: '▪', + squarf: '▪', + blacksquar: '▪', + blacksquare: '▪', + FilledVerySmallSquare: '▪', + blk34: '▓', + blk12: '▒', + blk14: '░', + block: '█', + srect: '▭', + rect: '▭', + sdot: '⋅', + sdotb: '⊡', + dotsquare: '⊡', + triangle: '▵', + tri: '▵', + trine: '▵', + utri: '▵', + triangledown: '▿', + dtri: '▿', + tridown: '▿', + triangleleft: '◃', + ltri: '◃', + triangleright: '▹', + rtri: '▹', + blacktriangle: '▴', + utrif: '▴', + blacktriangledown: '▾', + dtrif: '▾', + blacktriangleleft: '◂', + ltrif: '◂', + blacktriangleright: '▸', + rtrif: '▸', + loz: '◊', + lozenge: '◊', + blacklozenge: '⧫', + lozf: '⧫', + bigcirc: '◯', + xcirc: '◯', + circ: 'ˆ', + Circle: '○', + cir: '○', + o: '○', + bullet: '•', + bull: '•', + hellip: '…', + mldr: '…', + nldr: '‥', + boxh: '─', + HorizontalLine: '─', + boxv: '│', + boxdr: '┌', + boxdl: '┐', + boxur: '└', + boxul: '┘', + boxvr: '├', + boxvl: '┤', + boxhd: '┬', + boxhu: '┴', + boxvh: '┼', + boxH: '═', + boxV: '║', + boxdR: '╒', + boxDr: '╓', + boxDR: '╔', + boxDl: '╕', + boxdL: '╖', + boxDL: '╗', + boxuR: '╘', + boxUr: '╙', + boxUR: '╚', + boxUl: '╜', + boxuL: '╛', + boxUL: '╝', + boxvR: '╞', + boxVr: '╟', + boxVR: '╠', + boxVl: '╢', + boxvL: '╡', + boxVL: '╣', + boxHd: '╤', + boxhD: '╥', + boxHD: '╦', + boxHu: '╧', + boxhU: '╨', + boxHU: '╩', + boxvH: '╪', + boxVh: '╫', + boxVH: '╬', +}; + +/** + * Punctuation & Diacritics + * @type {Record} + */ +export const PUNCTUATION = { + excl: '!', + iexcl: '¡', + brvbar: '¦', + sect: '§', + uml: '¨', + copy: '©', + ordf: 'ª', + laquo: '«', + not: '¬', + shy: '\u00ad', + reg: '®', + macr: '¯', + deg: '°', + plusmn: '±', + sup2: '²', + sup3: '³', + acute: '´', + micro: 'µ', + para: '¶', + middot: '·', + cedil: '¸', + sup1: '¹', + ordm: 'º', + raquo: '»', + frac14: '¼', + frac12: '½', + frac34: '¾', + iquest: '¿', + nbsp: '\u00a0', + comma: ',', + period: '.', + colon: ':', + semi: ';', + vert: '|', + Verbar: '‖', + verbar: '|', + dblac: '˝', + circ: 'ˆ', + caron: 'ˇ', + breve: '˘', + dot: '˙', + ring: '˚', + ogon: '˛', + tilde: '˜', + DiacriticalGrave: '`', + DiacriticalAcute: '´', + DiacriticalTilde: '˜', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + grave: '`', + acute: '´', +}; + +/** + * Currency Symbols + * @type {Record} + */ +export const CURRENCY = { + cent: '¢', + pound: '£', + curren: '¤', + yen: '¥', + euro: '€', + dollar: '$', + euro: '€', + fnof: 'ƒ', + inr: '₹', + af: '؋', + birr: 'ብር', + peso: '₱', + rub: '₽', + won: '₩', + yuan: '¥', + cedil: '¸', +}; + +/** + * Fractions + * @type {Record} + */ +export const FRACTIONS = { + frac12: '½', + half: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', +}; + +/** + * Miscellaneous Symbols + * @type {Record} + */ +export const MISC_SYMBOLS = { + trade: '™', + TRADE: '™', + telrec: '⌕', + target: '⌖', + ulcorn: '⌜', + ulcorner: '⌜', + urcorn: '⌝', + urcorner: '⌝', + dlcorn: '⌞', + llcorner: '⌞', + drcorn: '⌟', + lrcorner: '⌟', + intercal: '⊺', + intcal: '⊺', + oplus: '⊕', + CirclePlus: '⊕', + ominus: '⊖', + CircleMinus: '⊖', + otimes: '⊗', + CircleTimes: '⊗', + osol: '⊘', + odot: '⊙', + CircleDot: '⊙', + oast: '⊛', + circledast: '⊛', + odash: '⊝', + circleddash: '⊝', + ocirc: '⊚', + circledcirc: '⊚', + boxplus: '⊞', + plusb: '⊞', + boxminus: '⊟', + minusb: '⊟', + boxtimes: '⊠', + timesb: '⊠', + boxdot: '⊡', + sdotb: '⊡', + veebar: '⊻', + vee: '∨', + barvee: '⊽', + and: '∧', + wedge: '∧', + Cap: '⋒', + Cup: '⋓', + Fork: '⋔', + pitchfork: '⋔', + epar: '⋕', + ltlarr: '⥶', + nvap: '≍⃒', + nvsim: '∼⃒', + nvge: '≥⃒', + nvle: '≤⃒', + nvlt: '<⃒', + nvgt: '>⃒', + nvltrie: '⊴⃒', + nvrtrie: '⊵⃒', + Vdash: '⊩', + dashv: '⊣', + vDash: '⊨', + Vdash: '⊩', + Vvdash: '⊪', + nvdash: '⊬', + nvDash: '⊭', + nVdash: '⊮', + nVDash: '⊯', +}; + +/** + * All entities combined (if you need everything) + * @type {Record} + */ +export const ALL_ENTITIES = { + ...BASIC_LATIN, + ...LATIN_ACCENTS, + ...LATIN_EXTENDED, + ...GREEK, + ...CYRILLIC, + ...MATH, + ...MATH_ADVANCED, + ...ARROWS, + ...SHAPES, + ...PUNCTUATION, + ...CURRENCY, + ...FRACTIONS, + ...MISC_SYMBOLS, +}; + +export const XML = { + amp: "&", + apos: "'", + gt: ">", + lt: "<", + quot: "\"" +} +export const COMMON_HTML = { + nbsp: '\u00a0', + copy: '\u00a9', + reg: '\u00ae', + trade: '\u2122', + mdash: '\u2014', + ndash: '\u2013', + hellip: '\u2026', + laquo: '\u00ab', + raquo: '\u00bb', + lsquo: '\u2018', + rsquo: '\u2019', + ldquo: '\u201c', + rdquo: '\u201d', + bull: '\u2022', + para: '\u00b6', + sect: '\u00a7', + deg: '\u00b0', + frac12: '\u00bd', + frac14: '\u00bc', + frac34: '\u00be', +} +// --------------------------------------------------------------------------- +// Note: NUMERIC_ENTITIES (&#NNN; / &#xHH;) are handled by the scanner directly +// via String.fromCodePoint() without any map lookup. +// --------------------------------------------------------------------------- \ No newline at end of file diff --git a/node_modules/@nodable/entities/src/entityTries.js b/node_modules/@nodable/entities/src/entityTries.js new file mode 100644 index 00000000..9565ebdd --- /dev/null +++ b/node_modules/@nodable/entities/src/entityTries.js @@ -0,0 +1,49 @@ +// entityTries.js +// Builds integer-keyed tries so the decoder never allocates a string object +// during lookup — every key is a plain charCode number. +// +// trie1: Map +// trie2: Map> +// trie3: Map>> + +import { ALL_ENTITIES } from './entities.js'; + +// Reverse map: character sequence → "&name;" +const CHAR_TO_ENTITY = new Map(); +for (const [name, chars] of Object.entries(ALL_ENTITIES)) { + CHAR_TO_ENTITY.set(chars, `&${name};`); +} + +export const trie1 = new Map(); // code0 → entity string +export const trie2 = new Map(); // code0 → Map → entity string +export const trie3 = new Map(); // code0 → Map → Map → entity string + +for (const [chars, entity] of CHAR_TO_ENTITY) { + const len = chars.length; + + if (len === 1) { + const c0 = chars.charCodeAt(0); + // Keep shortest match only if no longer match already claimed this code + // (longer matches are inserted in the same pass so we just overwrite — + // trie1 is only consulted after trie2/trie3 both miss, so no conflict) + trie1.set(c0, entity); + + } else if (len === 2) { + const c0 = chars.charCodeAt(0); + const c1 = chars.charCodeAt(1); + let inner = trie2.get(c0); + if (inner === undefined) { inner = new Map(); trie2.set(c0, inner); } + inner.set(c1, entity); + + } else if (len === 3) { + const c0 = chars.charCodeAt(0); + const c1 = chars.charCodeAt(1); + const c2 = chars.charCodeAt(2); + let mid = trie3.get(c0); + if (mid === undefined) { mid = new Map(); trie3.set(c0, mid); } + let inner = mid.get(c1); + if (inner === undefined) { inner = new Map(); mid.set(c1, inner); } + inner.set(c2, entity); + } + // HTML5 has no named entity whose character sequence is longer than 3 chars +} \ No newline at end of file diff --git a/node_modules/@nodable/entities/src/index.d.ts b/node_modules/@nodable/entities/src/index.d.ts new file mode 100644 index 00000000..5528d442 --- /dev/null +++ b/node_modules/@nodable/entities/src/index.d.ts @@ -0,0 +1,264 @@ +// --------------------------------------------------------------------------- +// @nodable/entities — TypeScript declarations +// --------------------------------------------------------------------------- + +/** A function-based entity replacement value (used for numeric refs). */ +export type EntityValFn = (match: string, captured: string, ...rest: unknown[]) => string; + +// --------------------------------------------------------------------------- +// Encoder options +// --------------------------------------------------------------------------- + +export interface EntityEncoderOptions { + /** + * Whether to encode XML unsafe characters: `&`, `<`, `>`, `"`, `'`. + * @default true + */ + encodeXmlSafe?: boolean; + + /** + * Whether to encode non‑ASCII characters (e.g. `é` → `é`) using the + * built‑in named entity trie. + * @default true + */ + encodeAllNamed?: boolean; + + /** + * Maximum number of replacements performed **cumulatively** across all + * `encode()` calls. `0` means unlimited. + * + * Use `reset()` to reset the internal counter. + * @default 0 + */ + maxReplacements?: number; +} + +// --------------------------------------------------------------------------- +// EntityEncoder class +// --------------------------------------------------------------------------- + +/** + * High‑performance encoder that replaces characters with XML/HTML entities. + * + * - Escapes XML unsafe characters (`&`, `<`, `>`, `"`, `'`) when `encodeXmlSafe` is true. + * - Replaces non‑ASCII characters (e.g. `é`, `©`) with named entities using + * a compact trie‑based lookup when `encodeAllNamed` is true. + * - Supports a cumulative replacement limit (`maxReplacements`) that persists + * across multiple `encode()` calls until `reset()` is called. + * + * @example + * const encoder = new EntityEncoder({ encodeXmlSafe: true, encodeAllNamed: true }); + * encoder.encode(''); // "<foo>" + * encoder.encode('© 2025'); // "© 2025" + * + * // With limit + * const limited = new EntityEncoder({ maxReplacements: 2 }); + * limited.encode('<>&'); // "<>&" (third replacement omitted) + * limited.reset(); // reset counter + */ +export class EntityEncoder { + constructor(options?: EntityEncoderOptions); + + /** + * Encode a string by replacing XML‑unsafe characters and (optionally) + * non‑ASCII characters with named entities. + * + * If `maxReplacements` is set and the cumulative limit has been reached, + * the input string is returned unchanged. + * + * @returns Encoded string (may be identical to input if no replacements needed + * or the limit has been exhausted). + */ + encode(str: string): string; + + /** + * Reset the internal replacement counter. + * Does **not** change `encodeXmlSafe`, `encodeAllNamed`, or `maxReplacements`. + */ + reset(): void; +} + +// --------------------------------------------------------------------------- +// Constructor options for EntityDecoder (existing) +// --------------------------------------------------------------------------- + +/** + * Controls which entity categories count toward the expansion limits. + * + * - `'external'` — only untrusted / injected entities (default) + * - `'base'` — only built‑in XML entities + user‑supplied `namedEntities` + * - `'all'` — all entities regardless of tier + * - `string[]` — explicit combination, e.g. `['external', 'base']` + */ +export type ApplyLimitsTo = 'external' | 'base' | 'all' | Array<'external' | 'base'>; + +export interface EntityDecoderLimitOptions { + /** + * Maximum number of entity references expanded **per document**. + * `0` means unlimited. + * @default 0 + */ + maxTotalExpansions?: number; + + /** + * Maximum number of characters **added** by entity expansion per document. + * `0` means unlimited. + * @default 0 + */ + maxExpandedLength?: number; + + /** + * Which entity tiers count toward the expansion limits. + * + * - `'external'` (default) – only input/runtime + persistent external entities + * - `'base'` – only built‑in XML + `namedEntities` + * - `'all'` – every entity regardless of tier + * - `string[]` – explicit combination, e.g. `['external', 'base']` + * + * @default 'external' + */ + applyLimitsTo?: ApplyLimitsTo; +} + +export interface EntityDecoderNCROptions { + /** + * XML version used for NCR classification. + * @default 1.0 + */ + xmlVersion?: 1.0 | 1.1; + + /** + * Base action for all numeric references. + * @default 'allow' + */ + onNCR?: 'allow' | 'leave' | 'remove' | 'throw'; + + /** + * Action for null NCR (U+0000). + * @default 'remove' + */ + nullNCR?: 'remove' | 'throw'; +} + +export interface EntityDecoderOptions { + /** + * Extra named entities merged into the **base map** (trusted, counts as `'base'` tier). + * These are combined with the built‑in XML entities (`lt`, `gt`, `quot`, `apos`). + * Values containing `&` are silently skipped to prevent recursive expansion. + * + * @default null + */ + namedEntities?: Record | null; + + + /** + * Hook called once on the fully decoded string (after all replacements). + * + * - Receives `(resolved, original)` and **must return a string**. + * - To reject expansion, return `original`. + * - To sanitize, return a cleaned version of `resolved`. + * + * @example + * postCheck: (resolved, original) => + * /<[a-z]/i.test(resolved) ? original : resolved + */ + postCheck?: ((resolved: string, original: string) => string) | null; + + /** + * Whether numeric character references (`&#NNN;`, `&#xHH;`) are allowed. + * @default true + */ + numericAllowed?: boolean; + + /** + * Array of entity names or numeric references to leave unexpanded. + * @default [] + */ + leave?: string[]; + + /** + * Array of entity names or numeric references to remove. + * @default [] + */ + remove?: string[]; + + /** + * Security limits for entity expansion. + */ + limit?: EntityDecoderLimitOptions; + + /** + * Numeric Character Reference (NCR) policy. + */ + ncr?: EntityDecoderNCROptions; +} + +// --------------------------------------------------------------------------- +// EntityDecoder class (default export) +// --------------------------------------------------------------------------- + +/** + * Single‑pass, zero‑regex entity decoder for XML/HTML content. + * + * ## Entity lookup priority (highest → lowest) + * 1. **input / runtime** – injected via `addInputEntities()` (DOCTYPE per document) + * 2. **persistent external** – set via `setExternalEntities()` / `addExternalEntity()` + * 3. **base map** – built‑in XML entities + user‑supplied `namedEntities` + * + * Numeric references (`&#NNN;`, `&#xHH;`) are resolved directly and count as the `'base'` tier. + * + * @example + * const decoder = new EntityDecoder({ + * namedEntities: COMMON_HTML, + * maxTotalExpansions: 100 + * }); + * decoder.setExternalEntities({ brand: 'Acme' }); + * + * decoder.addInputEntities({ version: '1.0' }); + * decoder.decode('&brand; v&version; <'); // 'Acme v1.0 <' + * + * decoder.reset(); // clears input entities + counters, keeps external entities + */ +export default class EntityDecoder { + constructor(options?: EntityDecoderOptions); + + setExternalEntities( + map: Record + ): void; + + addExternalEntity(key: string, value: string): void; + + addInputEntities( + map: Record< + string, + | string + | { regx: RegExp; val: string | EntityValFn } + | { regex: RegExp; val: string | EntityValFn } + > + ): void; + + reset(): this; + + decode(str: string): string; +} + +// --------------------------------------------------------------------------- +// Named entity group exports (for use with `namedEntities` option) +// --------------------------------------------------------------------------- + +export const COMMON_HTML: Record; +export const ALL_ENTITIES: Record; +export const XML: Record; +export const BASIC_LATIN: Record; +export const LATIN_ACCENTS: Record; +export const LATIN_EXTENDED: Record; +export const GREEK: Record; +export const CYRILLIC: Record; +export const MATH: Record; +export const MATH_ADVANCED: Record; +export const ARROWS: Record; +export const SHAPES: Record; +export const PUNCTUATION: Record; +export const CURRENCY: Record; +export const FRACTIONS: Record; +export const MISC_SYMBOLS: Record; \ No newline at end of file diff --git a/node_modules/@nodable/entities/src/index.js b/node_modules/@nodable/entities/src/index.js new file mode 100644 index 00000000..2db6c143 --- /dev/null +++ b/node_modules/@nodable/entities/src/index.js @@ -0,0 +1,29 @@ +/** + * @nodable/entities + * + * Standalone, zero-dependency XML/HTML entity replacement. + * + + */ + +export { default as EntityDecoder } from './EntityDecoder.js'; +export { + COMMON_HTML, + XML, + ALL_ENTITIES, + ARROWS, + BASIC_LATIN, + CURRENCY, + MATH, + MATH_ADVANCED, + CYRILLIC, + FRACTIONS, + GREEK, + LATIN_ACCENTS, + LATIN_EXTENDED, + MISC_SYMBOLS, + PUNCTUATION, + SHAPES, +} from './entities.js'; + +export { default as EntityEncoder } from './EntityEncoder.js'; \ No newline at end of file diff --git a/node_modules/fast-xml-builder/package.json b/node_modules/fast-xml-builder/package.json index f5aca140..8eb9401d 100644 --- a/node_modules/fast-xml-builder/package.json +++ b/node_modules/fast-xml-builder/package.json @@ -1,6 +1,6 @@ { "name": "fast-xml-builder", - "version": "1.1.4", + "version": "1.1.5", "description": "Build XML from JSON without C/C++ based libraries", "main": "./lib/fxb.cjs", "type": "module", diff --git a/node_modules/fast-xml-builder/src/fxb.js b/node_modules/fast-xml-builder/src/fxb.js index 71ab97d7..7c14a5b0 100644 --- a/node_modules/fast-xml-builder/src/fxb.js +++ b/node_modules/fast-xml-builder/src/fxb.js @@ -486,9 +486,13 @@ function buildEmptyObjNode(val, key, attrStr, level) { 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, ']]]]>` + this.newLine; } else if (this.options.commentPropName !== false && key === this.options.commentPropName) { - return this.indentate(level) + `` + this.newLine; + const safeVal = String(val) + .replace(/--/g, '- -') // -- is illegal anywhere in comment content + .replace(/-$/, '- '); // trailing - would form -- with the closing --> + return this.indentate(level) + `` + this.newLine; } else if (key[0] === "?") {//PI tag return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar; } else { diff --git a/node_modules/fast-xml-builder/src/orderedJs2Xml.js b/node_modules/fast-xml-builder/src/orderedJs2Xml.js index 4191cba4..638a0293 100644 --- a/node_modules/fast-xml-builder/src/orderedJs2Xml.js +++ b/node_modules/fast-xml-builder/src/orderedJs2Xml.js @@ -82,12 +82,18 @@ 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, ']]]]>`; 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, '- -') // -- is illegal anywhere in comment content + .replace(/-$/, '- '); // trailing - would form -- with the closing --> + xmlStr += indentation + ``; isPreviousElementTag = true; matcher.pop(); continue; @@ -289,4 +295,12 @@ function replaceEntitiesValue(textValue, options) { } } return textValue; +} + +function cdataVal(val) { + +} + +function commentVal(val) { + } \ No newline at end of file diff --git a/node_modules/fast-xml-parser/CHANGELOG.md b/node_modules/fast-xml-parser/CHANGELOG.md index 9fc8b8c1..926231f0 100644 --- a/node_modules/fast-xml-parser/CHANGELOG.md +++ b/node_modules/fast-xml-parser/CHANGELOG.md @@ -2,6 +2,62 @@ Note: Due to some last quick changes on v4, detail of v4.5.3 & v4.5.4 are not updated here. v4.5.4x is the last tag of v4 in github repository. I'm extremely sorry for the confusion +**5.7.0 / 2026-04-17** +- Use `@nodable/entities` v2.1.0 + - breaking changes + - single entity scan. You're not allowed to user entity value to form another entity name. + - you cant add numeric external entity + - entity error message when expantion limit is crossed might change + - typings are updated for new options related to process entity + - please follow documentation of `@nodable/entities` for more detail. + - performance + - if processEntities is false, then there should not be impact on performance. + - if processEntities is true, but you dont pass entity decoder separately then performance may degrade by approx 8-10% + - if processEntities is true, and you pass entity decoder separately + - if no entity then performance should be same as before + - if there are entities then performance should be increased from past versions + - ignoreAttributes is not required to be set to set xml version for NCR entity value +- update 'fast-xml-builder' to sanitize malicious CDATA and comment's content + +**5.6.0 / 2026-04-15** +- fix: entity replacement for numeric entities +- use @nodable/entities to replace entities + - this may change some error messages related to entities expansion limit or inavlid use + - post check would be exposed in future version + +**5.5.12 / 2026-04-13** +- Performance Improvement: update path-expression-matcher + - use proxy pattern than Proxy class + +**5.5.11 / 2026-04-08** +- Performance Improvement + - integrate ExpressionSet for stopNodes + +**5.5.10 / 2026-04-03** +- increase default entity explansion limit as many projects demand for that +- performance improvement + - reduce calls to toString + - early return when entities are not present + - prepare rawAttrsForMatcher only if user sets `jPath: false` + +**5.5.9 / 2026-03-23** +- combine typing files + + +**4.5.5 / 2026-03-22** + +apply fixes from v5 (legacy maintenance branch v4-maintenance) + +- support maxEntityCount +- support onDangerousProperty +- support maxNestedTags +- handle prototype pollution +- fix incorrect entity name replacement +- fix incorrect condition for entity expansion + +**5.5.8 / 2026-03-20** +- pass read only matcher in callback + **5.5.7 / 2026-03-19** - fix: entity expansion limits - update strnum package to 2.2.0 diff --git a/node_modules/fast-xml-parser/README.md b/node_modules/fast-xml-parser/README.md index fb651628..6b5fb217 100644 --- a/node_modules/fast-xml-parser/README.md +++ b/node_modules/fast-xml-parser/README.md @@ -16,13 +16,17 @@ It can handle big files (tested up to 100mb). XML Entities, HTML entities, and D --- # Your Support, Our Motivation -## Try out our New Thoughts +Please join [Discord community](https://discord.gg/X4Qp9u6Vz) for pre release announcements and discussions. This will prevent us to release breaking changes. + + + + ## Financial Support @@ -34,38 +38,14 @@ Sponsor this project - donate button


- +> This is a donation. No goods or services are expected in return. Any requests for refunds for those purposes will be rejected. ![fxp_sponsors](https://raw.githubusercontent.com/NaturalIntelligence/ThankYouBackers/main/assets/NI_sponsors.jpg) - -> This is a donation. No goods or services are expected in return. Any requests for refunds for those purposes will be rejected. +> This image update once in 6 months mostly ## Users diff --git a/node_modules/fast-xml-parser/lib/fxbuilder.min.js b/node_modules/fast-xml-parser/lib/fxbuilder.min.js index 53d3e2f5..9e7512be 100644 --- a/node_modules/fast-xml-parser/lib/fxbuilder.min.js +++ b/node_modules/fast-xml-parser/lib/fxbuilder.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.XMLBuilder=e():t.XMLBuilder=e()}(this,()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{default:()=>N});class i{constructor(t,e={}){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let i=0,s="";for(;i0&&(this.path[this.path.length-1].values=void 0);const s=this.path.length;this.siblingStacks[s]||(this.siblingStacks[s]=new Map);const n=this.siblingStacks[s],o=i?`${i}:${t}`:t,r=n.get(o)||0;let a=0;for(const t of n.values())a+=t;n.set(o,r+1);const h={tag:t,position:a,counter:r};null!=i&&(h.namespace=i),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0===this.path.length)return;const e=this.path[this.path.length-1];return e.values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const i=t||this.separator;return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i)}toArray(){return this.path.map(t=>t.tag)}reset(){this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const s=t[i];if("deep-wildcard"===s.type){if(i--,i<0)return!0;const s=t[i];let n=!1;for(let t=e;t>=0;t--){const o=t===this.path.length-1;if(this._matchSegment(s,this.path[t],o)){e=t-1,i--,n=!0;break}}if(!n)return!1}else{const t=e===this.path.length-1;if(!this._matchSegment(s,this.path[e],t))return!1;e--,i--}}return i<0}_matchSegment(t,e,i){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!i)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue){const i=e.values[t.attrName];if(String(i)!==String(t.attrValue))return!1}}if(void 0!==t.position){if(!i)return!1;const s=e.counter??0;if("first"===t.position&&0!==s)return!1;if("odd"===t.position&&s%2!=1)return!1;if("even"===t.position&&s%2!=0)return!1;if("nth"===t.position&&s!==t.positionValue)return!1}return!0}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}}function n(t,e){let n="";e.format&&e.indentBy.length>0&&(n="\n");const r=[];if(e.stopNodes&&Array.isArray(e.stopNodes))for(let t=0;te.maxNestedTags)throw new Error("Maximum nested tags exceeded");if(!Array.isArray(t)){if(null!=t){let i=t.toString();return i=c(i,e),i}return""}for(let f=0;f`,d=!1,s.pop();continue}if(m===e.commentPropName){h+=i+`\x3c!--${g[m][0][e.textNodeName]}--\x3e`,d=!0,s.pop();continue}if("?"===m[0]){const t=u(g[":@"],e,N),n="?xml"===m?"":i;let o=g[m][0][e.textNodeName];o=0!==o.length?" "+o:"",h+=n+`<${m}${o}${t}?>`,d=!0,s.pop();continue}let y=i;""!==y&&(y+=e.indentBy);const x=i+`<${m}${u(g[":@"],e,N)}`;let P;P=N?a(g[m],e):o(g[m],e,y,s,n),-1!==e.unpairedTags.indexOf(m)?e.suppressUnpairedNode?h+=x+">":h+=x+"/>":P&&0!==P.length||!e.suppressEmptyNode?P&&P.endsWith(">")?h+=x+`>${P}${i}`:(h+=x+">",P&&""!==i&&(P.includes("/>")||P.includes("`):h+=x+"/>",d=!0,s.pop()}return h}function r(t,e){if(!t||e.ignoreAttributes)return null;const i={};let s=!1;for(let n in t)Object.prototype.hasOwnProperty.call(t,n)&&(i[n.startsWith(e.attributeNamePrefix)?n.substr(e.attributeNamePrefix.length):n]=t[n],s=!0);return s?i:null}function a(t,e){if(!Array.isArray(t))return null!=t?t.toString():"";let i="";for(let s=0;s${s}`:i+=`<${o}${t}/>`}}}return i}function h(t,e){let i="";if(t&&!e.ignoreAttributes)for(let s in t){if(!Object.prototype.hasOwnProperty.call(t,s))continue;let n=t[s];!0===n&&e.suppressBooleanAttributes?i+=` ${s.substr(e.attributeNamePrefix.length)}`:i+=` ${s.substr(e.attributeNamePrefix.length)}="${n}"`}return i}function p(t){const e=Object.keys(t);for(let i=0;i0&&e.processEntities)for(let i=0;i","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1,maxNestedTags:100,jPath:!0};function f(t){if(this.options=Object.assign({},d,t),this.options.stopNodes&&Array.isArray(this.options.stopNodes)&&(this.options.stopNodes=this.options.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),this.stopNodeExpressions=[],this.options.stopNodes&&Array.isArray(this.options.stopNodes))for(let t=0;t{for(const i of e){if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:()=>!1,this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=b),this.processTextOrObjNode=g,this.options.format?(this.indentate=m,this.tagEndChar=">\n",this.newLine="\n"):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}function g(t,e,i,s){const n=this.extractAttributes(t);if(s.push(e,n),this.checkStopNode(s)){const n=this.buildRawContent(t),o=this.buildAttributesForStopNode(t);return s.pop(),this.buildObjectNode(n,e,o,i)}const o=this.j2x(t,i+1,s);return s.pop(),void 0!==t[this.options.textNodeName]&&1===Object.keys(t).length?this.buildTextValNode(t[this.options.textNodeName],e,o.attrStr,i,s):this.buildObjectNode(o.val,e,o.attrStr,i)}function m(t){return this.options.indentBy.repeat(t)}function b(t){return!(!t.startsWith(this.options.attributeNamePrefix)||t===this.options.textNodeName)&&t.substr(this.attrPrefixLen)}f.prototype.build=function(t){if(this.options.preserveOrder)return n(t,this.options);{Array.isArray(t)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(t={[this.options.arrayNodeName]:t});const e=new s;return this.j2x(t,0,e).val}},f.prototype.j2x=function(t,e,i){let s="",n="";if(this.options.maxNestedTags&&i.getDepth()>=this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");const o=this.options.jPath?i.toString():i,r=this.checkStopNode(i);for(let a in t)if(Object.prototype.hasOwnProperty.call(t,a))if(void 0===t[a])this.isAttribute(a)&&(n+="");else if(null===t[a])this.isAttribute(a)||a===this.options.cdataPropName?n+="":"?"===a[0]?n+=this.indentate(e)+"<"+a+"?"+this.tagEndChar:n+=this.indentate(e)+"<"+a+"/"+this.tagEndChar;else if(t[a]instanceof Date)n+=this.buildTextValNode(t[a],a,"",e,i);else if("object"!=typeof t[a]){const h=this.isAttribute(a);if(h&&!this.ignoreAttributesFn(h,o))s+=this.buildAttrPairStr(h,""+t[a],r);else if(!h)if(a===this.options.textNodeName){let e=this.options.tagValueProcessor(a,""+t[a]);n+=this.replaceEntitiesValue(e)}else{i.push(a);const s=this.checkStopNode(i);if(i.pop(),s){const i=""+t[a];n+=""===i?this.indentate(e)+"<"+a+this.closeTag(a)+this.tagEndChar:this.indentate(e)+"<"+a+">"+i+""+t+"${t}`;else if("object"==typeof t&&null!==t){const s=this.buildRawContent(t),n=this.buildAttributesForStopNode(t);e+=""===s?`<${i}${n}/>`:`<${i}${n}>${s}`}}else if("object"==typeof s&&null!==s){const t=this.buildRawContent(s),n=this.buildAttributesForStopNode(s);e+=""===t?`<${i}${n}/>`:`<${i}${n}>${t}`}else e+=`<${i}>${s}`}return e},f.prototype.buildAttributesForStopNode=function(t){if(!t||"object"!=typeof t)return"";let e="";if(this.options.attributesGroupName&&t[this.options.attributesGroupName]){const i=t[this.options.attributesGroupName];for(let t in i){if(!Object.prototype.hasOwnProperty.call(i,t))continue;const s=t.startsWith(this.options.attributeNamePrefix)?t.substring(this.options.attributeNamePrefix.length):t,n=i[t];!0===n&&this.options.suppressBooleanAttributes?e+=" "+s:e+=" "+s+'="'+n+'"'}}else for(let i in t){if(!Object.prototype.hasOwnProperty.call(t,i))continue;const s=this.isAttribute(i);if(s){const n=t[i];!0===n&&this.options.suppressBooleanAttributes?e+=" "+s:e+=" "+s+'="'+n+'"'}}return e},f.prototype.buildObjectNode=function(t,e,i,s){if(""===t)return"?"===e[0]?this.indentate(s)+"<"+e+i+"?"+this.tagEndChar:this.indentate(s)+"<"+e+i+this.closeTag(e)+this.tagEndChar;{let n=""+t+n}},f.prototype.closeTag=function(t){let e="";return-1!==this.options.unpairedTags.indexOf(t)?this.options.suppressUnpairedNode||(e="/"):e=this.options.suppressEmptyNode?"/":`>`+this.newLine;if(!1!==this.options.commentPropName&&e===this.options.commentPropName)return this.indentate(s)+`\x3c!--${t}--\x3e`+this.newLine;if("?"===e[0])return this.indentate(s)+"<"+e+i+"?"+this.tagEndChar;{let n=this.options.tagValueProcessor(e,t);return n=this.replaceEntitiesValue(n),""===n?this.indentate(s)+"<"+e+i+this.closeTag(e)+this.tagEndChar:this.indentate(s)+"<"+e+i+">"+n+"0&&this.options.processEntities)for(let e=0;e(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{default:()=>y});class i{constructor(t,e={},i){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=i,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let i=0,s="";for(;i0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return!1;const i=e[e.length-1];return void 0!==i.values&&t in i.values}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=!0){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class n{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new s(this)}push(t,e=null,i=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const s=this.path.length;this.siblingStacks[s]||(this.siblingStacks[s]=new Map);const n=this.siblingStacks[s],r=i?`${i}:${t}`:t,o=n.get(r)||0;let a=0;for(const t of n.values())a+=t;n.set(r,o+1);const h={tag:t,position:a,counter:o};null!=i&&(h.namespace=i),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;this._pathStringCache=null;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const i=t||this.separator;if(i===this.separator&&!0===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const s=t[i];if("deep-wildcard"===s.type){if(i--,i<0)return!0;const s=t[i];let n=!1;for(let t=e;t>=0;t--)if(this._matchSegment(s,this.path[t],t===this.path.length-1)){e=t-1,i--,n=!0;break}if(!n)return!1}else{if(!this._matchSegment(s,this.path[e],e===this.path.length-1))return!1;e--,i--}}return i<0}_matchSegment(t,e,i){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!i)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return!1}if(void 0!==t.position){if(!i)return!1;const s=e.counter??0;if("first"===t.position&&0!==s)return!1;if("odd"===t.position&&s%2!=1)return!1;if("even"===t.position&&s%2!=0)return!1;if("nth"===t.position&&s!==t.positionValue)return!1}return!0}matchesAny(t){return t.matchesAny(this)}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}readOnly(){return this._view}}function r(t,e){let s="";e.format&&e.indentBy.length>0&&(s="\n");const r=[];if(e.stopNodes&&Array.isArray(e.stopNodes))for(let t=0;te.maxNestedTags)throw new Error("Maximum nested tags exceeded");if(!Array.isArray(t)){if(null!=t){let i=t.toString();return i=g(i,e),i}return""}for(let d=0;d/g,"]]]]>`,p=!1,s.pop();continue}if(m===e.commentPropName){const t=f[m][0][e.textNodeName];r+=i+`\x3c!--${String(t).replace(/--/g,"- -").replace(/-$/,"- ")}--\x3e`,p=!0,s.pop();continue}if("?"===m[0]){const t=l(f[":@"],e,N),n="?xml"===m?"":i;let o=f[m][0][e.textNodeName];o=0!==o.length?" "+o:"",r+=n+`<${m}${o}${t}?>`,p=!0,s.pop();continue}let y=i;""!==y&&(y+=e.indentBy);const x=i+`<${m}${l(f[":@"],e,N)}`;let A;A=N?h(f[m],e):o(f[m],e,y,s,n),-1!==e.unpairedTags.indexOf(m)?e.suppressUnpairedNode?r+=x+">":r+=x+"/>":A&&0!==A.length||!e.suppressEmptyNode?A&&A.endsWith(">")?r+=x+`>${A}${i}`:(r+=x+">",A&&""!==i&&(A.includes("/>")||A.includes("`):r+=x+"/>",p=!0,s.pop()}return r}function a(t,e){if(!t||e.ignoreAttributes)return null;const i={};let s=!1;for(let n in t)Object.prototype.hasOwnProperty.call(t,n)&&(i[n.startsWith(e.attributeNamePrefix)?n.substr(e.attributeNamePrefix.length):n]=t[n],s=!0);return s?i:null}function h(t,e){if(!Array.isArray(t))return null!=t?t.toString():"";let i="";for(let s=0;s${s}`:i+=`<${r}${t}/>`}}}return i}function p(t,e){let i="";if(t&&!e.ignoreAttributes)for(let s in t){if(!Object.prototype.hasOwnProperty.call(t,s))continue;let n=t[s];!0===n&&e.suppressBooleanAttributes?i+=` ${s.substr(e.attributeNamePrefix.length)}`:i+=` ${s.substr(e.attributeNamePrefix.length)}="${n}"`}return i}function u(t){const e=Object.keys(t);for(let i=0;i0&&e.processEntities)for(let i=0;i","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1,maxNestedTags:100,jPath:!0};function f(t){if(this.options=Object.assign({},d,t),this.options.stopNodes&&Array.isArray(this.options.stopNodes)&&(this.options.stopNodes=this.options.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),this.stopNodeExpressions=[],this.options.stopNodes&&Array.isArray(this.options.stopNodes))for(let t=0;t{for(const i of e){if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:()=>!1,this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=N),this.processTextOrObjNode=m,this.options.format?(this.indentate=b,this.tagEndChar=">\n",this.newLine="\n"):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}function m(t,e,i,s){const n=this.extractAttributes(t);if(s.push(e,n),this.checkStopNode(s)){const n=this.buildRawContent(t),r=this.buildAttributesForStopNode(t);return s.pop(),this.buildObjectNode(n,e,r,i)}const r=this.j2x(t,i+1,s);return s.pop(),void 0!==t[this.options.textNodeName]&&1===Object.keys(t).length?this.buildTextValNode(t[this.options.textNodeName],e,r.attrStr,i,s):this.buildObjectNode(r.val,e,r.attrStr,i)}function b(t){return this.options.indentBy.repeat(t)}function N(t){return!(!t.startsWith(this.options.attributeNamePrefix)||t===this.options.textNodeName)&&t.substr(this.attrPrefixLen)}f.prototype.build=function(t){if(this.options.preserveOrder)return r(t,this.options);{Array.isArray(t)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(t={[this.options.arrayNodeName]:t});const e=new n;return this.j2x(t,0,e).val}},f.prototype.j2x=function(t,e,i){let s="",n="";if(this.options.maxNestedTags&&i.getDepth()>=this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");const r=this.options.jPath?i.toString():i,o=this.checkStopNode(i);for(let a in t)if(Object.prototype.hasOwnProperty.call(t,a))if(void 0===t[a])this.isAttribute(a)&&(n+="");else if(null===t[a])this.isAttribute(a)||a===this.options.cdataPropName?n+="":"?"===a[0]?n+=this.indentate(e)+"<"+a+"?"+this.tagEndChar:n+=this.indentate(e)+"<"+a+"/"+this.tagEndChar;else if(t[a]instanceof Date)n+=this.buildTextValNode(t[a],a,"",e,i);else if("object"!=typeof t[a]){const h=this.isAttribute(a);if(h&&!this.ignoreAttributesFn(h,r))s+=this.buildAttrPairStr(h,""+t[a],o);else if(!h)if(a===this.options.textNodeName){let e=this.options.tagValueProcessor(a,""+t[a]);n+=this.replaceEntitiesValue(e)}else{i.push(a);const s=this.checkStopNode(i);if(i.pop(),s){const i=""+t[a];n+=""===i?this.indentate(e)+"<"+a+this.closeTag(a)+this.tagEndChar:this.indentate(e)+"<"+a+">"+i+""+t+"${t}`;else if("object"==typeof t&&null!==t){const s=this.buildRawContent(t),n=this.buildAttributesForStopNode(t);e+=""===s?`<${i}${n}/>`:`<${i}${n}>${s}`}}else if("object"==typeof s&&null!==s){const t=this.buildRawContent(s),n=this.buildAttributesForStopNode(s);e+=""===t?`<${i}${n}/>`:`<${i}${n}>${t}`}else e+=`<${i}>${s}`}return e},f.prototype.buildAttributesForStopNode=function(t){if(!t||"object"!=typeof t)return"";let e="";if(this.options.attributesGroupName&&t[this.options.attributesGroupName]){const i=t[this.options.attributesGroupName];for(let t in i){if(!Object.prototype.hasOwnProperty.call(i,t))continue;const s=t.startsWith(this.options.attributeNamePrefix)?t.substring(this.options.attributeNamePrefix.length):t,n=i[t];!0===n&&this.options.suppressBooleanAttributes?e+=" "+s:e+=" "+s+'="'+n+'"'}}else for(let i in t){if(!Object.prototype.hasOwnProperty.call(t,i))continue;const s=this.isAttribute(i);if(s){const n=t[i];!0===n&&this.options.suppressBooleanAttributes?e+=" "+s:e+=" "+s+'="'+n+'"'}}return e},f.prototype.buildObjectNode=function(t,e,i,s){if(""===t)return"?"===e[0]?this.indentate(s)+"<"+e+i+"?"+this.tagEndChar:this.indentate(s)+"<"+e+i+this.closeTag(e)+this.tagEndChar;{let n=""+t+n}},f.prototype.closeTag=function(t){let e="";return-1!==this.options.unpairedTags.indexOf(t)?this.options.suppressUnpairedNode||(e="/"):e=this.options.suppressEmptyNode?"/":`>/g,"]]]]>`+this.newLine}if(!1!==this.options.commentPropName&&e===this.options.commentPropName){const e=String(t).replace(/--/g,"- -").replace(/-$/,"- ");return this.indentate(s)+`\x3c!--${e}--\x3e`+this.newLine}if("?"===e[0])return this.indentate(s)+"<"+e+i+"?"+this.tagEndChar;{let n=this.options.tagValueProcessor(e,t);return n=this.replaceEntitiesValue(n),""===n?this.indentate(s)+"<"+e+i+this.closeTag(e)+this.tagEndChar:this.indentate(s)+"<"+e+i+">"+n+"0&&this.options.processEntities)for(let e=0;e {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions\n * \n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n * \n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n * \n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Default path separator (default: '.')\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag: string, values: object, position: number, counter: number }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n }\n\n /**\n * Push a new tag onto the path\n * @param {string} tagName - Name of the tag\n * @param {Object} attrValues - Attribute key-value pairs for current node (optional)\n * @param {string} namespace - Namespace for the tag (optional)\n */\n push(tagName, attrValues = null, namespace = null) {\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n const prev = this.path[this.path.length - 1];\n prev.values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n // Store namespace if provided\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n // Store values only for current node\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) {\n return undefined;\n }\n\n const node = this.path.pop();\n\n // Clean up sibling tracking for levels deeper than current\n // After pop, path.length is the new depth\n // We need to clean up siblingStacks[path.length + 1] and beyond\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values\n * Useful when attributes are parsed after push\n * @param {Object} attrValues - Attribute values\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value\n * @param {string} attrName - Attribute name\n * @returns {*} Attribute value or undefined\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n const current = this.path[this.path.length - 1];\n return current.values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute\n * @param {string} attrName - Attribute name\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent)\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name)\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition for backward compatibility)\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string\n * @param {string} separator - Optional separator (uses default if not provided)\n * @param {boolean} includeNamespace - Whether to include namespace in output (default: true)\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n return this.path.map(n => {\n if (includeNamespace && n.namespace) {\n return `${n.namespace}:${n.tag}`;\n }\n return n.tag;\n }).join(sep);\n }\n\n /**\n * Get path as array of tag names\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty\n */\n reset() {\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression\n * @param {Expression} expression - The expression to match against\n * @returns {boolean} True if current path matches the expression\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n // Handle deep wildcard patterns\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n // Simple path matching (no deep wildcards)\n return this._matchSimple(segments);\n }\n\n /**\n * Match simple path (no deep wildcards)\n * @private\n */\n _matchSimple(segments) {\n // Path must be same length as segments\n if (this.path.length !== segments.length) {\n return false;\n }\n\n // Match each segment bottom-to-top\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n const node = this.path[i];\n const isCurrentNode = (i === this.path.length - 1);\n\n if (!this._matchSegment(segment, node, isCurrentNode)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match path with deep wildcards\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1; // Start from current node (bottom)\n let segIdx = segments.length - 1; // Start from last segment\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n // \"..\" matches zero or more levels\n segIdx--;\n\n if (segIdx < 0) {\n // Pattern ends with \"..\", always matches\n return true;\n }\n\n // Find where next segment matches in the path\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n const isCurrentNode = (i === this.path.length - 1);\n if (this._matchSegment(nextSeg, this.path[i], isCurrentNode)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n // Regular segment\n const isCurrentNode = (pathIdx === this.path.length - 1);\n if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n // All segments must be consumed\n return segIdx < 0;\n }\n\n /**\n * Match a single segment against a node\n * @private\n * @param {Object} segment - Segment from Expression\n * @param {Object} node - Node from path\n * @param {boolean} isCurrentNode - Whether this is the current (last) node\n * @returns {boolean}\n */\n _matchSegment(segment, node, isCurrentNode) {\n // Match tag name (* is wildcard)\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n // Match namespace if specified in segment\n if (segment.namespace !== undefined) {\n // Segment has namespace - node must match it\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n // If segment has no namespace, it matches nodes with or without namespace\n\n // Match attribute name (check if node has this attribute)\n // Can only check for current node since ancestors don't have values\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n // Can't check attributes for ancestor nodes (values not stored)\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n // Match attribute value (only possible for current node)\n if (segment.attrValue !== undefined) {\n const actualValue = node.values[segment.attrName];\n // Both should be strings\n if (String(actualValue) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n // Match position (only for current node)\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n // Can't check position for ancestor nodes\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth') {\n if (counter !== segment.positionValue) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Create a snapshot of current state\n * @returns {Object} State snapshot\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot\n * @param {Object} snapshot - State snapshot\n */\n restore(snapshot) {\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n}","import { Expression, Matcher } from 'path-expression-matcher';\n\nconst EOL = \"\\n\";\n\n/**\n * \n * @param {array} jArray \n * @param {any} options \n * @returns \n */\nexport default function toXml(jArray, options) {\n let indentation = \"\";\n if (options.format && options.indentBy.length > 0) {\n indentation = EOL;\n }\n\n // Pre-compile stopNode expressions for pattern matching\n const stopNodeExpressions = [];\n if (options.stopNodes && Array.isArray(options.stopNodes)) {\n for (let i = 0; i < options.stopNodes.length; i++) {\n const node = options.stopNodes[i];\n if (typeof node === 'string') {\n stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n stopNodeExpressions.push(node);\n }\n }\n }\n\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n\n return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions);\n}\n\nfunction arrToStr(arr, options, indentation, matcher, stopNodeExpressions) {\n let xmlStr = \"\";\n let isPreviousElementTag = false;\n\n if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n\n if (!Array.isArray(arr)) {\n // Non-array values (e.g. string tag values) should be treated as text content\n if (arr !== undefined && arr !== null) {\n let text = arr.toString();\n text = replaceEntitiesValue(text, options);\n return text;\n }\n return \"\";\n }\n\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const tagName = propName(tagObj);\n if (tagName === undefined) continue;\n\n // Extract attributes from \":@\" property\n const attrValues = extractAttributeValues(tagObj[\":@\"], options);\n\n // Push tag to matcher WITH attributes\n matcher.push(tagName, attrValues);\n\n // Check if this is a stop node using Expression matching\n const isStopNode = checkStopNode(matcher, stopNodeExpressions);\n\n if (tagName === options.textNodeName) {\n let tagText = tagObj[tagName];\n if (!isStopNode) {\n tagText = options.tagValueProcessor(tagName, tagText);\n tagText = replaceEntitiesValue(tagText, options);\n }\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += tagText;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.cdataPropName) {\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += ``;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.commentPropName) {\n xmlStr += indentation + ``;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n } else if (tagName[0] === \"?\") {\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tempInd = tagName === \"?xml\" ? \"\" : indentation;\n let piTextNodeName = tagObj[tagName][0][options.textNodeName];\n piTextNodeName = piTextNodeName.length !== 0 ? \" \" + piTextNodeName : \"\"; //remove extra spacing\n xmlStr += tempInd + `<${tagName}${piTextNodeName}${attStr}?>`;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n }\n\n let newIdentation = indentation;\n if (newIdentation !== \"\") {\n newIdentation += options.indentBy;\n }\n\n // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tagStart = indentation + `<${tagName}${attStr}`;\n\n // If this is a stopNode, get raw content without processing\n let tagValue;\n if (isStopNode) {\n tagValue = getRawContent(tagObj[tagName], options);\n } else {\n\n tagValue = arrToStr(tagObj[tagName], options, newIdentation, matcher, stopNodeExpressions);\n }\n\n if (options.unpairedTags.indexOf(tagName) !== -1) {\n if (options.suppressUnpairedNode) xmlStr += tagStart + \">\";\n else xmlStr += tagStart + \"/>\";\n } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {\n xmlStr += tagStart + \"/>\";\n } else if (tagValue && tagValue.endsWith(\">\")) {\n xmlStr += tagStart + `>${tagValue}${indentation}`;\n } else {\n xmlStr += tagStart + \">\";\n if (tagValue && indentation !== \"\" && (tagValue.includes(\"/>\") || tagValue.includes(\"`;\n }\n isPreviousElementTag = true;\n\n // Pop tag from matcher\n matcher.pop();\n }\n\n return xmlStr;\n}\n\n/**\n * Extract attribute values from the \":@\" object and return as plain object\n * for passing to matcher.push()\n */\nfunction extractAttributeValues(attrMap, options) {\n if (!attrMap || options.ignoreAttributes) return null;\n\n const attrValues = {};\n let hasAttrs = false;\n\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // Remove the attribute prefix to get clean attribute name\n const cleanAttrName = attr.startsWith(options.attributeNamePrefix)\n ? attr.substr(options.attributeNamePrefix.length)\n : attr;\n attrValues[cleanAttrName] = attrMap[attr];\n hasAttrs = true;\n }\n\n return hasAttrs ? attrValues : null;\n}\n\n/**\n * Extract raw content from a stopNode without any processing\n * This preserves the content exactly as-is, including special characters\n */\nfunction getRawContent(arr, options) {\n if (!Array.isArray(arr)) {\n // Non-array values return as-is\n if (arr !== undefined && arr !== null) {\n return arr.toString();\n }\n return \"\";\n }\n\n let content = \"\";\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const tagName = propName(item);\n\n if (tagName === options.textNodeName) {\n // Raw text content - NO processing, NO entity replacement\n content += item[tagName];\n } else if (tagName === options.cdataPropName) {\n // CDATA content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName === options.commentPropName) {\n // Comment content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName && tagName[0] === \"?\") {\n // Processing instruction - skip for stopNodes\n continue;\n } else if (tagName) {\n // Nested tags within stopNode\n // Recursively get raw content and reconstruct the tag\n // For stopNodes, we don't process attributes either\n const attStr = attr_to_str_raw(item[\":@\"], options);\n const nestedContent = getRawContent(item[tagName], options);\n\n if (!nestedContent || nestedContent.length === 0) {\n content += `<${tagName}${attStr}/>`;\n } else {\n content += `<${tagName}${attStr}>${nestedContent}`;\n }\n }\n }\n return content;\n}\n\n/**\n * Build attribute string for stopNodes - NO entity replacement\n */\nfunction attr_to_str_raw(attrMap, options) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // For stopNodes, use raw value without processing\n let attrVal = attrMap[attr];\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n if (key !== \":@\") return key;\n }\n}\n\nfunction attr_to_str(attrMap, options, isStopNode) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n let attrVal;\n\n if (isStopNode) {\n // For stopNodes, use raw value without any processing\n attrVal = attrMap[attr];\n } else {\n // Normal processing: apply attributeValueProcessor and entity replacement\n attrVal = options.attributeValueProcessor(attr, attrMap[attr]);\n attrVal = replaceEntitiesValue(attrVal, options);\n }\n\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction checkStopNode(matcher, stopNodeExpressions) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction replaceEntitiesValue(textValue, options) {\n if (textValue && textValue.length > 0 && options.processEntities) {\n for (let i = 0; i < options.entities.length; i++) {\n const entity = options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}","'use strict';\n//parse Empty Node as self closing node\nimport buildFromOrderedJs from './orderedJs2Xml.js';\nimport getIgnoreAttributesFn from \"./ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\n\nconst defaultOptions = {\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n cdataPropName: false,\n format: false,\n indentBy: ' ',\n suppressEmptyNode: false,\n suppressUnpairedNode: true,\n suppressBooleanAttributes: true,\n tagValueProcessor: function (key, a) {\n return a;\n },\n attributeValueProcessor: function (attrName, a) {\n return a;\n },\n preserveOrder: false,\n commentPropName: false,\n unpairedTags: [],\n entities: [\n { regex: new RegExp(\"&\", \"g\"), val: \"&\" },//it must be on top\n { regex: new RegExp(\">\", \"g\"), val: \">\" },\n { regex: new RegExp(\"<\", \"g\"), val: \"<\" },\n { regex: new RegExp(\"\\'\", \"g\"), val: \"'\" },\n { regex: new RegExp(\"\\\"\", \"g\"), val: \""\" }\n ],\n processEntities: true,\n stopNodes: [],\n // transformTagName: false,\n // transformAttributeName: false,\n oneListGroup: false,\n maxNestedTags: 100,\n jPath: true // When true, callbacks receive string jPath; when false, receive Matcher instance\n};\n\nexport default function Builder(options) {\n this.options = Object.assign({}, defaultOptions, options);\n\n // Convert old-style stopNodes for backward compatibility\n // Old syntax: \"*.tag\" meant \"tag anywhere in tree\"\n // New syntax: \"..tag\" means \"tag anywhere in tree\"\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n this.options.stopNodes = this.options.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Convert old wildcard syntax to deep wildcard\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n\n // Pre-compile stopNode expressions for pattern matching\n this.stopNodeExpressions = [];\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const node = this.options.stopNodes[i];\n if (typeof node === 'string') {\n this.stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n this.stopNodeExpressions.push(node);\n }\n }\n }\n\n if (this.options.ignoreAttributes === true || this.options.attributesGroupName) {\n this.isAttribute = function (/*a*/) {\n return false;\n };\n } else {\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.attrPrefixLen = this.options.attributeNamePrefix.length;\n this.isAttribute = isAttribute;\n }\n\n this.processTextOrObjNode = processTextOrObjNode\n\n if (this.options.format) {\n this.indentate = indentate;\n this.tagEndChar = '>\\n';\n this.newLine = '\\n';\n } else {\n this.indentate = function () {\n return '';\n };\n this.tagEndChar = '>';\n this.newLine = '';\n }\n}\n\nBuilder.prototype.build = function (jObj) {\n if (this.options.preserveOrder) {\n return buildFromOrderedJs(jObj, this.options);\n } else {\n if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) {\n jObj = {\n [this.options.arrayNodeName]: jObj\n }\n }\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n return this.j2x(jObj, 0, matcher).val;\n }\n};\n\nBuilder.prototype.j2x = function (jObj, level, matcher) {\n let attrStr = '';\n let val = '';\n if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n // Get jPath based on option: string for backward compatibility, or Matcher for new features\n const jPath = this.options.jPath ? matcher.toString() : matcher;\n\n // Check if current node is a stopNode (will be used for attribute encoding)\n const isCurrentStopNode = this.checkStopNode(matcher);\n\n for (let key in jObj) {\n if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;\n if (typeof jObj[key] === 'undefined') {\n // supress undefined node only if it is not an attribute\n if (this.isAttribute(key)) {\n val += '';\n }\n } else if (jObj[key] === null) {\n // null attribute should be ignored by the attribute list, but should not cause the tag closing\n if (this.isAttribute(key)) {\n val += '';\n } else if (key === this.options.cdataPropName) {\n val += '';\n } else if (key[0] === '?') {\n val += this.indentate(level) + '<' + key + '?' + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n }\n // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n } else if (jObj[key] instanceof Date) {\n val += this.buildTextValNode(jObj[key], key, '', level, matcher);\n } else if (typeof jObj[key] !== 'object') {\n //premitive type\n const attr = this.isAttribute(key);\n if (attr && !this.ignoreAttributesFn(attr, jPath)) {\n attrStr += this.buildAttrPairStr(attr, '' + jObj[key], isCurrentStopNode);\n } else if (!attr) {\n //tag value\n if (key === this.options.textNodeName) {\n let newval = this.options.tagValueProcessor(key, '' + jObj[key]);\n val += this.replaceEntitiesValue(newval);\n } else {\n // Check if this is a stopNode before building\n matcher.push(key);\n const isStopNode = this.checkStopNode(matcher);\n matcher.pop();\n\n if (isStopNode) {\n // Build as raw content without encoding\n const textValue = '' + jObj[key];\n if (textValue === '') {\n val += this.indentate(level) + '<' + key + this.closeTag(key) + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '>' + textValue + '' + textValue + '${item}`;\n } else if (typeof item === 'object' && item !== null) {\n const nestedContent = this.buildRawContent(item);\n const nestedAttrs = this.buildAttributesForStopNode(item);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object\n const nestedContent = this.buildRawContent(value);\n const nestedAttrs = this.buildAttributesForStopNode(value);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n } else {\n // Primitive value\n content += `<${key}>${value}`;\n }\n }\n\n return content;\n};\n\n// Build attribute string for stopNode (no entity encoding)\nBuilder.prototype.buildAttributesForStopNode = function (obj) {\n if (!obj || typeof obj !== 'object') return '';\n\n let attrStr = '';\n\n // Check for attributesGroupName (when attributes are grouped)\n if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {\n const attrGroup = obj[this.options.attributesGroupName];\n for (let attrKey in attrGroup) {\n if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;\n const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix)\n ? attrKey.substring(this.options.attributeNamePrefix.length)\n : attrKey;\n const val = attrGroup[attrKey];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + cleanKey;\n } else {\n attrStr += ' ' + cleanKey + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n } else {\n // Look for individual attributes\n for (let key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const attr = this.isAttribute(key);\n if (attr) {\n const val = obj[key];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + attr;\n } else {\n attrStr += ' ' + attr + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n }\n }\n\n return attrStr;\n};\n\nBuilder.prototype.buildObjectNode = function (val, key, attrStr, level) {\n if (val === \"\") {\n if (key[0] === \"?\") return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n else {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n }\n } else {\n\n let tagEndExp = '' + val + tagEndExp);\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {\n return this.indentate(level) + `` + this.newLine;\n } else {\n return (\n this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +\n val +\n this.indentate(level) + tagEndExp);\n }\n }\n}\n\nBuilder.prototype.closeTag = function (key) {\n let closeTag = \"\";\n if (this.options.unpairedTags.indexOf(key) !== -1) { //unpaired\n if (!this.options.suppressUnpairedNode) closeTag = \"/\"\n } else if (this.options.suppressEmptyNode) { //empty\n closeTag = \"/\";\n } else {\n closeTag = `>` + this.newLine;\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName) {\n return this.indentate(level) + `` + this.newLine;\n } else if (key[0] === \"?\") {//PI tag\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n // Normal processing: apply tagValueProcessor and entity replacement\n let textValue = this.options.tagValueProcessor(key, val);\n textValue = this.replaceEntitiesValue(textValue);\n\n if (textValue === '') {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n } else {\n return this.indentate(level) + '<' + key + attrStr + '>' +\n textValue +\n ' 0 && this.options.processEntities) {\n for (let i = 0; i < this.options.entities.length; i++) {\n const entity = this.options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction indentate(level) {\n return this.options.indentBy.repeat(level);\n}\n\nfunction isAttribute(name /*, options*/) {\n if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {\n return name.substr(this.attrPrefixLen);\n } else {\n return false;\n }\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","// Re-export from fast-xml-builder for backward compatibility\nimport XMLBuilder from 'fast-xml-builder';\nexport default XMLBuilder;\n\n// If there are any named exports you also want to re-export:\nexport * from 'fast-xml-builder';"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Expression","constructor","pattern","options","separator","segments","_parse","_hasDeepWildcard","some","seg","type","_hasAttributeCondition","undefined","attrName","_hasPositionSelector","position","i","currentPart","length","trim","push","_parseSegment","part","segment","bracketContent","withoutBrackets","bracketMatch","match","content","slice","namespace","tag","tagAndPosition","includes","nsIndex","indexOf","substring","Error","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","test","eqIndex","attrValue","nthMatch","positionValue","parseInt","hasDeepWildcard","hasAttributeCondition","hasPositionSelector","toString","Matcher","path","siblingStacks","tagName","attrValues","values","currentLevel","Map","siblings","siblingKey","counter","count","set","node","pop","updateCurrent","current","getCurrentTag","getCurrentNamespace","getAttrValue","hasAttr","getPosition","getCounter","getIndex","getDepth","includeNamespace","sep","map","n","join","toArray","reset","matches","expression","_matchWithDeepWildcard","_matchSimple","isCurrentNode","_matchSegment","pathIdx","segIdx","nextSeg","found","actualValue","String","snapshot","restore","toXml","jArray","indentation","format","indentBy","stopNodeExpressions","stopNodes","Array","isArray","arrToStr","arr","matcher","xmlStr","isPreviousElementTag","maxNestedTags","text","replaceEntitiesValue","tagObj","propName","extractAttributeValues","isStopNode","checkStopNode","textNodeName","tagText","tagValueProcessor","cdataPropName","commentPropName","attStr","attr_to_str","tempInd","piTextNodeName","newIdentation","tagStart","tagValue","getRawContent","unpairedTags","suppressUnpairedNode","suppressEmptyNode","endsWith","attrMap","ignoreAttributes","hasAttrs","attr","startsWith","attributeNamePrefix","substr","item","attr_to_str_raw","nestedContent","attrStr","attrVal","suppressBooleanAttributes","keys","attributeValueProcessor","textValue","processEntities","entities","entity","replace","regex","val","defaultOptions","attributesGroupName","a","preserveOrder","RegExp","oneListGroup","jPath","Builder","assign","isAttribute","ignoreAttributesFn","attrPrefixLen","processTextOrObjNode","indentate","tagEndChar","newLine","object","level","extractAttributes","rawContent","buildRawContent","buildAttributesForStopNode","buildObjectNode","result","j2x","buildTextValNode","repeat","name","build","jObj","buildFromOrderedJs","arrayNodeName","isCurrentStopNode","Date","buildAttrPairStr","newval","closeTag","arrLen","listTagVal","listTagAttr","j","Ks","L","attrGroup","attrKey","nestedAttrs","cleanKey","tagEndExp","piClosingChar"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"./lib/fxbuilder.min.js","mappings":"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","sources":["webpack://XMLBuilder/webpack/universalModuleDefinition","webpack://XMLBuilder/webpack/bootstrap","webpack://XMLBuilder/webpack/runtime/define property getters","webpack://XMLBuilder/webpack/runtime/hasOwnProperty shorthand","webpack://XMLBuilder/webpack/runtime/make namespace object","webpack://XMLBuilder/./node_modules/path-expression-matcher/src/Expression.js","webpack://XMLBuilder/./node_modules/path-expression-matcher/src/Matcher.js","webpack://XMLBuilder/./node_modules/fast-xml-builder/src/orderedJs2Xml.js","webpack://XMLBuilder/./node_modules/fast-xml-builder/src/fxb.js","webpack://XMLBuilder/./node_modules/fast-xml-builder/src/ignoreAttributes.js","webpack://XMLBuilder/./src/xmlbuilder/json2xml.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"XMLBuilder\"] = factory();\n\telse\n\t\troot[\"XMLBuilder\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n */\n push(tagName, attrValues = null, namespace = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}","import { Expression, Matcher } from 'path-expression-matcher';\n\nconst EOL = \"\\n\";\n\n/**\n * \n * @param {array} jArray \n * @param {any} options \n * @returns \n */\nexport default function toXml(jArray, options) {\n let indentation = \"\";\n if (options.format && options.indentBy.length > 0) {\n indentation = EOL;\n }\n\n // Pre-compile stopNode expressions for pattern matching\n const stopNodeExpressions = [];\n if (options.stopNodes && Array.isArray(options.stopNodes)) {\n for (let i = 0; i < options.stopNodes.length; i++) {\n const node = options.stopNodes[i];\n if (typeof node === 'string') {\n stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n stopNodeExpressions.push(node);\n }\n }\n }\n\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n\n return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions);\n}\n\nfunction arrToStr(arr, options, indentation, matcher, stopNodeExpressions) {\n let xmlStr = \"\";\n let isPreviousElementTag = false;\n\n if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n\n if (!Array.isArray(arr)) {\n // Non-array values (e.g. string tag values) should be treated as text content\n if (arr !== undefined && arr !== null) {\n let text = arr.toString();\n text = replaceEntitiesValue(text, options);\n return text;\n }\n return \"\";\n }\n\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const tagName = propName(tagObj);\n if (tagName === undefined) continue;\n\n // Extract attributes from \":@\" property\n const attrValues = extractAttributeValues(tagObj[\":@\"], options);\n\n // Push tag to matcher WITH attributes\n matcher.push(tagName, attrValues);\n\n // Check if this is a stop node using Expression matching\n const isStopNode = checkStopNode(matcher, stopNodeExpressions);\n\n if (tagName === options.textNodeName) {\n let tagText = tagObj[tagName];\n if (!isStopNode) {\n tagText = options.tagValueProcessor(tagName, tagText);\n tagText = replaceEntitiesValue(tagText, options);\n }\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += tagText;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.cdataPropName) {\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n const val = tagObj[tagName][0][options.textNodeName];\n const safeVal = String(val).replace(/\\]\\]>/g, ']]]]>`;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.commentPropName) {\n const val = tagObj[tagName][0][options.textNodeName]\n const safeVal = String(val)\n .replace(/--/g, '- -') // -- is illegal anywhere in comment content\n .replace(/-$/, '- '); // trailing - would form -- with the closing -->\n xmlStr += indentation + ``;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n } else if (tagName[0] === \"?\") {\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tempInd = tagName === \"?xml\" ? \"\" : indentation;\n let piTextNodeName = tagObj[tagName][0][options.textNodeName];\n piTextNodeName = piTextNodeName.length !== 0 ? \" \" + piTextNodeName : \"\"; //remove extra spacing\n xmlStr += tempInd + `<${tagName}${piTextNodeName}${attStr}?>`;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n }\n\n let newIdentation = indentation;\n if (newIdentation !== \"\") {\n newIdentation += options.indentBy;\n }\n\n // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tagStart = indentation + `<${tagName}${attStr}`;\n\n // If this is a stopNode, get raw content without processing\n let tagValue;\n if (isStopNode) {\n tagValue = getRawContent(tagObj[tagName], options);\n } else {\n\n tagValue = arrToStr(tagObj[tagName], options, newIdentation, matcher, stopNodeExpressions);\n }\n\n if (options.unpairedTags.indexOf(tagName) !== -1) {\n if (options.suppressUnpairedNode) xmlStr += tagStart + \">\";\n else xmlStr += tagStart + \"/>\";\n } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {\n xmlStr += tagStart + \"/>\";\n } else if (tagValue && tagValue.endsWith(\">\")) {\n xmlStr += tagStart + `>${tagValue}${indentation}`;\n } else {\n xmlStr += tagStart + \">\";\n if (tagValue && indentation !== \"\" && (tagValue.includes(\"/>\") || tagValue.includes(\"`;\n }\n isPreviousElementTag = true;\n\n // Pop tag from matcher\n matcher.pop();\n }\n\n return xmlStr;\n}\n\n/**\n * Extract attribute values from the \":@\" object and return as plain object\n * for passing to matcher.push()\n */\nfunction extractAttributeValues(attrMap, options) {\n if (!attrMap || options.ignoreAttributes) return null;\n\n const attrValues = {};\n let hasAttrs = false;\n\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // Remove the attribute prefix to get clean attribute name\n const cleanAttrName = attr.startsWith(options.attributeNamePrefix)\n ? attr.substr(options.attributeNamePrefix.length)\n : attr;\n attrValues[cleanAttrName] = attrMap[attr];\n hasAttrs = true;\n }\n\n return hasAttrs ? attrValues : null;\n}\n\n/**\n * Extract raw content from a stopNode without any processing\n * This preserves the content exactly as-is, including special characters\n */\nfunction getRawContent(arr, options) {\n if (!Array.isArray(arr)) {\n // Non-array values return as-is\n if (arr !== undefined && arr !== null) {\n return arr.toString();\n }\n return \"\";\n }\n\n let content = \"\";\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const tagName = propName(item);\n\n if (tagName === options.textNodeName) {\n // Raw text content - NO processing, NO entity replacement\n content += item[tagName];\n } else if (tagName === options.cdataPropName) {\n // CDATA content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName === options.commentPropName) {\n // Comment content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName && tagName[0] === \"?\") {\n // Processing instruction - skip for stopNodes\n continue;\n } else if (tagName) {\n // Nested tags within stopNode\n // Recursively get raw content and reconstruct the tag\n // For stopNodes, we don't process attributes either\n const attStr = attr_to_str_raw(item[\":@\"], options);\n const nestedContent = getRawContent(item[tagName], options);\n\n if (!nestedContent || nestedContent.length === 0) {\n content += `<${tagName}${attStr}/>`;\n } else {\n content += `<${tagName}${attStr}>${nestedContent}`;\n }\n }\n }\n return content;\n}\n\n/**\n * Build attribute string for stopNodes - NO entity replacement\n */\nfunction attr_to_str_raw(attrMap, options) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // For stopNodes, use raw value without processing\n let attrVal = attrMap[attr];\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n if (key !== \":@\") return key;\n }\n}\n\nfunction attr_to_str(attrMap, options, isStopNode) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n let attrVal;\n\n if (isStopNode) {\n // For stopNodes, use raw value without any processing\n attrVal = attrMap[attr];\n } else {\n // Normal processing: apply attributeValueProcessor and entity replacement\n attrVal = options.attributeValueProcessor(attr, attrMap[attr]);\n attrVal = replaceEntitiesValue(attrVal, options);\n }\n\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction checkStopNode(matcher, stopNodeExpressions) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction replaceEntitiesValue(textValue, options) {\n if (textValue && textValue.length > 0 && options.processEntities) {\n for (let i = 0; i < options.entities.length; i++) {\n const entity = options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction cdataVal(val) {\n\n}\n\nfunction commentVal(val) {\n\n}","'use strict';\n//parse Empty Node as self closing node\nimport buildFromOrderedJs from './orderedJs2Xml.js';\nimport getIgnoreAttributesFn from \"./ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\n\nconst defaultOptions = {\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n cdataPropName: false,\n format: false,\n indentBy: ' ',\n suppressEmptyNode: false,\n suppressUnpairedNode: true,\n suppressBooleanAttributes: true,\n tagValueProcessor: function (key, a) {\n return a;\n },\n attributeValueProcessor: function (attrName, a) {\n return a;\n },\n preserveOrder: false,\n commentPropName: false,\n unpairedTags: [],\n entities: [\n { regex: new RegExp(\"&\", \"g\"), val: \"&\" },//it must be on top\n { regex: new RegExp(\">\", \"g\"), val: \">\" },\n { regex: new RegExp(\"<\", \"g\"), val: \"<\" },\n { regex: new RegExp(\"\\'\", \"g\"), val: \"'\" },\n { regex: new RegExp(\"\\\"\", \"g\"), val: \""\" }\n ],\n processEntities: true,\n stopNodes: [],\n // transformTagName: false,\n // transformAttributeName: false,\n oneListGroup: false,\n maxNestedTags: 100,\n jPath: true // When true, callbacks receive string jPath; when false, receive Matcher instance\n};\n\nexport default function Builder(options) {\n this.options = Object.assign({}, defaultOptions, options);\n\n // Convert old-style stopNodes for backward compatibility\n // Old syntax: \"*.tag\" meant \"tag anywhere in tree\"\n // New syntax: \"..tag\" means \"tag anywhere in tree\"\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n this.options.stopNodes = this.options.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Convert old wildcard syntax to deep wildcard\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n\n // Pre-compile stopNode expressions for pattern matching\n this.stopNodeExpressions = [];\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const node = this.options.stopNodes[i];\n if (typeof node === 'string') {\n this.stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n this.stopNodeExpressions.push(node);\n }\n }\n }\n\n if (this.options.ignoreAttributes === true || this.options.attributesGroupName) {\n this.isAttribute = function (/*a*/) {\n return false;\n };\n } else {\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.attrPrefixLen = this.options.attributeNamePrefix.length;\n this.isAttribute = isAttribute;\n }\n\n this.processTextOrObjNode = processTextOrObjNode\n\n if (this.options.format) {\n this.indentate = indentate;\n this.tagEndChar = '>\\n';\n this.newLine = '\\n';\n } else {\n this.indentate = function () {\n return '';\n };\n this.tagEndChar = '>';\n this.newLine = '';\n }\n}\n\nBuilder.prototype.build = function (jObj) {\n if (this.options.preserveOrder) {\n return buildFromOrderedJs(jObj, this.options);\n } else {\n if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) {\n jObj = {\n [this.options.arrayNodeName]: jObj\n }\n }\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n return this.j2x(jObj, 0, matcher).val;\n }\n};\n\nBuilder.prototype.j2x = function (jObj, level, matcher) {\n let attrStr = '';\n let val = '';\n if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n // Get jPath based on option: string for backward compatibility, or Matcher for new features\n const jPath = this.options.jPath ? matcher.toString() : matcher;\n\n // Check if current node is a stopNode (will be used for attribute encoding)\n const isCurrentStopNode = this.checkStopNode(matcher);\n\n for (let key in jObj) {\n if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;\n if (typeof jObj[key] === 'undefined') {\n // supress undefined node only if it is not an attribute\n if (this.isAttribute(key)) {\n val += '';\n }\n } else if (jObj[key] === null) {\n // null attribute should be ignored by the attribute list, but should not cause the tag closing\n if (this.isAttribute(key)) {\n val += '';\n } else if (key === this.options.cdataPropName) {\n val += '';\n } else if (key[0] === '?') {\n val += this.indentate(level) + '<' + key + '?' + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n }\n // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n } else if (jObj[key] instanceof Date) {\n val += this.buildTextValNode(jObj[key], key, '', level, matcher);\n } else if (typeof jObj[key] !== 'object') {\n //premitive type\n const attr = this.isAttribute(key);\n if (attr && !this.ignoreAttributesFn(attr, jPath)) {\n attrStr += this.buildAttrPairStr(attr, '' + jObj[key], isCurrentStopNode);\n } else if (!attr) {\n //tag value\n if (key === this.options.textNodeName) {\n let newval = this.options.tagValueProcessor(key, '' + jObj[key]);\n val += this.replaceEntitiesValue(newval);\n } else {\n // Check if this is a stopNode before building\n matcher.push(key);\n const isStopNode = this.checkStopNode(matcher);\n matcher.pop();\n\n if (isStopNode) {\n // Build as raw content without encoding\n const textValue = '' + jObj[key];\n if (textValue === '') {\n val += this.indentate(level) + '<' + key + this.closeTag(key) + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '>' + textValue + '' + textValue + '${item}`;\n } else if (typeof item === 'object' && item !== null) {\n const nestedContent = this.buildRawContent(item);\n const nestedAttrs = this.buildAttributesForStopNode(item);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object\n const nestedContent = this.buildRawContent(value);\n const nestedAttrs = this.buildAttributesForStopNode(value);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n } else {\n // Primitive value\n content += `<${key}>${value}`;\n }\n }\n\n return content;\n};\n\n// Build attribute string for stopNode (no entity encoding)\nBuilder.prototype.buildAttributesForStopNode = function (obj) {\n if (!obj || typeof obj !== 'object') return '';\n\n let attrStr = '';\n\n // Check for attributesGroupName (when attributes are grouped)\n if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {\n const attrGroup = obj[this.options.attributesGroupName];\n for (let attrKey in attrGroup) {\n if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;\n const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix)\n ? attrKey.substring(this.options.attributeNamePrefix.length)\n : attrKey;\n const val = attrGroup[attrKey];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + cleanKey;\n } else {\n attrStr += ' ' + cleanKey + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n } else {\n // Look for individual attributes\n for (let key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const attr = this.isAttribute(key);\n if (attr) {\n const val = obj[key];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + attr;\n } else {\n attrStr += ' ' + attr + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n }\n }\n\n return attrStr;\n};\n\nBuilder.prototype.buildObjectNode = function (val, key, attrStr, level) {\n if (val === \"\") {\n if (key[0] === \"?\") return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n else {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n }\n } else {\n\n let tagEndExp = '' + val + tagEndExp);\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {\n return this.indentate(level) + `` + this.newLine;\n } else {\n return (\n this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +\n val +\n this.indentate(level) + tagEndExp);\n }\n }\n}\n\nBuilder.prototype.closeTag = function (key) {\n let closeTag = \"\";\n if (this.options.unpairedTags.indexOf(key) !== -1) { //unpaired\n if (!this.options.suppressUnpairedNode) closeTag = \"/\"\n } else if (this.options.suppressEmptyNode) { //empty\n closeTag = \"/\";\n } else {\n closeTag = `>/g, ']]]]>` + this.newLine;\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName) {\n const safeVal = String(val)\n .replace(/--/g, '- -') // -- is illegal anywhere in comment content\n .replace(/-$/, '- '); // trailing - would form -- with the closing -->\n return this.indentate(level) + `` + this.newLine;\n } else if (key[0] === \"?\") {//PI tag\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n // Normal processing: apply tagValueProcessor and entity replacement\n let textValue = this.options.tagValueProcessor(key, val);\n textValue = this.replaceEntitiesValue(textValue);\n\n if (textValue === '') {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n } else {\n return this.indentate(level) + '<' + key + attrStr + '>' +\n textValue +\n ' 0 && this.options.processEntities) {\n for (let i = 0; i < this.options.entities.length; i++) {\n const entity = this.options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction indentate(level) {\n return this.options.indentBy.repeat(level);\n}\n\nfunction isAttribute(name /*, options*/) {\n if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {\n return name.substr(this.attrPrefixLen);\n } else {\n return false;\n }\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","// Re-export from fast-xml-builder for backward compatibility\nimport XMLBuilder from 'fast-xml-builder';\nexport default XMLBuilder;\n\n// If there are any named exports you also want to re-export:\nexport * from 'fast-xml-builder';"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Expression","constructor","pattern","options","data","separator","segments","_parse","_hasDeepWildcard","some","seg","type","_hasAttributeCondition","undefined","attrName","_hasPositionSelector","position","i","currentPart","length","trim","push","_parseSegment","part","segment","bracketContent","withoutBrackets","bracketMatch","match","content","slice","namespace","tag","tagAndPosition","includes","nsIndex","indexOf","substring","Error","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","test","eqIndex","attrValue","nthMatch","positionValue","parseInt","hasDeepWildcard","hasAttributeCondition","hasPositionSelector","toString","MatcherView","matcher","_matcher","getCurrentTag","path","getCurrentNamespace","getAttrValue","values","hasAttr","current","getPosition","getCounter","counter","getIndex","getDepth","includeNamespace","toArray","map","n","matches","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","tagName","attrValues","currentLevel","Map","siblings","siblingKey","count","set","node","pop","updateCurrent","sep","result","join","reset","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","nextSeg","found","isCurrentNode","String","snapshot","restore","readOnly","toXml","jArray","indentation","format","indentBy","stopNodeExpressions","stopNodes","Array","isArray","arrToStr","arr","xmlStr","isPreviousElementTag","maxNestedTags","text","replaceEntitiesValue","tagObj","propName","extractAttributeValues","isStopNode","checkStopNode","textNodeName","tagText","tagValueProcessor","cdataPropName","val","replace","commentPropName","attStr","attr_to_str","tempInd","piTextNodeName","newIdentation","tagStart","tagValue","getRawContent","unpairedTags","suppressUnpairedNode","suppressEmptyNode","endsWith","attrMap","ignoreAttributes","hasAttrs","attr","startsWith","attributeNamePrefix","substr","item","attr_to_str_raw","nestedContent","attrStr","attrVal","suppressBooleanAttributes","keys","attributeValueProcessor","textValue","processEntities","entities","entity","regex","defaultOptions","attributesGroupName","a","preserveOrder","RegExp","oneListGroup","jPath","Builder","assign","isAttribute","ignoreAttributesFn","attrPrefixLen","processTextOrObjNode","indentate","tagEndChar","newLine","object","level","extractAttributes","rawContent","buildRawContent","buildAttributesForStopNode","buildObjectNode","j2x","buildTextValNode","repeat","name","build","jObj","buildFromOrderedJs","arrayNodeName","isCurrentStopNode","Date","buildAttrPairStr","newval","closeTag","arrLen","listTagVal","listTagAttr","j","Ks","L","attrGroup","attrKey","nestedAttrs","cleanKey","tagEndExp","piClosingChar","safeVal"],"sourceRoot":""} \ No newline at end of file diff --git a/node_modules/fast-xml-parser/lib/fxp.cjs b/node_modules/fast-xml-parser/lib/fxp.cjs index 544c4666..65cde85e 100644 --- a/node_modules/fast-xml-parser/lib/fxp.cjs +++ b/node_modules/fast-xml-parser/lib/fxp.cjs @@ -1 +1 @@ -(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{XMLBuilder:()=>Ot,XMLParser:()=>ft,XMLValidator:()=>$t});const i=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",n=new RegExp("^["+i+"]["+i+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function s(t,e){const i=[];let n=e.exec(t);for(;n;){const s=[];s.startIndex=e.lastIndex-n[0].length;const r=n.length;for(let t=0;t<"!==t[r]){if(p(t[r]))continue;return b("InvalidChar","char '"+t[r]+"' is not expected.",w(t,r))}{let o=r;if(r++,"!"===t[r]){r=c(t,r);continue}{let a=!1;"/"===t[r]&&(a=!0,r++);let h="";for(;r"!==t[r]&&" "!==t[r]&&"\t"!==t[r]&&"\n"!==t[r]&&"\r"!==t[r];r++)h+=t[r];if(h=h.trim(),"/"===h[h.length-1]&&(h=h.substring(0,h.length-1),r--),!y(h)){let e;return e=0===h.trim().length?"Invalid space after '<'.":"Tag '"+h+"' is an invalid name.",b("InvalidTag",e,w(t,r))}const l=g(t,r);if(!1===l)return b("InvalidAttr","Attributes for '"+h+"' have open quote.",w(t,r));let d=l.value;if(r=l.index,"/"===d[d.length-1]){const i=r-d.length;d=d.substring(0,d.length-1);const s=x(d,e);if(!0!==s)return b(s.err.code,s.err.msg,w(t,i+s.err.line));n=!0}else if(a){if(!l.tagClosed)return b("InvalidTag","Closing tag '"+h+"' doesn't have proper closing.",w(t,r));if(d.trim().length>0)return b("InvalidTag","Closing tag '"+h+"' can't have attributes or invalid starting.",w(t,o));if(0===i.length)return b("InvalidTag","Closing tag '"+h+"' has not been opened.",w(t,o));{const e=i.pop();if(h!==e.tagName){let i=w(t,e.tagStartPos);return b("InvalidTag","Expected closing tag '"+e.tagName+"' (opened in line "+i.line+", col "+i.col+") instead of closing tag '"+h+"'.",w(t,o))}0==i.length&&(s=!0)}}else{const a=x(d,e);if(!0!==a)return b(a.err.code,a.err.msg,w(t,r-d.length+a.err.line));if(!0===s)return b("InvalidXml","Multiple possible root nodes found.",w(t,r));-1!==e.unpairedTags.indexOf(h)||i.push({tagName:h,tagStartPos:o}),n=!0}for(r++;r<"===t[r]){if("!"===t[r+1]){r++,r=c(t,r);continue}if("?"!==t[r+1])break;if(r=u(t,++r),r.err)return r}else if("&"===t[r]){const e=N(t,r);if(-1==e)return b("InvalidChar","char '&' is not expected.",w(t,r));r=e}else if(!0===s&&!p(t[r]))return b("InvalidXml","Extra text at the end",w(t,r));"<"===t[r]&&r--}}}return n?1==i.length?b("InvalidTag","Unclosed tag '"+i[0].tagName+"'.",w(t,i[0].tagStartPos)):!(i.length>0)||b("InvalidXml","Invalid '"+JSON.stringify(i.map(t=>t.tagName),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):b("InvalidXml","Start tag expected.",1)}function p(t){return" "===t||"\t"===t||"\n"===t||"\r"===t}function u(t,e){const i=e;for(;e5&&"xml"===n)return b("InvalidXml","XML declaration allowed only at the start of the document.",w(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}continue}return e}function c(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){let i=1;for(e+=8;e<"===t[e])i++;else if(">"===t[e]&&(i--,0===i))break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}const d='"',f="'";function g(t,e){let i="",n="",s=!1;for(;e"===t[e]&&""===n){s=!0;break}i+=t[e]}return""===n&&{value:i,index:e,tagClosed:s}}const m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function x(t,e){const i=s(t,m),n={};for(let t=0;to.includes(t)?"__"+t:t,P={preserveOrder:!1,attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,parseTagValue:!0,parseAttributeValue:!1,trimValues:!0,cdataPropName:!1,numberParseOptions:{hex:!0,leadingZeros:!0,eNotation:!0},tagValueProcessor:function(t,e){return e},attributeValueProcessor:function(t,e){return e},stopNodes:[],alwaysCreateTextNode:!1,isArray:()=>!1,commentPropName:!1,unpairedTags:[],processEntities:!0,htmlEntities:!1,ignoreDeclaration:!1,ignorePiTags:!1,transformTagName:!1,transformAttributeName:!1,updateTag:function(t,e,i){return t},captureMetaData:!1,maxNestedTags:100,strictReservedNames:!0,jPath:!0,onDangerousProperty:T};function S(t,e){if("string"!=typeof t)return;const i=t.toLowerCase();if(o.some(t=>i===t.toLowerCase()))throw new Error(`[SECURITY] Invalid ${e}: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`);if(a.some(t=>i===t.toLowerCase()))throw new Error(`[SECURITY] Invalid ${e}: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`)}function A(t){return"boolean"==typeof t?{enabled:t,maxEntitySize:1e4,maxExpansionDepth:10,maxTotalExpansions:1e3,maxExpandedLength:1e5,maxEntityCount:100,allowedTags:null,tagFilter:null}:"object"==typeof t&&null!==t?{enabled:!1!==t.enabled,maxEntitySize:Math.max(1,t.maxEntitySize??1e4),maxExpansionDepth:Math.max(1,t.maxExpansionDepth??10),maxTotalExpansions:Math.max(1,t.maxTotalExpansions??1e3),maxExpandedLength:Math.max(1,t.maxExpandedLength??1e5),maxEntityCount:Math.max(1,t.maxEntityCount??100),allowedTags:t.allowedTags??null,tagFilter:t.tagFilter??null}:A(!0)}const C=function(t){const e=Object.assign({},P,t),i=[{value:e.attributeNamePrefix,name:"attributeNamePrefix"},{value:e.attributesGroupName,name:"attributesGroupName"},{value:e.textNodeName,name:"textNodeName"},{value:e.cdataPropName,name:"cdataPropName"},{value:e.commentPropName,name:"commentPropName"}];for(const{value:t,name:e}of i)t&&S(t,e);return null===e.onDangerousProperty&&(e.onDangerousProperty=T),e.processEntities=A(e.processEntities),e.stopNodes&&Array.isArray(e.stopNodes)&&(e.stopNodes=e.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),e};let O;O="function"!=typeof Symbol?"@@xmlMetadata":Symbol("XML Node Metadata");class ${constructor(t){this.tagname=t,this.child=[],this[":@"]=Object.create(null)}add(t,e){"__proto__"===t&&(t="#__proto__"),this.child.push({[t]:e})}addChild(t,e){"__proto__"===t.tagname&&(t.tagname="#__proto__"),t[":@"]&&Object.keys(t[":@"]).length>0?this.child.push({[t.tagname]:t.child,":@":t[":@"]}):this.child.push({[t.tagname]:t.child}),void 0!==e&&(this.child[this.child.length-1][O]={startIndex:e})}static getMetaDataSymbol(){return O}}class I{constructor(t){this.suppressValidationErr=!t,this.options=t}readDocType(t,e){const i=Object.create(null);let n=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");{e+=9;let s=1,r=!1,o=!1,a="";for(;e<"!==t[e]||o)if(">"===t[e]){if(o?"-"===t[e-1]&&"-"===t[e-2]&&(o=!1,s--):s--,0===s)break}else"["===t[e]?r=!0:a+=t[e];else{if(r&&_(t,"!ENTITY",e)){let s,r;if(e+=7,[s,r,e]=this.readEntityExp(t,e+1,this.suppressValidationErr),-1===r.indexOf("&")){if(!1!==this.options.enabled&&null!=this.options.maxEntityCount&&n>=this.options.maxEntityCount)throw new Error(`Entity count (${n+1}) exceeds maximum allowed (${this.options.maxEntityCount})`);const t=s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i[s]={regx:RegExp(`&${t};`,"g"),val:r},n++}}else if(r&&_(t,"!ELEMENT",e)){e+=8;const{index:i}=this.readElementExp(t,e+1);e=i}else if(r&&_(t,"!ATTLIST",e))e+=8;else if(r&&_(t,"!NOTATION",e)){e+=9;const{index:i}=this.readNotationExp(t,e+1,this.suppressValidationErr);e=i}else{if(!_(t,"!--",e))throw new Error("Invalid DOCTYPE");o=!0}s++,a=""}if(0!==s)throw new Error("Unclosed DOCTYPE")}return{entities:i,i:e}}readEntityExp(t,e){const i=e=j(t,e);for(;ethis.options.maxEntitySize)throw new Error(`Entity "${n}" size (${s.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);return[n,s,--e]}readNotationExp(t,e){const i=e=j(t,e);for(;e{for(;e0&&(this.path[this.path.length-1].values=void 0);const n=this.path.length;this.siblingStacks[n]||(this.siblingStacks[n]=new Map);const s=this.siblingStacks[n],r=i?`${i}:${t}`:t,o=s.get(r)||0;let a=0;for(const t of s.values())a+=t;s.set(r,o+1);const h={tag:t,position:a,counter:o};null!=i&&(h.namespace=i),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0===this.path.length)return;const e=this.path[this.path.length-1];return e.values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const i=t||this.separator;return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i)}toArray(){return this.path.map(t=>t.tag)}reset(){this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const n=t[i];if("deep-wildcard"===n.type){if(i--,i<0)return!0;const n=t[i];let s=!1;for(let t=e;t>=0;t--){const r=t===this.path.length-1;if(this._matchSegment(n,this.path[t],r)){e=t-1,i--,s=!0;break}}if(!s)return!1}else{const t=e===this.path.length-1;if(!this._matchSegment(n,this.path[e],t))return!1;e--,i--}}return i<0}_matchSegment(t,e,i){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!i)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue){const i=e.values[t.attrName];if(String(i)!==String(t.attrValue))return!1}}if(void 0!==t.position){if(!i)return!1;const n=e.counter??0;if("first"===t.position&&0!==n)return!1;if("odd"===t.position&&n%2!=1)return!1;if("even"===t.position&&n%2!=0)return!1;if("nth"===t.position&&n!==t.positionValue)return!1}return!0}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}}class G{constructor(t,e={}){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let i=0,n="";for(;i0){const i=t.substring(0,e);if("xmlns"!==i)return i}}class B{constructor(t){var e;if(this.options=t,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:" "},cent:{regex:/&(cent|#162);/g,val:"¢"},pound:{regex:/&(pound|#163);/g,val:"£"},yen:{regex:/&(yen|#165);/g,val:"¥"},euro:{regex:/&(euro|#8364);/g,val:"€"},copyright:{regex:/&(copy|#169);/g,val:"©"},reg:{regex:/&(reg|#174);/g,val:"®"},inr:{regex:/&(inr|#8377);/g,val:"₹"},num_dec:{regex:/&#([0-9]{1,7});/g,val:(t,e)=>st(e,10,"&#")},num_hex:{regex:/&#x([0-9a-fA-F]{1,6});/g,val:(t,e)=>st(e,16,"&#x")}},this.addExternalEntities=W,this.parseXml=Z,this.parseTextData=Y,this.resolveNameSpace=X,this.buildAttributesMap=q,this.isItStopNode=H,this.replaceEntitiesValue=K,this.readStopNodeData=it,this.saveTextToParentTag=Q,this.addChild=J,this.ignoreAttributesFn="function"==typeof(e=this.options.ignoreAttributes)?e:Array.isArray(e)?t=>{for(const i of e){if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:()=>!1,this.entityExpansionCount=0,this.currentExpandedLength=0,this.matcher=new L,this.isCurrentNodeStopNode=!1,this.options.stopNodes&&this.options.stopNodes.length>0){this.stopNodeExpressions=[];for(let t=0;t0)){o||(t=this.replaceEntitiesValue(t,e,i));const n=this.options.jPath?i.toString():i,a=this.options.tagValueProcessor(e,t,n,s,r);return null==a?t:typeof a!=typeof t||a!==t?a:this.options.trimValues||t.trim()===t?nt(t,this.options.parseTagValue,this.options.numberParseOptions):t}}function X(t){if(this.options.removeNSPrefix){const e=t.split(":"),i="/"===t.charAt(0)?"/":"";if("xmlns"===e[0])return"";2===e.length&&(t=i+e[1])}return t}const z=new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?","gm");function q(t,e,i){if(!0!==this.options.ignoreAttributes&&"string"==typeof t){const n=s(t,z),r=n.length,o={},a={};for(let t=0;t0&&"object"==typeof e&&e.updateCurrent&&e.updateCurrent(a);for(let t=0;t",r,"Closing Tag is not closed.");let s=t.substring(r+2,e).trim();if(this.options.removeNSPrefix){const t=s.indexOf(":");-1!==t&&(s=s.substr(t+1))}s=rt(this.options.transformTagName,s,"",this.options).tagName,i&&(n=this.saveTextToParentTag(n,i,this.matcher));const o=this.matcher.getCurrentTag();if(s&&-1!==this.options.unpairedTags.indexOf(s))throw new Error(`Unpaired tag can not be used as closing tag: `);o&&-1!==this.options.unpairedTags.indexOf(o)&&(this.matcher.pop(),this.tagsNodeStack.pop()),this.matcher.pop(),this.isCurrentNodeStopNode=!1,i=this.tagsNodeStack.pop(),n="",r=e}else if("?"===t[r+1]){let e=et(t,r,!1,"?>");if(!e)throw new Error("Pi Tag is not closed.");if(n=this.saveTextToParentTag(n,i,this.matcher),this.options.ignoreDeclaration&&"?xml"===e.tagName||this.options.ignorePiTags);else{const t=new $(e.tagName);t.add(this.options.textNodeName,""),e.tagName!==e.tagExp&&e.attrExpPresent&&(t[":@"]=this.buildAttributesMap(e.tagExp,this.matcher,e.tagName)),this.addChild(i,t,this.matcher,r)}r=e.closeIndex+1}else if("!--"===t.substr(r+1,3)){const e=tt(t,"--\x3e",r+4,"Comment is not closed.");if(this.options.commentPropName){const s=t.substring(r+4,e-2);n=this.saveTextToParentTag(n,i,this.matcher),i.add(this.options.commentPropName,[{[this.options.textNodeName]:s}])}r=e}else if("!D"===t.substr(r+1,2)){const e=s.readDocType(t,r);this.docTypeEntities=e.entities,r=e.i}else if("!["===t.substr(r+1,2)){const e=tt(t,"]]>",r,"CDATA is not closed.")-2,s=t.substring(r+9,e);n=this.saveTextToParentTag(n,i,this.matcher);let o=this.parseTextData(s,i.tagname,this.matcher,!0,!1,!0,!0);null==o&&(o=""),this.options.cdataPropName?i.add(this.options.cdataPropName,[{[this.options.textNodeName]:s}]):i.add(this.options.textNodeName,o),r=e+2}else{let s=et(t,r,this.options.removeNSPrefix);if(!s){const e=t.substring(Math.max(0,r-50),Math.min(t.length,r+50));throw new Error(`readTagExp returned undefined at position ${r}. Context: "${e}"`)}let o=s.tagName;const a=s.rawTagName;let h=s.tagExp,l=s.attrExpPresent,p=s.closeIndex;if(({tagName:o,tagExp:h}=rt(this.options.transformTagName,o,h,this.options)),this.options.strictReservedNames&&(o===this.options.commentPropName||o===this.options.cdataPropName||o===this.options.textNodeName||o===this.options.attributesGroupName))throw new Error(`Invalid tag name: ${o}`);i&&n&&"!xml"!==i.tagname&&(n=this.saveTextToParentTag(n,i,this.matcher,!1));const u=i;u&&-1!==this.options.unpairedTags.indexOf(u.tagname)&&(i=this.tagsNodeStack.pop(),this.matcher.pop());let c=!1;h.length>0&&h.lastIndexOf("/")===h.length-1&&(c=!0,"/"===o[o.length-1]?(o=o.substr(0,o.length-1),h=o):h=h.substr(0,h.length-1),l=o!==h);let d,f=null,g={};d=U(a),o!==e.tagname&&this.matcher.push(o,{},d),o!==h&&l&&(f=this.buildAttributesMap(h,this.matcher,o),f&&(g=R(f,this.options))),o!==e.tagname&&(this.isCurrentNodeStopNode=this.isItStopNode(this.stopNodeExpressions,this.matcher));const m=r;if(this.isCurrentNodeStopNode){let e="";if(c)r=s.closeIndex;else if(-1!==this.options.unpairedTags.indexOf(o))r=s.closeIndex;else{const i=this.readStopNodeData(t,a,p+1);if(!i)throw new Error(`Unexpected end of ${a}`);r=i.i,e=i.tagContent}const n=new $(o);f&&(n[":@"]=f),n.add(this.options.textNodeName,e),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(i,n,this.matcher,m)}else{if(c){({tagName:o,tagExp:h}=rt(this.options.transformTagName,o,h,this.options));const t=new $(o);f&&(t[":@"]=f),this.addChild(i,t,this.matcher,m),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else{if(-1!==this.options.unpairedTags.indexOf(o)){const t=new $(o);f&&(t[":@"]=f),this.addChild(i,t,this.matcher,m),this.matcher.pop(),this.isCurrentNodeStopNode=!1,r=s.closeIndex;continue}{const t=new $(o);if(this.tagsNodeStack.length>this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");this.tagsNodeStack.push(i),f&&(t[":@"]=f),this.addChild(i,t,this.matcher,m),i=t}}n="",r=p}}else n+=t[r];return e.child};function J(t,e,i,n){this.options.captureMetaData||(n=void 0);const s=this.options.jPath?i.toString():i,r=this.options.updateTag(e.tagname,s,e[":@"]);!1===r||("string"==typeof r?(e.tagname=r,t.addChild(e,n)):t.addChild(e,n))}function K(t,e,i){const n=this.options.processEntities;if(!n||!n.enabled)return t;if(n.allowedTags){const s=this.options.jPath?i.toString():i;if(!(Array.isArray(n.allowedTags)?n.allowedTags.includes(e):n.allowedTags(e,s)))return t}if(n.tagFilter){const s=this.options.jPath?i.toString():i;if(!n.tagFilter(e,s))return t}for(const e of Object.keys(this.docTypeEntities)){const i=this.docTypeEntities[e],s=t.match(i.regx);if(s){if(this.entityExpansionCount+=s.length,n.maxTotalExpansions&&this.entityExpansionCount>n.maxTotalExpansions)throw new Error(`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${n.maxTotalExpansions}`);const e=t.length;if(t=t.replace(i.regx,i.val),n.maxExpandedLength&&(this.currentExpandedLength+=t.length-e,this.currentExpandedLength>n.maxExpandedLength))throw new Error(`Total expanded content size exceeded: ${this.currentExpandedLength} > ${n.maxExpandedLength}`)}}for(const e of Object.keys(this.lastEntities)){const i=this.lastEntities[e],s=t.match(i.regex);if(s&&(this.entityExpansionCount+=s.length,n.maxTotalExpansions&&this.entityExpansionCount>n.maxTotalExpansions))throw new Error(`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${n.maxTotalExpansions}`);t=t.replace(i.regex,i.val)}if(-1===t.indexOf("&"))return t;if(this.options.htmlEntities)for(const e of Object.keys(this.htmlEntities)){const i=this.htmlEntities[e],s=t.match(i.regex);if(s&&(this.entityExpansionCount+=s.length,n.maxTotalExpansions&&this.entityExpansionCount>n.maxTotalExpansions))throw new Error(`Entity expansion limit exceeded: ${this.entityExpansionCount} > ${n.maxTotalExpansions}`);t=t.replace(i.regex,i.val)}return t.replace(this.ampEntity.regex,this.ampEntity.val)}function Q(t,e,i,n){return t&&(void 0===n&&(n=0===e.child.length),void 0!==(t=this.parseTextData(t,e.tagname,i,!1,!!e[":@"]&&0!==Object.keys(e[":@"]).length,n))&&""!==t&&e.add(this.options.textNodeName,t),t=""),t}function H(t,e){if(!t||0===t.length)return!1;for(let i=0;i"){let n,s="";for(let r=e;r",i,`${e} is not closed`);if(t.substring(i+2,r).trim()===e&&(s--,0===s))return{tagContent:t.substring(n,i),i:r};i=r}else if("?"===t[i+1])i=tt(t,"?>",i+1,"StopNode is not closed.");else if("!--"===t.substr(i+1,3))i=tt(t,"--\x3e",i+3,"StopNode is not closed.");else if("!["===t.substr(i+1,2))i=tt(t,"]]>",i,"StopNode is not closed.")-2;else{const n=et(t,i,">");n&&((n&&n.tagName)===e&&"/"!==n.tagExp[n.tagExp.length-1]&&s++,i=n.closeIndex)}}function nt(t,e,i){if(e&&"string"==typeof t){const e=t.trim();return"true"===e||"false"!==e&&function(t,e={}){if(e=Object.assign({},M,e),!t||"string"!=typeof t)return t;let i=t.trim();if(void 0!==e.skipLike&&e.skipLike.test(i))return t;if("0"===t)return 0;if(e.hex&&V.test(i))return function(t){if(parseInt)return parseInt(t,16);if(Number.parseInt)return Number.parseInt(t,16);if(window&&window.parseInt)return window.parseInt(t,16);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}(i);if(isFinite(i)){if(i.includes("e")||i.includes("E"))return function(t,e,i){if(!i.eNotation)return t;const n=e.match(F);if(n){let s=n[1]||"";const r=-1===n[3].indexOf("e")?"E":"e",o=n[2],a=s?t[o.length+1]===r:t[o.length]===r;return o.length>1&&a?t:(1!==o.length||!n[3].startsWith(`.${r}`)&&n[3][0]!==r)&&o.length>0?i.leadingZeros&&!a?(e=(n[1]||"")+n[3],Number(e)):t:Number(e)}return t}(t,i,e);{const s=k.exec(i);if(s){const r=s[1]||"",o=s[2];let a=(n=s[3])&&-1!==n.indexOf(".")?("."===(n=n.replace(/0+$/,""))?n="0":"."===n[0]?n="0"+n:"."===n[n.length-1]&&(n=n.substring(0,n.length-1)),n):n;const h=r?"."===t[o.length+1]:"."===t[o.length];if(!e.leadingZeros&&(o.length>1||1===o.length&&!h))return t;{const n=Number(i),s=String(n);if(0===n)return n;if(-1!==s.search(/[eE]/))return e.eNotation?n:t;if(-1!==i.indexOf("."))return"0"===s||s===a||s===`${r}${a}`?n:t;let h=o?a:i;return o?h===s||r+h===s?n:t:h===s||h===r+s?n:t}}return t}}var n;return function(t,e,i){const n=e===1/0;switch(i.infinity.toLowerCase()){case"null":return null;case"infinity":return e;case"string":return n?"Infinity":"-Infinity";default:return t}}(t,Number(i),e)}(t,i)}return void 0!==t?t:""}function st(t,e,i){const n=Number.parseInt(t,e);return n>=0&&n<=1114111?String.fromCodePoint(n):i+t+";"}function rt(t,e,i,n){if(t){const n=t(e);i===e&&(i=n),e=n}return{tagName:e=ot(e,n),tagExp:i}}function ot(t,e){if(a.includes(t))throw new Error(`[SECURITY] Invalid name: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`);return o.includes(t)?e.onDangerousProperty(t):t}const at=$.getMetaDataSymbol();function ht(t,e){if(!t||"object"!=typeof t)return{};if(!e)return t;const i={};for(const n in t)n.startsWith(e)?i[n.substring(e.length)]=t[n]:i[n]=t[n];return i}function lt(t,e,i){return pt(t,e,i)}function pt(t,e,i){let n;const s={};for(let r=0;r0&&(s[e.textNodeName]=n):void 0!==n&&(s[e.textNodeName]=n),s}function ut(t){const e=Object.keys(t);for(let t=0;t0&&(i="\n");const n=[];if(e.stopNodes&&Array.isArray(e.stopNodes))for(let t=0;te.maxNestedTags)throw new Error("Maximum nested tags exceeded");if(!Array.isArray(t)){if(null!=t){let i=t.toString();return i=vt(i,e),i}return""}for(let a=0;a`,o=!1,n.pop();continue}if(l===e.commentPropName){r+=i+`\x3c!--${h[l][0][e.textNodeName]}--\x3e`,o=!0,n.pop();continue}if("?"===l[0]){const t=yt(h[":@"],e,u),s="?xml"===l?"":i;let a=h[l][0][e.textNodeName];a=0!==a.length?" "+a:"",r+=s+`<${l}${a}${t}?>`,o=!0,n.pop();continue}let c=i;""!==c&&(c+=e.indentBy);const d=i+`<${l}${yt(h[":@"],e,u)}`;let f;f=u?Nt(h[l],e):mt(h[l],e,c,n,s),-1!==e.unpairedTags.indexOf(l)?e.suppressUnpairedNode?r+=d+">":r+=d+"/>":f&&0!==f.length||!e.suppressEmptyNode?f&&f.endsWith(">")?r+=d+`>${f}${i}`:(r+=d+">",f&&""!==i&&(f.includes("/>")||f.includes("`):r+=d+"/>",o=!0,n.pop()}return r}function xt(t,e){if(!t||e.ignoreAttributes)return null;const i={};let n=!1;for(let s in t)Object.prototype.hasOwnProperty.call(t,s)&&(i[s.startsWith(e.attributeNamePrefix)?s.substr(e.attributeNamePrefix.length):s]=t[s],n=!0);return n?i:null}function Nt(t,e){if(!Array.isArray(t))return null!=t?t.toString():"";let i="";for(let n=0;n${n}`:i+=`<${r}${t}/>`}}}return i}function bt(t,e){let i="";if(t&&!e.ignoreAttributes)for(let n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;let s=t[n];!0===s&&e.suppressBooleanAttributes?i+=` ${n.substr(e.attributeNamePrefix.length)}`:i+=` ${n.substr(e.attributeNamePrefix.length)}="${s}"`}return i}function Et(t){const e=Object.keys(t);for(let i=0;i0&&e.processEntities)for(let i=0;i","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1,maxNestedTags:100,jPath:!0};function Pt(t){if(this.options=Object.assign({},Tt,t),this.options.stopNodes&&Array.isArray(this.options.stopNodes)&&(this.options.stopNodes=this.options.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),this.stopNodeExpressions=[],this.options.stopNodes&&Array.isArray(this.options.stopNodes))for(let t=0;t{for(const i of e){if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:()=>!1,this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=Ct),this.processTextOrObjNode=St,this.options.format?(this.indentate=At,this.tagEndChar=">\n",this.newLine="\n"):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}function St(t,e,i,n){const s=this.extractAttributes(t);if(n.push(e,s),this.checkStopNode(n)){const s=this.buildRawContent(t),r=this.buildAttributesForStopNode(t);return n.pop(),this.buildObjectNode(s,e,r,i)}const r=this.j2x(t,i+1,n);return n.pop(),void 0!==t[this.options.textNodeName]&&1===Object.keys(t).length?this.buildTextValNode(t[this.options.textNodeName],e,r.attrStr,i,n):this.buildObjectNode(r.val,e,r.attrStr,i)}function At(t){return this.options.indentBy.repeat(t)}function Ct(t){return!(!t.startsWith(this.options.attributeNamePrefix)||t===this.options.textNodeName)&&t.substr(this.attrPrefixLen)}Pt.prototype.build=function(t){if(this.options.preserveOrder)return gt(t,this.options);{Array.isArray(t)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(t={[this.options.arrayNodeName]:t});const e=new L;return this.j2x(t,0,e).val}},Pt.prototype.j2x=function(t,e,i){let n="",s="";if(this.options.maxNestedTags&&i.getDepth()>=this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");const r=this.options.jPath?i.toString():i,o=this.checkStopNode(i);for(let a in t)if(Object.prototype.hasOwnProperty.call(t,a))if(void 0===t[a])this.isAttribute(a)&&(s+="");else if(null===t[a])this.isAttribute(a)||a===this.options.cdataPropName?s+="":"?"===a[0]?s+=this.indentate(e)+"<"+a+"?"+this.tagEndChar:s+=this.indentate(e)+"<"+a+"/"+this.tagEndChar;else if(t[a]instanceof Date)s+=this.buildTextValNode(t[a],a,"",e,i);else if("object"!=typeof t[a]){const h=this.isAttribute(a);if(h&&!this.ignoreAttributesFn(h,r))n+=this.buildAttrPairStr(h,""+t[a],o);else if(!h)if(a===this.options.textNodeName){let e=this.options.tagValueProcessor(a,""+t[a]);s+=this.replaceEntitiesValue(e)}else{i.push(a);const n=this.checkStopNode(i);if(i.pop(),n){const i=""+t[a];s+=""===i?this.indentate(e)+"<"+a+this.closeTag(a)+this.tagEndChar:this.indentate(e)+"<"+a+">"+i+""+t+"${t}`;else if("object"==typeof t&&null!==t){const n=this.buildRawContent(t),s=this.buildAttributesForStopNode(t);e+=""===n?`<${i}${s}/>`:`<${i}${s}>${n}`}}else if("object"==typeof n&&null!==n){const t=this.buildRawContent(n),s=this.buildAttributesForStopNode(n);e+=""===t?`<${i}${s}/>`:`<${i}${s}>${t}`}else e+=`<${i}>${n}`}return e},Pt.prototype.buildAttributesForStopNode=function(t){if(!t||"object"!=typeof t)return"";let e="";if(this.options.attributesGroupName&&t[this.options.attributesGroupName]){const i=t[this.options.attributesGroupName];for(let t in i){if(!Object.prototype.hasOwnProperty.call(i,t))continue;const n=t.startsWith(this.options.attributeNamePrefix)?t.substring(this.options.attributeNamePrefix.length):t,s=i[t];!0===s&&this.options.suppressBooleanAttributes?e+=" "+n:e+=" "+n+'="'+s+'"'}}else for(let i in t){if(!Object.prototype.hasOwnProperty.call(t,i))continue;const n=this.isAttribute(i);if(n){const s=t[i];!0===s&&this.options.suppressBooleanAttributes?e+=" "+n:e+=" "+n+'="'+s+'"'}}return e},Pt.prototype.buildObjectNode=function(t,e,i,n){if(""===t)return"?"===e[0]?this.indentate(n)+"<"+e+i+"?"+this.tagEndChar:this.indentate(n)+"<"+e+i+this.closeTag(e)+this.tagEndChar;{let s=""+t+s}},Pt.prototype.closeTag=function(t){let e="";return-1!==this.options.unpairedTags.indexOf(t)?this.options.suppressUnpairedNode||(e="/"):e=this.options.suppressEmptyNode?"/":`>`+this.newLine;if(!1!==this.options.commentPropName&&e===this.options.commentPropName)return this.indentate(n)+`\x3c!--${t}--\x3e`+this.newLine;if("?"===e[0])return this.indentate(n)+"<"+e+i+"?"+this.tagEndChar;{let s=this.options.tagValueProcessor(e,t);return s=this.replaceEntitiesValue(s),""===s?this.indentate(n)+"<"+e+i+this.closeTag(e)+this.tagEndChar:this.indentate(n)+"<"+e+i+">"+s+"0&&this.options.processEntities)for(let e=0;e{"use strict";var t={d:(e,n)=>{for(var i in n)t.o(n,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:n[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{XMLBuilder:()=>Bt,XMLParser:()=>Tt,XMLValidator:()=>Ut});const n=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",i=new RegExp("^["+n+"]["+n+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function s(t,e){const n=[];let i=e.exec(t);for(;i;){const s=[];s.startIndex=e.lastIndex-i[0].length;const r=i.length;for(let t=0;t<"!==t[r]){if(u(t[r]))continue;return b("InvalidChar","char '"+t[r]+"' is not expected.",w(t,r))}{let o=r;if(r++,"!"===t[r]){r=c(t,r);continue}{let a=!1;"/"===t[r]&&(a=!0,r++);let h="";for(;r"!==t[r]&&" "!==t[r]&&"\t"!==t[r]&&"\n"!==t[r]&&"\r"!==t[r];r++)h+=t[r];if(h=h.trim(),"/"===h[h.length-1]&&(h=h.substring(0,h.length-1),r--),!E(h)){let e;return e=0===h.trim().length?"Invalid space after '<'.":"Tag '"+h+"' is an invalid name.",b("InvalidTag",e,w(t,r))}const l=g(t,r);if(!1===l)return b("InvalidAttr","Attributes for '"+h+"' have open quote.",w(t,r));let d=l.value;if(r=l.index,"/"===d[d.length-1]){const n=r-d.length;d=d.substring(0,d.length-1);const s=x(d,e);if(!0!==s)return b(s.err.code,s.err.msg,w(t,n+s.err.line));i=!0}else if(a){if(!l.tagClosed)return b("InvalidTag","Closing tag '"+h+"' doesn't have proper closing.",w(t,r));if(d.trim().length>0)return b("InvalidTag","Closing tag '"+h+"' can't have attributes or invalid starting.",w(t,o));if(0===n.length)return b("InvalidTag","Closing tag '"+h+"' has not been opened.",w(t,o));{const e=n.pop();if(h!==e.tagName){let n=w(t,e.tagStartPos);return b("InvalidTag","Expected closing tag '"+e.tagName+"' (opened in line "+n.line+", col "+n.col+") instead of closing tag '"+h+"'.",w(t,o))}0==n.length&&(s=!0)}}else{const a=x(d,e);if(!0!==a)return b(a.err.code,a.err.msg,w(t,r-d.length+a.err.line));if(!0===s)return b("InvalidXml","Multiple possible root nodes found.",w(t,r));-1!==e.unpairedTags.indexOf(h)||n.push({tagName:h,tagStartPos:o}),i=!0}for(r++;r<"===t[r]){if("!"===t[r+1]){r++,r=c(t,r);continue}if("?"!==t[r+1])break;if(r=p(t,++r),r.err)return r}else if("&"===t[r]){const e=N(t,r);if(-1==e)return b("InvalidChar","char '&' is not expected.",w(t,r));r=e}else if(!0===s&&!u(t[r]))return b("InvalidXml","Extra text at the end",w(t,r));"<"===t[r]&&r--}}}return i?1==n.length?b("InvalidTag","Unclosed tag '"+n[0].tagName+"'.",w(t,n[0].tagStartPos)):!(n.length>0)||b("InvalidXml","Invalid '"+JSON.stringify(n.map(t=>t.tagName),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):b("InvalidXml","Start tag expected.",1)}function u(t){return" "===t||"\t"===t||"\n"===t||"\r"===t}function p(t,e){const n=e;for(;e5&&"xml"===i)return b("InvalidXml","XML declaration allowed only at the start of the document.",w(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}continue}return e}function c(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){let n=1;for(e+=8;e<"===t[e])n++;else if(">"===t[e]&&(n--,0===n))break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}const d='"',f="'";function g(t,e){let n="",i="",s=!1;for(;e"===t[e]&&""===i){s=!0;break}n+=t[e]}return""===i&&{value:n,index:e,tagClosed:s}}const m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function x(t,e){const n=s(t,m),i={};for(let t=0;to.includes(t)?"__"+t:t,_={preserveOrder:!1,attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,parseTagValue:!0,parseAttributeValue:!1,trimValues:!0,cdataPropName:!1,numberParseOptions:{hex:!0,leadingZeros:!0,eNotation:!0},tagValueProcessor:function(t,e){return e},attributeValueProcessor:function(t,e){return e},stopNodes:[],alwaysCreateTextNode:!1,isArray:()=>!1,commentPropName:!1,unpairedTags:[],processEntities:!0,htmlEntities:!1,entityDecoder:null,ignoreDeclaration:!1,ignorePiTags:!1,transformTagName:!1,transformAttributeName:!1,updateTag:function(t,e,n){return t},captureMetaData:!1,maxNestedTags:100,strictReservedNames:!0,jPath:!0,onDangerousProperty:S};function A(t,e){if("string"!=typeof t)return;const n=t.toLowerCase();if(o.some(t=>n===t.toLowerCase()))throw new Error(`[SECURITY] Invalid ${e}: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`);if(a.some(t=>n===t.toLowerCase()))throw new Error(`[SECURITY] Invalid ${e}: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`)}function T(t,e){return"boolean"==typeof t?{enabled:t,maxEntitySize:1e4,maxExpansionDepth:1e4,maxTotalExpansions:1/0,maxExpandedLength:1e5,maxEntityCount:1e3,allowedTags:null,tagFilter:null,appliesTo:"all"}:"object"==typeof t&&null!==t?{enabled:!1!==t.enabled,maxEntitySize:Math.max(1,t.maxEntitySize??1e4),maxExpansionDepth:Math.max(1,t.maxExpansionDepth??1e4),maxTotalExpansions:Math.max(1,t.maxTotalExpansions??1/0),maxExpandedLength:Math.max(1,t.maxExpandedLength??1e5),maxEntityCount:Math.max(1,t.maxEntityCount??1e3),allowedTags:t.allowedTags??null,tagFilter:t.tagFilter??null,appliesTo:t.appliesTo??"all"}:T(!0)}const C=function(t){const e=Object.assign({},_,t),n=[{value:e.attributeNamePrefix,name:"attributeNamePrefix"},{value:e.attributesGroupName,name:"attributesGroupName"},{value:e.textNodeName,name:"textNodeName"},{value:e.cdataPropName,name:"cdataPropName"},{value:e.commentPropName,name:"commentPropName"}];for(const{value:t,name:e}of n)t&&A(t,e);return null===e.onDangerousProperty&&(e.onDangerousProperty=S),e.processEntities=T(e.processEntities,e.htmlEntities),e.unpairedTagsSet=new Set(e.unpairedTags),e.stopNodes&&Array.isArray(e.stopNodes)&&(e.stopNodes=e.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),e};let P;P="function"!=typeof Symbol?"@@xmlMetadata":Symbol("XML Node Metadata");class O{constructor(t){this.tagname=t,this.child=[],this[":@"]=Object.create(null)}add(t,e){"__proto__"===t&&(t="#__proto__"),this.child.push({[t]:e})}addChild(t,e){"__proto__"===t.tagname&&(t.tagname="#__proto__"),t[":@"]&&Object.keys(t[":@"]).length>0?this.child.push({[t.tagname]:t.child,":@":t[":@"]}):this.child.push({[t.tagname]:t.child}),void 0!==e&&(this.child[this.child.length-1][P]={startIndex:e})}static getMetaDataSymbol(){return P}}class ${constructor(t){this.suppressValidationErr=!t,this.options=t}readDocType(t,e){const n=Object.create(null);let i=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");{e+=9;let s=1,r=!1,o=!1,a="";for(;e<"!==t[e]||o)if(">"===t[e]){if(o?"-"===t[e-1]&&"-"===t[e-2]&&(o=!1,s--):s--,0===s)break}else"["===t[e]?r=!0:a+=t[e];else{if(r&&D(t,"!ENTITY",e)){let s,r;if(e+=7,[s,r,e]=this.readEntityExp(t,e+1,this.suppressValidationErr),-1===r.indexOf("&")){if(!1!==this.options.enabled&&null!=this.options.maxEntityCount&&i>=this.options.maxEntityCount)throw new Error(`Entity count (${i+1}) exceeds maximum allowed (${this.options.maxEntityCount})`);n[s]=r,i++}}else if(r&&D(t,"!ELEMENT",e)){e+=8;const{index:n}=this.readElementExp(t,e+1);e=n}else if(r&&D(t,"!ATTLIST",e))e+=8;else if(r&&D(t,"!NOTATION",e)){e+=9;const{index:n}=this.readNotationExp(t,e+1,this.suppressValidationErr);e=n}else{if(!D(t,"!--",e))throw new Error("Invalid DOCTYPE");o=!0}s++,a=""}if(0!==s)throw new Error("Unclosed DOCTYPE")}return{entities:n,i:e}}readEntityExp(t,e){const n=e=I(t,e);for(;ethis.options.maxEntitySize)throw new Error(`Entity "${i}" size (${s.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`);return[i,s,--e]}readNotationExp(t,e){const n=e=I(t,e);for(;e{for(;e0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return!1;const n=e[e.length-1];return void 0!==n.values&&t in n.values}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=!0){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class R{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new F(this)}push(t,e=null,n=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const i=this.path.length;this.siblingStacks[i]||(this.siblingStacks[i]=new Map);const s=this.siblingStacks[i],r=n?`${n}:${t}`:t,o=s.get(r)||0;let a=0;for(const t of s.values())a+=t;s.set(r,o+1);const h={tag:t,position:a,counter:o};null!=n&&(h.namespace=n),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;this._pathStringCache=null;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const n=t||this.separator;if(n===this.separator&&!0===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(n);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(n)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const i=t[n];if("deep-wildcard"===i.type){if(n--,n<0)return!0;const i=t[n];let s=!1;for(let t=e;t>=0;t--)if(this._matchSegment(i,this.path[t],t===this.path.length-1)){e=t-1,n--,s=!0;break}if(!s)return!1}else{if(!this._matchSegment(i,this.path[e],e===this.path.length-1))return!1;e--,n--}}return n<0}_matchSegment(t,e,n){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!n)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return!1}if(void 0!==t.position){if(!n)return!1;const i=e.counter??0;if("first"===t.position&&0!==i)return!1;if("odd"===t.position&&i%2!=1)return!1;if("even"===t.position&&i%2!=0)return!1;if("nth"===t.position&&i!==t.positionValue)return!1}return!0}matchesAny(t){return t.matchesAny(this)}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}readOnly(){return this._view}}class G{constructor(t,e={},n){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=n,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let n=0,i="";for(;n",lt:"<",quot:'"'},X={nbsp:" ",copy:"©",reg:"®",trade:"™",mdash:"—",ndash:"–",hellip:"…",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",bull:"•",para:"¶",sect:"§",deg:"°",frac12:"½",frac14:"¼",frac34:"¾"},Y=new Set("!?\\\\/[]$%{}^&*()<>|+");function z(t){if("#"===t[0])throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${t}"`);for(const e of t)if(Y.has(e))throw new Error(`[EntityReplacer] Invalid character '${e}' in entity name: "${t}"`);return t}function q(...t){const e=Object.create(null);for(const n of t)if(n)for(const t of Object.keys(n)){const i=n[t];if("string"==typeof i)e[t]=i;else if(i&&"object"==typeof i&&void 0!==i.val){const n=i.val;"string"==typeof n&&(e[t]=n)}}return e}const Z="external",J="base",K="all",Q=Object.freeze({allow:0,leave:1,remove:2,throw:3}),H=new Set([9,10,13]);class tt{constructor(t={}){var e;this._limit=t.limit||{},this._maxTotalExpansions=this._limit.maxTotalExpansions||0,this._maxExpandedLength=this._limit.maxExpandedLength||0,this._postCheck="function"==typeof t.postCheck?t.postCheck:t=>t,this._limitTiers=(e=this._limit.applyLimitsTo??Z)&&e!==Z?e===K?new Set([K]):e===J?new Set([J]):Array.isArray(e)?new Set(e):new Set([Z]):new Set([Z]),this._numericAllowed=t.numericAllowed??!0,this._baseMap=q(W,t.namedEntities||null),this._externalMap=Object.create(null),this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this._removeSet=new Set(t.remove&&Array.isArray(t.remove)?t.remove:[]),this._leaveSet=new Set(t.leave&&Array.isArray(t.leave)?t.leave:[]);const n=function(t){if(!t)return{xmlVersion:1,onLevel:Q.allow,nullLevel:Q.remove};const e=1.1===t.xmlVersion?1.1:1,n=Q[t.onNCR]??Q.allow,i=Q[t.nullNCR]??Q.remove;return{xmlVersion:e,onLevel:n,nullLevel:Math.max(i,Q.remove)}}(t.ncr);this._ncrXmlVersion=n.xmlVersion,this._ncrOnLevel=n.onLevel,this._ncrNullLevel=n.nullLevel}setExternalEntities(t){if(t)for(const e of Object.keys(t))z(e);this._externalMap=q(t)}addExternalEntity(t,e){z(t),"string"==typeof e&&-1===e.indexOf("&")&&(this._externalMap[t]=e)}addInputEntities(t){this._totalExpansions=0,this._expandedLength=0,this._inputMap=q(t)}reset(){return this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this}setXmlVersion(t){this._ncrXmlVersion=1.1===t?1.1:1}decode(t){if("string"!=typeof t||0===t.length)return t;const e=t,n=[],i=t.length;let s=0,r=0;const o=this._maxTotalExpansions>0,a=this._maxExpandedLength>0,h=o||a;for(;r=i||59!==t.charCodeAt(e)){r++;continue}const l=t.slice(r+1,e);if(0===l.length){r++;continue}let u,p;if(this._removeSet.has(l))u="",void 0===p&&(p=Z);else{if(this._leaveSet.has(l)){r++;continue}if(35===l.charCodeAt(0)){const t=this._resolveNCR(l);if(void 0===t){r++;continue}u=t,p=J}else{const t=this._resolveName(l);u=t?.value,p=t?.tier}}if(void 0!==u){if(r>s&&n.push(t.slice(s,r)),n.push(u),s=e+1,r=s,h&&this._tierCounts(p)){if(o&&(this._totalExpansions++,this._totalExpansions>this._maxTotalExpansions))throw new Error(`[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}`);if(a){const t=u.length-(l.length+2);if(t>0&&(this._expandedLength+=t,this._expandedLength>this._maxExpandedLength))throw new Error(`[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}`)}}}else r++}s=55296&&t<=57343||1===this._ncrXmlVersion&&t>=1&&t<=31&&!H.has(t)?Q.remove:-1}_applyNCRAction(t,e,n){switch(t){case Q.allow:return String.fromCodePoint(n);case Q.remove:return"";case Q.leave:return;case Q.throw:throw new Error(`[EntityDecoder] Prohibited numeric character reference &${e}; (U+${n.toString(16).toUpperCase().padStart(4,"0")})`);default:return String.fromCodePoint(n)}}_resolveNCR(t){const e=t.charCodeAt(1);let n;if(n=120===e||88===e?parseInt(t.slice(2),16):parseInt(t.slice(1),10),Number.isNaN(n)||n<0||n>1114111)return;const i=this._classifyNCR(n);if(!this._numericAllowed&&i0){const n=t.substring(0,e);if("xmlns"!==n)return n}}class it{constructor(t){var e;this.options=t,this.currentNode=null,this.tagsNodeStack=[],this.parseXml=ht,this.parseTextData=st,this.resolveNameSpace=rt,this.buildAttributesMap=at,this.isItStopNode=ct,this.replaceEntitiesValue=ut,this.readStopNodeData=mt,this.saveTextToParentTag=pt,this.addChild=lt,this.ignoreAttributesFn="function"==typeof(e=this.options.ignoreAttributes)?e:Array.isArray(e)?t=>{for(const n of e){if("string"==typeof n&&t===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}}:()=>!1,this.entityExpansionCount=0,this.currentExpandedLength=0;let n={...W};this.options.entityDecoder?this.entityDecoder=this.options.entityDecoder:("object"==typeof this.options.htmlEntities?n=this.options.htmlEntities:!0===this.options.htmlEntities&&(n={...X,...U}),this.entityDecoder=new tt({namedEntities:n,numericAllowed:this.options.htmlEntities,limit:{maxTotalExpansions:this.options.processEntities.maxTotalExpansions,maxExpandedLength:this.options.processEntities.maxExpandedLength,applyLimitsTo:this.options.processEntities.appliesTo}})),this.matcher=new R,this.readonlyMatcher=this.matcher.readOnly(),this.isCurrentNodeStopNode=!1,this.stopNodeExpressionsSet=new B;const i=this.options.stopNodes;if(i&&i.length>0){for(let t=0;t0)){o||(t=this.replaceEntitiesValue(t,e,n));const i=a.jPath?n.toString():n,h=a.tagValueProcessor(e,t,i,s,r);return null==h?t:typeof h!=typeof t||h!==t?h:a.trimValues||t.trim()===t?xt(t,a.parseTagValue,a.numberParseOptions):t}}function rt(t){if(this.options.removeNSPrefix){const e=t.split(":"),n="/"===t.charAt(0)?"/":"";if("xmlns"===e[0])return"";2===e.length&&(t=n+e[1])}return t}const ot=new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?","gm");function at(t,e,n,i=!1){const r=this.options;if(!0===i||!0!==r.ignoreAttributes&&"string"==typeof t){const i=s(t,ot),o=i.length,a={},h=new Array(o);let l=!1;const u={};for(let t=0;t",a,"Closing Tag is not closed.");let r=t.substring(a+2,e).trim();if(s.removeNSPrefix){const t=r.indexOf(":");-1!==t&&(r=r.substr(t+1))}r=Nt(s.transformTagName,r,"",s).tagName,n&&(i=this.saveTextToParentTag(i,n,this.readonlyMatcher));const o=this.matcher.getCurrentTag();if(r&&s.unpairedTagsSet.has(r))throw new Error(`Unpaired tag can not be used as closing tag: `);o&&s.unpairedTagsSet.has(o)&&(this.matcher.pop(),this.tagsNodeStack.pop()),this.matcher.pop(),this.isCurrentNodeStopNode=!1,n=this.tagsNodeStack.pop(),i="",a=e}else if(63===h){let e=gt(t,a,!1,"?>");if(!e)throw new Error("Pi Tag is not closed.");i=this.saveTextToParentTag(i,n,this.readonlyMatcher);const r=this.buildAttributesMap(e.tagExp,this.matcher,e.tagName,!0);if(r){const t=r[this.options.attributeNamePrefix+"version"];this.entityDecoder.setXmlVersion(Number(t)||1)}if(s.ignoreDeclaration&&"?xml"===e.tagName||s.ignorePiTags);else{const t=new O(e.tagName);t.add(s.textNodeName,""),e.tagName!==e.tagExp&&e.attrExpPresent&&!0!==s.ignoreAttributes&&(t[":@"]=r),this.addChild(n,t,this.readonlyMatcher,a)}a=e.closeIndex+1}else if(33===h&&45===t.charCodeAt(a+2)&&45===t.charCodeAt(a+3)){const e=dt(t,"--\x3e",a+4,"Comment is not closed.");if(s.commentPropName){const r=t.substring(a+4,e-2);i=this.saveTextToParentTag(i,n,this.readonlyMatcher),n.add(s.commentPropName,[{[s.textNodeName]:r}])}a=e}else if(33===h&&68===t.charCodeAt(a+2)){const e=r.readDocType(t,a);this.entityDecoder.addInputEntities(e.entities),a=e.i}else if(33===h&&91===t.charCodeAt(a+2)){const e=dt(t,"]]>",a,"CDATA is not closed.")-2,r=t.substring(a+9,e);i=this.saveTextToParentTag(i,n,this.readonlyMatcher);let o=this.parseTextData(r,n.tagname,this.readonlyMatcher,!0,!1,!0,!0);null==o&&(o=""),s.cdataPropName?n.add(s.cdataPropName,[{[s.textNodeName]:r}]):n.add(s.textNodeName,o),a=e+2}else{let r=gt(t,a,s.removeNSPrefix);if(!r){const e=t.substring(Math.max(0,a-50),Math.min(o,a+50));throw new Error(`readTagExp returned undefined at position ${a}. Context: "${e}"`)}let h=r.tagName;const l=r.rawTagName;let u=r.tagExp,p=r.attrExpPresent,c=r.closeIndex;if(({tagName:h,tagExp:u}=Nt(s.transformTagName,h,u,s)),s.strictReservedNames&&(h===s.commentPropName||h===s.cdataPropName||h===s.textNodeName||h===s.attributesGroupName))throw new Error(`Invalid tag name: ${h}`);n&&i&&"!xml"!==n.tagname&&(i=this.saveTextToParentTag(i,n,this.readonlyMatcher,!1));const d=n;d&&s.unpairedTagsSet.has(d.tagname)&&(n=this.tagsNodeStack.pop(),this.matcher.pop());let f=!1;u.length>0&&u.lastIndexOf("/")===u.length-1&&(f=!0,"/"===h[h.length-1]?(h=h.substr(0,h.length-1),u=h):u=u.substr(0,u.length-1),p=h!==u);let g,m=null,x={};g=nt(l),h!==e.tagname&&this.matcher.push(h,{},g),h!==u&&p&&(m=this.buildAttributesMap(u,this.matcher,h),m&&(x=et(m,s))),h!==e.tagname&&(this.isCurrentNodeStopNode=this.isItStopNode());const N=a;if(this.isCurrentNodeStopNode){let e="";if(f)a=r.closeIndex;else if(s.unpairedTagsSet.has(h))a=r.closeIndex;else{const n=this.readStopNodeData(t,l,c+1);if(!n)throw new Error(`Unexpected end of ${l}`);a=n.i,e=n.tagContent}const i=new O(h);m&&(i[":@"]=m),i.add(s.textNodeName,e),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(n,i,this.readonlyMatcher,N)}else{if(f){({tagName:h,tagExp:u}=Nt(s.transformTagName,h,u,s));const t=new O(h);m&&(t[":@"]=m),this.addChild(n,t,this.readonlyMatcher,N),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else{if(s.unpairedTagsSet.has(h)){const t=new O(h);m&&(t[":@"]=m),this.addChild(n,t,this.readonlyMatcher,N),this.matcher.pop(),this.isCurrentNodeStopNode=!1,a=r.closeIndex;continue}{const t=new O(h);if(this.tagsNodeStack.length>s.maxNestedTags)throw new Error("Maximum nested tags exceeded");this.tagsNodeStack.push(n),m&&(t[":@"]=m),this.addChild(n,t,this.readonlyMatcher,N),n=t}}i="",a=c}}}else i+=t[a];return e.child};function lt(t,e,n,i){this.options.captureMetaData||(i=void 0);const s=this.options.jPath?n.toString():n,r=this.options.updateTag(e.tagname,s,e[":@"]);!1===r||("string"==typeof r?(e.tagname=r,t.addChild(e,i)):t.addChild(e,i))}function ut(t,e,n){const i=this.options.processEntities;if(!i||!i.enabled)return t;if(i.allowedTags){const s=this.options.jPath?n.toString():n;if(!(Array.isArray(i.allowedTags)?i.allowedTags.includes(e):i.allowedTags(e,s)))return t}if(i.tagFilter){const s=this.options.jPath?n.toString():n;if(!i.tagFilter(e,s))return t}return this.entityDecoder.decode(t)}function pt(t,e,n,i){return t&&(void 0===i&&(i=0===e.child.length),void 0!==(t=this.parseTextData(t,e.tagname,n,!1,!!e[":@"]&&0!==Object.keys(e[":@"]).length,i))&&""!==t&&e.add(this.options.textNodeName,t),t=""),t}function ct(){return 0!==this.stopNodeExpressionsSet.size&&this.matcher.matchesAny(this.stopNodeExpressionsSet)}function dt(t,e,n,i){const s=t.indexOf(e,n);if(-1===s)throw new Error(i);return s+e.length-1}function ft(t,e,n,i){const s=t.indexOf(e,n);if(-1===s)throw new Error(i);return s}function gt(t,e,n,i=">"){const s=function(t,e,n=">"){let i=0;const s=[],r=t.length,o=n.charCodeAt(0),a=n.length>1?n.charCodeAt(1):-1;for(let n=e;n",n,`${e} is not closed`);if(t.substring(n+2,r).trim()===e&&(s--,0===s))return{tagContent:t.substring(i,n),i:r};n=r}else if(63===r)n=dt(t,"?>",n+1,"StopNode is not closed.");else if(33===r&&45===t.charCodeAt(n+2)&&45===t.charCodeAt(n+3))n=dt(t,"--\x3e",n+3,"StopNode is not closed.");else if(33===r&&91===t.charCodeAt(n+2))n=dt(t,"]]>",n,"StopNode is not closed.")-2;else{const i=gt(t,n,">");i&&((i&&i.tagName)===e&&"/"!==i.tagExp[i.tagExp.length-1]&&s++,n=i.closeIndex)}}}function xt(t,e,n){if(e&&"string"==typeof t){const e=t.trim();return"true"===e||"false"!==e&&function(t,e={}){if(e=Object.assign({},L,e),!t||"string"!=typeof t)return t;let n=t.trim();if(0===n.length)return t;if(void 0!==e.skipLike&&e.skipLike.test(n))return t;if("0"===n)return 0;if(e.hex&&j.test(n))return function(t){if(parseInt)return parseInt(t,16);if(Number.parseInt)return Number.parseInt(t,16);if(window&&window.parseInt)return window.parseInt(t,16);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}(n);if(isFinite(n)){if(n.includes("e")||n.includes("E"))return function(t,e,n){if(!n.eNotation)return t;const i=e.match(k);if(i){let s=i[1]||"";const r=-1===i[3].indexOf("e")?"E":"e",o=i[2],a=s?t[o.length+1]===r:t[o.length]===r;return o.length>1&&a?t:(1!==o.length||!i[3].startsWith(`.${r}`)&&i[3][0]!==r)&&o.length>0?n.leadingZeros&&!a?(e=(i[1]||"")+i[3],Number(e)):t:Number(e)}return t}(t,n,e);{const s=V.exec(n);if(s){const r=s[1]||"",o=s[2];let a=(i=s[3])&&-1!==i.indexOf(".")?("."===(i=i.replace(/0+$/,""))?i="0":"."===i[0]?i="0"+i:"."===i[i.length-1]&&(i=i.substring(0,i.length-1)),i):i;const h=r?"."===t[o.length+1]:"."===t[o.length];if(!e.leadingZeros&&(o.length>1||1===o.length&&!h))return t;{const i=Number(n),s=String(i);if(0===i)return i;if(-1!==s.search(/[eE]/))return e.eNotation?i:t;if(-1!==n.indexOf("."))return"0"===s||s===a||s===`${r}${a}`?i:t;let h=o?a:n;return o?h===s||r+h===s?i:t:h===s||h===r+s?i:t}}return t}}var i;return function(t,e,n){const i=e===1/0;switch(n.infinity.toLowerCase()){case"null":return null;case"infinity":return e;case"string":return i?"Infinity":"-Infinity";default:return t}}(t,Number(n),e)}(t,n)}return void 0!==t?t:""}function Nt(t,e,n,i){if(t){const i=t(e);n===e&&(n=i),e=i}return{tagName:e=bt(e,i),tagExp:n}}function bt(t,e){if(a.includes(t))throw new Error(`[SECURITY] Invalid name: "${t}" is a reserved JavaScript keyword that could cause prototype pollution`);return o.includes(t)?e.onDangerousProperty(t):t}const yt=O.getMetaDataSymbol();function Et(t,e){if(!t||"object"!=typeof t)return{};if(!e)return t;const n={};for(const i in t)i.startsWith(e)?n[i.substring(e.length)]=t[i]:n[i]=t[i];return n}function wt(t,e,n,i){return vt(t,e,n,i)}function vt(t,e,n,i){let s;const r={};for(let o=0;o0&&(r[e.textNodeName]=s):void 0!==s&&(r[e.textNodeName]=s),r}function St(t){const e=Object.keys(t);for(let t=0;t0&&(n="\n");const i=[];if(e.stopNodes&&Array.isArray(e.stopNodes))for(let t=0;te.maxNestedTags)throw new Error("Maximum nested tags exceeded");if(!Array.isArray(t)){if(null!=t){let n=t.toString();return n=Vt(n,e),n}return""}for(let a=0;a/g,"]]]]>`,o=!1,i.pop();continue}if(l===e.commentPropName){const t=h[l][0][e.textNodeName];r+=n+`\x3c!--${String(t).replace(/--/g,"- -").replace(/-$/,"- ")}--\x3e`,o=!0,i.pop();continue}if("?"===l[0]){const t=Mt(h[":@"],e,p),s="?xml"===l?"":n;let a=h[l][0][e.textNodeName];a=0!==a.length?" "+a:"",r+=s+`<${l}${a}${t}?>`,o=!0,i.pop();continue}let c=n;""!==c&&(c+=e.indentBy);const d=n+`<${l}${Mt(h[":@"],e,p)}`;let f;f=p?$t(h[l],e):Pt(h[l],e,c,i,s),-1!==e.unpairedTags.indexOf(l)?e.suppressUnpairedNode?r+=d+">":r+=d+"/>":f&&0!==f.length||!e.suppressEmptyNode?f&&f.endsWith(">")?r+=d+`>${f}${n}`:(r+=d+">",f&&""!==n&&(f.includes("/>")||f.includes("`):r+=d+"/>",o=!0,i.pop()}return r}function Ot(t,e){if(!t||e.ignoreAttributes)return null;const n={};let i=!1;for(let s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[s.startsWith(e.attributeNamePrefix)?s.substr(e.attributeNamePrefix.length):s]=t[s],i=!0);return i?n:null}function $t(t,e){if(!Array.isArray(t))return null!=t?t.toString():"";let n="";for(let i=0;i${i}`:n+=`<${r}${t}/>`}}}return n}function It(t,e){let n="";if(t&&!e.ignoreAttributes)for(let i in t){if(!Object.prototype.hasOwnProperty.call(t,i))continue;let s=t[i];!0===s&&e.suppressBooleanAttributes?n+=` ${i.substr(e.attributeNamePrefix.length)}`:n+=` ${i.substr(e.attributeNamePrefix.length)}="${s}"`}return n}function Dt(t){const e=Object.keys(t);for(let n=0;n0&&e.processEntities)for(let n=0;n","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1,maxNestedTags:100,jPath:!0};function kt(t){if(this.options=Object.assign({},Lt,t),this.options.stopNodes&&Array.isArray(this.options.stopNodes)&&(this.options.stopNodes=this.options.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),this.stopNodeExpressions=[],this.options.stopNodes&&Array.isArray(this.options.stopNodes))for(let t=0;t{for(const n of e){if("string"==typeof n&&t===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}}:()=>!1,this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=Gt),this.processTextOrObjNode=Ft,this.options.format?(this.indentate=Rt,this.tagEndChar=">\n",this.newLine="\n"):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}function Ft(t,e,n,i){const s=this.extractAttributes(t);if(i.push(e,s),this.checkStopNode(i)){const s=this.buildRawContent(t),r=this.buildAttributesForStopNode(t);return i.pop(),this.buildObjectNode(s,e,r,n)}const r=this.j2x(t,n+1,i);return i.pop(),void 0!==t[this.options.textNodeName]&&1===Object.keys(t).length?this.buildTextValNode(t[this.options.textNodeName],e,r.attrStr,n,i):this.buildObjectNode(r.val,e,r.attrStr,n)}function Rt(t){return this.options.indentBy.repeat(t)}function Gt(t){return!(!t.startsWith(this.options.attributeNamePrefix)||t===this.options.textNodeName)&&t.substr(this.attrPrefixLen)}kt.prototype.build=function(t){if(this.options.preserveOrder)return Ct(t,this.options);{Array.isArray(t)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(t={[this.options.arrayNodeName]:t});const e=new R;return this.j2x(t,0,e).val}},kt.prototype.j2x=function(t,e,n){let i="",s="";if(this.options.maxNestedTags&&n.getDepth()>=this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");const r=this.options.jPath?n.toString():n,o=this.checkStopNode(n);for(let a in t)if(Object.prototype.hasOwnProperty.call(t,a))if(void 0===t[a])this.isAttribute(a)&&(s+="");else if(null===t[a])this.isAttribute(a)||a===this.options.cdataPropName?s+="":"?"===a[0]?s+=this.indentate(e)+"<"+a+"?"+this.tagEndChar:s+=this.indentate(e)+"<"+a+"/"+this.tagEndChar;else if(t[a]instanceof Date)s+=this.buildTextValNode(t[a],a,"",e,n);else if("object"!=typeof t[a]){const h=this.isAttribute(a);if(h&&!this.ignoreAttributesFn(h,r))i+=this.buildAttrPairStr(h,""+t[a],o);else if(!h)if(a===this.options.textNodeName){let e=this.options.tagValueProcessor(a,""+t[a]);s+=this.replaceEntitiesValue(e)}else{n.push(a);const i=this.checkStopNode(n);if(n.pop(),i){const n=""+t[a];s+=""===n?this.indentate(e)+"<"+a+this.closeTag(a)+this.tagEndChar:this.indentate(e)+"<"+a+">"+n+""+t+"${t}`;else if("object"==typeof t&&null!==t){const i=this.buildRawContent(t),s=this.buildAttributesForStopNode(t);e+=""===i?`<${n}${s}/>`:`<${n}${s}>${i}`}}else if("object"==typeof i&&null!==i){const t=this.buildRawContent(i),s=this.buildAttributesForStopNode(i);e+=""===t?`<${n}${s}/>`:`<${n}${s}>${t}`}else e+=`<${n}>${i}`}return e},kt.prototype.buildAttributesForStopNode=function(t){if(!t||"object"!=typeof t)return"";let e="";if(this.options.attributesGroupName&&t[this.options.attributesGroupName]){const n=t[this.options.attributesGroupName];for(let t in n){if(!Object.prototype.hasOwnProperty.call(n,t))continue;const i=t.startsWith(this.options.attributeNamePrefix)?t.substring(this.options.attributeNamePrefix.length):t,s=n[t];!0===s&&this.options.suppressBooleanAttributes?e+=" "+i:e+=" "+i+'="'+s+'"'}}else for(let n in t){if(!Object.prototype.hasOwnProperty.call(t,n))continue;const i=this.isAttribute(n);if(i){const s=t[n];!0===s&&this.options.suppressBooleanAttributes?e+=" "+i:e+=" "+i+'="'+s+'"'}}return e},kt.prototype.buildObjectNode=function(t,e,n,i){if(""===t)return"?"===e[0]?this.indentate(i)+"<"+e+n+"?"+this.tagEndChar:this.indentate(i)+"<"+e+n+this.closeTag(e)+this.tagEndChar;{let s=""+t+s}},kt.prototype.closeTag=function(t){let e="";return-1!==this.options.unpairedTags.indexOf(t)?this.options.suppressUnpairedNode||(e="/"):e=this.options.suppressEmptyNode?"/":`>/g,"]]]]>`+this.newLine}if(!1!==this.options.commentPropName&&e===this.options.commentPropName){const e=String(t).replace(/--/g,"- -").replace(/-$/,"- ");return this.indentate(i)+`\x3c!--${e}--\x3e`+this.newLine}if("?"===e[0])return this.indentate(i)+"<"+e+n+"?"+this.tagEndChar;{let s=this.options.tagValueProcessor(e,t);return s=this.replaceEntitiesValue(s),""===s?this.indentate(i)+"<"+e+n+this.closeTag(e)+this.tagEndChar:this.indentate(i)+"<"+e+n+">"+s+"0&&this.options.processEntities)for(let e=0;e + * @updated + * + * Update this file when path-expression-matcher releases a new version. + * Source: https://github.com/NaturalIntelligence/path-expression-matcher + */ + +/** + * Options for creating an Expression + */ +interface ExpressionOptions { + /** + * Path separator character + * @default '.' + */ + separator?: string; +} + +/** + * Parsed segment from an expression pattern + */ +interface Segment { + type: 'tag' | 'deep-wildcard'; + tag?: string; + namespace?: string; + attrName?: string; + attrValue?: string; + position?: 'first' | 'last' | 'odd' | 'even' | 'nth'; + positionValue?: number; +} + +/** + * Expression - Parses and stores a tag pattern expression. + * Patterns are parsed once and stored in an optimized structure for fast matching. + * + * @example + * ```typescript + * const expr = new Expression("root.users.user"); + * const expr2 = new Expression("..user[id]:first"); + * const expr3 = new Expression("root/users/user", { separator: '/' }); + * ``` + * + * Pattern Syntax: + * - `root.users.user` — Match exact path + * - `..user` — Match "user" at any depth (deep wildcard) + * - `user[id]` — Match user tag with "id" attribute + * - `user[id=123]` — Match user tag where id="123" + * - `user:first` — Match first occurrence of user tag + * - `ns::user` — Match user tag with namespace "ns" + * - `ns::user[id]:first` — Combine namespace, attribute, and position + */ +declare class Expression { + readonly pattern: string; + readonly separator: string; + readonly segments: Segment[]; + + constructor(pattern: string, options?: ExpressionOptions); + + get length(): number; + hasDeepWildcard(): boolean; + hasAttributeCondition(): boolean; + hasPositionSelector(): boolean; + toString(): string; +} + +// --------------------------------------------------------------------------- +// MatcherView +// --------------------------------------------------------------------------- + +/** + * A lightweight, live read-only view of a Matcher instance. + * + * Returned by `Matcher.readOnly()`. The same instance is reused across every + * callback invocation — no allocation overhead per call. Reads directly from + * the parent Matcher's internal state so it always reflects the current parser + * position with no copying or freezing. + * + * Mutation methods (`push`, `pop`, `reset`, `updateCurrent`, `restore`) are + * simply absent — misuse is caught at compile time by TypeScript. + * + * This is the type received by all FXP user callbacks when `jPath: false`. + */ +interface MatcherView { + readonly separator: string; + + /** Check if current path matches an Expression. */ + matches(expression: Expression): boolean; + + /** Get current tag name, or `undefined` if path is empty. */ + getCurrentTag(): string | undefined; + + /** Get current namespace, or `undefined` if not present. */ + getCurrentNamespace(): string | undefined; + + /** Get attribute value of the current node. */ + getAttrValue(attrName: string): any; + + /** Check if the current node has a given attribute. */ + hasAttr(attrName: string): boolean; + + /** Sibling position of the current node (child index in parent). */ + getPosition(): number; -type Matcher = unknown; -type Expression = unknown; + /** Occurrence counter of the current tag name at this level. */ + getCounter(): number; + + /** Number of nodes in the current path. */ + getDepth(): number; + + /** Current path as a string (e.g. `"root.users.user"`). */ + toString(separator?: string, includeNamespace?: boolean): string; + + /** Current path as an array of tag names. */ + toArray(): string[]; + + /** + * Create a snapshot of the current state. + * The snapshot can be passed to the real Matcher.restore() if needed. + */ + snapshot(): MatcherSnapshot; +} + +/** + * @deprecated Use {@link MatcherView} instead. + * Alias kept for backward compatibility. + */ +type ReadonlyMatcher = MatcherView; + +/** Internal node structure — exposed via snapshot only. */ +interface PathNode { + tag: string; + namespace?: string; + position: number; + counter: number; + values?: Record; +} + +/** Snapshot of matcher state returned by `snapshot()` and `readOnly().snapshot()`. */ +interface MatcherSnapshot { + path: PathNode[]; + siblingStacks: Map[]; +} + +/********************************************************************** + * + * END of path-expression-matcher relevant typings + * + **********************************************************************/ + + + +// jPath: true → string +// jPath: false → MatcherView +type JPathOrMatcher = string | MatcherView; +type JPathOrExpression = string | Expression; type ProcessEntitiesOptions = { /** @@ -63,9 +216,17 @@ type ProcessEntitiesOptions = { * * Defaults to `null` */ - tagFilter?: ((tagName: string, jPathOrMatcher: string | Matcher) => boolean) | null; + tagFilter?: ((tagName: string, jPathOrMatcher: JPathOrMatcher) => boolean) | null; }; +type EntityDecoderOptions = { + setExternalEntities: (entities: Record) => void; + addInputEntities: (entities: Record) => void; + reset: () => void; + decode: (text: string) => string; + setXmlVersion: (version: string) => void; +} + type X2jOptions = { /** * Preserve the order of tags in resulting JS object @@ -108,7 +269,7 @@ type X2jOptions = { * * Defaults to `true` */ - ignoreAttributes?: boolean | (string | RegExp)[] | ((attrName: string, jPathOrMatcher: string | Matcher) => boolean); + ignoreAttributes?: boolean | (string | RegExp)[] | ((attrName: string, jPathOrMatcher: JPathOrMatcher) => boolean); /** * Whether to remove namespace string from tag and attribute names @@ -175,7 +336,7 @@ type X2jOptions = { * * Defaults to `(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode) => val` */ - tagValueProcessor?: (tagName: string, tagValue: string, jPathOrMatcher: string | Matcher, hasAttributes: boolean, isLeafNode: boolean) => unknown; + tagValueProcessor?: (tagName: string, tagValue: string, jPathOrMatcher: JPathOrMatcher, hasAttributes: boolean, isLeafNode: boolean) => unknown; /** * Control how attribute value should be parsed @@ -188,7 +349,7 @@ type X2jOptions = { * * Defaults to `(attrName, val, jPathOrMatcher) => val` */ - attributeValueProcessor?: (attrName: string, attrValue: string, jPathOrMatcher: string | Matcher) => unknown; + attributeValueProcessor?: (attrName: string, attrValue: string, jPathOrMatcher: JPathOrMatcher) => unknown; /** * Options to pass to `strnum` for parsing numbers @@ -206,7 +367,7 @@ type X2jOptions = { * * Defaults to `[]` */ - stopNodes?: (string | Expression)[]; + stopNodes?: JPathOrExpression[]; /** * List of tags without closing tags @@ -233,7 +394,7 @@ type X2jOptions = { * * Defaults to `() => false` */ - isArray?: (tagName: string, jPathOrMatcher: string | Matcher, isLeafNode: boolean, isAttribute: boolean) => boolean; + isArray?: (tagName: string, jPathOrMatcher: JPathOrMatcher, isLeafNode: boolean, isAttribute: boolean) => boolean; /** * Whether to process default and DOCTYPE entities @@ -252,9 +413,14 @@ type X2jOptions = { * Whether to process HTML entities * * Defaults to `false` + * @deprecated Use `entityDecoder` instead */ htmlEntities?: boolean; + /** + * Custom entity decoder + */ + entityDecoder?: EntityDecoderOptions; /** * Whether to ignore the declaration tag from output * @@ -295,7 +461,7 @@ type X2jOptions = { * * Defaults to `(tagName, jPathOrMatcher, attrs) => tagName` */ - updateTag?: (tagName: string, jPathOrMatcher: string | Matcher, attrs: { [k: string]: string }) => string | boolean; + updateTag?: (tagName: string, jPathOrMatcher: JPathOrMatcher, attrs: { [k: string]: string }) => string | boolean; /** * If true, adds a Symbol to all object nodes, accessible by {@link XMLParser.getMetaDataSymbol} with @@ -477,7 +643,7 @@ type XmlBuilderOptions = { * * Defaults to `[]` */ - stopNodes?: (string | Expression)[]; + stopNodes?: JPathOrExpression[]; /** * Control how tag value should be parsed. Called only if tag value is not empty @@ -560,7 +726,9 @@ declare class XMLParser { declare class XMLValidator { static validate(xmlData: string, options?: validationOptions): true | ValidationError; } - +/** + * @deprecated Use npm package 'fast-xml-builder' instead + */ declare class XMLBuilder { constructor(options?: XmlBuilderOptions); build(jObj: any): string; @@ -589,7 +757,13 @@ declare namespace fxp { strnumOptions, validationOptions, ProcessEntitiesOptions, + Expression, + ReadonlyMatcher, + MatcherView, + JPathOrMatcher, + JPathOrExpression, + EntityDecoderOptions } } -export = fxp; +export = fxp; \ No newline at end of file diff --git a/node_modules/fast-xml-parser/lib/fxp.min.js b/node_modules/fast-xml-parser/lib/fxp.min.js index 8b50a694..f62f7ec5 100644 --- a/node_modules/fast-xml-parser/lib/fxp.min.js +++ b/node_modules/fast-xml-parser/lib/fxp.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.fxp=e():t.fxp=e()}(this,()=>(()=>{"use strict";var t={d:(e,i)=>{for(var r in i)t.o(i,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:i[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{XMLBuilder:()=>It,XMLParser:()=>gt,XMLValidator:()=>jt});var i=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",r=new RegExp("^["+i+"]["+i+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function n(t,e){for(var i=[],r=e.exec(t);r;){var n=[];n.startIndex=e.lastIndex-r[0].length;for(var s=r.length,o=0;o<"!==t[s]){if(l(t[s]))continue;return b("InvalidChar","char '"+t[s]+"' is not expected.",y(t,s))}var o=s;if("!"===t[++s]){s=d(t,s);continue}var a=!1;"/"===t[s]&&(a=!0,s++);for(var u="";s"!==t[s]&&" "!==t[s]&&"\t"!==t[s]&&"\n"!==t[s]&&"\r"!==t[s];s++)u+=t[s];if("/"===(u=u.trim())[u.length-1]&&(u=u.substring(0,u.length-1),s--),!E(u))return b("InvalidTag",0===u.trim().length?"Invalid space after '<'.":"Tag '"+u+"' is an invalid name.",y(t,s));var f=g(t,s);if(!1===f)return b("InvalidAttr","Attributes for '"+u+"' have open quote.",y(t,s));var c=f.value;if(s=f.index,"/"===c[c.length-1]){var m=s-c.length,N=x(c=c.substring(0,c.length-1),e);if(!0!==N)return b(N.err.code,N.err.msg,y(t,m+N.err.line));r=!0}else if(a){if(!f.tagClosed)return b("InvalidTag","Closing tag '"+u+"' doesn't have proper closing.",y(t,s));if(c.trim().length>0)return b("InvalidTag","Closing tag '"+u+"' can't have attributes or invalid starting.",y(t,o));if(0===i.length)return b("InvalidTag","Closing tag '"+u+"' has not been opened.",y(t,o));var w=i.pop();if(u!==w.tagName){var T=y(t,w.tagStartPos);return b("InvalidTag","Expected closing tag '"+w.tagName+"' (opened in line "+T.line+", col "+T.col+") instead of closing tag '"+u+"'.",y(t,o))}0==i.length&&(n=!0)}else{var S=x(c,e);if(!0!==S)return b(S.err.code,S.err.msg,y(t,s-c.length+S.err.line));if(!0===n)return b("InvalidXml","Multiple possible root nodes found.",y(t,s));-1!==e.unpairedTags.indexOf(u)||i.push({tagName:u,tagStartPos:o}),r=!0}for(s++;s<"===t[s]){if("!"===t[s+1]){s=d(t,++s);continue}if("?"!==t[s+1])break;if((s=p(t,++s)).err)return s}else if("&"===t[s]){var P=v(t,s);if(-1==P)return b("InvalidChar","char '&' is not expected.",y(t,s));s=P}else if(!0===n&&!l(t[s]))return b("InvalidXml","Extra text at the end",y(t,s));"<"===t[s]&&s--}return r?1==i.length?b("InvalidTag","Unclosed tag '"+i[0].tagName+"'.",y(t,i[0].tagStartPos)):!(i.length>0)||b("InvalidXml","Invalid '"+JSON.stringify(i.map(function(t){return t.tagName}),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):b("InvalidXml","Start tag expected.",1)}function l(t){return" "===t||"\t"===t||"\n"===t||"\r"===t}function p(t,e){for(var i=e;e5&&"xml"===r)return b("InvalidXml","XML declaration allowed only at the start of the document.",y(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}}return e}function d(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){var i=1;for(e+=8;e<"===t[e])i++;else if(">"===t[e]&&0===--i)break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}var f='"',c="'";function g(t,e){for(var i="",r="",n=!1;e"===t[e]&&""===r){n=!0;break}i+=t[e]}return""===r&&{value:i,index:e,tagClosed:n}}var m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function x(t,e){for(var i=n(t,m),r={},s=0;s0?this.child.push(((i={})[t.tagname]=t.child,i[":@"]=t[":@"],i)):this.child.push(((r={})[t.tagname]=t.child,r)),void 0!==e&&(this.child[this.child.length-1][C]={startIndex:e})},t.getMetaDataSymbol=function(){return C},t}(),j=function(){function t(t){this.suppressValidationErr=!t,this.options=t}var e=t.prototype;return e.readDocType=function(t,e){var i=Object.create(null),r=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");e+=9;for(var n=1,s=!1,o=!1;e<"!==t[e]||o)if(">"===t[e]){if(o?"-"===t[e-1]&&"-"===t[e-2]&&(o=!1,n--):n--,0===n)break}else"["===t[e]?s=!0:t[e];else{if(s&&_(t,"!ENTITY",e)){e+=7;var a=void 0,h=void 0,u=this.readEntityExp(t,e+1,this.suppressValidationErr);if(a=u[0],h=u[1],e=u[2],-1===h.indexOf("&")){if(!1!==this.options.enabled&&null!=this.options.maxEntityCount&&r>=this.options.maxEntityCount)throw new Error("Entity count ("+(r+1)+") exceeds maximum allowed ("+this.options.maxEntityCount+")");var l=a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i[a]={regx:RegExp("&"+l+";","g"),val:h},r++}}else if(s&&_(t,"!ELEMENT",e))e+=8,e=this.readElementExp(t,e+1).index;else if(s&&_(t,"!ATTLIST",e))e+=8;else if(s&&_(t,"!NOTATION",e))e+=9,e=this.readNotationExp(t,e+1,this.suppressValidationErr).index;else{if(!_(t,"!--",e))throw new Error("Invalid DOCTYPE");o=!0}n++}if(0!==n)throw new Error("Unclosed DOCTYPE");return{entities:i,i:e}},e.readEntityExp=function(t,e){for(var i=e=$(t,e);ethis.options.maxEntitySize)throw new Error('Entity "'+r+'" size ('+n.length+") exceeds maximum allowed size ("+this.options.maxEntitySize+")");return[r,n,--e]},e.readNotationExp=function(t,e){for(var i=e=$(t,e);et.length)&&(e=t.length);for(var i=0,r=Array(e);i0&&(this.path[this.path.length-1].values=void 0);const r=this.path.length;this.siblingStacks[r]||(this.siblingStacks[r]=new Map);const n=this.siblingStacks[r],s=i?`${i}:${t}`:t,o=n.get(s)||0;let a=0;for(const t of n.values())a+=t;n.set(s,o+1);const h={tag:t,position:a,counter:o};null!=i&&(h.namespace=i),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0===this.path.length)return;const e=this.path[this.path.length-1];return e.values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const i=t||this.separator;return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(i)}toArray(){return this.path.map(t=>t.tag)}reset(){this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const r=t[i];if("deep-wildcard"===r.type){if(i--,i<0)return!0;const r=t[i];let n=!1;for(let t=e;t>=0;t--){const s=t===this.path.length-1;if(this._matchSegment(r,this.path[t],s)){e=t-1,i--,n=!0;break}}if(!n)return!1}else{const t=e===this.path.length-1;if(!this._matchSegment(r,this.path[e],t))return!1;e--,i--}}return i<0}_matchSegment(t,e,i){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!i)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue){const i=e.values[t.attrName];if(String(i)!==String(t.attrValue))return!1}}if(void 0!==t.position){if(!i)return!1;const r=e.counter??0;if("first"===t.position&&0!==r)return!1;if("odd"===t.position&&r%2!=1)return!1;if("even"===t.position&&r%2!=0)return!1;if("nth"===t.position&&r!==t.positionValue)return!1}return!0}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}}class R{constructor(t,e={}){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let i=0,r="";for(;i0){var i=t.substring(0,e);if("xmlns"!==i)return i}}}var W=function(t){var e;if(this.options=t,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:" "},cent:{regex:/&(cent|#162);/g,val:"¢"},pound:{regex:/&(pound|#163);/g,val:"£"},yen:{regex:/&(yen|#165);/g,val:"¥"},euro:{regex:/&(euro|#8364);/g,val:"€"},copyright:{regex:/&(copy|#169);/g,val:"©"},reg:{regex:/&(reg|#174);/g,val:"®"},inr:{regex:/&(inr|#8377);/g,val:"₹"},num_dec:{regex:/&#([0-9]{1,7});/g,val:function(t,e){return st(e,10,"&#")}},num_hex:{regex:/&#x([0-9a-fA-F]{1,6});/g,val:function(t,e){return st(e,16,"&#x")}}},this.addExternalEntities=Y,this.parseXml=J,this.parseTextData=X,this.resolveNameSpace=z,this.buildAttributesMap=Z,this.isItStopNode=tt,this.replaceEntitiesValue=Q,this.readStopNodeData=rt,this.saveTextToParentTag=H,this.addChild=K,this.ignoreAttributesFn="function"==typeof(e=this.options.ignoreAttributes)?e:Array.isArray(e)?function(t){for(var i,r=function(t,e){var i="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(i)return(i=i.call(t)).next.bind(i);if(Array.isArray(t)||(i=function(t,e){if(t){if("string"==typeof t)return L(t,e);var i={}.toString.call(t).slice(8,-1);return"Object"===i&&t.constructor&&(i=t.constructor.name),"Map"===i||"Set"===i?Array.from(t):"Arguments"===i||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(i)?L(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){i&&(t=i);var r=0;return function(){return r>=t.length?{done:!0}:{done:!1,value:t[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(e);!(i=r()).done;){var n=i.value;if("string"==typeof n&&t===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}}:function(){return!1},this.entityExpansionCount=0,this.currentExpandedLength=0,this.matcher=new G,this.isCurrentNodeStopNode=!1,this.options.stopNodes&&this.options.stopNodes.length>0){this.stopNodeExpressions=[];for(var i=0;i0)){o||(t=this.replaceEntitiesValue(t,e,i));var a=this.options.jPath?i.toString():i,h=this.options.tagValueProcessor(e,t,a,n,s);return null==h?t:typeof h!=typeof t||h!==t?h:this.options.trimValues||t.trim()===t?nt(t,this.options.parseTagValue,this.options.numberParseOptions):t}}function z(t){if(this.options.removeNSPrefix){var e=t.split(":"),i="/"===t.charAt(0)?"/":"";if("xmlns"===e[0])return"";2===e.length&&(t=i+e[1])}return t}var q=new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?","gm");function Z(t,e,i){if(!0!==this.options.ignoreAttributes&&"string"==typeof t){for(var r=n(t,q),s=r.length,o={},a={},h=0;h0&&"object"==typeof e&&e.updateCurrent&&e.updateCurrent(a);for(var d=0;d",s,"Closing Tag is not closed."),a=t.substring(s+2,o).trim();if(this.options.removeNSPrefix){var h=a.indexOf(":");-1!==h&&(a=a.substr(h+1))}a=ot(this.options.transformTagName,a,"",this.options).tagName,i&&(r=this.saveTextToParentTag(r,i,this.matcher));var u=this.matcher.getCurrentTag();if(a&&-1!==this.options.unpairedTags.indexOf(a))throw new Error("Unpaired tag can not be used as closing tag: ");u&&-1!==this.options.unpairedTags.indexOf(u)&&(this.matcher.pop(),this.tagsNodeStack.pop()),this.matcher.pop(),this.isCurrentNodeStopNode=!1,i=this.tagsNodeStack.pop(),r="",s=o}else if("?"===t[s+1]){var l=it(t,s,!1,"?>");if(!l)throw new Error("Pi Tag is not closed.");if(r=this.saveTextToParentTag(r,i,this.matcher),this.options.ignoreDeclaration&&"?xml"===l.tagName||this.options.ignorePiTags);else{var p=new I(l.tagName);p.add(this.options.textNodeName,""),l.tagName!==l.tagExp&&l.attrExpPresent&&(p[":@"]=this.buildAttributesMap(l.tagExp,this.matcher,l.tagName)),this.addChild(i,p,this.matcher,s)}s=l.closeIndex+1}else if("!--"===t.substr(s+1,3)){var d=et(t,"--\x3e",s+4,"Comment is not closed.");if(this.options.commentPropName){var f,c=t.substring(s+4,d-2);r=this.saveTextToParentTag(r,i,this.matcher),i.add(this.options.commentPropName,[(f={},f[this.options.textNodeName]=c,f)])}s=d}else if("!D"===t.substr(s+1,2)){var g=n.readDocType(t,s);this.docTypeEntities=g.entities,s=g.i}else if("!["===t.substr(s+1,2)){var m=et(t,"]]>",s,"CDATA is not closed.")-2,x=t.substring(s+9,m);r=this.saveTextToParentTag(r,i,this.matcher);var v,b=this.parseTextData(x,i.tagname,this.matcher,!0,!1,!0,!0);null==b&&(b=""),this.options.cdataPropName?i.add(this.options.cdataPropName,[(v={},v[this.options.textNodeName]=x,v)]):i.add(this.options.textNodeName,b),s=m+2}else{var N=it(t,s,this.options.removeNSPrefix);if(!N){var E=t.substring(Math.max(0,s-50),Math.min(t.length,s+50));throw new Error("readTagExp returned undefined at position "+s+'. Context: "'+E+'"')}var y=N.tagName,w=N.rawTagName,T=N.tagExp,S=N.attrExpPresent,P=N.closeIndex,A=ot(this.options.transformTagName,y,T,this.options);if(y=A.tagName,T=A.tagExp,this.options.strictReservedNames&&(y===this.options.commentPropName||y===this.options.cdataPropName||y===this.options.textNodeName||y===this.options.attributesGroupName))throw new Error("Invalid tag name: "+y);i&&r&&"!xml"!==i.tagname&&(r=this.saveTextToParentTag(r,i,this.matcher,!1));var C=i;C&&-1!==this.options.unpairedTags.indexOf(C.tagname)&&(i=this.tagsNodeStack.pop(),this.matcher.pop());var O=!1;T.length>0&&T.lastIndexOf("/")===T.length-1&&(O=!0,T="/"===y[y.length-1]?y=y.substr(0,y.length-1):T.substr(0,T.length-1),S=y!==T);var $,_=null;$=B(w),y!==e.tagname&&this.matcher.push(y,{},$),y!==T&&S&&(_=this.buildAttributesMap(T,this.matcher,y))&&U(_,this.options),y!==e.tagname&&(this.isCurrentNodeStopNode=this.isItStopNode(this.stopNodeExpressions,this.matcher));var D=s;if(this.isCurrentNodeStopNode){var V="";if(O)s=N.closeIndex;else if(-1!==this.options.unpairedTags.indexOf(y))s=N.closeIndex;else{var k=this.readStopNodeData(t,w,P+1);if(!k)throw new Error("Unexpected end of "+w);s=k.i,V=k.tagContent}var M=new I(y);_&&(M[":@"]=_),M.add(this.options.textNodeName,V),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(i,M,this.matcher,D)}else{if(O){var F=ot(this.options.transformTagName,y,T,this.options);y=F.tagName,T=F.tagExp;var L=new I(y);_&&(L[":@"]=_),this.addChild(i,L,this.matcher,D),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else{if(-1!==this.options.unpairedTags.indexOf(y)){var G=new I(y);_&&(G[":@"]=_),this.addChild(i,G,this.matcher,D),this.matcher.pop(),this.isCurrentNodeStopNode=!1,s=N.closeIndex;continue}var R=new I(y);if(this.tagsNodeStack.length>this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");this.tagsNodeStack.push(i),_&&(R[":@"]=_),this.addChild(i,R,this.matcher,D),i=R}r="",s=P}}else r+=t[s];return e.child};function K(t,e,i,r){this.options.captureMetaData||(r=void 0);var n=this.options.jPath?i.toString():i,s=this.options.updateTag(e.tagname,n,e[":@"]);!1===s||("string"==typeof s?(e.tagname=s,t.addChild(e,r)):t.addChild(e,r))}function Q(t,e,i){var r=this.options.processEntities;if(!r||!r.enabled)return t;if(r.allowedTags){var n=this.options.jPath?i.toString():i;if(!(Array.isArray(r.allowedTags)?r.allowedTags.includes(e):r.allowedTags(e,n)))return t}if(r.tagFilter){var s=this.options.jPath?i.toString():i;if(!r.tagFilter(e,s))return t}for(var o=0,a=Object.keys(this.docTypeEntities);or.maxTotalExpansions)throw new Error("Entity expansion limit exceeded: "+this.entityExpansionCount+" > "+r.maxTotalExpansions);var p=t.length;if(t=t.replace(u.regx,u.val),r.maxExpandedLength&&(this.currentExpandedLength+=t.length-p,this.currentExpandedLength>r.maxExpandedLength))throw new Error("Total expanded content size exceeded: "+this.currentExpandedLength+" > "+r.maxExpandedLength)}}for(var d=0,f=Object.keys(this.lastEntities);dr.maxTotalExpansions))throw new Error("Entity expansion limit exceeded: "+this.entityExpansionCount+" > "+r.maxTotalExpansions);t=t.replace(g.regex,g.val)}if(-1===t.indexOf("&"))return t;if(this.options.htmlEntities)for(var x=0,v=Object.keys(this.htmlEntities);xr.maxTotalExpansions))throw new Error("Entity expansion limit exceeded: "+this.entityExpansionCount+" > "+r.maxTotalExpansions);t=t.replace(N.regex,N.val)}return t.replace(this.ampEntity.regex,this.ampEntity.val)}function H(t,e,i,r){return t&&(void 0===r&&(r=0===e.child.length),void 0!==(t=this.parseTextData(t,e.tagname,i,!1,!!e[":@"]&&0!==Object.keys(e[":@"]).length,r))&&""!==t&&e.add(this.options.textNodeName,t),t=""),t}function tt(t,e){if(!t||0===t.length)return!1;for(var i=0;i");var n=function(t,e,i){var r;void 0===i&&(i=">");for(var n="",s=e;s",i,e+" is not closed");if(t.substring(i+2,s).trim()===e&&0===--n)return{tagContent:t.substring(r,i),i:s};i=s}else if("?"===t[i+1])i=et(t,"?>",i+1,"StopNode is not closed.");else if("!--"===t.substr(i+1,3))i=et(t,"--\x3e",i+3,"StopNode is not closed.");else if("!["===t.substr(i+1,2))i=et(t,"]]>",i,"StopNode is not closed.")-2;else{var o=it(t,i,">");o&&((o&&o.tagName)===e&&"/"!==o.tagExp[o.tagExp.length-1]&&n++,i=o.closeIndex)}}function nt(t,e,i){if(e&&"string"==typeof t){var r=t.trim();return"true"===r||"false"!==r&&function(t,e={}){if(e=Object.assign({},M,e),!t||"string"!=typeof t)return t;let i=t.trim();if(void 0!==e.skipLike&&e.skipLike.test(i))return t;if("0"===t)return 0;if(e.hex&&V.test(i))return function(t){if(parseInt)return parseInt(t,16);if(Number.parseInt)return Number.parseInt(t,16);if(window&&window.parseInt)return window.parseInt(t,16);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}(i);if(isFinite(i)){if(i.includes("e")||i.includes("E"))return function(t,e,i){if(!i.eNotation)return t;const r=e.match(F);if(r){let n=r[1]||"";const s=-1===r[3].indexOf("e")?"E":"e",o=r[2],a=n?t[o.length+1]===s:t[o.length]===s;return o.length>1&&a?t:(1!==o.length||!r[3].startsWith(`.${s}`)&&r[3][0]!==s)&&o.length>0?i.leadingZeros&&!a?(e=(r[1]||"")+r[3],Number(e)):t:Number(e)}return t}(t,i,e);{const n=k.exec(i);if(n){const s=n[1]||"",o=n[2];let a=(r=n[3])&&-1!==r.indexOf(".")?("."===(r=r.replace(/0+$/,""))?r="0":"."===r[0]?r="0"+r:"."===r[r.length-1]&&(r=r.substring(0,r.length-1)),r):r;const h=s?"."===t[o.length+1]:"."===t[o.length];if(!e.leadingZeros&&(o.length>1||1===o.length&&!h))return t;{const r=Number(i),n=String(r);if(0===r)return r;if(-1!==n.search(/[eE]/))return e.eNotation?r:t;if(-1!==i.indexOf("."))return"0"===n||n===a||n===`${s}${a}`?r:t;let h=o?a:i;return o?h===n||s+h===n?r:t:h===n||h===s+n?r:t}}return t}}var r;return function(t,e,i){const r=e===1/0;switch(i.infinity.toLowerCase()){case"null":return null;case"infinity":return e;case"string":return r?"Infinity":"-Infinity";default:return t}}(t,Number(i),e)}(t,i)}return void 0!==t?t:""}function st(t,e,i){var r=Number.parseInt(t,e);return r>=0&&r<=1114111?String.fromCodePoint(r):i+t+";"}function ot(t,e,i,r){if(t){var n=t(e);i===e&&(i=n),e=n}return{tagName:e=at(e,r),tagExp:i}}function at(t,e){if(a.includes(t))throw new Error('[SECURITY] Invalid name: "'+t+'" is a reserved JavaScript keyword that could cause prototype pollution');return o.includes(t)?e.onDangerousProperty(t):t}var ht=I.getMetaDataSymbol();function ut(t,e){if(!t||"object"!=typeof t)return{};if(!e)return t;var i={};for(var r in t)r.startsWith(e)?i[r.substring(e.length)]=t[r]:i[r]=t[r];return i}function lt(t,e,i){return pt(t,e,i)}function pt(t,e,i){for(var r,n={},s=0;s0&&(n[e.textNodeName]=r):void 0!==r&&(n[e.textNodeName]=r),n}function dt(t){for(var e=Object.keys(t),i=0;i0&&(i="\n");const r=[];if(e.stopNodes&&Array.isArray(e.stopNodes))for(let t=0;te.maxNestedTags)throw new Error("Maximum nested tags exceeded");if(!Array.isArray(t)){if(null!=t){let i=t.toString();return i=Tt(i,e),i}return""}for(let a=0;a`,o=!1,r.pop();continue}if(u===e.commentPropName){s+=i+`\x3c!--${h[u][0][e.textNodeName]}--\x3e`,o=!0,r.pop();continue}if("?"===u[0]){const t=yt(h[":@"],e,p),n="?xml"===u?"":i;let a=h[u][0][e.textNodeName];a=0!==a.length?" "+a:"",s+=n+`<${u}${a}${t}?>`,o=!0,r.pop();continue}let d=i;""!==d&&(d+=e.indentBy);const f=i+`<${u}${yt(h[":@"],e,p)}`;let c;c=p?bt(h[u],e):xt(h[u],e,d,r,n),-1!==e.unpairedTags.indexOf(u)?e.suppressUnpairedNode?s+=f+">":s+=f+"/>":c&&0!==c.length||!e.suppressEmptyNode?c&&c.endsWith(">")?s+=f+`>${c}${i}`:(s+=f+">",c&&""!==i&&(c.includes("/>")||c.includes("`):s+=f+"/>",o=!0,r.pop()}return s}function vt(t,e){if(!t||e.ignoreAttributes)return null;const i={};let r=!1;for(let n in t)Object.prototype.hasOwnProperty.call(t,n)&&(i[n.startsWith(e.attributeNamePrefix)?n.substr(e.attributeNamePrefix.length):n]=t[n],r=!0);return r?i:null}function bt(t,e){if(!Array.isArray(t))return null!=t?t.toString():"";let i="";for(let r=0;r${r}`:i+=`<${s}${t}/>`}}}return i}function Nt(t,e){let i="";if(t&&!e.ignoreAttributes)for(let r in t){if(!Object.prototype.hasOwnProperty.call(t,r))continue;let n=t[r];!0===n&&e.suppressBooleanAttributes?i+=` ${r.substr(e.attributeNamePrefix.length)}`:i+=` ${r.substr(e.attributeNamePrefix.length)}="${n}"`}return i}function Et(t){const e=Object.keys(t);for(let i=0;i0&&e.processEntities)for(let i=0;i","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1,maxNestedTags:100,jPath:!0};function Pt(t){if(this.options=Object.assign({},St,t),this.options.stopNodes&&Array.isArray(this.options.stopNodes)&&(this.options.stopNodes=this.options.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),this.stopNodeExpressions=[],this.options.stopNodes&&Array.isArray(this.options.stopNodes))for(let t=0;t{for(const i of e){if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:()=>!1,this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=Ot),this.processTextOrObjNode=At,this.options.format?(this.indentate=Ct,this.tagEndChar=">\n",this.newLine="\n"):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}function At(t,e,i,r){const n=this.extractAttributes(t);if(r.push(e,n),this.checkStopNode(r)){const n=this.buildRawContent(t),s=this.buildAttributesForStopNode(t);return r.pop(),this.buildObjectNode(n,e,s,i)}const s=this.j2x(t,i+1,r);return r.pop(),void 0!==t[this.options.textNodeName]&&1===Object.keys(t).length?this.buildTextValNode(t[this.options.textNodeName],e,s.attrStr,i,r):this.buildObjectNode(s.val,e,s.attrStr,i)}function Ct(t){return this.options.indentBy.repeat(t)}function Ot(t){return!(!t.startsWith(this.options.attributeNamePrefix)||t===this.options.textNodeName)&&t.substr(this.attrPrefixLen)}Pt.prototype.build=function(t){if(this.options.preserveOrder)return mt(t,this.options);{Array.isArray(t)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(t={[this.options.arrayNodeName]:t});const e=new G;return this.j2x(t,0,e).val}},Pt.prototype.j2x=function(t,e,i){let r="",n="";if(this.options.maxNestedTags&&i.getDepth()>=this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");const s=this.options.jPath?i.toString():i,o=this.checkStopNode(i);for(let a in t)if(Object.prototype.hasOwnProperty.call(t,a))if(void 0===t[a])this.isAttribute(a)&&(n+="");else if(null===t[a])this.isAttribute(a)||a===this.options.cdataPropName?n+="":"?"===a[0]?n+=this.indentate(e)+"<"+a+"?"+this.tagEndChar:n+=this.indentate(e)+"<"+a+"/"+this.tagEndChar;else if(t[a]instanceof Date)n+=this.buildTextValNode(t[a],a,"",e,i);else if("object"!=typeof t[a]){const h=this.isAttribute(a);if(h&&!this.ignoreAttributesFn(h,s))r+=this.buildAttrPairStr(h,""+t[a],o);else if(!h)if(a===this.options.textNodeName){let e=this.options.tagValueProcessor(a,""+t[a]);n+=this.replaceEntitiesValue(e)}else{i.push(a);const r=this.checkStopNode(i);if(i.pop(),r){const i=""+t[a];n+=""===i?this.indentate(e)+"<"+a+this.closeTag(a)+this.tagEndChar:this.indentate(e)+"<"+a+">"+i+""+t+"${t}`;else if("object"==typeof t&&null!==t){const r=this.buildRawContent(t),n=this.buildAttributesForStopNode(t);e+=""===r?`<${i}${n}/>`:`<${i}${n}>${r}`}}else if("object"==typeof r&&null!==r){const t=this.buildRawContent(r),n=this.buildAttributesForStopNode(r);e+=""===t?`<${i}${n}/>`:`<${i}${n}>${t}`}else e+=`<${i}>${r}`}return e},Pt.prototype.buildAttributesForStopNode=function(t){if(!t||"object"!=typeof t)return"";let e="";if(this.options.attributesGroupName&&t[this.options.attributesGroupName]){const i=t[this.options.attributesGroupName];for(let t in i){if(!Object.prototype.hasOwnProperty.call(i,t))continue;const r=t.startsWith(this.options.attributeNamePrefix)?t.substring(this.options.attributeNamePrefix.length):t,n=i[t];!0===n&&this.options.suppressBooleanAttributes?e+=" "+r:e+=" "+r+'="'+n+'"'}}else for(let i in t){if(!Object.prototype.hasOwnProperty.call(t,i))continue;const r=this.isAttribute(i);if(r){const n=t[i];!0===n&&this.options.suppressBooleanAttributes?e+=" "+r:e+=" "+r+'="'+n+'"'}}return e},Pt.prototype.buildObjectNode=function(t,e,i,r){if(""===t)return"?"===e[0]?this.indentate(r)+"<"+e+i+"?"+this.tagEndChar:this.indentate(r)+"<"+e+i+this.closeTag(e)+this.tagEndChar;{let n=""+t+n}},Pt.prototype.closeTag=function(t){let e="";return-1!==this.options.unpairedTags.indexOf(t)?this.options.suppressUnpairedNode||(e="/"):e=this.options.suppressEmptyNode?"/":`>`+this.newLine;if(!1!==this.options.commentPropName&&e===this.options.commentPropName)return this.indentate(r)+`\x3c!--${t}--\x3e`+this.newLine;if("?"===e[0])return this.indentate(r)+"<"+e+i+"?"+this.tagEndChar;{let n=this.options.tagValueProcessor(e,t);return n=this.replaceEntitiesValue(n),""===n?this.indentate(r)+"<"+e+i+this.closeTag(e)+this.tagEndChar:this.indentate(r)+"<"+e+i+">"+n+"0&&this.options.processEntities)for(let e=0;e(()=>{"use strict";var t={d:(e,r)=>{for(var i in r)t.o(r,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:r[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{XMLBuilder:()=>Wt,XMLParser:()=>Pt,XMLValidator:()=>Xt});var r=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",i=new RegExp("^["+r+"]["+r+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function n(t,e){for(var r=[],i=e.exec(t);i;){var n=[];n.startIndex=e.lastIndex-i[0].length;for(var s=i.length,a=0;a<"!==t[s]){if(u(t[s]))continue;return b("InvalidChar","char '"+t[s]+"' is not expected.",E(t,s))}var a=s;if("!"===t[++s]){s=d(t,s);continue}var o=!1;"/"===t[s]&&(o=!0,s++);for(var l="";s"!==t[s]&&" "!==t[s]&&"\t"!==t[s]&&"\n"!==t[s]&&"\r"!==t[s];s++)l+=t[s];if("/"===(l=l.trim())[l.length-1]&&(l=l.substring(0,l.length-1),s--),!y(l))return b("InvalidTag",0===l.trim().length?"Invalid space after '<'.":"Tag '"+l+"' is an invalid name.",E(t,s));var c=g(t,s);if(!1===c)return b("InvalidAttr","Attributes for '"+l+"' have open quote.",E(t,s));var f=c.value;if(s=c.index,"/"===f[f.length-1]){var m=s-f.length,N=v(f=f.substring(0,f.length-1),e);if(!0!==N)return b(N.err.code,N.err.msg,E(t,m+N.err.line));i=!0}else if(o){if(!c.tagClosed)return b("InvalidTag","Closing tag '"+l+"' doesn't have proper closing.",E(t,s));if(f.trim().length>0)return b("InvalidTag","Closing tag '"+l+"' can't have attributes or invalid starting.",E(t,a));if(0===r.length)return b("InvalidTag","Closing tag '"+l+"' has not been opened.",E(t,a));var w=r.pop();if(l!==w.tagName){var S=E(t,w.tagStartPos);return b("InvalidTag","Expected closing tag '"+w.tagName+"' (opened in line "+S.line+", col "+S.col+") instead of closing tag '"+l+"'.",E(t,a))}0==r.length&&(n=!0)}else{var _=v(f,e);if(!0!==_)return b(_.err.code,_.err.msg,E(t,s-f.length+_.err.line));if(!0===n)return b("InvalidXml","Multiple possible root nodes found.",E(t,s));-1!==e.unpairedTags.indexOf(l)||r.push({tagName:l,tagStartPos:a}),i=!0}for(s++;s<"===t[s]){if("!"===t[s+1]){s=d(t,++s);continue}if("?"!==t[s+1])break;if((s=p(t,++s)).err)return s}else if("&"===t[s]){var A=x(t,s);if(-1==A)return b("InvalidChar","char '&' is not expected.",E(t,s));s=A}else if(!0===n&&!u(t[s]))return b("InvalidXml","Extra text at the end",E(t,s));"<"===t[s]&&s--}return i?1==r.length?b("InvalidTag","Unclosed tag '"+r[0].tagName+"'.",E(t,r[0].tagStartPos)):!(r.length>0)||b("InvalidXml","Invalid '"+JSON.stringify(r.map(function(t){return t.tagName}),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):b("InvalidXml","Start tag expected.",1)}function u(t){return" "===t||"\t"===t||"\n"===t||"\r"===t}function p(t,e){for(var r=e;e5&&"xml"===i)return b("InvalidXml","XML declaration allowed only at the start of the document.",E(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}}return e}function d(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){var r=1;for(e+=8;e<"===t[e])r++;else if(">"===t[e]&&0===--r)break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}var c='"',f="'";function g(t,e){for(var r="",i="",n=!1;e"===t[e]&&""===i){n=!0;break}r+=t[e]}return""===i&&{value:r,index:e,tagClosed:n}}var m=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function v(t,e){for(var r=n(t,m),i={},s=0;s0?this.child.push(((r={})[t.tagname]=t.child,r[":@"]=t[":@"],r)):this.child.push(((i={})[t.tagname]=t.child,i)),void 0!==e&&(this.child[this.child.length-1][C]={startIndex:e})},t.getMetaDataSymbol=function(){return C},t}(),I=function(){function t(t){this.suppressValidationErr=!t,this.options=t}var e=t.prototype;return e.readDocType=function(t,e){var r=Object.create(null),i=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");e+=9;for(var n=1,s=!1,a=!1;e<"!==t[e]||a)if(">"===t[e]){if(a?"-"===t[e-1]&&"-"===t[e-2]&&(a=!1,n--):n--,0===n)break}else"["===t[e]?s=!0:t[e];else{if(s&&D(t,"!ENTITY",e)){e+=7;var o,h=void 0,l=this.readEntityExp(t,e+1,this.suppressValidationErr);if(o=l[0],h=l[1],e=l[2],-1===h.indexOf("&")){if(!1!==this.options.enabled&&null!=this.options.maxEntityCount&&i>=this.options.maxEntityCount)throw new Error("Entity count ("+(i+1)+") exceeds maximum allowed ("+this.options.maxEntityCount+")");r[o]=h,i++}}else if(s&&D(t,"!ELEMENT",e))e+=8,e=this.readElementExp(t,e+1).index;else if(s&&D(t,"!ATTLIST",e))e+=8;else if(s&&D(t,"!NOTATION",e))e+=9,e=this.readNotationExp(t,e+1,this.suppressValidationErr).index;else{if(!D(t,"!--",e))throw new Error("Invalid DOCTYPE");a=!0}n++}if(0!==n)throw new Error("Unclosed DOCTYPE");return{entities:r,i:e}},e.readEntityExp=function(t,e){for(var r=e=j(t,e);ethis.options.maxEntitySize)throw new Error('Entity "'+i+'" size ('+n.length+") exceeds maximum allowed size ("+this.options.maxEntitySize+")");return[i,n,--e]},e.readNotationExp=function(t,e){for(var r=e=j(t,e);et.length)&&(e=t.length);for(var r=0,i=Array(e);r0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return!1;const r=e[e.length-1];return void 0!==r.values&&t in r.values}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=!0){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class G{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new R(this)}push(t,e=null,r=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const i=this.path.length;this.siblingStacks[i]||(this.siblingStacks[i]=new Map);const n=this.siblingStacks[i],s=r?`${r}:${t}`:t,a=n.get(s)||0;let o=0;for(const t of n.values())o+=t;n.set(s,a+1);const h={tag:t,position:o,counter:a};null!=r&&(h.namespace=r),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;this._pathStringCache=null;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const r=t||this.separator;if(r===this.separator&&!0===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(r);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(r)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const i=t[r];if("deep-wildcard"===i.type){if(r--,r<0)return!0;const i=t[r];let n=!1;for(let t=e;t>=0;t--)if(this._matchSegment(i,this.path[t],t===this.path.length-1)){e=t-1,r--,n=!0;break}if(!n)return!1}else{if(!this._matchSegment(i,this.path[e],e===this.path.length-1))return!1;e--,r--}}return r<0}_matchSegment(t,e,r){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!r)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return!1}if(void 0!==t.position){if(!r)return!1;const i=e.counter??0;if("first"===t.position&&0!==i)return!1;if("odd"===t.position&&i%2!=1)return!1;if("even"===t.position&&i%2!=0)return!1;if("nth"===t.position&&i!==t.positionValue)return!1}return!0}matchesAny(t){return t.matchesAny(this)}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}readOnly(){return this._view}}class U{constructor(t,e={},r){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=r,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let r=0,i="";for(;r",lt:"<",quot:'"'},Y={nbsp:" ",copy:"©",reg:"®",trade:"™",mdash:"—",ndash:"–",hellip:"…",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",bull:"•",para:"¶",sect:"§",deg:"°",frac12:"½",frac14:"¼",frac34:"¾"},z=new Set("!?\\\\/[]$%{}^&*()<>|+");function q(t){if("#"===t[0])throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${t}"`);for(const e of t)if(z.has(e))throw new Error(`[EntityReplacer] Invalid character '${e}' in entity name: "${t}"`);return t}function Z(...t){const e=Object.create(null);for(const r of t)if(r)for(const t of Object.keys(r)){const i=r[t];if("string"==typeof i)e[t]=i;else if(i&&"object"==typeof i&&void 0!==i.val){const r=i.val;"string"==typeof r&&(e[t]=r)}}return e}const J="external",K="base",Q="all",H=Object.freeze({allow:0,leave:1,remove:2,throw:3}),tt=new Set([9,10,13]);class et{constructor(t={}){var e;this._limit=t.limit||{},this._maxTotalExpansions=this._limit.maxTotalExpansions||0,this._maxExpandedLength=this._limit.maxExpandedLength||0,this._postCheck="function"==typeof t.postCheck?t.postCheck:t=>t,this._limitTiers=(e=this._limit.applyLimitsTo??J)&&e!==J?e===Q?new Set([Q]):e===K?new Set([K]):Array.isArray(e)?new Set(e):new Set([J]):new Set([J]),this._numericAllowed=t.numericAllowed??!0,this._baseMap=Z(X,t.namedEntities||null),this._externalMap=Object.create(null),this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this._removeSet=new Set(t.remove&&Array.isArray(t.remove)?t.remove:[]),this._leaveSet=new Set(t.leave&&Array.isArray(t.leave)?t.leave:[]);const r=function(t){if(!t)return{xmlVersion:1,onLevel:H.allow,nullLevel:H.remove};const e=1.1===t.xmlVersion?1.1:1,r=H[t.onNCR]??H.allow,i=H[t.nullNCR]??H.remove;return{xmlVersion:e,onLevel:r,nullLevel:Math.max(i,H.remove)}}(t.ncr);this._ncrXmlVersion=r.xmlVersion,this._ncrOnLevel=r.onLevel,this._ncrNullLevel=r.nullLevel}setExternalEntities(t){if(t)for(const e of Object.keys(t))q(e);this._externalMap=Z(t)}addExternalEntity(t,e){q(t),"string"==typeof e&&-1===e.indexOf("&")&&(this._externalMap[t]=e)}addInputEntities(t){this._totalExpansions=0,this._expandedLength=0,this._inputMap=Z(t)}reset(){return this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this}setXmlVersion(t){this._ncrXmlVersion=1.1===t?1.1:1}decode(t){if("string"!=typeof t||0===t.length)return t;const e=t,r=[],i=t.length;let n=0,s=0;const a=this._maxTotalExpansions>0,o=this._maxExpandedLength>0,h=a||o;for(;s=i||59!==t.charCodeAt(e)){s++;continue}const l=t.slice(s+1,e);if(0===l.length){s++;continue}let u,p;if(this._removeSet.has(l))u="",void 0===p&&(p=J);else{if(this._leaveSet.has(l)){s++;continue}if(35===l.charCodeAt(0)){const t=this._resolveNCR(l);if(void 0===t){s++;continue}u=t,p=K}else{const t=this._resolveName(l);u=t?.value,p=t?.tier}}if(void 0!==u){if(s>n&&r.push(t.slice(n,s)),r.push(u),n=e+1,s=n,h&&this._tierCounts(p)){if(a&&(this._totalExpansions++,this._totalExpansions>this._maxTotalExpansions))throw new Error(`[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}`);if(o){const t=u.length-(l.length+2);if(t>0&&(this._expandedLength+=t,this._expandedLength>this._maxExpandedLength))throw new Error(`[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}`)}}}else s++}n=55296&&t<=57343||1===this._ncrXmlVersion&&t>=1&&t<=31&&!tt.has(t)?H.remove:-1}_applyNCRAction(t,e,r){switch(t){case H.allow:return String.fromCodePoint(r);case H.remove:return"";case H.leave:return;case H.throw:throw new Error(`[EntityDecoder] Prohibited numeric character reference &${e}; (U+${r.toString(16).toUpperCase().padStart(4,"0")})`);default:return String.fromCodePoint(r)}}_resolveNCR(t){const e=t.charCodeAt(1);let r;if(r=120===e||88===e?parseInt(t.slice(2),16):parseInt(t.slice(1),10),Number.isNaN(r)||r<0||r>1114111)return;const i=this._classifyNCR(r);if(!this._numericAllowed&&i0){var r=t.substring(0,e);if("xmlns"!==r)return r}}}var st=function(t){var e;this.options=t,this.currentNode=null,this.tagsNodeStack=[],this.parseXml=ut,this.parseTextData=at,this.resolveNameSpace=ot,this.buildAttributesMap=lt,this.isItStopNode=ft,this.replaceEntitiesValue=dt,this.readStopNodeData=xt,this.saveTextToParentTag=ct,this.addChild=pt,this.ignoreAttributesFn="function"==typeof(e=this.options.ignoreAttributes)?e:Array.isArray(e)?function(t){for(var r,i=function(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(r)return(r=r.call(t)).next.bind(r);if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return F(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?F(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var i=0;return function(){return i>=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(e);!(r=i()).done;){var n=r.value;if("string"==typeof n&&t===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}}:function(){return!1},this.entityExpansionCount=0,this.currentExpandedLength=0;var r=rt({},X);this.options.entityDecoder?this.entityDecoder=this.options.entityDecoder:("object"==typeof this.options.htmlEntities?r=this.options.htmlEntities:!0===this.options.htmlEntities&&(r=rt({},Y,W)),this.entityDecoder=new et({namedEntities:r,numericAllowed:this.options.htmlEntities,limit:{maxTotalExpansions:this.options.processEntities.maxTotalExpansions,maxExpandedLength:this.options.processEntities.maxExpandedLength,applyLimitsTo:this.options.processEntities.appliesTo}})),this.matcher=new G,this.readonlyMatcher=this.matcher.readOnly(),this.isCurrentNodeStopNode=!1,this.stopNodeExpressionsSet=new B;var i=this.options.stopNodes;if(i&&i.length>0){for(var n=0;n0)){a||(t=this.replaceEntitiesValue(t,e,r));var h=o.jPath?r.toString():r,l=o.tagValueProcessor(e,t,h,n,s);return null==l?t:typeof l!=typeof t||l!==t?l:o.trimValues||t.trim()===t?bt(t,o.parseTagValue,o.numberParseOptions):t}}function ot(t){if(this.options.removeNSPrefix){var e=t.split(":"),r="/"===t.charAt(0)?"/":"";if("xmlns"===e[0])return"";2===e.length&&(t=r+e[1])}return t}var ht=new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?","gm");function lt(t,e,r,i){void 0===i&&(i=!1);var s=this.options;if(!0===i||!0!==s.ignoreAttributes&&"string"==typeof t){for(var a=n(t,ht),o=a.length,h={},l=new Array(o),u=!1,p={},d=0;d",o,"Closing Tag is not closed."),u=t.substring(o+2,l).trim();if(n.removeNSPrefix){var p=u.indexOf(":");-1!==p&&(u=u.substr(p+1))}u=Nt(n.transformTagName,u,"",n).tagName,r&&(i=this.saveTextToParentTag(i,r,this.readonlyMatcher));var d=this.matcher.getCurrentTag();if(u&&n.unpairedTagsSet.has(u))throw new Error("Unpaired tag can not be used as closing tag: ");d&&n.unpairedTagsSet.has(d)&&(this.matcher.pop(),this.tagsNodeStack.pop()),this.matcher.pop(),this.isCurrentNodeStopNode=!1,r=this.tagsNodeStack.pop(),i="",o=l}else if(63===h){var c=vt(t,o,!1,"?>");if(!c)throw new Error("Pi Tag is not closed.");i=this.saveTextToParentTag(i,r,this.readonlyMatcher);var f=this.buildAttributesMap(c.tagExp,this.matcher,c.tagName,!0);if(f){var g=f[this.options.attributeNamePrefix+"version"];this.entityDecoder.setXmlVersion(Number(g)||1)}if(n.ignoreDeclaration&&"?xml"===c.tagName||n.ignorePiTags);else{var m=new O(c.tagName);m.add(n.textNodeName,""),c.tagName!==c.tagExp&&c.attrExpPresent&&!0!==n.ignoreAttributes&&(m[":@"]=f),this.addChild(r,m,this.readonlyMatcher,o)}o=c.closeIndex+1}else if(33===h&&45===t.charCodeAt(o+2)&&45===t.charCodeAt(o+3)){var v=gt(t,"--\x3e",o+4,"Comment is not closed.");if(n.commentPropName){var x,b=t.substring(o+4,v-2);i=this.saveTextToParentTag(i,r,this.readonlyMatcher),r.add(n.commentPropName,[(x={},x[n.textNodeName]=b,x)])}o=v}else if(33===h&&68===t.charCodeAt(o+2)){var N=s.readDocType(t,o);this.entityDecoder.addInputEntities(N.entities),o=N.i}else if(33===h&&91===t.charCodeAt(o+2)){var y=gt(t,"]]>",o,"CDATA is not closed.")-2,E=t.substring(o+9,y);i=this.saveTextToParentTag(i,r,this.readonlyMatcher);var w,S=this.parseTextData(E,r.tagname,this.readonlyMatcher,!0,!1,!0,!0);null==S&&(S=""),n.cdataPropName?r.add(n.cdataPropName,[(w={},w[n.textNodeName]=E,w)]):r.add(n.textNodeName,S),o=y+2}else{var _=vt(t,o,n.removeNSPrefix);if(!_){var A=t.substring(Math.max(0,o-50),Math.min(a,o+50));throw new Error("readTagExp returned undefined at position "+o+'. Context: "'+A+'"')}var T=_.tagName,C=_.rawTagName,P=_.tagExp,j=_.attrExpPresent,D=_.closeIndex,$=Nt(n.transformTagName,T,P,n);if(T=$.tagName,P=$.tagExp,n.strictReservedNames&&(T===n.commentPropName||T===n.cdataPropName||T===n.textNodeName||T===n.attributesGroupName))throw new Error("Invalid tag name: "+T);r&&i&&"!xml"!==r.tagname&&(i=this.saveTextToParentTag(i,r,this.readonlyMatcher,!1));var M=r;M&&n.unpairedTagsSet.has(M.tagname)&&(r=this.tagsNodeStack.pop(),this.matcher.pop());var V=!1;P.length>0&&P.lastIndexOf("/")===P.length-1&&(V=!0,P="/"===T[T.length-1]?T=T.substr(0,T.length-1):P.substr(0,P.length-1),j=T!==P);var L,k=null;L=nt(C),T!==e.tagname&&this.matcher.push(T,{},L),T!==P&&j&&(k=this.buildAttributesMap(P,this.matcher,T))&&it(k,n),T!==e.tagname&&(this.isCurrentNodeStopNode=this.isItStopNode());var F=o;if(this.isCurrentNodeStopNode){var R="";if(V)o=_.closeIndex;else if(n.unpairedTagsSet.has(T))o=_.closeIndex;else{var G=this.readStopNodeData(t,C,D+1);if(!G)throw new Error("Unexpected end of "+C);o=G.i,R=G.tagContent}var U=new O(T);k&&(U[":@"]=k),U.add(n.textNodeName,R),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(r,U,this.readonlyMatcher,F)}else{if(V){var B=Nt(n.transformTagName,T,P,n);T=B.tagName,P=B.tagExp;var W=new O(T);k&&(W[":@"]=k),this.addChild(r,W,this.readonlyMatcher,F),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else{if(n.unpairedTagsSet.has(T)){var X=new O(T);k&&(X[":@"]=k),this.addChild(r,X,this.readonlyMatcher,F),this.matcher.pop(),this.isCurrentNodeStopNode=!1,o=_.closeIndex;continue}var Y=new O(T);if(this.tagsNodeStack.length>n.maxNestedTags)throw new Error("Maximum nested tags exceeded");this.tagsNodeStack.push(r),k&&(Y[":@"]=k),this.addChild(r,Y,this.readonlyMatcher,F),r=Y}i="",o=D}}}else i+=t[o];return e.child};function pt(t,e,r,i){this.options.captureMetaData||(i=void 0);var n=this.options.jPath?r.toString():r,s=this.options.updateTag(e.tagname,n,e[":@"]);!1===s||("string"==typeof s?(e.tagname=s,t.addChild(e,i)):t.addChild(e,i))}function dt(t,e,r){var i=this.options.processEntities;if(!i||!i.enabled)return t;if(i.allowedTags){var n=this.options.jPath?r.toString():r;if(!(Array.isArray(i.allowedTags)?i.allowedTags.includes(e):i.allowedTags(e,n)))return t}if(i.tagFilter){var s=this.options.jPath?r.toString():r;if(!i.tagFilter(e,s))return t}return this.entityDecoder.decode(t)}function ct(t,e,r,i){return t&&(void 0===i&&(i=0===e.child.length),void 0!==(t=this.parseTextData(t,e.tagname,r,!1,!!e[":@"]&&0!==Object.keys(e[":@"]).length,i))&&""!==t&&e.add(this.options.textNodeName,t),t=""),t}function ft(){return 0!==this.stopNodeExpressionsSet.size&&this.matcher.matchesAny(this.stopNodeExpressionsSet)}function gt(t,e,r,i){var n=t.indexOf(e,r);if(-1===n)throw new Error(i);return n+e.length-1}function mt(t,e,r,i){var n=t.indexOf(e,r);if(-1===n)throw new Error(i);return n}function vt(t,e,r,i){void 0===i&&(i=">");var n=function(t,e,r){void 0===r&&(r=">");for(var i=0,n=[],s=t.length,a=r.charCodeAt(0),o=r.length>1?r.charCodeAt(1):-1,h=e;h",r,e+" is not closed");if(t.substring(r+2,o).trim()===e&&0===--n)return{tagContent:t.substring(i,r),i:o};r=o}else if(63===a)r=gt(t,"?>",r+1,"StopNode is not closed.");else if(33===a&&45===t.charCodeAt(r+2)&&45===t.charCodeAt(r+3))r=gt(t,"--\x3e",r+3,"StopNode is not closed.");else if(33===a&&91===t.charCodeAt(r+2))r=gt(t,"]]>",r,"StopNode is not closed.")-2;else{var h=vt(t,r,">");h&&((h&&h.tagName)===e&&"/"!==h.tagExp[h.tagExp.length-1]&&n++,r=h.closeIndex)}}}function bt(t,e,r){if(e&&"string"==typeof t){var i=t.trim();return"true"===i||"false"!==i&&function(t,e={}){if(e=Object.assign({},L,e),!t||"string"!=typeof t)return t;let r=t.trim();if(0===r.length)return t;if(void 0!==e.skipLike&&e.skipLike.test(r))return t;if("0"===r)return 0;if(e.hex&&M.test(r))return function(t){if(parseInt)return parseInt(t,16);if(Number.parseInt)return Number.parseInt(t,16);if(window&&window.parseInt)return window.parseInt(t,16);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}(r);if(isFinite(r)){if(r.includes("e")||r.includes("E"))return function(t,e,r){if(!r.eNotation)return t;const i=e.match(k);if(i){let n=i[1]||"";const s=-1===i[3].indexOf("e")?"E":"e",a=i[2],o=n?t[a.length+1]===s:t[a.length]===s;return a.length>1&&o?t:(1!==a.length||!i[3].startsWith(`.${s}`)&&i[3][0]!==s)&&a.length>0?r.leadingZeros&&!o?(e=(i[1]||"")+i[3],Number(e)):t:Number(e)}return t}(t,r,e);{const n=V.exec(r);if(n){const s=n[1]||"",a=n[2];let o=(i=n[3])&&-1!==i.indexOf(".")?("."===(i=i.replace(/0+$/,""))?i="0":"."===i[0]?i="0"+i:"."===i[i.length-1]&&(i=i.substring(0,i.length-1)),i):i;const h=s?"."===t[a.length+1]:"."===t[a.length];if(!e.leadingZeros&&(a.length>1||1===a.length&&!h))return t;{const i=Number(r),n=String(i);if(0===i)return i;if(-1!==n.search(/[eE]/))return e.eNotation?i:t;if(-1!==r.indexOf("."))return"0"===n||n===o||n===`${s}${o}`?i:t;let h=a?o:r;return a?h===n||s+h===n?i:t:h===n||h===s+n?i:t}}return t}}var i;return function(t,e,r){const i=e===1/0;switch(r.infinity.toLowerCase()){case"null":return null;case"infinity":return e;case"string":return i?"Infinity":"-Infinity";default:return t}}(t,Number(r),e)}(t,r)}return void 0!==t?t:""}function Nt(t,e,r,i){if(t){var n=t(e);r===e&&(r=n),e=n}return{tagName:e=yt(e,i),tagExp:r}}function yt(t,e){if(o.includes(t))throw new Error('[SECURITY] Invalid name: "'+t+'" is a reserved JavaScript keyword that could cause prototype pollution');return a.includes(t)?e.onDangerousProperty(t):t}var Et=O.getMetaDataSymbol();function wt(t,e){if(!t||"object"!=typeof t)return{};if(!e)return t;var r={};for(var i in t)i.startsWith(e)?r[i.substring(e.length)]=t[i]:r[i]=t[i];return r}function St(t,e,r,i){return _t(t,e,r,i)}function _t(t,e,r,i){for(var n,s={},a=0;a0&&(s[e.textNodeName]=n):void 0!==n&&(s[e.textNodeName]=n),s}function At(t){for(var e=Object.keys(t),r=0;r0&&(r="\n");const i=[];if(e.stopNodes&&Array.isArray(e.stopNodes))for(let t=0;te.maxNestedTags)throw new Error("Maximum nested tags exceeded");if(!Array.isArray(t)){if(null!=t){let r=t.toString();return r=kt(r,e),r}return""}for(let o=0;o/g,"]]]]>`,a=!1,i.pop();continue}if(l===e.commentPropName){const t=h[l][0][e.textNodeName];s+=r+`\x3c!--${String(t).replace(/--/g,"- -").replace(/-$/,"- ")}--\x3e`,a=!0,i.pop();continue}if("?"===l[0]){const t=Vt(h[":@"],e,p),n="?xml"===l?"":r;let o=h[l][0][e.textNodeName];o=0!==o.length?" "+o:"",s+=n+`<${l}${o}${t}?>`,a=!0,i.pop();continue}let d=r;""!==d&&(d+=e.indentBy);const c=r+`<${l}${Vt(h[":@"],e,p)}`;let f;f=p?Dt(h[l],e):It(h[l],e,d,i,n),-1!==e.unpairedTags.indexOf(l)?e.suppressUnpairedNode?s+=c+">":s+=c+"/>":f&&0!==f.length||!e.suppressEmptyNode?f&&f.endsWith(">")?s+=c+`>${f}${r}`:(s+=c+">",f&&""!==r&&(f.includes("/>")||f.includes("`):s+=c+"/>",a=!0,i.pop()}return s}function jt(t,e){if(!t||e.ignoreAttributes)return null;const r={};let i=!1;for(let n in t)Object.prototype.hasOwnProperty.call(t,n)&&(r[n.startsWith(e.attributeNamePrefix)?n.substr(e.attributeNamePrefix.length):n]=t[n],i=!0);return i?r:null}function Dt(t,e){if(!Array.isArray(t))return null!=t?t.toString():"";let r="";for(let i=0;i${i}`:r+=`<${s}${t}/>`}}}return r}function $t(t,e){let r="";if(t&&!e.ignoreAttributes)for(let i in t){if(!Object.prototype.hasOwnProperty.call(t,i))continue;let n=t[i];!0===n&&e.suppressBooleanAttributes?r+=` ${i.substr(e.attributeNamePrefix.length)}`:r+=` ${i.substr(e.attributeNamePrefix.length)}="${n}"`}return r}function Mt(t){const e=Object.keys(t);for(let r=0;r0&&e.processEntities)for(let r=0;r","g"),val:">"},{regex:new RegExp("<","g"),val:"<"},{regex:new RegExp("'","g"),val:"'"},{regex:new RegExp('"',"g"),val:"""}],processEntities:!0,stopNodes:[],oneListGroup:!1,maxNestedTags:100,jPath:!0};function Rt(t){if(this.options=Object.assign({},Ft,t),this.options.stopNodes&&Array.isArray(this.options.stopNodes)&&(this.options.stopNodes=this.options.stopNodes.map(t=>"string"==typeof t&&t.startsWith("*.")?".."+t.substring(2):t)),this.stopNodeExpressions=[],this.options.stopNodes&&Array.isArray(this.options.stopNodes))for(let t=0;t{for(const r of e){if("string"==typeof r&&t===r)return!0;if(r instanceof RegExp&&r.test(t))return!0}}:()=>!1,this.attrPrefixLen=this.options.attributeNamePrefix.length,this.isAttribute=Bt),this.processTextOrObjNode=Gt,this.options.format?(this.indentate=Ut,this.tagEndChar=">\n",this.newLine="\n"):(this.indentate=function(){return""},this.tagEndChar=">",this.newLine="")}function Gt(t,e,r,i){const n=this.extractAttributes(t);if(i.push(e,n),this.checkStopNode(i)){const n=this.buildRawContent(t),s=this.buildAttributesForStopNode(t);return i.pop(),this.buildObjectNode(n,e,s,r)}const s=this.j2x(t,r+1,i);return i.pop(),void 0!==t[this.options.textNodeName]&&1===Object.keys(t).length?this.buildTextValNode(t[this.options.textNodeName],e,s.attrStr,r,i):this.buildObjectNode(s.val,e,s.attrStr,r)}function Ut(t){return this.options.indentBy.repeat(t)}function Bt(t){return!(!t.startsWith(this.options.attributeNamePrefix)||t===this.options.textNodeName)&&t.substr(this.attrPrefixLen)}Rt.prototype.build=function(t){if(this.options.preserveOrder)return Ot(t,this.options);{Array.isArray(t)&&this.options.arrayNodeName&&this.options.arrayNodeName.length>1&&(t={[this.options.arrayNodeName]:t});const e=new G;return this.j2x(t,0,e).val}},Rt.prototype.j2x=function(t,e,r){let i="",n="";if(this.options.maxNestedTags&&r.getDepth()>=this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");const s=this.options.jPath?r.toString():r,a=this.checkStopNode(r);for(let o in t)if(Object.prototype.hasOwnProperty.call(t,o))if(void 0===t[o])this.isAttribute(o)&&(n+="");else if(null===t[o])this.isAttribute(o)||o===this.options.cdataPropName?n+="":"?"===o[0]?n+=this.indentate(e)+"<"+o+"?"+this.tagEndChar:n+=this.indentate(e)+"<"+o+"/"+this.tagEndChar;else if(t[o]instanceof Date)n+=this.buildTextValNode(t[o],o,"",e,r);else if("object"!=typeof t[o]){const h=this.isAttribute(o);if(h&&!this.ignoreAttributesFn(h,s))i+=this.buildAttrPairStr(h,""+t[o],a);else if(!h)if(o===this.options.textNodeName){let e=this.options.tagValueProcessor(o,""+t[o]);n+=this.replaceEntitiesValue(e)}else{r.push(o);const i=this.checkStopNode(r);if(r.pop(),i){const r=""+t[o];n+=""===r?this.indentate(e)+"<"+o+this.closeTag(o)+this.tagEndChar:this.indentate(e)+"<"+o+">"+r+""+t+"${t}`;else if("object"==typeof t&&null!==t){const i=this.buildRawContent(t),n=this.buildAttributesForStopNode(t);e+=""===i?`<${r}${n}/>`:`<${r}${n}>${i}`}}else if("object"==typeof i&&null!==i){const t=this.buildRawContent(i),n=this.buildAttributesForStopNode(i);e+=""===t?`<${r}${n}/>`:`<${r}${n}>${t}`}else e+=`<${r}>${i}`}return e},Rt.prototype.buildAttributesForStopNode=function(t){if(!t||"object"!=typeof t)return"";let e="";if(this.options.attributesGroupName&&t[this.options.attributesGroupName]){const r=t[this.options.attributesGroupName];for(let t in r){if(!Object.prototype.hasOwnProperty.call(r,t))continue;const i=t.startsWith(this.options.attributeNamePrefix)?t.substring(this.options.attributeNamePrefix.length):t,n=r[t];!0===n&&this.options.suppressBooleanAttributes?e+=" "+i:e+=" "+i+'="'+n+'"'}}else for(let r in t){if(!Object.prototype.hasOwnProperty.call(t,r))continue;const i=this.isAttribute(r);if(i){const n=t[r];!0===n&&this.options.suppressBooleanAttributes?e+=" "+i:e+=" "+i+'="'+n+'"'}}return e},Rt.prototype.buildObjectNode=function(t,e,r,i){if(""===t)return"?"===e[0]?this.indentate(i)+"<"+e+r+"?"+this.tagEndChar:this.indentate(i)+"<"+e+r+this.closeTag(e)+this.tagEndChar;{let n=""+t+n}},Rt.prototype.closeTag=function(t){let e="";return-1!==this.options.unpairedTags.indexOf(t)?this.options.suppressUnpairedNode||(e="/"):e=this.options.suppressEmptyNode?"/":`>/g,"]]]]>`+this.newLine}if(!1!==this.options.commentPropName&&e===this.options.commentPropName){const e=String(t).replace(/--/g,"- -").replace(/-$/,"- ");return this.indentate(i)+`\x3c!--${e}--\x3e`+this.newLine}if("?"===e[0])return this.indentate(i)+"<"+e+r+"?"+this.tagEndChar;{let n=this.options.tagValueProcessor(e,t);return n=this.replaceEntitiesValue(n),""===n?this.indentate(i)+"<"+e+r+this.closeTag(e)+this.tagEndChar:this.indentate(i)+"<"+e+r+">"+n+"0&&this.options.processEntities)for(let e=0;e {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n/**\n * Dangerous property names that could lead to prototype pollution or security issues\n */\nexport const DANGEROUS_PROPERTY_NAMES = [\n // '__proto__',\n // 'constructor',\n // 'prototype',\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__'\n];\n\nexport const criticalProperties = [\"__proto__\", \"constructor\", \"prototype\"];","'use strict';\n\nimport { getAllMatches, isName } from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/()/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n\n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i + 1] === '?') {\n i += 2;\n i = readPI(xmlData, i);\n if (i.err) return i;\n } else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n\n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\" + tagName + \"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\" + tagName + \"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\" + otg.tagName + \"' (opened in line \" + openPos.line + \", col \" + openPos.col + \") instead of closing tag '\" + tagName + \"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if (options.unpairedTags.indexOf(tagName) !== -1) {\n //don't push into stack\n } else {\n tags.push({ tagName, tagStartPos });\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i + 1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else {\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n } else {\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if (isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\" + xmlData[i] + \"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n } else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\" + tags[0].tagName + \"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n } else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\" +\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '') +\n \"' found.\", { line: 1, col: 1 });\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char) {\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Select all the attributes whether valid or invalid.\n */\nconst validAttrStrRegxp = new RegExp('(\\\\s*)([^\\\\s=]+)(\\\\s*=)?(\\\\s*([\\'\"])(([\\\\s\\\\S])*?)\\\\5)?', 'g');\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = getAllMatches(attrStr, validAttrStrRegxp);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\" + matches[i][2] + \"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}\n","import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from \"../util.js\";\n\nconst defaultOnDangerousProperty = (name) => {\n if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return \"__\" + name;\n }\n return name;\n};\n\n\nexport const defaultOptions = {\n preserveOrder: false,\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n removeNSPrefix: false, // remove NS from tag name or attribute name if true\n allowBooleanAttributes: false, //a tag can have attributes without any value\n //ignoreRootElement : false,\n parseTagValue: true,\n parseAttributeValue: false,\n trimValues: true, //Trim string values of tag and attributes\n cdataPropName: false,\n numberParseOptions: {\n hex: true,\n leadingZeros: true,\n eNotation: true\n },\n tagValueProcessor: function (tagName, val) {\n return val;\n },\n attributeValueProcessor: function (attrName, val) {\n return val;\n },\n stopNodes: [], //nested tags will not be parsed even for errors\n alwaysCreateTextNode: false,\n isArray: () => false,\n commentPropName: false,\n unpairedTags: [],\n processEntities: true,\n htmlEntities: false,\n ignoreDeclaration: false,\n ignorePiTags: false,\n transformTagName: false,\n transformAttributeName: false,\n updateTag: function (tagName, jPath, attrs) {\n return tagName\n },\n // skipEmptyListItem: false\n captureMetaData: false,\n maxNestedTags: 100,\n strictReservedNames: true,\n jPath: true, // if true, pass jPath string to callbacks; if false, pass matcher instance\n onDangerousProperty: defaultOnDangerousProperty\n};\n\n\n/**\n * Validates that a property name is safe to use\n * @param {string} propertyName - The property name to validate\n * @param {string} optionName - The option field name (for error message)\n * @throws {Error} If property name is dangerous\n */\nfunction validatePropertyName(propertyName, optionName) {\n if (typeof propertyName !== 'string') {\n return; // Only validate string property names\n }\n\n const normalized = propertyName.toLowerCase();\n if (DANGEROUS_PROPERTY_NAMES.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n\n if (criticalProperties.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n}\n\n/**\n * Normalizes processEntities option for backward compatibility\n * @param {boolean|object} value \n * @returns {object} Always returns normalized object\n */\nfunction normalizeProcessEntities(value) {\n // Boolean backward compatibility\n if (typeof value === 'boolean') {\n return {\n enabled: value, // true or false\n maxEntitySize: 10000,\n maxExpansionDepth: 10,\n maxTotalExpansions: 1000,\n maxExpandedLength: 100000,\n maxEntityCount: 100,\n allowedTags: null,\n tagFilter: null\n };\n }\n\n // Object config - merge with defaults\n if (typeof value === 'object' && value !== null) {\n return {\n enabled: value.enabled !== false,\n maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000),\n maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10),\n maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? 1000),\n maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000),\n maxEntityCount: Math.max(1, value.maxEntityCount ?? 100),\n allowedTags: value.allowedTags ?? null,\n tagFilter: value.tagFilter ?? null\n };\n }\n\n // Default to enabled with limits\n return normalizeProcessEntities(true);\n}\n\nexport const buildOptions = function (options) {\n const built = Object.assign({}, defaultOptions, options);\n\n // Validate property names to prevent prototype pollution\n const propertyNameOptions = [\n { value: built.attributeNamePrefix, name: 'attributeNamePrefix' },\n { value: built.attributesGroupName, name: 'attributesGroupName' },\n { value: built.textNodeName, name: 'textNodeName' },\n { value: built.cdataPropName, name: 'cdataPropName' },\n { value: built.commentPropName, name: 'commentPropName' }\n ];\n\n for (const { value, name } of propertyNameOptions) {\n if (value) {\n validatePropertyName(value, name);\n }\n }\n\n if (built.onDangerousProperty === null) {\n built.onDangerousProperty = defaultOnDangerousProperty;\n }\n\n // Always normalize processEntities for backward compatibility and validation\n built.processEntities = normalizeProcessEntities(built.processEntities);\n\n // Convert old-style stopNodes for backward compatibility\n if (built.stopNodes && Array.isArray(built.stopNodes)) {\n built.stopNodes = built.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Old syntax: *.tagname meant \"tagname anywhere\"\n // Convert to new syntax: ..tagname\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n //console.debug(built.processEntities)\n return built;\n};","'use strict';\n\nlet METADATA_SYMBOL;\n\nif (typeof Symbol !== \"function\") {\n METADATA_SYMBOL = \"@@xmlMetadata\";\n} else {\n METADATA_SYMBOL = Symbol(\"XML Node Metadata\");\n}\n\nexport default class XmlNode {\n constructor(tagname) {\n this.tagname = tagname;\n this.child = []; //nested tags, text, cdata, comments in order\n this[\":@\"] = Object.create(null); //attributes map\n }\n add(key, val) {\n // this.child.push( {name : key, val: val, isCdata: isCdata });\n if (key === \"__proto__\") key = \"#__proto__\";\n this.child.push({ [key]: val });\n }\n addChild(node, startIndex) {\n if (node.tagname === \"__proto__\") node.tagname = \"#__proto__\";\n if (node[\":@\"] && Object.keys(node[\":@\"]).length > 0) {\n this.child.push({ [node.tagname]: node.child, [\":@\"]: node[\":@\"] });\n } else {\n this.child.push({ [node.tagname]: node.child });\n }\n // if requested, add the startIndex\n if (startIndex !== undefined) {\n // Note: for now we just overwrite the metadata. If we had more complex metadata,\n // we might need to do an object append here: metadata = { ...metadata, startIndex }\n this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };\n }\n }\n /** symbol used for metadata */\n static getMetaDataSymbol() {\n return METADATA_SYMBOL;\n }\n}\n","import { isName } from '../util.js';\n\nexport default class DocTypeReader {\n constructor(options) {\n this.suppressValidationErr = !options;\n this.options = options;\n }\n\n readDocType(xmlData, i) {\n const entities = Object.create(null);\n let entityCount = 0;\n\n if (xmlData[i + 3] === 'O' &&\n xmlData[i + 4] === 'C' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'Y' &&\n xmlData[i + 7] === 'P' &&\n xmlData[i + 8] === 'E') {\n i = i + 9;\n let angleBracketsCount = 1;\n let hasBody = false, comment = false;\n let exp = \"\";\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === '<' && !comment) { //Determine the tag type\n if (hasBody && hasSeq(xmlData, \"!ENTITY\", i)) {\n i += 7;\n let entityName, val;\n [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);\n if (val.indexOf(\"&\") === -1) { //Parameter entities are not supported\n if (this.options.enabled !== false &&\n this.options.maxEntityCount != null &&\n entityCount >= this.options.maxEntityCount) {\n throw new Error(\n `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`\n );\n }\n //const escaped = entityName.replace(/[.\\-+*:]/g, '\\\\.');\n const escaped = entityName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n entities[entityName] = {\n regx: RegExp(`&${escaped};`, \"g\"),\n val: val\n };\n entityCount++;\n }\n }\n else if (hasBody && hasSeq(xmlData, \"!ELEMENT\", i)) {\n i += 8;//Not supported\n const { index } = this.readElementExp(xmlData, i + 1);\n i = index;\n } else if (hasBody && hasSeq(xmlData, \"!ATTLIST\", i)) {\n i += 8;//Not supported\n // const {index} = this.readAttlistExp(xmlData,i+1);\n // i = index;\n } else if (hasBody && hasSeq(xmlData, \"!NOTATION\", i)) {\n i += 9;//Not supported\n const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);\n i = index;\n } else if (hasSeq(xmlData, \"!--\", i)) comment = true;\n else throw new Error(`Invalid DOCTYPE`);\n\n angleBracketsCount++;\n exp = \"\";\n } else if (xmlData[i] === '>') { //Read tag content\n if (comment) {\n if (xmlData[i - 1] === \"-\" && xmlData[i - 2] === \"-\") {\n comment = false;\n angleBracketsCount--;\n }\n } else {\n angleBracketsCount--;\n }\n if (angleBracketsCount === 0) {\n break;\n }\n } else if (xmlData[i] === '[') {\n hasBody = true;\n } else {\n exp += xmlData[i];\n }\n }\n if (angleBracketsCount !== 0) {\n throw new Error(`Unclosed DOCTYPE`);\n }\n } else {\n throw new Error(`Invalid Tag instead of DOCTYPE`);\n }\n return { entities, i };\n }\n readEntityExp(xmlData, i) {\n //External entities are not supported\n // \n\n //Parameter entities are not supported\n // \n\n //Internal entities are supported\n // \n\n // Skip leading whitespace after this.options.maxEntitySize) {\n throw new Error(\n `Entity \"${entityName}\" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`\n );\n }\n\n i--;\n return [entityName, entityValue, i];\n }\n\n readNotationExp(xmlData, i) {\n // Skip leading whitespace after \n // \n // \n // \n // \n\n // Skip leading whitespace after {\n while (index < data.length && /\\s/.test(data[index])) {\n index++;\n }\n return index;\n};\n\n\n\nfunction hasSeq(data, seq, i) {\n for (let j = 0; j < seq.length; j++) {\n if (seq[j] !== data[i + j + 1]) return false;\n }\n return true;\n}\n\nfunction validateEntityName(name) {\n if (isName(name))\n return name;\n else\n throw new Error(`Invalid entity name ${name}`);\n}","const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;\nconst numRegex = /^([\\-\\+])?(0*)([0-9]*(\\.[0-9]*)?)$/;\n// const octRegex = /^0x[a-z0-9]+/;\n// const binRegex = /0x[a-z0-9]+/;\n\n\nconst consider = {\n hex: true,\n // oct: false,\n leadingZeros: true,\n decimalPoint: \"\\.\",\n eNotation: true,\n //skipLike: /regex/,\n infinity: \"original\", // \"null\", \"infinity\" (Infinity type), \"string\" (\"Infinity\" (the string literal))\n};\n\nexport default function toNumber(str, options = {}) {\n options = Object.assign({}, consider, options);\n if (!str || typeof str !== \"string\") return str;\n\n let trimmedStr = str.trim();\n\n if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;\n else if (str === \"0\") return 0;\n else if (options.hex && hexRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 16);\n // }else if (options.oct && octRegex.test(str)) {\n // return Number.parseInt(val, 8);\n } else if (!isFinite(trimmedStr)) { //Infinity\n return handleInfinity(str, Number(trimmedStr), options);\n } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation\n return resolveEnotation(str, trimmedStr, options);\n // }else if (options.parseBin && binRegex.test(str)) {\n // return Number.parseInt(val, 2);\n } else {\n //separate negative sign, leading zeros, and rest number\n const match = numRegex.exec(trimmedStr);\n // +00.123 => [ , '+', '00', '.123', ..\n if (match) {\n const sign = match[1] || \"\";\n const leadingZeros = match[2];\n let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros\n const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.\n str[leadingZeros.length + 1] === \".\"\n : str[leadingZeros.length] === \".\";\n\n //trim ending zeros for floating number\n if (!options.leadingZeros //leading zeros are not allowed\n && (leadingZeros.length > 1\n || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {\n // 00, 00.3, +03.24, 03, 03.24\n return str;\n }\n else {//no leading zeros or leading zeros are allowed\n const num = Number(trimmedStr);\n const parsedStr = String(num);\n\n if (num === 0) return num;\n if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation\n if (options.eNotation) return num;\n else return str;\n } else if (trimmedStr.indexOf(\".\") !== -1) { //floating number\n if (parsedStr === \"0\") return num; //0.0\n else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000\n else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;\n else return str;\n }\n\n let n = leadingZeros ? numTrimmedByZeros : trimmedStr;\n if (leadingZeros) {\n // -009 => -9\n return (n === parsedStr) || (sign + n === parsedStr) ? num : str\n } else {\n // +9\n return (n === parsedStr) || (n === sign + parsedStr) ? num : str\n }\n }\n } else { //non-numeric string\n return str;\n }\n }\n}\n\nconst eNotationRegx = /^([-+])?(0*)(\\d*(\\.\\d*)?[eE][-\\+]?\\d+)$/;\nfunction resolveEnotation(str, trimmedStr, options) {\n if (!options.eNotation) return str;\n const notation = trimmedStr.match(eNotationRegx);\n if (notation) {\n let sign = notation[1] || \"\";\n const eChar = notation[3].indexOf(\"e\") === -1 ? \"E\" : \"e\";\n const leadingZeros = notation[2];\n const eAdjacentToLeadingZeros = sign ? // 0E.\n str[leadingZeros.length + 1] === eChar\n : str[leadingZeros.length] === eChar;\n\n if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;\n else if (leadingZeros.length === 1\n && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {\n return Number(trimmedStr);\n } else if (leadingZeros.length > 0) {\n // Has leading zeros — only accept if leadingZeros option allows it\n if (options.leadingZeros && !eAdjacentToLeadingZeros) {\n trimmedStr = (notation[1] || \"\") + notation[3];\n return Number(trimmedStr);\n } else return str;\n } else {\n // No leading zeros — always valid e-notation, parse it\n return Number(trimmedStr);\n }\n } else {\n return str;\n }\n}\n\n/**\n * \n * @param {string} numStr without leading zeros\n * @returns \n */\nfunction trimZeros(numStr) {\n if (numStr && numStr.indexOf(\".\") !== -1) {//float\n numStr = numStr.replace(/0+$/, \"\"); //remove ending zeros\n if (numStr === \".\") numStr = \"0\";\n else if (numStr[0] === \".\") numStr = \"0\" + numStr;\n else if (numStr[numStr.length - 1] === \".\") numStr = numStr.substring(0, numStr.length - 1);\n return numStr;\n }\n return numStr;\n}\n\nfunction parse_int(numStr, base) {\n //polyfill\n if (parseInt) return parseInt(numStr, base);\n else if (Number.parseInt) return Number.parseInt(numStr, base);\n else if (window && window.parseInt) return window.parseInt(numStr, base);\n else throw new Error(\"parseInt, Number.parseInt, window.parseInt are not supported\")\n}\n\n/**\n * Handle infinite values based on user option\n * @param {string} str - original input string\n * @param {number} num - parsed number (Infinity or -Infinity)\n * @param {object} options - user options\n * @returns {string|number|null} based on infinity option\n */\nfunction handleInfinity(str, num, options) {\n const isPositive = num === Infinity;\n\n switch (options.infinity.toLowerCase()) {\n case \"null\":\n return null;\n case \"infinity\":\n return num; // Return Infinity or -Infinity\n case \"string\":\n return isPositive ? \"Infinity\" : \"-Infinity\";\n case \"original\":\n default:\n return str; // Return original string like \"1e1000\"\n }\n}","/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions\n * \n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n * \n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n * \n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Default path separator (default: '.')\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag: string, values: object, position: number, counter: number }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n }\n\n /**\n * Push a new tag onto the path\n * @param {string} tagName - Name of the tag\n * @param {Object} attrValues - Attribute key-value pairs for current node (optional)\n * @param {string} namespace - Namespace for the tag (optional)\n */\n push(tagName, attrValues = null, namespace = null) {\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n const prev = this.path[this.path.length - 1];\n prev.values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n // Store namespace if provided\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n // Store values only for current node\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) {\n return undefined;\n }\n\n const node = this.path.pop();\n\n // Clean up sibling tracking for levels deeper than current\n // After pop, path.length is the new depth\n // We need to clean up siblingStacks[path.length + 1] and beyond\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values\n * Useful when attributes are parsed after push\n * @param {Object} attrValues - Attribute values\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value\n * @param {string} attrName - Attribute name\n * @returns {*} Attribute value or undefined\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n const current = this.path[this.path.length - 1];\n return current.values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute\n * @param {string} attrName - Attribute name\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent)\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name)\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition for backward compatibility)\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string\n * @param {string} separator - Optional separator (uses default if not provided)\n * @param {boolean} includeNamespace - Whether to include namespace in output (default: true)\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n return this.path.map(n => {\n if (includeNamespace && n.namespace) {\n return `${n.namespace}:${n.tag}`;\n }\n return n.tag;\n }).join(sep);\n }\n\n /**\n * Get path as array of tag names\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty\n */\n reset() {\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression\n * @param {Expression} expression - The expression to match against\n * @returns {boolean} True if current path matches the expression\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n // Handle deep wildcard patterns\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n // Simple path matching (no deep wildcards)\n return this._matchSimple(segments);\n }\n\n /**\n * Match simple path (no deep wildcards)\n * @private\n */\n _matchSimple(segments) {\n // Path must be same length as segments\n if (this.path.length !== segments.length) {\n return false;\n }\n\n // Match each segment bottom-to-top\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n const node = this.path[i];\n const isCurrentNode = (i === this.path.length - 1);\n\n if (!this._matchSegment(segment, node, isCurrentNode)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match path with deep wildcards\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1; // Start from current node (bottom)\n let segIdx = segments.length - 1; // Start from last segment\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n // \"..\" matches zero or more levels\n segIdx--;\n\n if (segIdx < 0) {\n // Pattern ends with \"..\", always matches\n return true;\n }\n\n // Find where next segment matches in the path\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n const isCurrentNode = (i === this.path.length - 1);\n if (this._matchSegment(nextSeg, this.path[i], isCurrentNode)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n // Regular segment\n const isCurrentNode = (pathIdx === this.path.length - 1);\n if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n // All segments must be consumed\n return segIdx < 0;\n }\n\n /**\n * Match a single segment against a node\n * @private\n * @param {Object} segment - Segment from Expression\n * @param {Object} node - Node from path\n * @param {boolean} isCurrentNode - Whether this is the current (last) node\n * @returns {boolean}\n */\n _matchSegment(segment, node, isCurrentNode) {\n // Match tag name (* is wildcard)\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n // Match namespace if specified in segment\n if (segment.namespace !== undefined) {\n // Segment has namespace - node must match it\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n // If segment has no namespace, it matches nodes with or without namespace\n\n // Match attribute name (check if node has this attribute)\n // Can only check for current node since ancestors don't have values\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n // Can't check attributes for ancestor nodes (values not stored)\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n // Match attribute value (only possible for current node)\n if (segment.attrValue !== undefined) {\n const actualValue = node.values[segment.attrName];\n // Both should be strings\n if (String(actualValue) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n // Match position (only for current node)\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n // Can't check position for ancestor nodes\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth') {\n if (counter !== segment.positionValue) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Create a snapshot of current state\n * @returns {Object} State snapshot\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot\n * @param {Object} snapshot - State snapshot\n */\n restore(snapshot) {\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n}","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","'use strict';\n///@ts-check\n\nimport { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';\nimport xmlNode from './xmlNode.js';\nimport DocTypeReader from './DocTypeReader.js';\nimport toNumber from \"strnum\";\nimport getIgnoreAttributesFn from \"../ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\n\n// const regx =\n// '<((!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\\\/)(NAME)\\\\s*>))([^<]*)'\n// .replace(/NAME/g, util.nameRegexp);\n\n//const tagsRegx = new RegExp(\"<(\\\\/?[\\\\w:\\\\-\\._]+)([^>]*)>(\\\\s*\"+cdataRegx+\")*([^<]+)?\",\"g\");\n//const tagsRegx = new RegExp(\"<(\\\\/?)((\\\\w*:)?([\\\\w:\\\\-\\._]+))([^>]*)>([^<]*)(\"+cdataRegx+\"([^<]*))*([^<]+)?\",\"g\");\n\n// Helper functions for attribute and namespace handling\n\n/**\n * Extract raw attributes (without prefix) from prefixed attribute map\n * @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap\n * @param {object} options - Parser options containing attributeNamePrefix\n * @returns {object} Raw attributes for matcher\n */\nfunction extractRawAttributes(prefixedAttrs, options) {\n if (!prefixedAttrs) return {};\n\n // Handle attributesGroupName option\n const attrs = options.attributesGroupName\n ? prefixedAttrs[options.attributesGroupName]\n : prefixedAttrs;\n\n if (!attrs) return {};\n\n const rawAttrs = {};\n for (const key in attrs) {\n // Remove the attribute prefix to get raw name\n if (key.startsWith(options.attributeNamePrefix)) {\n const rawName = key.substring(options.attributeNamePrefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * Extract namespace from raw tag name\n * @param {string} rawTagName - Tag name possibly with namespace (e.g., \"soap:Envelope\")\n * @returns {string|undefined} Namespace or undefined\n */\nfunction extractNamespace(rawTagName) {\n if (!rawTagName || typeof rawTagName !== 'string') return undefined;\n\n const colonIndex = rawTagName.indexOf(':');\n if (colonIndex !== -1 && colonIndex > 0) {\n const ns = rawTagName.substring(0, colonIndex);\n // Don't treat xmlns as a namespace\n if (ns !== 'xmlns') {\n return ns;\n }\n }\n return undefined;\n}\n\nexport default class OrderedObjParser {\n constructor(options) {\n this.options = options;\n this.currentNode = null;\n this.tagsNodeStack = [];\n this.docTypeEntities = {};\n this.lastEntities = {\n \"apos\": { regex: /&(apos|#39|#x27);/g, val: \"'\" },\n \"gt\": { regex: /&(gt|#62|#x3E);/g, val: \">\" },\n \"lt\": { regex: /&(lt|#60|#x3C);/g, val: \"<\" },\n \"quot\": { regex: /&(quot|#34|#x22);/g, val: \"\\\"\" },\n };\n this.ampEntity = { regex: /&(amp|#38|#x26);/g, val: \"&\" };\n this.htmlEntities = {\n \"space\": { regex: /&(nbsp|#160);/g, val: \" \" },\n // \"lt\" : { regex: /&(lt|#60);/g, val: \"<\" },\n // \"gt\" : { regex: /&(gt|#62);/g, val: \">\" },\n // \"amp\" : { regex: /&(amp|#38);/g, val: \"&\" },\n // \"quot\" : { regex: /&(quot|#34);/g, val: \"\\\"\" },\n // \"apos\" : { regex: /&(apos|#39);/g, val: \"'\" },\n \"cent\": { regex: /&(cent|#162);/g, val: \"¢\" },\n \"pound\": { regex: /&(pound|#163);/g, val: \"£\" },\n \"yen\": { regex: /&(yen|#165);/g, val: \"¥\" },\n \"euro\": { regex: /&(euro|#8364);/g, val: \"€\" },\n \"copyright\": { regex: /&(copy|#169);/g, val: \"©\" },\n \"reg\": { regex: /&(reg|#174);/g, val: \"®\" },\n \"inr\": { regex: /&(inr|#8377);/g, val: \"₹\" },\n \"num_dec\": { regex: /&#([0-9]{1,7});/g, val: (_, str) => fromCodePoint(str, 10, \"&#\") },\n \"num_hex\": { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (_, str) => fromCodePoint(str, 16, \"&#x\") },\n };\n this.addExternalEntities = addExternalEntities;\n this.parseXml = parseXml;\n this.parseTextData = parseTextData;\n this.resolveNameSpace = resolveNameSpace;\n this.buildAttributesMap = buildAttributesMap;\n this.isItStopNode = isItStopNode;\n this.replaceEntitiesValue = replaceEntitiesValue;\n this.readStopNodeData = readStopNodeData;\n this.saveTextToParentTag = saveTextToParentTag;\n this.addChild = addChild;\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n\n // Initialize path matcher for path-expression-matcher\n this.matcher = new Matcher();\n\n // Flag to track if current node is a stop node (optimization)\n this.isCurrentNodeStopNode = false;\n\n // Pre-compile stopNodes expressions\n if (this.options.stopNodes && this.options.stopNodes.length > 0) {\n this.stopNodeExpressions = [];\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const stopNodeExp = this.options.stopNodes[i];\n if (typeof stopNodeExp === 'string') {\n // Convert string to Expression object\n this.stopNodeExpressions.push(new Expression(stopNodeExp));\n } else if (stopNodeExp instanceof Expression) {\n // Already an Expression object\n this.stopNodeExpressions.push(stopNodeExp);\n }\n }\n }\n }\n\n}\n\nfunction addExternalEntities(externalEntities) {\n const entKeys = Object.keys(externalEntities);\n for (let i = 0; i < entKeys.length; i++) {\n const ent = entKeys[i];\n const escaped = ent.replace(/[.\\-+*:]/g, '\\\\.');\n this.lastEntities[ent] = {\n regex: new RegExp(\"&\" + escaped + \";\", \"g\"),\n val: externalEntities[ent]\n }\n }\n}\n\n/**\n * @param {string} val\n * @param {string} tagName\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n * @param {boolean} dontTrim\n * @param {boolean} hasAttributes\n * @param {boolean} isLeafNode\n * @param {boolean} escapeEntities\n */\nfunction parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {\n if (val !== undefined) {\n if (this.options.trimValues && !dontTrim) {\n val = val.trim();\n }\n if (val.length > 0) {\n if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const newval = this.options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);\n if (newval === null || newval === undefined) {\n //don't parse\n return val;\n } else if (typeof newval !== typeof val || newval !== val) {\n //overwrite\n return newval;\n } else if (this.options.trimValues) {\n return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);\n } else {\n const trimmedVal = val.trim();\n if (trimmedVal === val) {\n return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);\n } else {\n return val;\n }\n }\n }\n }\n}\n\nfunction resolveNameSpace(tagname) {\n if (this.options.removeNSPrefix) {\n const tags = tagname.split(':');\n const prefix = tagname.charAt(0) === '/' ? '/' : '';\n if (tags[0] === 'xmlns') {\n return '';\n }\n if (tags.length === 2) {\n tagname = prefix + tags[1];\n }\n }\n return tagname;\n}\n\n//TODO: change regex to capture NS\n//const attrsRegx = new RegExp(\"([\\\\w\\\\-\\\\.\\\\:]+)\\\\s*=\\\\s*(['\\\"])((.|\\n)*?)\\\\2\",\"gm\");\nconst attrsRegx = new RegExp('([^\\\\s=]+)\\\\s*(=\\\\s*([\\'\"])([\\\\s\\\\S]*?)\\\\3)?', 'gm');\n\nfunction buildAttributesMap(attrStr, jPath, tagName) {\n if (this.options.ignoreAttributes !== true && typeof attrStr === 'string') {\n // attrStr = attrStr.replace(/\\r?\\n/g, ' ');\n //attrStr = attrStr || attrStr.trim();\n\n const matches = getAllMatches(attrStr, attrsRegx);\n const len = matches.length; //don't make it inline\n const attrs = {};\n\n // First pass: parse all attributes and update matcher with raw values\n // This ensures the matcher has all attribute values when processors run\n const rawAttrsForMatcher = {};\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n const oldVal = matches[i][4];\n\n if (attrName.length && oldVal !== undefined) {\n let parsedVal = oldVal;\n if (this.options.trimValues) {\n parsedVal = parsedVal.trim();\n }\n parsedVal = this.replaceEntitiesValue(parsedVal, tagName, jPath);\n rawAttrsForMatcher[attrName] = parsedVal;\n }\n }\n\n // Update matcher with raw attribute values BEFORE running processors\n if (Object.keys(rawAttrsForMatcher).length > 0 && typeof jPath === 'object' && jPath.updateCurrent) {\n jPath.updateCurrent(rawAttrsForMatcher);\n }\n\n // Second pass: now process attributes with matcher having full attribute context\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n\n // Convert jPath to string if needed for ignoreAttributesFn\n const jPathStr = this.options.jPath ? jPath.toString() : jPath;\n if (this.ignoreAttributesFn(attrName, jPathStr)) {\n continue\n }\n\n let oldVal = matches[i][4];\n let aName = this.options.attributeNamePrefix + attrName;\n\n if (attrName.length) {\n if (this.options.transformAttributeName) {\n aName = this.options.transformAttributeName(aName);\n }\n //if (aName === \"__proto__\") aName = \"#__proto__\";\n aName = sanitizeName(aName, this.options);\n\n if (oldVal !== undefined) {\n if (this.options.trimValues) {\n oldVal = oldVal.trim();\n }\n oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPathOrMatcher);\n if (newVal === null || newVal === undefined) {\n //don't parse\n attrs[aName] = oldVal;\n } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {\n //overwrite\n attrs[aName] = newVal;\n } else {\n //parse\n attrs[aName] = parseValue(\n oldVal,\n this.options.parseAttributeValue,\n this.options.numberParseOptions\n );\n }\n } else if (this.options.allowBooleanAttributes) {\n attrs[aName] = true;\n }\n }\n }\n\n if (!Object.keys(attrs).length) {\n return;\n }\n if (this.options.attributesGroupName) {\n const attrCollection = {};\n attrCollection[this.options.attributesGroupName] = attrs;\n return attrCollection;\n }\n return attrs\n }\n}\n\nconst parseXml = function (xmlData) {\n xmlData = xmlData.replace(/\\r\\n?/g, \"\\n\"); //TODO: remove this line\n const xmlObj = new xmlNode('!xml');\n let currentNode = xmlObj;\n let textData = \"\";\n\n // Reset matcher for new document\n this.matcher.reset();\n\n // Reset entity expansion counters for this document\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n\n const docTypeReader = new DocTypeReader(this.options.processEntities);\n for (let i = 0; i < xmlData.length; i++) {//for each char in XML data\n const ch = xmlData[i];\n if (ch === '<') {\n // const nextIndex = i+1;\n // const _2ndChar = xmlData[nextIndex];\n if (xmlData[i + 1] === '/') {//Closing Tag\n const closeIndex = findClosingIndex(xmlData, \">\", i, \"Closing Tag is not closed.\")\n let tagName = xmlData.substring(i + 2, closeIndex).trim();\n\n if (this.options.removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n }\n }\n\n tagName = transformTagName(this.options.transformTagName, tagName, \"\", this.options).tagName;\n\n if (currentNode) {\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n }\n\n //check if last tag of nested tag was unpaired tag\n const lastTagName = this.matcher.getCurrentTag();\n if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) {\n throw new Error(`Unpaired tag can not be used as closing tag: `);\n }\n if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) {\n // Pop the unpaired tag\n this.matcher.pop();\n this.tagsNodeStack.pop();\n }\n // Pop the closing tag\n this.matcher.pop();\n this.isCurrentNodeStopNode = false; // Reset flag when closing tag\n\n currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope\n textData = \"\";\n i = closeIndex;\n } else if (xmlData[i + 1] === '?') {\n\n let tagData = readTagExp(xmlData, i, false, \"?>\");\n if (!tagData) throw new Error(\"Pi Tag is not closed.\");\n\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n if ((this.options.ignoreDeclaration && tagData.tagName === \"?xml\") || this.options.ignorePiTags) {\n //do nothing\n } else {\n\n const childNode = new xmlNode(tagData.tagName);\n childNode.add(this.options.textNodeName, \"\");\n\n if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) {\n childNode[\":@\"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName);\n }\n this.addChild(currentNode, childNode, this.matcher, i);\n }\n\n\n i = tagData.closeIndex + 1;\n } else if (xmlData.substr(i + 1, 3) === '!--') {\n const endIndex = findClosingIndex(xmlData, \"-->\", i + 4, \"Comment is not closed.\")\n if (this.options.commentPropName) {\n const comment = xmlData.substring(i + 4, endIndex - 2);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n\n currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]);\n }\n i = endIndex;\n } else if (xmlData.substr(i + 1, 2) === '!D') {\n const result = docTypeReader.readDocType(xmlData, i);\n this.docTypeEntities = result.entities;\n i = result.i;\n } else if (xmlData.substr(i + 1, 2) === '![') {\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"CDATA is not closed.\") - 2;\n const tagExp = xmlData.substring(i + 9, closeIndex);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n\n let val = this.parseTextData(tagExp, currentNode.tagname, this.matcher, true, false, true, true);\n if (val == undefined) val = \"\";\n\n //cdata should be set even if it is 0 length string\n if (this.options.cdataPropName) {\n currentNode.add(this.options.cdataPropName, [{ [this.options.textNodeName]: tagExp }]);\n } else {\n currentNode.add(this.options.textNodeName, val);\n }\n\n i = closeIndex + 2;\n } else {//Opening tag\n let result = readTagExp(xmlData, i, this.options.removeNSPrefix);\n\n // Safety check: readTagExp can return undefined\n if (!result) {\n // Log context for debugging\n const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlData.length, i + 50));\n throw new Error(`readTagExp returned undefined at position ${i}. Context: \"${context}\"`);\n }\n\n let tagName = result.tagName;\n const rawTagName = result.rawTagName;\n let tagExp = result.tagExp;\n let attrExpPresent = result.attrExpPresent;\n let closeIndex = result.closeIndex;\n\n ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));\n\n if (this.options.strictReservedNames &&\n (tagName === this.options.commentPropName\n || tagName === this.options.cdataPropName\n || tagName === this.options.textNodeName\n || tagName === this.options.attributesGroupName\n )) {\n throw new Error(`Invalid tag name: ${tagName}`);\n }\n\n //save text as child node\n if (currentNode && textData) {\n if (currentNode.tagname !== '!xml') {\n //when nested tag is found\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher, false);\n }\n }\n\n //check if last tag was unpaired tag\n const lastTag = currentNode;\n if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) {\n currentNode = this.tagsNodeStack.pop();\n this.matcher.pop();\n }\n\n // Clean up self-closing syntax BEFORE processing attributes\n // This is where tagExp gets the trailing / removed\n let isSelfClosing = false;\n if (tagExp.length > 0 && tagExp.lastIndexOf(\"/\") === tagExp.length - 1) {\n isSelfClosing = true;\n if (tagName[tagName.length - 1] === \"/\") {\n tagName = tagName.substr(0, tagName.length - 1);\n tagExp = tagName;\n } else {\n tagExp = tagExp.substr(0, tagExp.length - 1);\n }\n\n // Re-check attrExpPresent after cleaning\n attrExpPresent = (tagName !== tagExp);\n }\n\n // Now process attributes with CLEAN tagExp (no trailing /)\n let prefixedAttrs = null;\n let rawAttrs = {};\n let namespace = undefined;\n\n // Extract namespace from rawTagName\n namespace = extractNamespace(rawTagName);\n\n // Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path\n if (tagName !== xmlObj.tagname) {\n this.matcher.push(tagName, {}, namespace);\n }\n\n // Now build attributes - callbacks will see correct matcher state\n if (tagName !== tagExp && attrExpPresent) {\n // Build attributes (returns prefixed attributes for the tree)\n // Note: buildAttributesMap now internally updates the matcher with raw attributes\n prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);\n\n if (prefixedAttrs) {\n // Extract raw attributes (without prefix) for our use\n rawAttrs = extractRawAttributes(prefixedAttrs, this.options);\n }\n }\n\n // Now check if this is a stop node (after attributes are set)\n if (tagName !== xmlObj.tagname) {\n this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher);\n }\n\n const startIndex = i;\n if (this.isCurrentNodeStopNode) {\n let tagContent = \"\";\n\n // For self-closing tags, content is empty\n if (isSelfClosing) {\n i = result.closeIndex;\n }\n //unpaired tag\n else if (this.options.unpairedTags.indexOf(tagName) !== -1) {\n i = result.closeIndex;\n }\n //normal tag\n else {\n //read until closing tag is found\n const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);\n if (!result) throw new Error(`Unexpected end of ${rawTagName}`);\n i = result.i;\n tagContent = result.tagContent;\n }\n\n const childNode = new xmlNode(tagName);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n\n // For stop nodes, store raw content as-is without any processing\n childNode.add(this.options.textNodeName, tagContent);\n\n this.matcher.pop(); // Pop the stop node tag\n this.isCurrentNodeStopNode = false; // Reset flag\n\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n } else {\n //selfClosing tag\n if (isSelfClosing) {\n ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));\n\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n this.matcher.pop(); // Pop self-closing tag\n this.isCurrentNodeStopNode = false; // Reset flag\n }\n else if (this.options.unpairedTags.indexOf(tagName) !== -1) {//unpaired tag\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n this.matcher.pop(); // Pop unpaired tag\n this.isCurrentNodeStopNode = false; // Reset flag\n i = result.closeIndex;\n // Continue to next iteration without changing currentNode\n continue;\n }\n //opening tag\n else {\n const childNode = new xmlNode(tagName);\n if (this.tagsNodeStack.length > this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n this.tagsNodeStack.push(currentNode);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n currentNode = childNode;\n }\n textData = \"\";\n i = closeIndex;\n }\n }\n } else {\n textData += xmlData[i];\n }\n }\n return xmlObj.child;\n}\n\nfunction addChild(currentNode, childNode, matcher, startIndex) {\n // unset startIndex if not requested\n if (!this.options.captureMetaData) startIndex = undefined;\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;\n const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[\":@\"])\n if (result === false) {\n //do nothing\n } else if (typeof result === \"string\") {\n childNode.tagname = result\n currentNode.addChild(childNode, startIndex);\n } else {\n currentNode.addChild(childNode, startIndex);\n }\n}\n\n/**\n * @param {object} val - Entity object with regex and val properties\n * @param {string} tagName - Tag name\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n */\nfunction replaceEntitiesValue(val, tagName, jPath) {\n const entityConfig = this.options.processEntities;\n\n if (!entityConfig || !entityConfig.enabled) {\n return val;\n }\n\n // Check if tag is allowed to contain entities\n if (entityConfig.allowedTags) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const allowed = Array.isArray(entityConfig.allowedTags)\n ? entityConfig.allowedTags.includes(tagName)\n : entityConfig.allowedTags(tagName, jPathOrMatcher);\n\n if (!allowed) {\n return val;\n }\n }\n\n // Apply custom tag filter if provided\n if (entityConfig.tagFilter) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {\n return val; // Skip based on custom filter\n }\n }\n\n // Replace DOCTYPE entities\n for (const entityName of Object.keys(this.docTypeEntities)) {\n const entity = this.docTypeEntities[entityName];\n const matches = val.match(entity.regx);\n\n if (matches) {\n // Track expansions\n this.entityExpansionCount += matches.length;\n\n // Check expansion limit\n if (entityConfig.maxTotalExpansions &&\n this.entityExpansionCount > entityConfig.maxTotalExpansions) {\n throw new Error(\n `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`\n );\n }\n\n // Store length before replacement\n const lengthBefore = val.length;\n val = val.replace(entity.regx, entity.val);\n\n // Check expanded length immediately after replacement\n if (entityConfig.maxExpandedLength) {\n this.currentExpandedLength += (val.length - lengthBefore);\n\n if (this.currentExpandedLength > entityConfig.maxExpandedLength) {\n throw new Error(\n `Total expanded content size exceeded: ${this.currentExpandedLength} > ${entityConfig.maxExpandedLength}`\n );\n }\n }\n }\n }\n // Replace standard entities\n for (const entityName of Object.keys(this.lastEntities)) {\n const entity = this.lastEntities[entityName];\n const matches = val.match(entity.regex);\n if (matches) {\n this.entityExpansionCount += matches.length;\n if (entityConfig.maxTotalExpansions &&\n this.entityExpansionCount > entityConfig.maxTotalExpansions) {\n throw new Error(\n `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`\n );\n }\n }\n val = val.replace(entity.regex, entity.val);\n }\n if (val.indexOf('&') === -1) return val;\n\n // Replace HTML entities if enabled\n if (this.options.htmlEntities) {\n for (const entityName of Object.keys(this.htmlEntities)) {\n const entity = this.htmlEntities[entityName];\n const matches = val.match(entity.regex);\n if (matches) {\n //console.log(matches);\n this.entityExpansionCount += matches.length;\n if (entityConfig.maxTotalExpansions &&\n this.entityExpansionCount > entityConfig.maxTotalExpansions) {\n throw new Error(\n `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`\n );\n }\n }\n val = val.replace(entity.regex, entity.val);\n }\n }\n\n // Replace ampersand entity last\n val = val.replace(this.ampEntity.regex, this.ampEntity.val);\n\n return val;\n}\n\n\nfunction saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {\n if (textData) { //store previously collected data as textNode\n if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0\n\n textData = this.parseTextData(textData,\n parentNode.tagname,\n matcher,\n false,\n parentNode[\":@\"] ? Object.keys(parentNode[\":@\"]).length !== 0 : false,\n isLeafNode);\n\n if (textData !== undefined && textData !== \"\")\n parentNode.add(this.options.textNodeName, textData);\n textData = \"\";\n }\n return textData;\n}\n\n//TODO: use jPath to simplify the logic\n/**\n * @param {Array} stopNodeExpressions - Array of compiled Expression objects\n * @param {Matcher} matcher - Current path matcher\n */\nfunction isItStopNode(stopNodeExpressions, matcher) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Returns the tag Expression and where it is ending handling single-double quotes situation\n * @param {string} xmlData \n * @param {number} i starting index\n * @returns \n */\nfunction tagExpWithClosingIndex(xmlData, i, closingChar = \">\") {\n let attrBoundary;\n let tagExp = \"\";\n for (let index = i; index < xmlData.length; index++) {\n let ch = xmlData[index];\n if (attrBoundary) {\n if (ch === attrBoundary) attrBoundary = \"\";//reset\n } else if (ch === '\"' || ch === \"'\") {\n attrBoundary = ch;\n } else if (ch === closingChar[0]) {\n if (closingChar[1]) {\n if (xmlData[index + 1] === closingChar[1]) {\n return {\n data: tagExp,\n index: index\n }\n }\n } else {\n return {\n data: tagExp,\n index: index\n }\n }\n } else if (ch === '\\t') {\n ch = \" \"\n }\n tagExp += ch;\n }\n}\n\nfunction findClosingIndex(xmlData, str, i, errMsg) {\n const closingIndex = xmlData.indexOf(str, i);\n if (closingIndex === -1) {\n throw new Error(errMsg)\n } else {\n return closingIndex + str.length - 1;\n }\n}\n\nfunction readTagExp(xmlData, i, removeNSPrefix, closingChar = \">\") {\n const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);\n if (!result) return;\n let tagExp = result.data;\n const closeIndex = result.index;\n const separatorIndex = tagExp.search(/\\s/);\n let tagName = tagExp;\n let attrExpPresent = true;\n if (separatorIndex !== -1) {//separate tag name and attributes expression\n tagName = tagExp.substring(0, separatorIndex);\n tagExp = tagExp.substring(separatorIndex + 1).trimStart();\n }\n\n const rawTagName = tagName;\n if (removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n attrExpPresent = tagName !== result.data.substr(colonIndex + 1);\n }\n }\n\n return {\n tagName: tagName,\n tagExp: tagExp,\n closeIndex: closeIndex,\n attrExpPresent: attrExpPresent,\n rawTagName: rawTagName,\n }\n}\n/**\n * find paired tag for a stop node\n * @param {string} xmlData \n * @param {string} tagName \n * @param {number} i \n */\nfunction readStopNodeData(xmlData, tagName, i) {\n const startIndex = i;\n // Starting at 1 since we already have an open tag\n let openTagCount = 1;\n\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === \"<\") {\n if (xmlData[i + 1] === \"/\") {//close tag\n const closeIndex = findClosingIndex(xmlData, \">\", i, `${tagName} is not closed`);\n let closeTagName = xmlData.substring(i + 2, closeIndex).trim();\n if (closeTagName === tagName) {\n openTagCount--;\n if (openTagCount === 0) {\n return {\n tagContent: xmlData.substring(startIndex, i),\n i: closeIndex\n }\n }\n }\n i = closeIndex;\n } else if (xmlData[i + 1] === '?') {\n const closeIndex = findClosingIndex(xmlData, \"?>\", i + 1, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (xmlData.substr(i + 1, 3) === '!--') {\n const closeIndex = findClosingIndex(xmlData, \"-->\", i + 3, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (xmlData.substr(i + 1, 2) === '![') {\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"StopNode is not closed.\") - 2;\n i = closeIndex;\n } else {\n const tagData = readTagExp(xmlData, i, '>')\n\n if (tagData) {\n const openTagName = tagData && tagData.tagName;\n if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== \"/\") {\n openTagCount++;\n }\n i = tagData.closeIndex;\n }\n }\n }\n }//end for loop\n}\n\nfunction parseValue(val, shouldParse, options) {\n if (shouldParse && typeof val === 'string') {\n //console.log(options)\n const newval = val.trim();\n if (newval === 'true') return true;\n else if (newval === 'false') return false;\n else return toNumber(val, options);\n } else {\n if (isExist(val)) {\n return val;\n } else {\n return '';\n }\n }\n}\n\nfunction fromCodePoint(str, base, prefix) {\n const codePoint = Number.parseInt(str, base);\n\n if (codePoint >= 0 && codePoint <= 0x10FFFF) {\n return String.fromCodePoint(codePoint);\n } else {\n return prefix + str + \";\";\n }\n}\n\nfunction transformTagName(fn, tagName, tagExp, options) {\n if (fn) {\n const newTagName = fn(tagName);\n if (tagExp === tagName) {\n tagExp = newTagName\n }\n tagName = newTagName;\n }\n tagName = sanitizeName(tagName, options);\n return { tagName, tagExp };\n}\n\n\n\nfunction sanitizeName(name, options) {\n if (criticalProperties.includes(name)) {\n throw new Error(`[SECURITY] Invalid name: \"${name}\" is a reserved JavaScript keyword that could cause prototype pollution`);\n } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return options.onDangerousProperty(name);\n }\n return name;\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","'use strict';\n\nimport XmlNode from './xmlNode.js';\nimport { Matcher } from 'path-expression-matcher';\n\nconst METADATA_SYMBOL = XmlNode.getMetaDataSymbol();\n\n/**\n * Helper function to strip attribute prefix from attribute map\n * @param {object} attrs - Attributes with prefix (e.g., {\"@_class\": \"code\"})\n * @param {string} prefix - Attribute prefix to remove (e.g., \"@_\")\n * @returns {object} Attributes without prefix (e.g., {\"class\": \"code\"})\n */\nfunction stripAttributePrefix(attrs, prefix) {\n if (!attrs || typeof attrs !== 'object') return {};\n if (!prefix) return attrs;\n\n const rawAttrs = {};\n for (const key in attrs) {\n if (key.startsWith(prefix)) {\n const rawName = key.substring(prefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * \n * @param {array} node \n * @param {any} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns \n */\nexport default function prettify(node, options, matcher) {\n return compress(node, options, matcher);\n}\n\n/**\n * \n * @param {array} arr \n * @param {object} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns object\n */\nfunction compress(arr, options, matcher) {\n let text;\n const compressedObj = {}; //This is intended to be a plain object\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const property = propName(tagObj);\n\n // Push current property to matcher WITH RAW ATTRIBUTES (no prefix)\n if (property !== undefined && property !== options.textNodeName) {\n const rawAttrs = stripAttributePrefix(\n tagObj[\":@\"] || {},\n options.attributeNamePrefix\n );\n matcher.push(property, rawAttrs);\n }\n\n if (property === options.textNodeName) {\n if (text === undefined) text = tagObj[property];\n else text += \"\" + tagObj[property];\n } else if (property === undefined) {\n continue;\n } else if (tagObj[property]) {\n\n let val = compress(tagObj[property], options, matcher);\n const isLeaf = isLeafTag(val, options);\n\n if (tagObj[\":@\"]) {\n assignAttributes(val, tagObj[\":@\"], matcher, options);\n } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {\n val = val[options.textNodeName];\n } else if (Object.keys(val).length === 0) {\n if (options.alwaysCreateTextNode) val[options.textNodeName] = \"\";\n else val = \"\";\n }\n\n if (tagObj[METADATA_SYMBOL] !== undefined && typeof val === \"object\" && val !== null) {\n val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata\n }\n\n\n if (compressedObj[property] !== undefined && Object.prototype.hasOwnProperty.call(compressedObj, property)) {\n if (!Array.isArray(compressedObj[property])) {\n compressedObj[property] = [compressedObj[property]];\n }\n compressedObj[property].push(val);\n } else {\n //TODO: if a node is not an array, then check if it should be an array\n //also determine if it is a leaf node\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? matcher.toString() : matcher;\n if (options.isArray(property, jPathOrMatcher, isLeaf)) {\n compressedObj[property] = [val];\n } else {\n compressedObj[property] = val;\n }\n }\n\n // Pop property from matcher after processing\n if (property !== undefined && property !== options.textNodeName) {\n matcher.pop();\n }\n }\n\n }\n // if(text && text.length > 0) compressedObj[options.textNodeName] = text;\n if (typeof text === \"string\") {\n if (text.length > 0) compressedObj[options.textNodeName] = text;\n } else if (text !== undefined) compressedObj[options.textNodeName] = text;\n\n\n return compressedObj;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== \":@\") return key;\n }\n}\n\nfunction assignAttributes(obj, attrMap, matcher, options) {\n if (attrMap) {\n const keys = Object.keys(attrMap);\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n const atrrName = keys[i]; // This is the PREFIXED name (e.g., \"@_class\")\n\n // Strip prefix for matcher path (for isArray callback)\n const rawAttrName = atrrName.startsWith(options.attributeNamePrefix)\n ? atrrName.substring(options.attributeNamePrefix.length)\n : atrrName;\n\n // For attributes, we need to create a temporary path\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath\n ? matcher.toString() + \".\" + rawAttrName\n : matcher;\n\n if (options.isArray(atrrName, jPathOrMatcher, true, true)) {\n obj[atrrName] = [attrMap[atrrName]];\n } else {\n obj[atrrName] = attrMap[atrrName];\n }\n }\n }\n}\n\nfunction isLeafTag(obj, options) {\n const { textNodeName } = options;\n const propCount = Object.keys(obj).length;\n\n if (propCount === 0) {\n return true;\n }\n\n if (\n propCount === 1 &&\n (obj[textNodeName] || typeof obj[textNodeName] === \"boolean\" || obj[textNodeName] === 0)\n ) {\n return true;\n }\n\n return false;\n}","import { buildOptions } from './OptionsBuilder.js';\nimport OrderedObjParser from './OrderedObjParser.js';\nimport prettify from './node2json.js';\nimport { validate } from \"../validator.js\";\nimport XmlNode from './xmlNode.js';\n\nexport default class XMLParser {\n\n constructor(options) {\n this.externalEntities = {};\n this.options = buildOptions(options);\n\n }\n /**\n * Parse XML dats to JS object \n * @param {string|Uint8Array} xmlData \n * @param {boolean|Object} validationOption \n */\n parse(xmlData, validationOption) {\n if (typeof xmlData !== \"string\" && xmlData.toString) {\n xmlData = xmlData.toString();\n } else if (typeof xmlData !== \"string\") {\n throw new Error(\"XML data is accepted in String or Bytes[] form.\")\n }\n\n if (validationOption) {\n if (validationOption === true) validationOption = {}; //validate with default options\n\n const result = validate(xmlData, validationOption);\n if (result !== true) {\n throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)\n }\n }\n const orderedObjParser = new OrderedObjParser(this.options);\n orderedObjParser.addExternalEntities(this.externalEntities);\n const orderedResult = orderedObjParser.parseXml(xmlData);\n if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;\n else return prettify(orderedResult, this.options, orderedObjParser.matcher);\n }\n\n /**\n * Add Entity which is not by default supported by this library\n * @param {string} key \n * @param {string} value \n */\n addEntity(key, value) {\n if (value.indexOf(\"&\") !== -1) {\n throw new Error(\"Entity value can't have '&'\")\n } else if (key.indexOf(\"&\") !== -1 || key.indexOf(\";\") !== -1) {\n throw new Error(\"An entity must be set without '&' and ';'. Eg. use '#xD' for ' '\")\n } else if (value === \"&\") {\n throw new Error(\"An entity with value '&' is not permitted\");\n } else {\n this.externalEntities[key] = value;\n }\n }\n\n /**\n * Returns a Symbol that can be used to access the metadata\n * property on a node.\n * \n * If Symbol is not available in the environment, an ordinary property is used\n * and the name of the property is here returned.\n * \n * The XMLMetaData property is only present when `captureMetaData`\n * is true in the options.\n */\n static getMetaDataSymbol() {\n return XmlNode.getMetaDataSymbol();\n }\n}\n","import { Expression, Matcher } from 'path-expression-matcher';\n\nconst EOL = \"\\n\";\n\n/**\n * \n * @param {array} jArray \n * @param {any} options \n * @returns \n */\nexport default function toXml(jArray, options) {\n let indentation = \"\";\n if (options.format && options.indentBy.length > 0) {\n indentation = EOL;\n }\n\n // Pre-compile stopNode expressions for pattern matching\n const stopNodeExpressions = [];\n if (options.stopNodes && Array.isArray(options.stopNodes)) {\n for (let i = 0; i < options.stopNodes.length; i++) {\n const node = options.stopNodes[i];\n if (typeof node === 'string') {\n stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n stopNodeExpressions.push(node);\n }\n }\n }\n\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n\n return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions);\n}\n\nfunction arrToStr(arr, options, indentation, matcher, stopNodeExpressions) {\n let xmlStr = \"\";\n let isPreviousElementTag = false;\n\n if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n\n if (!Array.isArray(arr)) {\n // Non-array values (e.g. string tag values) should be treated as text content\n if (arr !== undefined && arr !== null) {\n let text = arr.toString();\n text = replaceEntitiesValue(text, options);\n return text;\n }\n return \"\";\n }\n\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const tagName = propName(tagObj);\n if (tagName === undefined) continue;\n\n // Extract attributes from \":@\" property\n const attrValues = extractAttributeValues(tagObj[\":@\"], options);\n\n // Push tag to matcher WITH attributes\n matcher.push(tagName, attrValues);\n\n // Check if this is a stop node using Expression matching\n const isStopNode = checkStopNode(matcher, stopNodeExpressions);\n\n if (tagName === options.textNodeName) {\n let tagText = tagObj[tagName];\n if (!isStopNode) {\n tagText = options.tagValueProcessor(tagName, tagText);\n tagText = replaceEntitiesValue(tagText, options);\n }\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += tagText;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.cdataPropName) {\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += ``;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.commentPropName) {\n xmlStr += indentation + ``;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n } else if (tagName[0] === \"?\") {\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tempInd = tagName === \"?xml\" ? \"\" : indentation;\n let piTextNodeName = tagObj[tagName][0][options.textNodeName];\n piTextNodeName = piTextNodeName.length !== 0 ? \" \" + piTextNodeName : \"\"; //remove extra spacing\n xmlStr += tempInd + `<${tagName}${piTextNodeName}${attStr}?>`;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n }\n\n let newIdentation = indentation;\n if (newIdentation !== \"\") {\n newIdentation += options.indentBy;\n }\n\n // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tagStart = indentation + `<${tagName}${attStr}`;\n\n // If this is a stopNode, get raw content without processing\n let tagValue;\n if (isStopNode) {\n tagValue = getRawContent(tagObj[tagName], options);\n } else {\n\n tagValue = arrToStr(tagObj[tagName], options, newIdentation, matcher, stopNodeExpressions);\n }\n\n if (options.unpairedTags.indexOf(tagName) !== -1) {\n if (options.suppressUnpairedNode) xmlStr += tagStart + \">\";\n else xmlStr += tagStart + \"/>\";\n } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {\n xmlStr += tagStart + \"/>\";\n } else if (tagValue && tagValue.endsWith(\">\")) {\n xmlStr += tagStart + `>${tagValue}${indentation}`;\n } else {\n xmlStr += tagStart + \">\";\n if (tagValue && indentation !== \"\" && (tagValue.includes(\"/>\") || tagValue.includes(\"`;\n }\n isPreviousElementTag = true;\n\n // Pop tag from matcher\n matcher.pop();\n }\n\n return xmlStr;\n}\n\n/**\n * Extract attribute values from the \":@\" object and return as plain object\n * for passing to matcher.push()\n */\nfunction extractAttributeValues(attrMap, options) {\n if (!attrMap || options.ignoreAttributes) return null;\n\n const attrValues = {};\n let hasAttrs = false;\n\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // Remove the attribute prefix to get clean attribute name\n const cleanAttrName = attr.startsWith(options.attributeNamePrefix)\n ? attr.substr(options.attributeNamePrefix.length)\n : attr;\n attrValues[cleanAttrName] = attrMap[attr];\n hasAttrs = true;\n }\n\n return hasAttrs ? attrValues : null;\n}\n\n/**\n * Extract raw content from a stopNode without any processing\n * This preserves the content exactly as-is, including special characters\n */\nfunction getRawContent(arr, options) {\n if (!Array.isArray(arr)) {\n // Non-array values return as-is\n if (arr !== undefined && arr !== null) {\n return arr.toString();\n }\n return \"\";\n }\n\n let content = \"\";\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const tagName = propName(item);\n\n if (tagName === options.textNodeName) {\n // Raw text content - NO processing, NO entity replacement\n content += item[tagName];\n } else if (tagName === options.cdataPropName) {\n // CDATA content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName === options.commentPropName) {\n // Comment content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName && tagName[0] === \"?\") {\n // Processing instruction - skip for stopNodes\n continue;\n } else if (tagName) {\n // Nested tags within stopNode\n // Recursively get raw content and reconstruct the tag\n // For stopNodes, we don't process attributes either\n const attStr = attr_to_str_raw(item[\":@\"], options);\n const nestedContent = getRawContent(item[tagName], options);\n\n if (!nestedContent || nestedContent.length === 0) {\n content += `<${tagName}${attStr}/>`;\n } else {\n content += `<${tagName}${attStr}>${nestedContent}`;\n }\n }\n }\n return content;\n}\n\n/**\n * Build attribute string for stopNodes - NO entity replacement\n */\nfunction attr_to_str_raw(attrMap, options) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // For stopNodes, use raw value without processing\n let attrVal = attrMap[attr];\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n if (key !== \":@\") return key;\n }\n}\n\nfunction attr_to_str(attrMap, options, isStopNode) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n let attrVal;\n\n if (isStopNode) {\n // For stopNodes, use raw value without any processing\n attrVal = attrMap[attr];\n } else {\n // Normal processing: apply attributeValueProcessor and entity replacement\n attrVal = options.attributeValueProcessor(attr, attrMap[attr]);\n attrVal = replaceEntitiesValue(attrVal, options);\n }\n\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction checkStopNode(matcher, stopNodeExpressions) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction replaceEntitiesValue(textValue, options) {\n if (textValue && textValue.length > 0 && options.processEntities) {\n for (let i = 0; i < options.entities.length; i++) {\n const entity = options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}","'use strict';\n//parse Empty Node as self closing node\nimport buildFromOrderedJs from './orderedJs2Xml.js';\nimport getIgnoreAttributesFn from \"./ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\n\nconst defaultOptions = {\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n cdataPropName: false,\n format: false,\n indentBy: ' ',\n suppressEmptyNode: false,\n suppressUnpairedNode: true,\n suppressBooleanAttributes: true,\n tagValueProcessor: function (key, a) {\n return a;\n },\n attributeValueProcessor: function (attrName, a) {\n return a;\n },\n preserveOrder: false,\n commentPropName: false,\n unpairedTags: [],\n entities: [\n { regex: new RegExp(\"&\", \"g\"), val: \"&\" },//it must be on top\n { regex: new RegExp(\">\", \"g\"), val: \">\" },\n { regex: new RegExp(\"<\", \"g\"), val: \"<\" },\n { regex: new RegExp(\"\\'\", \"g\"), val: \"'\" },\n { regex: new RegExp(\"\\\"\", \"g\"), val: \""\" }\n ],\n processEntities: true,\n stopNodes: [],\n // transformTagName: false,\n // transformAttributeName: false,\n oneListGroup: false,\n maxNestedTags: 100,\n jPath: true // When true, callbacks receive string jPath; when false, receive Matcher instance\n};\n\nexport default function Builder(options) {\n this.options = Object.assign({}, defaultOptions, options);\n\n // Convert old-style stopNodes for backward compatibility\n // Old syntax: \"*.tag\" meant \"tag anywhere in tree\"\n // New syntax: \"..tag\" means \"tag anywhere in tree\"\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n this.options.stopNodes = this.options.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Convert old wildcard syntax to deep wildcard\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n\n // Pre-compile stopNode expressions for pattern matching\n this.stopNodeExpressions = [];\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const node = this.options.stopNodes[i];\n if (typeof node === 'string') {\n this.stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n this.stopNodeExpressions.push(node);\n }\n }\n }\n\n if (this.options.ignoreAttributes === true || this.options.attributesGroupName) {\n this.isAttribute = function (/*a*/) {\n return false;\n };\n } else {\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.attrPrefixLen = this.options.attributeNamePrefix.length;\n this.isAttribute = isAttribute;\n }\n\n this.processTextOrObjNode = processTextOrObjNode\n\n if (this.options.format) {\n this.indentate = indentate;\n this.tagEndChar = '>\\n';\n this.newLine = '\\n';\n } else {\n this.indentate = function () {\n return '';\n };\n this.tagEndChar = '>';\n this.newLine = '';\n }\n}\n\nBuilder.prototype.build = function (jObj) {\n if (this.options.preserveOrder) {\n return buildFromOrderedJs(jObj, this.options);\n } else {\n if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) {\n jObj = {\n [this.options.arrayNodeName]: jObj\n }\n }\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n return this.j2x(jObj, 0, matcher).val;\n }\n};\n\nBuilder.prototype.j2x = function (jObj, level, matcher) {\n let attrStr = '';\n let val = '';\n if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n // Get jPath based on option: string for backward compatibility, or Matcher for new features\n const jPath = this.options.jPath ? matcher.toString() : matcher;\n\n // Check if current node is a stopNode (will be used for attribute encoding)\n const isCurrentStopNode = this.checkStopNode(matcher);\n\n for (let key in jObj) {\n if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;\n if (typeof jObj[key] === 'undefined') {\n // supress undefined node only if it is not an attribute\n if (this.isAttribute(key)) {\n val += '';\n }\n } else if (jObj[key] === null) {\n // null attribute should be ignored by the attribute list, but should not cause the tag closing\n if (this.isAttribute(key)) {\n val += '';\n } else if (key === this.options.cdataPropName) {\n val += '';\n } else if (key[0] === '?') {\n val += this.indentate(level) + '<' + key + '?' + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n }\n // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n } else if (jObj[key] instanceof Date) {\n val += this.buildTextValNode(jObj[key], key, '', level, matcher);\n } else if (typeof jObj[key] !== 'object') {\n //premitive type\n const attr = this.isAttribute(key);\n if (attr && !this.ignoreAttributesFn(attr, jPath)) {\n attrStr += this.buildAttrPairStr(attr, '' + jObj[key], isCurrentStopNode);\n } else if (!attr) {\n //tag value\n if (key === this.options.textNodeName) {\n let newval = this.options.tagValueProcessor(key, '' + jObj[key]);\n val += this.replaceEntitiesValue(newval);\n } else {\n // Check if this is a stopNode before building\n matcher.push(key);\n const isStopNode = this.checkStopNode(matcher);\n matcher.pop();\n\n if (isStopNode) {\n // Build as raw content without encoding\n const textValue = '' + jObj[key];\n if (textValue === '') {\n val += this.indentate(level) + '<' + key + this.closeTag(key) + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '>' + textValue + '' + textValue + '${item}`;\n } else if (typeof item === 'object' && item !== null) {\n const nestedContent = this.buildRawContent(item);\n const nestedAttrs = this.buildAttributesForStopNode(item);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object\n const nestedContent = this.buildRawContent(value);\n const nestedAttrs = this.buildAttributesForStopNode(value);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n } else {\n // Primitive value\n content += `<${key}>${value}`;\n }\n }\n\n return content;\n};\n\n// Build attribute string for stopNode (no entity encoding)\nBuilder.prototype.buildAttributesForStopNode = function (obj) {\n if (!obj || typeof obj !== 'object') return '';\n\n let attrStr = '';\n\n // Check for attributesGroupName (when attributes are grouped)\n if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {\n const attrGroup = obj[this.options.attributesGroupName];\n for (let attrKey in attrGroup) {\n if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;\n const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix)\n ? attrKey.substring(this.options.attributeNamePrefix.length)\n : attrKey;\n const val = attrGroup[attrKey];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + cleanKey;\n } else {\n attrStr += ' ' + cleanKey + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n } else {\n // Look for individual attributes\n for (let key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const attr = this.isAttribute(key);\n if (attr) {\n const val = obj[key];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + attr;\n } else {\n attrStr += ' ' + attr + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n }\n }\n\n return attrStr;\n};\n\nBuilder.prototype.buildObjectNode = function (val, key, attrStr, level) {\n if (val === \"\") {\n if (key[0] === \"?\") return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n else {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n }\n } else {\n\n let tagEndExp = '' + val + tagEndExp);\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {\n return this.indentate(level) + `` + this.newLine;\n } else {\n return (\n this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +\n val +\n this.indentate(level) + tagEndExp);\n }\n }\n}\n\nBuilder.prototype.closeTag = function (key) {\n let closeTag = \"\";\n if (this.options.unpairedTags.indexOf(key) !== -1) { //unpaired\n if (!this.options.suppressUnpairedNode) closeTag = \"/\"\n } else if (this.options.suppressEmptyNode) { //empty\n closeTag = \"/\";\n } else {\n closeTag = `>` + this.newLine;\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName) {\n return this.indentate(level) + `` + this.newLine;\n } else if (key[0] === \"?\") {//PI tag\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n // Normal processing: apply tagValueProcessor and entity replacement\n let textValue = this.options.tagValueProcessor(key, val);\n textValue = this.replaceEntitiesValue(textValue);\n\n if (textValue === '') {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n } else {\n return this.indentate(level) + '<' + key + attrStr + '>' +\n textValue +\n ' 0 && this.options.processEntities) {\n for (let i = 0; i < this.options.entities.length; i++) {\n const entity = this.options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction indentate(level) {\n return this.options.indentBy.repeat(level);\n}\n\nfunction isAttribute(name /*, options*/) {\n if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {\n return name.substr(this.attrPrefixLen);\n } else {\n return false;\n }\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","// Re-export from fast-xml-builder for backward compatibility\nimport XMLBuilder from 'fast-xml-builder';\nexport default XMLBuilder;\n\n// If there are any named exports you also want to re-export:\nexport * from 'fast-xml-builder';","'use strict';\n\nimport { validate } from './validator.js';\nimport XMLParser from './xmlparser/XMLParser.js';\nimport XMLBuilder from './xmlbuilder/json2xml.js';\n\nconst XMLValidator = {\n validate: validate\n}\nexport {\n XMLParser,\n XMLValidator,\n XMLBuilder\n};"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","getAllMatches","string","regex","matches","match","exec","allmatches","startIndex","lastIndex","length","len","index","push","isName","DANGEROUS_PROPERTY_NAMES","criticalProperties","defaultOptions","allowBooleanAttributes","unpairedTags","validate","xmlData","options","assign","tags","tagFound","reachedRoot","substr","i","readPI","err","isWhiteSpace","getErrorObject","getLineNumberForPosition","tagStartPos","readCommentAndCDATA","closingTag","tagName","trim","substring","validateTagName","result","readAttributeStr","attrStr","attrStrStart","isValid","validateAttributeString","code","msg","line","tagClosed","otg","pop","openPos","col","indexOf","afterAmp","validateAmpersand","JSON","stringify","map","t","replace","char","start","tagname","angleBracketsCount","doubleQuote","singleQuote","startChar","validAttrStrRegxp","attrNames","getPositionFromMatch","undefined","attrName","validateAttrName","re","validateNumberAmpersand","count","message","lineNumber","lines","split","defaultOnDangerousProperty","name","includes","preserveOrder","attributeNamePrefix","attributesGroupName","textNodeName","ignoreAttributes","removeNSPrefix","parseTagValue","parseAttributeValue","trimValues","cdataPropName","numberParseOptions","hex","leadingZeros","eNotation","tagValueProcessor","val","attributeValueProcessor","stopNodes","alwaysCreateTextNode","isArray","commentPropName","processEntities","htmlEntities","ignoreDeclaration","ignorePiTags","transformTagName","transformAttributeName","updateTag","jPath","attrs","captureMetaData","maxNestedTags","strictReservedNames","onDangerousProperty","validatePropertyName","propertyName","optionName","normalized","toLowerCase","some","dangerous","Error","normalizeProcessEntities","enabled","maxEntitySize","maxExpansionDepth","maxTotalExpansions","maxExpandedLength","maxEntityCount","allowedTags","tagFilter","Math","max","_value$maxEntitySize","_value$maxExpansionDe","_value$maxTotalExpans","_value$maxExpandedLen","_value$maxEntityCount","_value$allowedTags","_value$tagFilter","METADATA_SYMBOL","buildOptions","built","_i","_propertyNameOptions","_propertyNameOptions$","Array","node","startsWith","XmlNode","child","create","_proto","add","_this$child$push","addChild","_this$child$push2","_this$child$push3","keys","getMetaDataSymbol","DocTypeReader","suppressValidationErr","readDocType","entities","entityCount","hasBody","comment","hasSeq","entityName","_this$readEntityExp","readEntityExp","escaped","regx","readElementExp","readNotationExp","skipWhitespace","test","validateEntityName","toUpperCase","entityValue","_this$readIdentifierV","readIdentifierVal","notationName","identifierType","publicIdentifier","systemIdentifier","_this$readIdentifierV2","_this$readIdentifierV3","_this$readIdentifierV4","type","identifierVal","elementName","contentModel","readAttlistExp","attributeName","attributeType","allowedNotations","notation","join","defaultValue","_this$readIdentifierV5","data","seq","j","hexRegex","numRegex","consider","decimalPoint","infinity","eNotationRegx","Matcher","constructor","separator","path","siblingStacks","attrValues","namespace","values","currentLevel","Map","siblings","siblingKey","counter","position","set","tag","updateCurrent","current","getCurrentTag","getCurrentNamespace","getAttrValue","hasAttr","getPosition","getCounter","getIndex","getDepth","toString","includeNamespace","sep","n","toArray","reset","expression","segments","hasDeepWildcard","_matchWithDeepWildcard","_matchSimple","segment","isCurrentNode","_matchSegment","pathIdx","segIdx","nextSeg","found","attrValue","actualValue","String","positionValue","snapshot","restore","Expression","pattern","_parse","_hasDeepWildcard","seg","_hasAttributeCondition","_hasPositionSelector","currentPart","_parseSegment","part","bracketContent","withoutBrackets","bracketMatch","content","slice","tagAndPosition","nsIndex","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","eqIndex","nthMatch","parseInt","hasAttributeCondition","hasPositionSelector","extractRawAttributes","prefixedAttrs","rawAttrs","extractNamespace","rawTagName","ns","OrderedObjParser","currentNode","tagsNodeStack","docTypeEntities","lastEntities","ampEntity","_","str","fromCodePoint","addExternalEntities","parseXml","parseTextData","resolveNameSpace","buildAttributesMap","isItStopNode","replaceEntitiesValue","readStopNodeData","saveTextToParentTag","ignoreAttributesFn","_step","_iterator","_createForOfIteratorHelperLoose","done","entityExpansionCount","currentExpandedLength","matcher","isCurrentNodeStopNode","stopNodeExpressions","stopNodeExp","externalEntities","entKeys","ent","dontTrim","hasAttributes","isLeafNode","escapeEntities","jPathOrMatcher","newval","parseValue","prefix","charAt","attrsRegx","rawAttrsForMatcher","oldVal","parsedVal","jPathStr","aName","sanitizeName","newVal","attrCollection","xmlObj","xmlNode","textData","docTypeReader","closeIndex","findClosingIndex","lastTagName","tagData","readTagExp","childNode","tagExp","attrExpPresent","endIndex","_ref","_ref2","context","min","_transformTagName","lastTag","isSelfClosing","tagContent","_transformTagName2","entityConfig","_i2","_Object$keys","entity","lengthBefore","_i3","_Object$keys2","_i4","_Object$keys3","parentNode","errMsg","closingIndex","closingChar","attrBoundary","ch","tagExpWithClosingIndex","separatorIndex","search","trimStart","openTagCount","shouldParse","trimmedStr","skipLike","numStr","Number","window","parse_int","isFinite","sign","eChar","eAdjacentToLeadingZeros","resolveEnotation","numTrimmedByZeros","decimalAdjacentToLeadingZeros","num","parsedStr","isPositive","Infinity","handleInfinity","toNumber","base","codePoint","fn","newTagName","stripAttributePrefix","prettify","compress","arr","text","compressedObj","tagObj","property","propName","isLeaf","isLeafTag","assignAttributes","attrMap","atrrName","rawAttrName","propCount","XMLParser","parse","validationOption","orderedObjParser","orderedResult","addEntity","toXml","jArray","indentation","format","indentBy","arrToStr","xmlStr","isPreviousElementTag","extractAttributeValues","isStopNode","checkStopNode","tagText","attStr","attr_to_str","tempInd","piTextNodeName","newIdentation","tagStart","tagValue","getRawContent","suppressUnpairedNode","suppressEmptyNode","endsWith","hasAttrs","attr","item","attr_to_str_raw","nestedContent","attrVal","suppressBooleanAttributes","textValue","a","oneListGroup","Builder","isAttribute","attrPrefixLen","processTextOrObjNode","indentate","tagEndChar","newLine","object","level","extractAttributes","rawContent","buildRawContent","buildAttributesForStopNode","buildObjectNode","j2x","buildTextValNode","repeat","build","jObj","buildFromOrderedJs","arrayNodeName","isCurrentStopNode","Date","buildAttrPairStr","closeTag","arrLen","listTagVal","listTagAttr","Ks","L","attrGroup","attrKey","nestedAttrs","cleanKey","tagEndExp","piClosingChar","XMLValidator"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"./lib/fxp.min.js","mappings":"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","sources":["webpack://fxp/webpack/universalModuleDefinition","webpack://fxp/webpack/bootstrap","webpack://fxp/webpack/runtime/define property getters","webpack://fxp/webpack/runtime/hasOwnProperty shorthand","webpack://fxp/webpack/runtime/make namespace object","webpack://fxp/./src/util.js","webpack://fxp/./src/validator.js","webpack://fxp/./src/xmlparser/OptionsBuilder.js","webpack://fxp/./src/xmlparser/xmlNode.js","webpack://fxp/./src/xmlparser/DocTypeReader.js","webpack://fxp/./node_modules/strnum/strnum.js","webpack://fxp/./node_modules/path-expression-matcher/src/Matcher.js","webpack://fxp/./node_modules/path-expression-matcher/src/Expression.js","webpack://fxp/./node_modules/path-expression-matcher/src/ExpressionSet.js","webpack://fxp/./node_modules/@nodable/entities/src/entities.js","webpack://fxp/./node_modules/@nodable/entities/src/EntityDecoder.js","webpack://fxp/./src/xmlparser/OrderedObjParser.js","webpack://fxp/./src/ignoreAttributes.js","webpack://fxp/./src/xmlparser/node2json.js","webpack://fxp/./src/xmlparser/XMLParser.js","webpack://fxp/./node_modules/fast-xml-builder/src/orderedJs2Xml.js","webpack://fxp/./node_modules/fast-xml-builder/src/fxb.js","webpack://fxp/./node_modules/fast-xml-builder/src/ignoreAttributes.js","webpack://fxp/./src/xmlbuilder/json2xml.js","webpack://fxp/./src/fxp.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"fxp\"] = factory();\n\telse\n\t\troot[\"fxp\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n/**\n * Dangerous property names that could lead to prototype pollution or security issues\n */\nexport const DANGEROUS_PROPERTY_NAMES = [\n // '__proto__',\n // 'constructor',\n // 'prototype',\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__'\n];\n\nexport const criticalProperties = [\"__proto__\", \"constructor\", \"prototype\"];","'use strict';\n\nimport { getAllMatches, isName } from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/()/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n\n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i + 1] === '?') {\n i += 2;\n i = readPI(xmlData, i);\n if (i.err) return i;\n } else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n\n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\" + tagName + \"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\" + tagName + \"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\" + otg.tagName + \"' (opened in line \" + openPos.line + \", col \" + openPos.col + \") instead of closing tag '\" + tagName + \"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if (options.unpairedTags.indexOf(tagName) !== -1) {\n //don't push into stack\n } else {\n tags.push({ tagName, tagStartPos });\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i + 1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else {\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n } else {\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if (isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\" + xmlData[i] + \"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n } else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\" + tags[0].tagName + \"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n } else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\" +\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '') +\n \"' found.\", { line: 1, col: 1 });\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char) {\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Select all the attributes whether valid or invalid.\n */\nconst validAttrStrRegxp = new RegExp('(\\\\s*)([^\\\\s=]+)(\\\\s*=)?(\\\\s*([\\'\"])(([\\\\s\\\\S])*?)\\\\5)?', 'g');\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = getAllMatches(attrStr, validAttrStrRegxp);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\" + matches[i][2] + \"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}\n","import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from \"../util.js\";\nimport { COMMON_HTML, CURRENCY } from '@nodable/entities';\n\nconst defaultOnDangerousProperty = (name) => {\n if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return \"__\" + name;\n }\n return name;\n};\n\n\nexport const defaultOptions = {\n preserveOrder: false,\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n removeNSPrefix: false, // remove NS from tag name or attribute name if true\n allowBooleanAttributes: false, //a tag can have attributes without any value\n //ignoreRootElement : false,\n parseTagValue: true,\n parseAttributeValue: false,\n trimValues: true, //Trim string values of tag and attributes\n cdataPropName: false,\n numberParseOptions: {\n hex: true,\n leadingZeros: true,\n eNotation: true\n },\n tagValueProcessor: function (tagName, val) {\n return val;\n },\n attributeValueProcessor: function (attrName, val) {\n return val;\n },\n stopNodes: [], //nested tags will not be parsed even for errors\n alwaysCreateTextNode: false,\n isArray: () => false,\n commentPropName: false,\n unpairedTags: [],\n processEntities: true,\n htmlEntities: false,\n entityDecoder: null,\n ignoreDeclaration: false,\n ignorePiTags: false,\n transformTagName: false,\n transformAttributeName: false,\n updateTag: function (tagName, jPath, attrs) {\n return tagName\n },\n // skipEmptyListItem: false\n captureMetaData: false,\n maxNestedTags: 100,\n strictReservedNames: true,\n jPath: true, // if true, pass jPath string to callbacks; if false, pass matcher instance\n onDangerousProperty: defaultOnDangerousProperty\n};\n\n\n/**\n * Validates that a property name is safe to use\n * @param {string} propertyName - The property name to validate\n * @param {string} optionName - The option field name (for error message)\n * @throws {Error} If property name is dangerous\n */\nfunction validatePropertyName(propertyName, optionName) {\n if (typeof propertyName !== 'string') {\n return; // Only validate string property names\n }\n\n const normalized = propertyName.toLowerCase();\n if (DANGEROUS_PROPERTY_NAMES.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n\n if (criticalProperties.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n}\n\n/**\n * Normalizes processEntities option for backward compatibility\n * @param {boolean|object} value \n * @returns {object} Always returns normalized object\n */\nfunction normalizeProcessEntities(value, htmlEntities) {\n // Boolean backward compatibility\n if (typeof value === 'boolean') {\n return {\n enabled: value, // true or false\n maxEntitySize: 10000,\n maxExpansionDepth: 10000,\n maxTotalExpansions: Infinity,\n maxExpandedLength: 100000,\n maxEntityCount: 1000,\n allowedTags: null,\n tagFilter: null,\n appliesTo: \"all\",\n };\n }\n\n // Object config - merge with defaults\n if (typeof value === 'object' && value !== null) {\n return {\n enabled: value.enabled !== false,\n maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000),\n maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10000),\n maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),\n maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000),\n maxEntityCount: Math.max(1, value.maxEntityCount ?? 1000),\n allowedTags: value.allowedTags ?? null,\n tagFilter: value.tagFilter ?? null,\n appliesTo: value.appliesTo ?? \"all\",\n };\n }\n\n // Default to enabled with limits\n return normalizeProcessEntities(true);\n}\n\nexport const buildOptions = function (options) {\n const built = Object.assign({}, defaultOptions, options);\n\n // Validate property names to prevent prototype pollution\n const propertyNameOptions = [\n { value: built.attributeNamePrefix, name: 'attributeNamePrefix' },\n { value: built.attributesGroupName, name: 'attributesGroupName' },\n { value: built.textNodeName, name: 'textNodeName' },\n { value: built.cdataPropName, name: 'cdataPropName' },\n { value: built.commentPropName, name: 'commentPropName' }\n ];\n\n for (const { value, name } of propertyNameOptions) {\n if (value) {\n validatePropertyName(value, name);\n }\n }\n\n if (built.onDangerousProperty === null) {\n built.onDangerousProperty = defaultOnDangerousProperty;\n }\n\n // Always normalize processEntities for backward compatibility and validation\n built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities);\n built.unpairedTagsSet = new Set(built.unpairedTags);\n // Convert old-style stopNodes for backward compatibility\n if (built.stopNodes && Array.isArray(built.stopNodes)) {\n built.stopNodes = built.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Old syntax: *.tagname meant \"tagname anywhere\"\n // Convert to new syntax: ..tagname\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n //console.debug(built.processEntities)\n return built;\n};","'use strict';\n\nlet METADATA_SYMBOL;\n\nif (typeof Symbol !== \"function\") {\n METADATA_SYMBOL = \"@@xmlMetadata\";\n} else {\n METADATA_SYMBOL = Symbol(\"XML Node Metadata\");\n}\n\nexport default class XmlNode {\n constructor(tagname) {\n this.tagname = tagname;\n this.child = []; //nested tags, text, cdata, comments in order\n this[\":@\"] = Object.create(null); //attributes map\n }\n add(key, val) {\n // this.child.push( {name : key, val: val, isCdata: isCdata });\n if (key === \"__proto__\") key = \"#__proto__\";\n this.child.push({ [key]: val });\n }\n addChild(node, startIndex) {\n if (node.tagname === \"__proto__\") node.tagname = \"#__proto__\";\n if (node[\":@\"] && Object.keys(node[\":@\"]).length > 0) {\n this.child.push({ [node.tagname]: node.child, [\":@\"]: node[\":@\"] });\n } else {\n this.child.push({ [node.tagname]: node.child });\n }\n // if requested, add the startIndex\n if (startIndex !== undefined) {\n // Note: for now we just overwrite the metadata. If we had more complex metadata,\n // we might need to do an object append here: metadata = { ...metadata, startIndex }\n this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };\n }\n }\n /** symbol used for metadata */\n static getMetaDataSymbol() {\n return METADATA_SYMBOL;\n }\n}\n","import { isName } from '../util.js';\n\nexport default class DocTypeReader {\n constructor(options) {\n this.suppressValidationErr = !options;\n this.options = options;\n }\n\n readDocType(xmlData, i) {\n const entities = Object.create(null);\n let entityCount = 0;\n\n if (xmlData[i + 3] === 'O' &&\n xmlData[i + 4] === 'C' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'Y' &&\n xmlData[i + 7] === 'P' &&\n xmlData[i + 8] === 'E') {\n i = i + 9;\n let angleBracketsCount = 1;\n let hasBody = false, comment = false;\n let exp = \"\";\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === '<' && !comment) { //Determine the tag type\n if (hasBody && hasSeq(xmlData, \"!ENTITY\", i)) {\n i += 7;\n let entityName, val;\n [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);\n if (val.indexOf(\"&\") === -1) { //Parameter entities are not supported\n if (this.options.enabled !== false &&\n this.options.maxEntityCount != null &&\n entityCount >= this.options.maxEntityCount) {\n throw new Error(\n `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`\n );\n }\n //const escaped = entityName.replace(/[.\\-+*:]/g, '\\\\.');\n //const escaped = entityName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n entities[entityName] = val;\n entityCount++;\n }\n }\n else if (hasBody && hasSeq(xmlData, \"!ELEMENT\", i)) {\n i += 8;//Not supported\n const { index } = this.readElementExp(xmlData, i + 1);\n i = index;\n } else if (hasBody && hasSeq(xmlData, \"!ATTLIST\", i)) {\n i += 8;//Not supported\n // const {index} = this.readAttlistExp(xmlData,i+1);\n // i = index;\n } else if (hasBody && hasSeq(xmlData, \"!NOTATION\", i)) {\n i += 9;//Not supported\n const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);\n i = index;\n } else if (hasSeq(xmlData, \"!--\", i)) comment = true;\n else throw new Error(`Invalid DOCTYPE`);\n\n angleBracketsCount++;\n exp = \"\";\n } else if (xmlData[i] === '>') { //Read tag content\n if (comment) {\n if (xmlData[i - 1] === \"-\" && xmlData[i - 2] === \"-\") {\n comment = false;\n angleBracketsCount--;\n }\n } else {\n angleBracketsCount--;\n }\n if (angleBracketsCount === 0) {\n break;\n }\n } else if (xmlData[i] === '[') {\n hasBody = true;\n } else {\n exp += xmlData[i];\n }\n }\n if (angleBracketsCount !== 0) {\n throw new Error(`Unclosed DOCTYPE`);\n }\n } else {\n throw new Error(`Invalid Tag instead of DOCTYPE`);\n }\n return { entities, i };\n }\n readEntityExp(xmlData, i) {\n //External entities are not supported\n // \n\n //Parameter entities are not supported\n // \n\n //Internal entities are supported\n // \n\n // Skip leading whitespace after this.options.maxEntitySize) {\n throw new Error(\n `Entity \"${entityName}\" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`\n );\n }\n\n i--;\n return [entityName, entityValue, i];\n }\n\n readNotationExp(xmlData, i) {\n // Skip leading whitespace after \n // \n // \n // \n // \n\n // Skip leading whitespace after {\n while (index < data.length && /\\s/.test(data[index])) {\n index++;\n }\n return index;\n};\n\n\n\nfunction hasSeq(data, seq, i) {\n for (let j = 0; j < seq.length; j++) {\n if (seq[j] !== data[i + j + 1]) return false;\n }\n return true;\n}\n\nfunction validateEntityName(name) {\n if (isName(name))\n return name;\n else\n throw new Error(`Invalid entity name ${name}`);\n}","const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;\nconst numRegex = /^([\\-\\+])?(0*)([0-9]*(\\.[0-9]*)?)$/;\n// const octRegex = /^0x[a-z0-9]+/;\n// const binRegex = /0x[a-z0-9]+/;\n\n\nconst consider = {\n hex: true,\n // oct: false,\n leadingZeros: true,\n decimalPoint: \"\\.\",\n eNotation: true,\n //skipLike: /regex/,\n infinity: \"original\", // \"null\", \"infinity\" (Infinity type), \"string\" (\"Infinity\" (the string literal))\n};\n\nexport default function toNumber(str, options = {}) {\n options = Object.assign({}, consider, options);\n if (!str || typeof str !== \"string\") return str;\n\n let trimmedStr = str.trim();\n\n if (trimmedStr.length === 0) return str;\n else if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;\n else if (trimmedStr === \"0\") return 0;\n else if (options.hex && hexRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 16);\n // }else if (options.oct && octRegex.test(str)) {\n // return Number.parseInt(val, 8);\n } else if (!isFinite(trimmedStr)) { //Infinity\n return handleInfinity(str, Number(trimmedStr), options);\n } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation\n return resolveEnotation(str, trimmedStr, options);\n // }else if (options.parseBin && binRegex.test(str)) {\n // return Number.parseInt(val, 2);\n } else {\n //separate negative sign, leading zeros, and rest number\n const match = numRegex.exec(trimmedStr);\n // +00.123 => [ , '+', '00', '.123', ..\n if (match) {\n const sign = match[1] || \"\";\n const leadingZeros = match[2];\n let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros\n const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.\n str[leadingZeros.length + 1] === \".\"\n : str[leadingZeros.length] === \".\";\n\n //trim ending zeros for floating number\n if (!options.leadingZeros //leading zeros are not allowed\n && (leadingZeros.length > 1\n || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {\n // 00, 00.3, +03.24, 03, 03.24\n return str;\n }\n else {//no leading zeros or leading zeros are allowed\n const num = Number(trimmedStr);\n const parsedStr = String(num);\n\n if (num === 0) return num;\n if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation\n if (options.eNotation) return num;\n else return str;\n } else if (trimmedStr.indexOf(\".\") !== -1) { //floating number\n if (parsedStr === \"0\") return num; //0.0\n else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000\n else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;\n else return str;\n }\n\n let n = leadingZeros ? numTrimmedByZeros : trimmedStr;\n if (leadingZeros) {\n // -009 => -9\n return (n === parsedStr) || (sign + n === parsedStr) ? num : str\n } else {\n // +9\n return (n === parsedStr) || (n === sign + parsedStr) ? num : str\n }\n }\n } else { //non-numeric string\n return str;\n }\n }\n}\n\nconst eNotationRegx = /^([-+])?(0*)(\\d*(\\.\\d*)?[eE][-\\+]?\\d+)$/;\nfunction resolveEnotation(str, trimmedStr, options) {\n if (!options.eNotation) return str;\n const notation = trimmedStr.match(eNotationRegx);\n if (notation) {\n let sign = notation[1] || \"\";\n const eChar = notation[3].indexOf(\"e\") === -1 ? \"E\" : \"e\";\n const leadingZeros = notation[2];\n const eAdjacentToLeadingZeros = sign ? // 0E.\n str[leadingZeros.length + 1] === eChar\n : str[leadingZeros.length] === eChar;\n\n if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;\n else if (leadingZeros.length === 1\n && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {\n return Number(trimmedStr);\n } else if (leadingZeros.length > 0) {\n // Has leading zeros — only accept if leadingZeros option allows it\n if (options.leadingZeros && !eAdjacentToLeadingZeros) {\n trimmedStr = (notation[1] || \"\") + notation[3];\n return Number(trimmedStr);\n } else return str;\n } else {\n // No leading zeros — always valid e-notation, parse it\n return Number(trimmedStr);\n }\n } else {\n return str;\n }\n}\n\n/**\n * \n * @param {string} numStr without leading zeros\n * @returns \n */\nfunction trimZeros(numStr) {\n if (numStr && numStr.indexOf(\".\") !== -1) {//float\n numStr = numStr.replace(/0+$/, \"\"); //remove ending zeros\n if (numStr === \".\") numStr = \"0\";\n else if (numStr[0] === \".\") numStr = \"0\" + numStr;\n else if (numStr[numStr.length - 1] === \".\") numStr = numStr.substring(0, numStr.length - 1);\n return numStr;\n }\n return numStr;\n}\n\nfunction parse_int(numStr, base) {\n //polyfill\n if (parseInt) return parseInt(numStr, base);\n else if (Number.parseInt) return Number.parseInt(numStr, base);\n else if (window && window.parseInt) return window.parseInt(numStr, base);\n else throw new Error(\"parseInt, Number.parseInt, window.parseInt are not supported\")\n}\n\n/**\n * Handle infinite values based on user option\n * @param {string} str - original input string\n * @param {number} num - parsed number (Infinity or -Infinity)\n * @param {object} options - user options\n * @returns {string|number|null} based on infinity option\n */\nfunction handleInfinity(str, num, options) {\n const isPositive = num === Infinity;\n\n switch (options.infinity.toLowerCase()) {\n case \"null\":\n return null;\n case \"infinity\":\n return num; // Return Infinity or -Infinity\n case \"string\":\n return isPositive ? \"Infinity\" : \"-Infinity\";\n case \"original\":\n default:\n return str; // Return original string like \"1e1000\"\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n */\n push(tagName, attrValues = null, namespace = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","/**\n * ExpressionSet - An indexed collection of Expressions for efficient bulk matching\n *\n * Instead of iterating all expressions on every tag, ExpressionSet pre-indexes\n * them at insertion time by depth and terminal tag name. At match time, only\n * the relevant bucket is evaluated — typically reducing checks from O(E) to O(1)\n * lookup plus O(small bucket) matches.\n *\n * Three buckets are maintained:\n * - `_byDepthAndTag` — exact depth + exact tag name (tightest, used first)\n * - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only)\n * - `_deepWildcards` — expressions containing `..` (cannot be depth-indexed)\n *\n * @example\n * import { Expression, ExpressionSet } from 'fast-xml-tagger';\n *\n * // Build once at config time\n * const stopNodes = new ExpressionSet();\n * stopNodes.add(new Expression('root.users.user'));\n * stopNodes.add(new Expression('root.config.setting'));\n * stopNodes.add(new Expression('..script'));\n *\n * // Query on every tag — hot path\n * if (stopNodes.matchesAny(matcher)) { ... }\n */\nexport default class ExpressionSet {\n constructor() {\n /** @type {Map} depth:tag → expressions */\n this._byDepthAndTag = new Map();\n\n /** @type {Map} depth → wildcard-tag expressions */\n this._wildcardByDepth = new Map();\n\n /** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */\n this._deepWildcards = [];\n\n /** @type {Set} pattern strings already added — used for deduplication */\n this._patterns = new Set();\n\n /** @type {boolean} whether the set is sealed against further additions */\n this._sealed = false;\n }\n\n /**\n * Add an Expression to the set.\n * Duplicate patterns (same pattern string) are silently ignored.\n *\n * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance\n * @returns {this} for chaining\n * @throws {TypeError} if called after seal()\n *\n * @example\n * set.add(new Expression('root.users.user'));\n * set.add(new Expression('..script'));\n */\n add(expression) {\n if (this._sealed) {\n throw new TypeError(\n 'ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.'\n );\n }\n\n // Deduplicate by pattern string\n if (this._patterns.has(expression.pattern)) return this;\n this._patterns.add(expression.pattern);\n\n if (expression.hasDeepWildcard()) {\n this._deepWildcards.push(expression);\n return this;\n }\n\n const depth = expression.length;\n const lastSeg = expression.segments[expression.segments.length - 1];\n const tag = lastSeg?.tag;\n\n if (!tag || tag === '*') {\n // Can index by depth but not by tag\n if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);\n this._wildcardByDepth.get(depth).push(expression);\n } else {\n // Tightest bucket: depth + tag\n const key = `${depth}:${tag}`;\n if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);\n this._byDepthAndTag.get(key).push(expression);\n }\n\n return this;\n }\n\n /**\n * Add multiple expressions at once.\n *\n * @param {import('./Expression.js').default[]} expressions - Array of Expression instances\n * @returns {this} for chaining\n *\n * @example\n * set.addAll([\n * new Expression('root.users.user'),\n * new Expression('root.config.setting'),\n * ]);\n */\n addAll(expressions) {\n for (const expr of expressions) this.add(expr);\n return this;\n }\n\n /**\n * Check whether a pattern string is already present in the set.\n *\n * @param {import('./Expression.js').default} expression\n * @returns {boolean}\n */\n has(expression) {\n return this._patterns.has(expression.pattern);\n }\n\n /**\n * Number of expressions in the set.\n * @type {number}\n */\n get size() {\n return this._patterns.size;\n }\n\n /**\n * Seal the set against further modifications.\n * Useful to prevent accidental mutations after config is built.\n * Calling add() or addAll() on a sealed set throws a TypeError.\n *\n * @returns {this}\n */\n seal() {\n this._sealed = true;\n return this;\n }\n\n /**\n * Whether the set has been sealed.\n * @type {boolean}\n */\n get isSealed() {\n return this._sealed;\n }\n\n /**\n * Test whether the matcher's current path matches any expression in the set.\n *\n * Evaluation order (cheapest → most expensive):\n * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions\n * 2. Depth-only wildcard bucket — O(1) lookup, rare\n * 3. Deep-wildcard list — always checked, but usually small\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {boolean} true if any expression matches the current path\n *\n * @example\n * if (stopNodes.matchesAny(matcher)) {\n * // handle stop node\n * }\n */\n matchesAny(matcher) {\n return this.findMatch(matcher) !== null;\n }\n /**\n * Find and return the first Expression that matches the matcher's current path.\n *\n * Uses the same evaluation order as matchesAny (cheapest → most expensive):\n * 1. Exact depth + tag bucket\n * 2. Depth-only wildcard bucket\n * 3. Deep-wildcard list\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {import('./Expression.js').default | null} the first matching Expression, or null\n *\n * @example\n * const expr = stopNodes.findMatch(matcher);\n * if (expr) {\n * // access expr.config, expr.pattern, etc.\n * }\n */\n findMatch(matcher) {\n const depth = matcher.getDepth();\n const tag = matcher.getCurrentTag();\n\n // 1. Tightest bucket — most expressions live here\n const exactKey = `${depth}:${tag}`;\n const exactBucket = this._byDepthAndTag.get(exactKey);\n if (exactBucket) {\n for (let i = 0; i < exactBucket.length; i++) {\n if (matcher.matches(exactBucket[i])) return exactBucket[i];\n }\n }\n\n // 2. Depth-matched wildcard-tag expressions\n const wildcardBucket = this._wildcardByDepth.get(depth);\n if (wildcardBucket) {\n for (let i = 0; i < wildcardBucket.length; i++) {\n if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];\n }\n }\n\n // 3. Deep wildcards — cannot be pre-filtered by depth or tag\n for (let i = 0; i < this._deepWildcards.length; i++) {\n if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];\n }\n\n return null;\n }\n}\n","// ---------------------------------------------------------------------------\n// Complete HTML5 named entity reference\n// Organized by logical categories for easy maintenance and selective importing\n// ---------------------------------------------------------------------------\n\n/**\n * Basic Latin & Special Characters\n * @type {Record}\n */\nexport const BASIC_LATIN = {\n amp: '&',\n AMP: '&',\n lt: '<',\n LT: '<',\n gt: '>',\n GT: '>',\n quot: '\"',\n QUOT: '\"',\n apos: \"'\",\n lsquo: '‘',\n rsquo: '’',\n ldquo: '“',\n rdquo: '”',\n lsquor: '‚',\n rsquor: '’',\n ldquor: '„',\n bdquo: '„',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n excl: '!',\n quest: '?',\n num: '#',\n dollar: '$',\n percent: '%',\n amp: '&',\n ast: '*',\n commat: '@',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n sol: '/',\n bsol: '\\\\',\n lbrace: '{',\n rbrace: '}',\n lbrack: '[',\n rbrack: ']',\n lpar: '(',\n rpar: ')',\n nbsp: '\\u00a0',\n iexcl: '¡',\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n COPY: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n REG: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n half: '½',\n frac34: '¾',\n iquest: '¿',\n times: '×',\n div: '÷',\n divide: '÷',\n};\n\n/**\n * Latin Extended & Accented Letters (A-Z)\n * @type {Record}\n */\nexport const LATIN_ACCENTS = {\n Agrave: 'À',\n agrave: 'à',\n Aacute: 'Á',\n aacute: 'á',\n Acirc: 'Â',\n acirc: 'â',\n Atilde: 'Ã',\n atilde: 'ã',\n Auml: 'Ä',\n auml: 'ä',\n Aring: 'Å',\n aring: 'å',\n AElig: 'Æ',\n aelig: 'æ',\n Ccedil: 'Ç',\n ccedil: 'ç',\n Egrave: 'È',\n egrave: 'è',\n Eacute: 'É',\n eacute: 'é',\n Ecirc: 'Ê',\n ecirc: 'ê',\n Euml: 'Ë',\n euml: 'ë',\n Igrave: 'Ì',\n igrave: 'ì',\n Iacute: 'Í',\n iacute: 'í',\n Icirc: 'Î',\n icirc: 'î',\n Iuml: 'Ï',\n iuml: 'ï',\n ETH: 'Ð',\n eth: 'ð',\n Ntilde: 'Ñ',\n ntilde: 'ñ',\n Ograve: 'Ò',\n ograve: 'ò',\n Oacute: 'Ó',\n oacute: 'ó',\n Ocirc: 'Ô',\n ocirc: 'ô',\n Otilde: 'Õ',\n otilde: 'õ',\n Ouml: 'Ö',\n ouml: 'ö',\n Oslash: 'Ø',\n oslash: 'ø',\n Ugrave: 'Ù',\n ugrave: 'ù',\n Uacute: 'Ú',\n uacute: 'ú',\n Ucirc: 'Û',\n ucirc: 'û',\n Uuml: 'Ü',\n uuml: 'ü',\n Yacute: 'Ý',\n yacute: 'ý',\n THORN: 'Þ',\n thorn: 'þ',\n szlig: 'ß',\n yuml: 'ÿ',\n Yuml: 'Ÿ',\n};\n\n/**\n * Latin Extended (Letters with diacritics)\n * @type {Record}\n */\nexport const LATIN_EXTENDED = {\n Amacr: 'Ā',\n amacr: 'ā',\n Abreve: 'Ă',\n abreve: 'ă',\n Aogon: 'Ą',\n aogon: 'ą',\n Cacute: 'Ć',\n cacute: 'ć',\n Ccirc: 'Ĉ',\n ccirc: 'ĉ',\n Cdot: 'Ċ',\n cdot: 'ċ',\n Ccaron: 'Č',\n ccaron: 'č',\n Dcaron: 'Ď',\n dcaron: 'ď',\n Dstrok: 'Đ',\n dstrok: 'đ',\n Emacr: 'Ē',\n emacr: 'ē',\n Ecaron: 'Ě',\n ecaron: 'ě',\n Edot: 'Ė',\n edot: 'ė',\n Eogon: 'Ę',\n eogon: 'ę',\n Gcirc: 'Ĝ',\n gcirc: 'ĝ',\n Gbreve: 'Ğ',\n gbreve: 'ğ',\n Gdot: 'Ġ',\n gdot: 'ġ',\n Gcedil: 'Ģ',\n Hcirc: 'Ĥ',\n hcirc: 'ĥ',\n Hstrok: 'Ħ',\n hstrok: 'ħ',\n Itilde: 'Ĩ',\n itilde: 'ĩ',\n Imacr: 'Ī',\n imacr: 'ī',\n Iogon: 'Į',\n iogon: 'į',\n Idot: 'İ',\n IJlig: 'IJ',\n ijlig: 'ij',\n Jcirc: 'Ĵ',\n jcirc: 'ĵ',\n Kcedil: 'Ķ',\n kcedil: 'ķ',\n kgreen: 'ĸ',\n Lacute: 'Ĺ',\n lacute: 'ĺ',\n Lcedil: 'Ļ',\n lcedil: 'ļ',\n Lcaron: 'Ľ',\n lcaron: 'ľ',\n Lmidot: 'Ŀ',\n lmidot: 'ŀ',\n Lstrok: 'Ł',\n lstrok: 'ł',\n Nacute: 'Ń',\n nacute: 'ń',\n Ncaron: 'Ň',\n ncaron: 'ň',\n Ncedil: 'Ņ',\n ncedil: 'ņ',\n ENG: 'Ŋ',\n eng: 'ŋ',\n Omacr: 'Ō',\n omacr: 'ō',\n Odblac: 'Ő',\n odblac: 'ő',\n OElig: 'Œ',\n oelig: 'œ',\n Racute: 'Ŕ',\n racute: 'ŕ',\n Rcaron: 'Ř',\n rcaron: 'ř',\n Rcedil: 'Ŗ',\n rcedil: 'ŗ',\n Sacute: 'Ś',\n sacute: 'ś',\n Scirc: 'Ŝ',\n scirc: 'ŝ',\n Scedil: 'Ş',\n scedil: 'ş',\n Scaron: 'Š',\n scaron: 'š',\n Tcedil: 'Ţ',\n tcedil: 'ţ',\n Tcaron: 'Ť',\n tcaron: 'ť',\n Tstrok: 'Ŧ',\n tstrok: 'ŧ',\n Utilde: 'Ũ',\n utilde: 'ũ',\n Umacr: 'Ū',\n umacr: 'ū',\n Ubreve: 'Ŭ',\n ubreve: 'ŭ',\n Uring: 'Ů',\n uring: 'ů',\n Udblac: 'Ű',\n udblac: 'ű',\n Uogon: 'Ų',\n uogon: 'ų',\n Wcirc: 'Ŵ',\n wcirc: 'ŵ',\n Ycirc: 'Ŷ',\n ycirc: 'ŷ',\n Zacute: 'Ź',\n zacute: 'ź',\n Zdot: 'Ż',\n zdot: 'ż',\n Zcaron: 'Ž',\n zcaron: 'ž',\n};\n\n/**\n * Greek Letters\n * @type {Record}\n */\nexport const GREEK = {\n Alpha: 'Α',\n alpha: 'α',\n Beta: 'Β',\n beta: 'β',\n Gamma: 'Γ',\n gamma: 'γ',\n Delta: 'Δ',\n delta: 'δ',\n Epsilon: 'Ε',\n epsilon: 'ε',\n epsiv: 'ϵ',\n varepsilon: 'ϵ',\n Zeta: 'Ζ',\n zeta: 'ζ',\n Eta: 'Η',\n eta: 'η',\n Theta: 'Θ',\n theta: 'θ',\n thetasym: 'ϑ',\n vartheta: 'ϑ',\n Iota: 'Ι',\n iota: 'ι',\n Kappa: 'Κ',\n kappa: 'κ',\n kappav: 'ϰ',\n varkappa: 'ϰ',\n Lambda: 'Λ',\n lambda: 'λ',\n Mu: 'Μ',\n mu: 'μ',\n Nu: 'Ν',\n nu: 'ν',\n Xi: 'Ξ',\n xi: 'ξ',\n Omicron: 'Ο',\n omicron: 'ο',\n Pi: 'Π',\n pi: 'π',\n piv: 'ϖ',\n varpi: 'ϖ',\n Rho: 'Ρ',\n rho: 'ρ',\n rhov: 'ϱ',\n varrho: 'ϱ',\n Sigma: 'Σ',\n sigma: 'σ',\n sigmaf: 'ς',\n sigmav: 'ς',\n varsigma: 'ς',\n Tau: 'Τ',\n tau: 'τ',\n Upsilon: 'Υ',\n upsilon: 'υ',\n upsi: 'υ',\n Upsi: 'ϒ',\n upsih: 'ϒ',\n Phi: 'Φ',\n phi: 'φ',\n phiv: 'ϕ',\n varphi: 'ϕ',\n Chi: 'Χ',\n chi: 'χ',\n Psi: 'Ψ',\n psi: 'ψ',\n Omega: 'Ω',\n omega: 'ω',\n ohm: 'Ω',\n Gammad: 'Ϝ',\n gammad: 'ϝ',\n digamma: 'ϝ',\n};\n\n/**\n * Cyrillic Letters\n * @type {Record}\n */\nexport const CYRILLIC = {\n Afr: '𝔄',\n afr: '𝔞',\n Acy: 'А',\n acy: 'а',\n Bcy: 'Б',\n bcy: 'б',\n Vcy: 'В',\n vcy: 'в',\n Gcy: 'Г',\n gcy: 'г',\n Dcy: 'Д',\n dcy: 'д',\n IEcy: 'Е',\n iecy: 'е',\n IOcy: 'Ё',\n iocy: 'ё',\n ZHcy: 'Ж',\n zhcy: 'ж',\n Zcy: 'З',\n zcy: 'з',\n Icy: 'И',\n icy: 'и',\n Jcy: 'Й',\n jcy: 'й',\n Kcy: 'К',\n kcy: 'к',\n Lcy: 'Л',\n lcy: 'л',\n Mcy: 'М',\n mcy: 'м',\n Ncy: 'Н',\n ncy: 'н',\n Ocy: 'О',\n ocy: 'о',\n Pcy: 'П',\n pcy: 'п',\n Rcy: 'Р',\n rcy: 'р',\n Scy: 'С',\n scy: 'с',\n Tcy: 'Т',\n tcy: 'т',\n Ucy: 'У',\n ucy: 'у',\n Fcy: 'Ф',\n fcy: 'ф',\n KHcy: 'Х',\n khcy: 'х',\n TScy: 'Ц',\n tscy: 'ц',\n CHcy: 'Ч',\n chcy: 'ч',\n SHcy: 'Ш',\n shcy: 'ш',\n SHCHcy: 'Щ',\n shchcy: 'щ',\n HARDcy: 'Ъ',\n hardcy: 'ъ',\n Ycy: 'Ы',\n ycy: 'ы',\n SOFTcy: 'Ь',\n softcy: 'ь',\n Ecy: 'Э',\n ecy: 'э',\n YUcy: 'Ю',\n yucy: 'ю',\n YAcy: 'Я',\n yacy: 'я',\n DJcy: 'Ђ',\n djcy: 'ђ',\n GJcy: 'Ѓ',\n gjcy: 'ѓ',\n Jukcy: 'Є',\n jukcy: 'є',\n DScy: 'Ѕ',\n dscy: 'ѕ',\n Iukcy: 'І',\n iukcy: 'і',\n YIcy: 'Ї',\n yicy: 'ї',\n Jsercy: 'Ј',\n jsercy: 'ј',\n LJcy: 'Љ',\n ljcy: 'љ',\n NJcy: 'Њ',\n njcy: 'њ',\n TSHcy: 'Ћ',\n tshcy: 'ћ',\n KJcy: 'Ќ',\n kjcy: 'ќ',\n Ubrcy: 'Ў',\n ubrcy: 'ў',\n DZcy: 'Џ',\n dzcy: 'џ',\n};\n\n/**\n * Mathematical Operators & Relations\n * @type {Record}\n */\nexport const MATH = {\n plus: '+',\n minus: '−',\n mnplus: '∓',\n mp: '∓',\n pm: '±',\n times: '×',\n div: '÷',\n divide: '÷',\n sdot: '⋅',\n star: '☆',\n starf: '★',\n bigstar: '★',\n lowast: '∗',\n ast: '*',\n midast: '*',\n compfn: '∘',\n smallcircle: '∘',\n bullet: '•',\n bull: '•',\n nbsp: '\\u00a0',\n hellip: '…',\n mldr: '…',\n prime: '′',\n Prime: '″',\n tprime: '‴',\n bprime: '‵',\n backprime: '‵',\n minus: '−',\n minusd: '∸',\n dotminus: '∸',\n plusdo: '∔',\n dotplus: '∔',\n plusmn: '±',\n minusplus: '∓',\n mnplus: '∓',\n mp: '∓',\n setminus: '∖',\n smallsetminus: '∖',\n Backslash: '∖',\n setmn: '∖',\n ssetmn: '∖',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n VerticalLine: '|',\n colon: ':',\n Colon: '∷',\n Proportion: '∷',\n ratio: '∶',\n equals: '=',\n ne: '≠',\n nequiv: '≢',\n equiv: '≡',\n Congruent: '≡',\n sim: '∼',\n thicksim: '∼',\n thksim: '∼',\n sime: '≃',\n simeq: '≃',\n TildeEqual: '≃',\n asymp: '≈',\n approx: '≈',\n thickapprox: '≈',\n thkap: '≈',\n TildeTilde: '≈',\n ncong: '≇',\n cong: '≅',\n TildeFullEqual: '≅',\n asympeq: '≍',\n CupCap: '≍',\n bump: '≎',\n Bumpeq: '≎',\n HumpDownHump: '≎',\n bumpe: '≏',\n bumpeq: '≏',\n HumpEqual: '≏',\n dotminus: '∸',\n minusd: '∸',\n plusdo: '∔',\n dotplus: '∔',\n le: '≤',\n LessEqual: '≤',\n ge: '≥',\n GreaterEqual: '≥',\n lesseqgtr: '⋚',\n lesseqqgtr: '⪋',\n greater: '>',\n less: '<',\n};\n\n/**\n * Mathematical Operators (Advanced)\n * @type {Record}\n */\nexport const MATH_ADVANCED = {\n alefsym: 'ℵ',\n aleph: 'ℵ',\n beth: 'ℶ',\n gimel: 'ℷ',\n daleth: 'ℸ',\n forall: '∀',\n ForAll: '∀',\n part: '∂',\n PartialD: '∂',\n exist: '∃',\n Exists: '∃',\n nexist: '∄',\n nexists: '∄',\n empty: '∅',\n emptyset: '∅',\n emptyv: '∅',\n varnothing: '∅',\n nabla: '∇',\n Del: '∇',\n isin: '∈',\n isinv: '∈',\n in: '∈',\n Element: '∈',\n notin: '∉',\n notinva: '∉',\n ni: '∋',\n niv: '∋',\n SuchThat: '∋',\n ReverseElement: '∋',\n notni: '∌',\n notniva: '∌',\n prod: '∏',\n Product: '∏',\n coprod: '∐',\n Coproduct: '∐',\n sum: '∑',\n Sum: '∑',\n minus: '−',\n mp: '∓',\n plusdo: '∔',\n dotplus: '∔',\n setminus: '∖',\n lowast: '∗',\n radic: '√',\n Sqrt: '√',\n prop: '∝',\n propto: '∝',\n Proportional: '∝',\n varpropto: '∝',\n infin: '∞',\n infintie: '⧝',\n ang: '∠',\n angle: '∠',\n angmsd: '∡',\n measuredangle: '∡',\n angsph: '∢',\n mid: '∣',\n VerticalBar: '∣',\n nmid: '∤',\n nsmid: '∤',\n npar: '∦',\n parallel: '∥',\n spar: '∥',\n nparallel: '∦',\n nspar: '∦',\n and: '∧',\n wedge: '∧',\n or: '∨',\n vee: '∨',\n cap: '∩',\n cup: '∪',\n int: '∫',\n Integral: '∫',\n conint: '∮',\n ContourIntegral: '∮',\n Conint: '∯',\n DoubleContourIntegral: '∯',\n Cconint: '∰',\n there4: '∴',\n therefore: '∴',\n Therefore: '∴',\n becaus: '∵',\n because: '∵',\n Because: '∵',\n ratio: '∶',\n Proportion: '∷',\n minusd: '∸',\n dotminus: '∸',\n mDDot: '∺',\n homtht: '∻',\n sim: '∼',\n bsimg: '∽',\n backsim: '∽',\n ac: '∾',\n mstpos: '∾',\n acd: '∿',\n VerticalTilde: '≀',\n wr: '≀',\n wreath: '≀',\n nsime: '≄',\n nsimeq: '≄',\n nsimeq: '≄',\n ncong: '≇',\n simne: '≆',\n ncongdot: '⩭̸',\n ngsim: '≵',\n nsim: '≁',\n napprox: '≉',\n nap: '≉',\n ngeq: '≱',\n nge: '≱',\n nleq: '≰',\n nle: '≰',\n ngtr: '≯',\n ngt: '≯',\n nless: '≮',\n nlt: '≮',\n nprec: '⊀',\n npr: '⊀',\n nsucc: '⊁',\n nsc: '⊁',\n};\n\n/**\n * Arrows\n * @type {Record}\n */\nexport const ARROWS = {\n larr: '←',\n leftarrow: '←',\n LeftArrow: '←',\n uarr: '↑',\n uparrow: '↑',\n UpArrow: '↑',\n rarr: '→',\n rightarrow: '→',\n RightArrow: '→',\n darr: '↓',\n downarrow: '↓',\n DownArrow: '↓',\n harr: '↔',\n leftrightarrow: '↔',\n LeftRightArrow: '↔',\n varr: '↕',\n updownarrow: '↕',\n UpDownArrow: '↕',\n nwarr: '↖',\n nwarrow: '↖',\n UpperLeftArrow: '↖',\n nearr: '↗',\n nearrow: '↗',\n UpperRightArrow: '↗',\n searr: '↘',\n searrow: '↘',\n LowerRightArrow: '↘',\n swarr: '↙',\n swarrow: '↙',\n LowerLeftArrow: '↙',\n lArr: '⇐',\n Leftarrow: '⇐',\n uArr: '⇑',\n Uparrow: '⇑',\n rArr: '⇒',\n Rightarrow: '⇒',\n dArr: '⇓',\n Downarrow: '⇓',\n hArr: '⇔',\n Leftrightarrow: '⇔',\n iff: '⇔',\n vArr: '⇕',\n Updownarrow: '⇕',\n lAarr: '⇚',\n Lleftarrow: '⇚',\n rAarr: '⇛',\n Rrightarrow: '⇛',\n lrarr: '⇆',\n leftrightarrows: '⇆',\n rlarr: '⇄',\n rightleftarrows: '⇄',\n lrhar: '⇋',\n leftrightharpoons: '⇋',\n ReverseEquilibrium: '⇋',\n rlhar: '⇌',\n rightleftharpoons: '⇌',\n Equilibrium: '⇌',\n udarr: '⇅',\n UpArrowDownArrow: '⇅',\n duarr: '⇵',\n DownArrowUpArrow: '⇵',\n llarr: '⇇',\n leftleftarrows: '⇇',\n rrarr: '⇉',\n rightrightarrows: '⇉',\n ddarr: '⇊',\n downdownarrows: '⇊',\n har: '↽',\n lhard: '↽',\n leftharpoondown: '↽',\n lharu: '↼',\n leftharpoonup: '↼',\n rhard: '⇁',\n rightharpoondown: '⇁',\n rharu: '⇀',\n rightharpoonup: '⇀',\n lsh: '↰',\n Lsh: '↰',\n rsh: '↱',\n Rsh: '↱',\n ldsh: '↲',\n rdsh: '↳',\n hookleftarrow: '↩',\n hookrightarrow: '↪',\n mapstoleft: '↤',\n mapstoup: '↥',\n map: '↦',\n mapsto: '↦',\n mapstodown: '↧',\n crarr: '↵',\n nwarrow: '↖',\n nearrow: '↗',\n searrow: '↘',\n swarrow: '↙',\n nleftarrow: '↚',\n nleftrightarrow: '↮',\n nrightarrow: '↛',\n nrarr: '↛',\n larrtl: '↢',\n rarrtl: '↣',\n leftarrowtail: '↢',\n rightarrowtail: '↣',\n twoheadleftarrow: '↞',\n twoheadrightarrow: '↠',\n Larr: '↞',\n Rarr: '↠',\n larrhk: '↩',\n rarrhk: '↪',\n larrlp: '↫',\n looparrowleft: '↫',\n rarrlp: '↬',\n looparrowright: '↬',\n harrw: '↭',\n leftrightsquigarrow: '↭',\n nrarrw: '↝̸',\n rarrw: '↝',\n rightsquigarrow: '↝',\n larrbfs: '⤟',\n rarrbfs: '⤠',\n nvHarr: '⤄',\n nvlArr: '⤂',\n nvrArr: '⤃',\n larrfs: '⤝',\n rarrfs: '⤞',\n Map: '⤅',\n larrsim: '⥳',\n rarrsim: '⥴',\n harrcir: '⥈',\n Uarrocir: '⥉',\n lurdshar: '⥊',\n ldrdhar: '⥧',\n ldrushar: '⥋',\n rdldhar: '⥩',\n lrhard: '⥭',\n rlhar: '⇌',\n uharr: '↾',\n uharl: '↿',\n dharr: '⇂',\n dharl: '⇃',\n Uarr: '↟',\n Darr: '↡',\n zigrarr: '⇝',\n nwArr: '⇖',\n neArr: '⇗',\n seArr: '⇘',\n swArr: '⇙',\n nharr: '↮',\n nhArr: '⇎',\n nlarr: '↚',\n nlArr: '⇍',\n nrarr: '↛',\n nrArr: '⇏',\n larrb: '⇤',\n LeftArrowBar: '⇤',\n rarrb: '⇥',\n RightArrowBar: '⇥',\n};\n\n/**\n * Geometric Shapes\n * @type {Record}\n */\nexport const SHAPES = {\n square: '□',\n Square: '□',\n squ: '□',\n squf: '▪',\n squarf: '▪',\n blacksquar: '▪',\n blacksquare: '▪',\n FilledVerySmallSquare: '▪',\n blk34: '▓',\n blk12: '▒',\n blk14: '░',\n block: '█',\n srect: '▭',\n rect: '▭',\n sdot: '⋅',\n sdotb: '⊡',\n dotsquare: '⊡',\n triangle: '▵',\n tri: '▵',\n trine: '▵',\n utri: '▵',\n triangledown: '▿',\n dtri: '▿',\n tridown: '▿',\n triangleleft: '◃',\n ltri: '◃',\n triangleright: '▹',\n rtri: '▹',\n blacktriangle: '▴',\n utrif: '▴',\n blacktriangledown: '▾',\n dtrif: '▾',\n blacktriangleleft: '◂',\n ltrif: '◂',\n blacktriangleright: '▸',\n rtrif: '▸',\n loz: '◊',\n lozenge: '◊',\n blacklozenge: '⧫',\n lozf: '⧫',\n bigcirc: '◯',\n xcirc: '◯',\n circ: 'ˆ',\n Circle: '○',\n cir: '○',\n o: '○',\n bullet: '•',\n bull: '•',\n hellip: '…',\n mldr: '…',\n nldr: '‥',\n boxh: '─',\n HorizontalLine: '─',\n boxv: '│',\n boxdr: '┌',\n boxdl: '┐',\n boxur: '└',\n boxul: '┘',\n boxvr: '├',\n boxvl: '┤',\n boxhd: '┬',\n boxhu: '┴',\n boxvh: '┼',\n boxH: '═',\n boxV: '║',\n boxdR: '╒',\n boxDr: '╓',\n boxDR: '╔',\n boxDl: '╕',\n boxdL: '╖',\n boxDL: '╗',\n boxuR: '╘',\n boxUr: '╙',\n boxUR: '╚',\n boxUl: '╜',\n boxuL: '╛',\n boxUL: '╝',\n boxvR: '╞',\n boxVr: '╟',\n boxVR: '╠',\n boxVl: '╢',\n boxvL: '╡',\n boxVL: '╣',\n boxHd: '╤',\n boxhD: '╥',\n boxHD: '╦',\n boxHu: '╧',\n boxhU: '╨',\n boxHU: '╩',\n boxvH: '╪',\n boxVh: '╫',\n boxVH: '╬',\n};\n\n/**\n * Punctuation & Diacritics\n * @type {Record}\n */\nexport const PUNCTUATION = {\n excl: '!',\n iexcl: '¡',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n frac34: '¾',\n iquest: '¿',\n nbsp: '\\u00a0',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n vert: '|',\n Verbar: '‖',\n verbar: '|',\n dblac: '˝',\n circ: 'ˆ',\n caron: 'ˇ',\n breve: '˘',\n dot: '˙',\n ring: '˚',\n ogon: '˛',\n tilde: '˜',\n DiacriticalGrave: '`',\n DiacriticalAcute: '´',\n DiacriticalTilde: '˜',\n DiacriticalDot: '˙',\n DiacriticalDoubleAcute: '˝',\n grave: '`',\n acute: '´',\n};\n\n/**\n * Currency Symbols\n * @type {Record}\n */\nexport const CURRENCY = {\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n euro: '€',\n dollar: '$',\n euro: '€',\n fnof: 'ƒ',\n inr: '₹',\n af: '؋',\n birr: 'ብር',\n peso: '₱',\n rub: '₽',\n won: '₩',\n yuan: '¥',\n cedil: '¸',\n};\n\n/**\n * Fractions\n * @type {Record}\n */\nexport const FRACTIONS = {\n frac12: '½',\n half: '½',\n frac13: '⅓',\n frac14: '¼',\n frac15: '⅕',\n frac16: '⅙',\n frac18: '⅛',\n frac23: '⅔',\n frac25: '⅖',\n frac34: '¾',\n frac35: '⅗',\n frac38: '⅜',\n frac45: '⅘',\n frac56: '⅚',\n frac58: '⅝',\n frac78: '⅞',\n frasl: '⁄',\n};\n\n/**\n * Miscellaneous Symbols\n * @type {Record}\n */\nexport const MISC_SYMBOLS = {\n trade: '™',\n TRADE: '™',\n telrec: '⌕',\n target: '⌖',\n ulcorn: '⌜',\n ulcorner: '⌜',\n urcorn: '⌝',\n urcorner: '⌝',\n dlcorn: '⌞',\n llcorner: '⌞',\n drcorn: '⌟',\n lrcorner: '⌟',\n intercal: '⊺',\n intcal: '⊺',\n oplus: '⊕',\n CirclePlus: '⊕',\n ominus: '⊖',\n CircleMinus: '⊖',\n otimes: '⊗',\n CircleTimes: '⊗',\n osol: '⊘',\n odot: '⊙',\n CircleDot: '⊙',\n oast: '⊛',\n circledast: '⊛',\n odash: '⊝',\n circleddash: '⊝',\n ocirc: '⊚',\n circledcirc: '⊚',\n boxplus: '⊞',\n plusb: '⊞',\n boxminus: '⊟',\n minusb: '⊟',\n boxtimes: '⊠',\n timesb: '⊠',\n boxdot: '⊡',\n sdotb: '⊡',\n veebar: '⊻',\n vee: '∨',\n barvee: '⊽',\n and: '∧',\n wedge: '∧',\n Cap: '⋒',\n Cup: '⋓',\n Fork: '⋔',\n pitchfork: '⋔',\n epar: '⋕',\n ltlarr: '⥶',\n nvap: '≍⃒',\n nvsim: '∼⃒',\n nvge: '≥⃒',\n nvle: '≤⃒',\n nvlt: '<⃒',\n nvgt: '>⃒',\n nvltrie: '⊴⃒',\n nvrtrie: '⊵⃒',\n Vdash: '⊩',\n dashv: '⊣',\n vDash: '⊨',\n Vdash: '⊩',\n Vvdash: '⊪',\n nvdash: '⊬',\n nvDash: '⊭',\n nVdash: '⊮',\n nVDash: '⊯',\n};\n\n/**\n * All entities combined (if you need everything)\n * @type {Record}\n */\nexport const ALL_ENTITIES = {\n ...BASIC_LATIN,\n ...LATIN_ACCENTS,\n ...LATIN_EXTENDED,\n ...GREEK,\n ...CYRILLIC,\n ...MATH,\n ...MATH_ADVANCED,\n ...ARROWS,\n ...SHAPES,\n ...PUNCTUATION,\n ...CURRENCY,\n ...FRACTIONS,\n ...MISC_SYMBOLS,\n};\n\nexport const XML = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: \"\\\"\"\n}\nexport const COMMON_HTML = {\n nbsp: '\\u00a0',\n copy: '\\u00a9',\n reg: '\\u00ae',\n trade: '\\u2122',\n mdash: '\\u2014',\n ndash: '\\u2013',\n hellip: '\\u2026',\n laquo: '\\u00ab',\n raquo: '\\u00bb',\n lsquo: '\\u2018',\n rsquo: '\\u2019',\n ldquo: '\\u201c',\n rdquo: '\\u201d',\n bull: '\\u2022',\n para: '\\u00b6',\n sect: '\\u00a7',\n deg: '\\u00b0',\n frac12: '\\u00bd',\n frac14: '\\u00bc',\n frac34: '\\u00be',\n}\n// ---------------------------------------------------------------------------\n// Note: NUMERIC_ENTITIES (&#NNN; / &#xHH;) are handled by the scanner directly\n// via String.fromCodePoint() without any map lookup.\n// ---------------------------------------------------------------------------","// ---------------------------------------------------------------------------\n// Built-in named entity map (name → replacement string)\n// No regex, no {regex,val} objects — just flat key/value pairs.\n// ---------------------------------------------------------------------------\n\nimport { XML as DEFAULT_XML_ENTITIES } from \"./entities.js\"\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst SPECIAL_CHARS = new Set('!?\\\\\\\\/[]$%{}^&*()<>|+');\n\n/**\n * Validate that an entity name contains no dangerous characters.\n * @param {string} name\n * @returns {string} the name, unchanged\n * @throws {Error} on invalid characters\n */\nfunction validateEntityName(name) {\n if (name[0] === '#') {\n throw new Error(`[EntityReplacer] Invalid character '#' in entity name: \"${name}\"`);\n }\n for (const ch of name) {\n if (SPECIAL_CHARS.has(ch)) {\n throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: \"${name}\"`);\n }\n }\n return name;\n}\n\n/**\n * Merge one or more entity maps into a flat name→string map.\n * Accepts either:\n * - plain string values: { amp: '&' }\n * - legacy {regex,val} / {regx,val}: { lt: { regex: /.../, val: '<' } }\n *\n * Values containing '&' are skipped (recursive expansion risk).\n *\n * @param {...object} maps\n * @returns {Record}\n */\nfunction mergeEntityMaps(...maps) {\n const out = Object.create(null);\n for (const map of maps) {\n if (!map) continue;\n for (const key of Object.keys(map)) {\n const raw = map[key];\n if (typeof raw === 'string') {\n out[key] = raw;\n } else if (raw && typeof raw === 'object' && raw.val !== undefined) {\n // Legacy {regex,val} or {regx,val} — extract the string val only\n const val = raw.val;\n if (typeof val === 'string') {\n out[key] = val;\n }\n // function vals are not supported in the scanner — skip\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// applyLimitsTo helpers\n// ---------------------------------------------------------------------------\n\nconst LIMIT_TIER_EXTERNAL = 'external'; // input/runtime + persistent external maps\nconst LIMIT_TIER_BASE = 'base'; // DEFAULT_XML_ENTITIES + namedEntities (system) maps\nconst LIMIT_TIER_ALL = 'all'; // every entity regardless of tier\n\n/**\n * Resolve `applyLimitsTo` option into a normalised Set of tier strings.\n * Accepted values: 'external' | 'base' | 'all' | string[]\n * Default: 'external' (only untrusted injected entities are counted).\n * @param {string|string[]|undefined} raw\n * @returns {Set}\n */\nfunction parseLimitTiers(raw) {\n if (!raw || raw === LIMIT_TIER_EXTERNAL) return new Set([LIMIT_TIER_EXTERNAL]);\n if (raw === LIMIT_TIER_ALL) return new Set([LIMIT_TIER_ALL]);\n if (raw === LIMIT_TIER_BASE) return new Set([LIMIT_TIER_BASE]);\n if (Array.isArray(raw)) return new Set(raw);\n return new Set([LIMIT_TIER_EXTERNAL]); // safe default for unrecognised values\n}\n\n// ---------------------------------------------------------------------------\n// NCR (Numeric Character Reference) classification\n// ---------------------------------------------------------------------------\n\n// Severity order — higher number = stricter action.\n// Used to enforce minimum action levels for specific codepoint ranges.\nconst NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 });\n\n// XML 1.0 §2.2: allowed chars are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n// Restricted C0: U+0001–U+001F excluding U+0009, U+000A, U+000D\nconst XML10_ALLOWED_C0 = new Set([0x09, 0x0A, 0x0D]);\n\n/**\n * Parse the `ncr` constructor option into flat, hot-path-friendly fields.\n * @param {object|undefined} ncr\n * @returns {{ xmlVersion: number, onLevel: number, nullLevel: number }}\n */\nfunction parseNCRConfig(ncr) {\n if (!ncr) {\n return { xmlVersion: 1.0, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove };\n }\n const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1.0;\n const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow;\n const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove;\n // 'allow' is not meaningful for null — clamp to at least 'remove'\n const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove);\n return { xmlVersion, onLevel, nullLevel: clampedNull };\n}\n\n// ---------------------------------------------------------------------------\n// EntityReplacer\n// ---------------------------------------------------------------------------\n\n/**\n * Single-pass, zero-regex entity replacer for XML/HTML content.\n *\n * Algorithm: scan the string once for '&', read to ';', resolve via map\n * or direct codepoint conversion, build output chunks, join once at the end.\n *\n * Entity lookup priority (highest → lowest):\n * 1. input / runtime (DOCTYPE entities for current document)\n * 2. persistent external (survive across documents)\n * 3. base named map (DEFAULT_XML_ENTITIES + user-supplied namedEntities)\n *\n * Both input and external resolve as the 'external' tier for limit purposes.\n * Base map entities resolve as the 'base' tier.\n *\n * Numeric / hex references (&#NNN; / &#xHH;) are resolved directly via\n * String.fromCodePoint() — no map needed. They count as 'base' tier.\n *\n * @example\n * const replacer = new EntityReplacer({ namedEntities: COMMON_HTML });\n * replacer.setExternalEntities({ brand: 'Acme' });\n *\n * const instance = replacer.reset();\n * instance.addInputEntities({ version: '1.0' });\n * instance.encode('&brand; v&version; <'); // 'Acme v1.0 <'\n */\nexport default class EntityDecoder {\n /**\n * @param {object} [options]\n * @param {object|null} [options.namedEntities] — extra named entities merged into base map\n * @param {object} [options.limit] — security limits\n * @param {number} [options.limit.maxTotalExpansions=0] — 0 = unlimited\n * @param {number} [options.limit.maxExpandedLength=0] — 0 = unlimited\n * @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external']\n * Which entity tiers count against the security limits:\n * - 'external' (default) — only input/runtime + persistent external entities\n * - 'base' — only DEFAULT_XML_ENTITIES + namedEntities\n * - 'all' — every entity regardless of tier\n * - string[] — explicit combination, e.g. ['external', 'base']\n * @param {((resolved: string, original: string) => string)|null} [options.postCheck=null]\n * @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string)\n * @param {string[]} [options.leave=[]] — entity names to keep as literal (unchanged in output)\n * @param {object} [options.ncr] — Numeric Character Reference controls\n * @param {1.0|1.1} [options.ncr.xmlVersion=1.0]\n * XML version governing which codepoint ranges are restricted:\n * - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited\n * - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is\n * @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow']\n * Base action for numeric references. Severity order: allow < leave < remove < throw.\n * For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove),\n * the effective action is max(onNCR, rangeMinimum).\n * @param {'remove'|'throw'} [options.ncr.nullNCR='remove']\n * Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe.\n */\n constructor(options = {}) {\n this._limit = options.limit || {};\n this._maxTotalExpansions = this._limit.maxTotalExpansions || 0;\n this._maxExpandedLength = this._limit.maxExpandedLength || 0;\n this._postCheck = typeof options.postCheck === 'function' ? options.postCheck : r => r;\n this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL);\n this._numericAllowed = options.numericAllowed ?? true;\n // Base map: DEFAULT_XML_ENTITIES + user-supplied extras. Immutable after construction.\n this._baseMap = mergeEntityMaps(DEFAULT_XML_ENTITIES, options.namedEntities || null);\n\n // Persistent external entities — survive across documents.\n // Stored as a separate map so reset() never touches them.\n /** @type {Record} */\n this._externalMap = Object.create(null);\n\n // Input / runtime entities — current document only, wiped on reset().\n /** @type {Record} */\n this._inputMap = Object.create(null);\n\n // Per-document counters\n this._totalExpansions = 0;\n this._expandedLength = 0;\n\n // --- New: remove / leave sets ---\n /** @type {Set} */\n this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []);\n /** @type {Set} */\n this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []);\n\n // --- NCR config (parsed into flat fields for hot-path speed) ---\n const ncrCfg = parseNCRConfig(options.ncr);\n this._ncrXmlVersion = ncrCfg.xmlVersion;\n this._ncrOnLevel = ncrCfg.onLevel;\n this._ncrNullLevel = ncrCfg.nullLevel;\n }\n\n // -------------------------------------------------------------------------\n // Persistent external entity registration\n // -------------------------------------------------------------------------\n\n /**\n * Replace the full set of persistent external entities.\n * All keys are validated — throws on invalid characters.\n * @param {Record} map\n */\n setExternalEntities(map) {\n if (map) {\n for (const key of Object.keys(map)) {\n validateEntityName(key);\n }\n }\n this._externalMap = mergeEntityMaps(map);\n }\n\n /**\n * Add a single persistent external entity.\n * @param {string} key\n * @param {string} value\n */\n addExternalEntity(key, value) {\n validateEntityName(key);\n if (typeof value === 'string' && value.indexOf('&') === -1) {\n this._externalMap[key] = value;\n }\n }\n\n // -------------------------------------------------------------------------\n // Input / runtime entity registration (per document)\n // -------------------------------------------------------------------------\n\n /**\n * Inject DOCTYPE entities for the current document.\n * Also resets per-document expansion counters.\n * @param {Record} map\n */\n addInputEntities(map) {\n this._totalExpansions = 0;\n this._expandedLength = 0;\n this._inputMap = mergeEntityMaps(map);\n }\n\n // -------------------------------------------------------------------------\n // Per-document reset\n // -------------------------------------------------------------------------\n\n /**\n * Wipe input/runtime entities and reset counters.\n * Call this before processing each new document.\n * @returns {this}\n */\n reset() {\n this._inputMap = Object.create(null);\n this._totalExpansions = 0;\n this._expandedLength = 0;\n return this;\n }\n\n // -------------------------------------------------------------------------\n // XML version (can be set after construction, e.g. once parser reads )\n // -------------------------------------------------------------------------\n\n /**\n * Update the XML version used for NCR classification.\n * Call this as soon as the document's `` declaration is parsed.\n * @param {1.0|1.1|number} version\n */\n setXmlVersion(version) {\n this._ncrXmlVersion = version === 1.1 ? 1.1 : 1.0;\n }\n\n // -------------------------------------------------------------------------\n // Primary API\n // -------------------------------------------------------------------------\n\n /**\n * Replace all entity references in `str` in a single pass.\n *\n * @param {string} str\n * @returns {string}\n */\n decode(str) {\n if (typeof str !== 'string' || str.length === 0) return str;\n //TODO: check if needed\n //if (str.indexOf('&') === -1) return str; // fast path — no entities at all\n\n const original = str;\n const chunks = [];\n const len = str.length;\n let last = 0; // start of next unprocessed literal chunk\n let i = 0;\n\n const limitExpansions = this._maxTotalExpansions > 0;\n const limitLength = this._maxExpandedLength > 0;\n const checkLimits = limitExpansions || limitLength;\n\n while (i < len) {\n // Scan forward to next '&'\n if (str.charCodeAt(i) !== 38 /* '&' */) { i++; continue; }\n\n // --- Found '&' at position i ---\n\n // Scan forward to ';'\n let j = i + 1;\n while (j < len && str.charCodeAt(j) !== 59 /* ';' */ && (j - i) <= 32) j++;\n\n if (j >= len || str.charCodeAt(j) !== 59) {\n // No closing ';' within window — treat '&' as literal\n i++;\n continue;\n }\n\n // Raw token between '&' and ';' (exclusive)\n const token = str.slice(i + 1, j);\n if (token.length === 0) { i++; continue; }\n\n let replacement;\n let tier; // which limit tier this entity belongs to\n\n if (this._removeSet.has(token)) {\n // Remove entity: replace with empty string\n replacement = '';\n // If entity was unknown (replacement undefined), we still need a tier for limits.\n // Treat as external tier because it's user-directed removal of an unknown reference.\n if (tier === undefined) {\n tier = LIMIT_TIER_EXTERNAL;\n }\n } else if (this._leaveSet.has(token)) {\n // Do not replace — keep original &token; as literal\n i++;\n continue;\n } else if (token.charCodeAt(0) === 35 /* '#' */) {\n // ---- Numeric / NCR reference ----\n // NCR classification always runs first — prohibited codepoints must be\n // caught regardless of numericAllowed.\n const ncrResult = this._resolveNCR(token);\n if (ncrResult === undefined) {\n // 'leave' action — keep original &token; as-is\n i++;\n continue;\n }\n replacement = ncrResult; // '' for remove, char string for allow\n tier = LIMIT_TIER_BASE;\n } else {\n // ---- Named reference ----\n const resolved = this._resolveName(token);\n replacement = resolved?.value;\n tier = resolved?.tier;\n }\n\n if (replacement === undefined) {\n // Unknown entity — leave as-is, advance past '&' only\n i++;\n continue;\n }\n\n // Flush literal chunk before this entity\n if (i > last) chunks.push(str.slice(last, i));\n chunks.push(replacement);\n last = j + 1; // skip past ';'\n i = last;\n\n // Apply expansion limits only if this tier is being tracked\n if (checkLimits && this._tierCounts(tier)) {\n if (limitExpansions) {\n this._totalExpansions++;\n if (this._totalExpansions > this._maxTotalExpansions) {\n throw new Error(\n `[EntityReplacer] Entity expansion count limit exceeded: ` +\n `${this._totalExpansions} > ${this._maxTotalExpansions}`\n );\n }\n }\n if (limitLength) {\n // delta: replacement.length minus the raw &token; length (token.length + 2 for '&' and ';')\n const delta = replacement.length - (token.length + 2);\n if (delta > 0) {\n this._expandedLength += delta;\n if (this._expandedLength > this._maxExpandedLength) {\n throw new Error(\n `[EntityReplacer] Expanded content length limit exceeded: ` +\n `${this._expandedLength} > ${this._maxExpandedLength}`\n );\n }\n }\n }\n }\n }\n\n // Flush trailing literal\n if (last < len) chunks.push(str.slice(last));\n\n // If nothing was replaced, chunks is empty — return original\n const result = chunks.length === 0 ? str : chunks.join('');\n\n return this._postCheck(result, original);\n }\n\n // -------------------------------------------------------------------------\n // Private: limit tier check\n // -------------------------------------------------------------------------\n\n /**\n * Returns true if a resolved entity of the given tier should count\n * against the expansion/length limits.\n * @param {string} tier — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE\n * @returns {boolean}\n */\n _tierCounts(tier) {\n if (this._limitTiers.has(LIMIT_TIER_ALL)) return true;\n return this._limitTiers.has(tier);\n }\n\n // -------------------------------------------------------------------------\n // Private: entity resolution\n // -------------------------------------------------------------------------\n\n /**\n * Resolve a named entity token (without & and ;).\n * Priority: inputMap > externalMap > baseMap\n * Returns the resolved value tagged with its limit tier.\n *\n * @param {string} name\n * @returns {{ value: string, tier: string }|undefined}\n */\n _resolveName(name) {\n // input and external both count as 'external' tier for limit purposes —\n // they are injected at runtime and are the untrusted surface.\n if (name in this._inputMap) return { value: this._inputMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._externalMap) return { value: this._externalMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._baseMap) return { value: this._baseMap[name], tier: LIMIT_TIER_BASE };\n return undefined;\n }\n\n /**\n * Classify a codepoint and return the minimum action level that must be applied.\n * Returns -1 when no minimum is imposed (normal allow path).\n *\n * Ranges checked (in priority order):\n * 1. U+0000 — null, governed by nullNCR (always ≥ remove)\n * 2. U+D800–U+DFFF — surrogates, always prohibited (min: remove)\n * 3. U+0001–U+001F \\ {0x09,0x0A,0x0D} — XML 1.0 restricted C0 (min: remove)\n * (skipped in XML 1.1 — C0 controls are allowed when written as NCRs)\n *\n * @param {number} cp — codepoint\n * @returns {number} — minimum NCR_LEVEL value, or -1 for no restriction\n */\n _classifyNCR(cp) {\n // 1. Null\n if (cp === 0) return this._ncrNullLevel;\n\n // 2. Surrogates — always prohibited, minimum 'remove'\n if (cp >= 0xD800 && cp <= 0xDFFF) return NCR_LEVEL.remove;\n\n // 3. XML 1.0 restricted C0 controls\n if (this._ncrXmlVersion === 1.0) {\n if (cp >= 0x01 && cp <= 0x1F && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove;\n }\n\n return -1; // no restriction\n }\n\n /**\n * Execute a resolved NCR action.\n *\n * @param {number} action — NCR_LEVEL value\n * @param {string} token — raw token (e.g. '#38') for error messages\n * @param {number} cp — codepoint, used only for error messages\n * @returns {string|undefined}\n * - decoded character string → 'allow'\n * - '' → 'remove'\n * - undefined → 'leave' (caller must skip past '&' only)\n * - throws Error → 'throw'\n */\n _applyNCRAction(action, token, cp) {\n switch (action) {\n case NCR_LEVEL.allow: return String.fromCodePoint(cp);\n case NCR_LEVEL.remove: return '';\n case NCR_LEVEL.leave: return undefined; // signal: keep literal\n case NCR_LEVEL.throw:\n throw new Error(\n `[EntityDecoder] Prohibited numeric character reference ` +\n `&${token}; (U+${cp.toString(16).toUpperCase().padStart(4, '0')})`\n );\n default: return String.fromCodePoint(cp);\n }\n }\n\n /**\n * Full NCR resolution pipeline for a numeric token.\n *\n * Steps:\n * 1. Parse the codepoint (decimal or hex).\n * 2. Validate the raw codepoint range (NaN, <0, >0x10FFFF).\n * 3. If numericAllowed is false and no minimum restriction applies → leave as-is.\n * 4. Classify the codepoint to find the minimum required action level.\n * 5. Resolve effective action = max(onNCR, minimum).\n * 6. Apply and return.\n *\n * @param {string} token — e.g. '#38', '#x26', '#X26'\n * @returns {string|undefined}\n * - string (incl. '') — replacement ('' = remove)\n * - undefined — leave original &token; as-is\n */\n _resolveNCR(token) {\n // Step 1: parse codepoint\n const second = token.charCodeAt(1);\n let cp;\n if (second === 120 /* x */ || second === 88 /* X */) {\n cp = parseInt(token.slice(2), 16);\n } else {\n cp = parseInt(token.slice(1), 10);\n }\n\n // Step 2: out-of-range → leave as-is unconditionally\n if (Number.isNaN(cp) || cp < 0 || cp > 0x10FFFF) return undefined;\n\n // Step 3: classify to get minimum action level\n const minimum = this._classifyNCR(cp);\n\n // Step 4: if numericAllowed is false and no hard minimum → leave\n if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return undefined;\n\n // Step 5: effective action = max(configured onNCR, range minimum)\n const effective = minimum === -1\n ? this._ncrOnLevel\n : Math.max(this._ncrOnLevel, minimum);\n\n // Step 6: apply\n return this._applyNCRAction(effective, token, cp);\n }\n}","'use strict';\n///@ts-check\n\nimport { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';\nimport xmlNode from './xmlNode.js';\nimport DocTypeReader from './DocTypeReader.js';\nimport toNumber from \"strnum\";\nimport getIgnoreAttributesFn from \"../ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\nimport { ExpressionSet } from 'path-expression-matcher';\nimport { EntityDecoder, XML, CURRENCY, COMMON_HTML } from '@nodable/entities';\n\n// const regx =\n// '<((!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\\\/)(NAME)\\\\s*>))([^<]*)'\n// .replace(/NAME/g, util.nameRegexp);\n\n//const tagsRegx = new RegExp(\"<(\\\\/?[\\\\w:\\\\-\\._]+)([^>]*)>(\\\\s*\"+cdataRegx+\")*([^<]+)?\",\"g\");\n//const tagsRegx = new RegExp(\"<(\\\\/?)((\\\\w*:)?([\\\\w:\\\\-\\._]+))([^>]*)>([^<]*)(\"+cdataRegx+\"([^<]*))*([^<]+)?\",\"g\");\n\n// Helper functions for attribute and namespace handling\n\n/**\n * Extract raw attributes (without prefix) from prefixed attribute map\n * @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap\n * @param {object} options - Parser options containing attributeNamePrefix\n * @returns {object} Raw attributes for matcher\n */\nfunction extractRawAttributes(prefixedAttrs, options) {\n if (!prefixedAttrs) return {};\n\n // Handle attributesGroupName option\n const attrs = options.attributesGroupName\n ? prefixedAttrs[options.attributesGroupName]\n : prefixedAttrs;\n\n if (!attrs) return {};\n\n const rawAttrs = {};\n for (const key in attrs) {\n // Remove the attribute prefix to get raw name\n if (key.startsWith(options.attributeNamePrefix)) {\n const rawName = key.substring(options.attributeNamePrefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * Extract namespace from raw tag name\n * @param {string} rawTagName - Tag name possibly with namespace (e.g., \"soap:Envelope\")\n * @returns {string|undefined} Namespace or undefined\n */\nfunction extractNamespace(rawTagName) {\n if (!rawTagName || typeof rawTagName !== 'string') return undefined;\n\n const colonIndex = rawTagName.indexOf(':');\n if (colonIndex !== -1 && colonIndex > 0) {\n const ns = rawTagName.substring(0, colonIndex);\n // Don't treat xmlns as a namespace\n if (ns !== 'xmlns') {\n return ns;\n }\n }\n return undefined;\n}\n\nexport default class OrderedObjParser {\n constructor(options) {\n this.options = options;\n this.currentNode = null;\n this.tagsNodeStack = [];\n this.parseXml = parseXml;\n this.parseTextData = parseTextData;\n this.resolveNameSpace = resolveNameSpace;\n this.buildAttributesMap = buildAttributesMap;\n this.isItStopNode = isItStopNode;\n this.replaceEntitiesValue = replaceEntitiesValue;\n this.readStopNodeData = readStopNodeData;\n this.saveTextToParentTag = saveTextToParentTag;\n this.addChild = addChild;\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n let namedEntities = { ...XML };\n if (this.options.entityDecoder) {\n this.entityDecoder = this.options.entityDecoder\n } else {\n if (typeof this.options.htmlEntities === \"object\") namedEntities = this.options.htmlEntities;\n else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };\n this.entityDecoder = new EntityDecoder({\n namedEntities: namedEntities,\n numericAllowed: this.options.htmlEntities,\n limit: {\n maxTotalExpansions: this.options.processEntities.maxTotalExpansions,\n maxExpandedLength: this.options.processEntities.maxExpandedLength,\n applyLimitsTo: this.options.processEntities.appliesTo,\n }\n //postCheck: resolved => resolved\n });\n }\n\n // Initialize path matcher for path-expression-matcher\n this.matcher = new Matcher();\n\n // Live read-only proxy of matcher — PEM creates and caches this internally.\n // All user callbacks receive this instead of the mutable matcher.\n this.readonlyMatcher = this.matcher.readOnly();\n\n // Flag to track if current node is a stop node (optimization)\n this.isCurrentNodeStopNode = false;\n\n // Pre-compile stopNodes expressions\n this.stopNodeExpressionsSet = new ExpressionSet();\n const stopNodesOpts = this.options.stopNodes;\n if (stopNodesOpts && stopNodesOpts.length > 0) {\n for (let i = 0; i < stopNodesOpts.length; i++) {\n const stopNodeExp = stopNodesOpts[i];\n if (typeof stopNodeExp === 'string') {\n // Convert string to Expression object\n this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));\n } else if (stopNodeExp instanceof Expression) {\n // Already an Expression object\n this.stopNodeExpressionsSet.add(stopNodeExp);\n }\n }\n this.stopNodeExpressionsSet.seal();\n }\n }\n\n}\n\n\n/**\n * @param {string} val\n * @param {string} tagName\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n * @param {boolean} dontTrim\n * @param {boolean} hasAttributes\n * @param {boolean} isLeafNode\n * @param {boolean} escapeEntities\n */\nfunction parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {\n const options = this.options;\n if (val !== undefined) {\n if (options.trimValues && !dontTrim) {\n val = val.trim();\n }\n if (val.length > 0) {\n if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;\n const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);\n if (newval === null || newval === undefined) {\n //don't parse\n return val;\n } else if (typeof newval !== typeof val || newval !== val) {\n //overwrite\n return newval;\n } else if (options.trimValues) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n const trimmedVal = val.trim();\n if (trimmedVal === val) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n return val;\n }\n }\n }\n }\n}\n\nfunction resolveNameSpace(tagname) {\n if (this.options.removeNSPrefix) {\n const tags = tagname.split(':');\n const prefix = tagname.charAt(0) === '/' ? '/' : '';\n if (tags[0] === 'xmlns') {\n return '';\n }\n if (tags.length === 2) {\n tagname = prefix + tags[1];\n }\n }\n return tagname;\n}\n\n//TODO: change regex to capture NS\n//const attrsRegx = new RegExp(\"([\\\\w\\\\-\\\\.\\\\:]+)\\\\s*=\\\\s*(['\\\"])((.|\\n)*?)\\\\2\",\"gm\");\nconst attrsRegx = new RegExp('([^\\\\s=]+)\\\\s*(=\\\\s*([\\'\"])([\\\\s\\\\S]*?)\\\\3)?', 'gm');\n\nfunction buildAttributesMap(attrStr, jPath, tagName, force = false) {\n const options = this.options;\n if (force === true || (options.ignoreAttributes !== true && typeof attrStr === 'string')) {\n // attrStr = attrStr.replace(/\\r?\\n/g, ' ');\n //attrStr = attrStr || attrStr.trim();\n\n const matches = getAllMatches(attrStr, attrsRegx);\n const len = matches.length; //don't make it inline\n const attrs = {};\n\n // Pre-process values once: trim + entity replacement\n // Reused in both matcher update and second pass\n const processedVals = new Array(len);\n let hasRawAttrs = false;\n const rawAttrsForMatcher = {};\n\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n const oldVal = matches[i][4];\n\n if (attrName.length && oldVal !== undefined) {\n let val = oldVal;\n if (options.trimValues) val = val.trim();\n val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);\n processedVals[i] = val;\n\n rawAttrsForMatcher[attrName] = val;\n hasRawAttrs = true;\n }\n }\n\n // Update matcher ONCE before second pass, if applicable\n if (hasRawAttrs && typeof jPath === 'object' && jPath.updateCurrent) {\n jPath.updateCurrent(rawAttrsForMatcher);\n }\n\n // Hoist toString() once — path doesn't change during attribute processing\n const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;\n\n // Second pass: apply processors, build final attrs\n let hasAttrs = false;\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n\n if (this.ignoreAttributesFn(attrName, jPathStr)) continue;\n\n let aName = options.attributeNamePrefix + attrName;\n\n if (attrName.length) {\n if (options.transformAttributeName) {\n aName = options.transformAttributeName(aName);\n }\n aName = sanitizeName(aName, options);\n\n if (matches[i][4] !== undefined) {\n // Reuse already-processed value — no double entity replacement\n const oldVal = processedVals[i];\n\n const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);\n if (newVal === null || newVal === undefined) {\n attrs[aName] = oldVal;\n } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {\n attrs[aName] = newVal;\n } else {\n attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);\n }\n hasAttrs = true;\n } else if (options.allowBooleanAttributes) {\n attrs[aName] = true;\n hasAttrs = true;\n }\n }\n }\n\n if (!hasAttrs) return;\n\n if (options.attributesGroupName) {\n const attrCollection = {};\n attrCollection[options.attributesGroupName] = attrs;\n return attrCollection;\n }\n return attrs;\n }\n}\nconst parseXml = function (xmlData) {\n xmlData = xmlData.replace(/\\r\\n?/g, \"\\n\"); //TODO: remove this line\n const xmlObj = new xmlNode('!xml');\n let currentNode = xmlObj;\n let textData = \"\";\n\n // Reset matcher for new document\n this.matcher.reset();\n this.entityDecoder.reset();\n\n // Reset entity expansion counters for this document\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n const options = this.options;\n const docTypeReader = new DocTypeReader(options.processEntities);\n const xmlLen = xmlData.length;\n for (let i = 0; i < xmlLen; i++) {//for each char in XML data\n const ch = xmlData[i];\n if (ch === '<') {\n // const nextIndex = i+1;\n // const _2ndChar = xmlData[nextIndex];\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//Closing Tag '/'\n const closeIndex = findClosingIndex(xmlData, \">\", i, \"Closing Tag is not closed.\")\n let tagName = xmlData.substring(i + 2, closeIndex).trim();\n\n if (options.removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n }\n }\n\n tagName = transformTagName(options.transformTagName, tagName, \"\", options).tagName;\n\n if (currentNode) {\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n }\n\n //check if last tag of nested tag was unpaired tag\n const lastTagName = this.matcher.getCurrentTag();\n if (tagName && options.unpairedTagsSet.has(tagName)) {\n throw new Error(`Unpaired tag can not be used as closing tag: `);\n }\n if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {\n // Pop the unpaired tag\n this.matcher.pop();\n this.tagsNodeStack.pop();\n }\n // Pop the closing tag\n this.matcher.pop();\n this.isCurrentNodeStopNode = false; // Reset flag when closing tag\n\n currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope\n textData = \"\";\n i = closeIndex;\n } else if (c1 === 63) { //'?'\n\n let tagData = readTagExp(xmlData, i, false, \"?>\");\n if (!tagData) throw new Error(\"Pi Tag is not closed.\");\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);\n if (attsMap) {\n const ver = attsMap[this.options.attributeNamePrefix + \"version\"];\n this.entityDecoder.setXmlVersion(Number(ver) || 1.0);\n }\n if ((options.ignoreDeclaration && tagData.tagName === \"?xml\") || options.ignorePiTags) {\n //do nothing\n } else {\n\n const childNode = new xmlNode(tagData.tagName);\n childNode.add(options.textNodeName, \"\");\n\n if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) {\n childNode[\":@\"] = attsMap\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, i);\n }\n\n\n i = tagData.closeIndex + 1;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { //'!--'\n const endIndex = findClosingIndex(xmlData, \"-->\", i + 4, \"Comment is not closed.\")\n if (options.commentPropName) {\n const comment = xmlData.substring(i + 4, endIndex - 2);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);\n }\n i = endIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 68) { //'!D'\n const result = docTypeReader.readDocType(xmlData, i);\n this.entityDecoder.addInputEntities(result.entities);\n i = result.i;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"CDATA is not closed.\") - 2;\n const tagExp = xmlData.substring(i + 9, closeIndex);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);\n if (val == undefined) val = \"\";\n\n //cdata should be set even if it is 0 length string\n if (options.cdataPropName) {\n currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);\n } else {\n currentNode.add(options.textNodeName, val);\n }\n\n i = closeIndex + 2;\n } else {//Opening tag\n let result = readTagExp(xmlData, i, options.removeNSPrefix);\n\n // Safety check: readTagExp can return undefined\n if (!result) {\n // Log context for debugging\n const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));\n throw new Error(`readTagExp returned undefined at position ${i}. Context: \"${context}\"`);\n }\n\n let tagName = result.tagName;\n const rawTagName = result.rawTagName;\n let tagExp = result.tagExp;\n let attrExpPresent = result.attrExpPresent;\n let closeIndex = result.closeIndex;\n\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n if (options.strictReservedNames &&\n (tagName === options.commentPropName\n || tagName === options.cdataPropName\n || tagName === options.textNodeName\n || tagName === options.attributesGroupName\n )) {\n throw new Error(`Invalid tag name: ${tagName}`);\n }\n\n //save text as child node\n if (currentNode && textData) {\n if (currentNode.tagname !== '!xml') {\n //when nested tag is found\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);\n }\n }\n\n //check if last tag was unpaired tag\n const lastTag = currentNode;\n if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {\n currentNode = this.tagsNodeStack.pop();\n this.matcher.pop();\n }\n\n // Clean up self-closing syntax BEFORE processing attributes\n // This is where tagExp gets the trailing / removed\n let isSelfClosing = false;\n if (tagExp.length > 0 && tagExp.lastIndexOf(\"/\") === tagExp.length - 1) {\n isSelfClosing = true;\n if (tagName[tagName.length - 1] === \"/\") {\n tagName = tagName.substr(0, tagName.length - 1);\n tagExp = tagName;\n } else {\n tagExp = tagExp.substr(0, tagExp.length - 1);\n }\n\n // Re-check attrExpPresent after cleaning\n attrExpPresent = (tagName !== tagExp);\n }\n\n // Now process attributes with CLEAN tagExp (no trailing /)\n let prefixedAttrs = null;\n let rawAttrs = {};\n let namespace = undefined;\n\n // Extract namespace from rawTagName\n namespace = extractNamespace(rawTagName);\n\n // Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path\n if (tagName !== xmlObj.tagname) {\n this.matcher.push(tagName, {}, namespace);\n }\n\n // Now build attributes - callbacks will see correct matcher state\n if (tagName !== tagExp && attrExpPresent) {\n // Build attributes (returns prefixed attributes for the tree)\n // Note: buildAttributesMap now internally updates the matcher with raw attributes\n prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);\n\n if (prefixedAttrs) {\n // Extract raw attributes (without prefix) for our use\n //TODO: seems a performance overhead\n rawAttrs = extractRawAttributes(prefixedAttrs, options);\n }\n }\n\n // Now check if this is a stop node (after attributes are set)\n if (tagName !== xmlObj.tagname) {\n this.isCurrentNodeStopNode = this.isItStopNode();\n }\n\n const startIndex = i;\n if (this.isCurrentNodeStopNode) {\n let tagContent = \"\";\n\n // For self-closing tags, content is empty\n if (isSelfClosing) {\n i = result.closeIndex;\n }\n //unpaired tag\n else if (options.unpairedTagsSet.has(tagName)) {\n i = result.closeIndex;\n }\n //normal tag\n else {\n //read until closing tag is found\n const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);\n if (!result) throw new Error(`Unexpected end of ${rawTagName}`);\n i = result.i;\n tagContent = result.tagContent;\n }\n\n const childNode = new xmlNode(tagName);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n\n // For stop nodes, store raw content as-is without any processing\n childNode.add(options.textNodeName, tagContent);\n\n this.matcher.pop(); // Pop the stop node tag\n this.isCurrentNodeStopNode = false; // Reset flag\n\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n } else {\n //selfClosing tag\n if (isSelfClosing) {\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n this.matcher.pop(); // Pop self-closing tag\n this.isCurrentNodeStopNode = false; // Reset flag\n }\n else if (options.unpairedTagsSet.has(tagName)) {//unpaired tag\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n this.matcher.pop(); // Pop unpaired tag\n this.isCurrentNodeStopNode = false; // Reset flag\n i = result.closeIndex;\n // Continue to next iteration without changing currentNode\n continue;\n }\n //opening tag\n else {\n const childNode = new xmlNode(tagName);\n if (this.tagsNodeStack.length > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n this.tagsNodeStack.push(currentNode);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n currentNode = childNode;\n }\n textData = \"\";\n i = closeIndex;\n }\n }\n } else {\n textData += xmlData[i];\n }\n }\n return xmlObj.child;\n}\n\nfunction addChild(currentNode, childNode, matcher, startIndex) {\n // unset startIndex if not requested\n if (!this.options.captureMetaData) startIndex = undefined;\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;\n const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[\":@\"])\n if (result === false) {\n //do nothing\n } else if (typeof result === \"string\") {\n childNode.tagname = result\n currentNode.addChild(childNode, startIndex);\n } else {\n currentNode.addChild(childNode, startIndex);\n }\n}\n\n/**\n * @param {object} val - Entity object with regex and val properties\n * @param {string} tagName - Tag name\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n */\nfunction replaceEntitiesValue(val, tagName, jPath) {\n const entityConfig = this.options.processEntities;\n\n if (!entityConfig || !entityConfig.enabled) {\n return val;\n }\n\n // Check if tag is allowed to contain entities\n if (entityConfig.allowedTags) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const allowed = Array.isArray(entityConfig.allowedTags)\n ? entityConfig.allowedTags.includes(tagName)\n : entityConfig.allowedTags(tagName, jPathOrMatcher);\n\n if (!allowed) {\n return val;\n }\n }\n\n // Apply custom tag filter if provided\n if (entityConfig.tagFilter) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {\n return val; // Skip based on custom filter\n }\n }\n\n return this.entityDecoder.decode(val);\n}\n\n\nfunction saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {\n if (textData) { //store previously collected data as textNode\n if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0\n\n textData = this.parseTextData(textData,\n parentNode.tagname,\n matcher,\n false,\n parentNode[\":@\"] ? Object.keys(parentNode[\":@\"]).length !== 0 : false,\n isLeafNode);\n\n if (textData !== undefined && textData !== \"\")\n parentNode.add(this.options.textNodeName, textData);\n textData = \"\";\n }\n return textData;\n}\n\n/**\n * @param {Array} stopNodeExpressions - Array of compiled Expression objects\n * @param {Matcher} matcher - Current path matcher\n */\nfunction isItStopNode() {\n if (this.stopNodeExpressionsSet.size === 0) return false;\n\n return this.matcher.matchesAny(this.stopNodeExpressionsSet);\n}\n\n/**\n * Returns the tag Expression and where it is ending handling single-double quotes situation\n * @param {string} xmlData \n * @param {number} i starting index\n * @returns \n */\nfunction tagExpWithClosingIndex(xmlData, i, closingChar = \">\") {\n let attrBoundary = 0;\n const chars = [];\n const len = xmlData.length;\n const closeCode0 = closingChar.charCodeAt(0);\n const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;\n\n for (let index = i; index < len; index++) {\n const code = xmlData.charCodeAt(index);\n\n if (attrBoundary) {\n if (code === attrBoundary) attrBoundary = 0;\n } else if (code === 34 || code === 39) { // \" or '\n attrBoundary = code;\n } else if (code === closeCode0) {\n if (closeCode1 !== -1) {\n if (xmlData.charCodeAt(index + 1) === closeCode1) {\n return { data: String.fromCharCode(...chars), index };\n }\n } else {\n return { data: String.fromCharCode(...chars), index };\n }\n } else if (code === 9) { // \\t\n chars.push(32); // space\n continue;\n }\n\n chars.push(code);\n }\n}\n\nfunction findClosingIndex(xmlData, str, i, errMsg) {\n const closingIndex = xmlData.indexOf(str, i);\n if (closingIndex === -1) {\n throw new Error(errMsg)\n } else {\n return closingIndex + str.length - 1;\n }\n}\n\nfunction findClosingChar(xmlData, char, i, errMsg) {\n const closingIndex = xmlData.indexOf(char, i);\n if (closingIndex === -1) throw new Error(errMsg);\n return closingIndex; // no offset needed\n}\n\nfunction readTagExp(xmlData, i, removeNSPrefix, closingChar = \">\") {\n const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);\n if (!result) return;\n let tagExp = result.data;\n const closeIndex = result.index;\n const separatorIndex = tagExp.search(/\\s/);\n let tagName = tagExp;\n let attrExpPresent = true;\n if (separatorIndex !== -1) {//separate tag name and attributes expression\n tagName = tagExp.substring(0, separatorIndex);\n tagExp = tagExp.substring(separatorIndex + 1).trimStart();\n }\n\n const rawTagName = tagName;\n if (removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n attrExpPresent = tagName !== result.data.substr(colonIndex + 1);\n }\n }\n\n return {\n tagName: tagName,\n tagExp: tagExp,\n closeIndex: closeIndex,\n attrExpPresent: attrExpPresent,\n rawTagName: rawTagName,\n }\n}\n/**\n * find paired tag for a stop node\n * @param {string} xmlData \n * @param {string} tagName \n * @param {number} i \n */\nfunction readStopNodeData(xmlData, tagName, i) {\n const startIndex = i;\n // Starting at 1 since we already have an open tag\n let openTagCount = 1;\n\n const xmllen = xmlData.length;\n for (; i < xmllen; i++) {\n if (xmlData[i] === \"<\") {\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//close tag '/'\n const closeIndex = findClosingChar(xmlData, \">\", i, `${tagName} is not closed`);\n let closeTagName = xmlData.substring(i + 2, closeIndex).trim();\n if (closeTagName === tagName) {\n openTagCount--;\n if (openTagCount === 0) {\n return {\n tagContent: xmlData.substring(startIndex, i),\n i: closeIndex\n }\n }\n }\n i = closeIndex;\n } else if (c1 === 63) { //?\n const closeIndex = findClosingIndex(xmlData, \"?>\", i + 1, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { // '!--'\n const closeIndex = findClosingIndex(xmlData, \"-->\", i + 3, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"StopNode is not closed.\") - 2;\n i = closeIndex;\n } else {\n const tagData = readTagExp(xmlData, i, '>')\n\n if (tagData) {\n const openTagName = tagData && tagData.tagName;\n if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== \"/\") {\n openTagCount++;\n }\n i = tagData.closeIndex;\n }\n }\n }\n }//end for loop\n}\n\nfunction parseValue(val, shouldParse, options) {\n if (shouldParse && typeof val === 'string') {\n //console.log(options)\n const newval = val.trim();\n if (newval === 'true') return true;\n else if (newval === 'false') return false;\n else return toNumber(val, options);\n } else {\n if (isExist(val)) {\n return val;\n } else {\n return '';\n }\n }\n}\n\nfunction fromCodePoint(str, base, prefix) {\n const codePoint = Number.parseInt(str, base);\n\n if (codePoint >= 0 && codePoint <= 0x10FFFF) {\n return String.fromCodePoint(codePoint);\n } else {\n return prefix + str + \";\";\n }\n}\n\nfunction transformTagName(fn, tagName, tagExp, options) {\n if (fn) {\n const newTagName = fn(tagName);\n if (tagExp === tagName) {\n tagExp = newTagName\n }\n tagName = newTagName;\n }\n tagName = sanitizeName(tagName, options);\n return { tagName, tagExp };\n}\n\n\n\nfunction sanitizeName(name, options) {\n if (criticalProperties.includes(name)) {\n throw new Error(`[SECURITY] Invalid name: \"${name}\" is a reserved JavaScript keyword that could cause prototype pollution`);\n } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return options.onDangerousProperty(name);\n }\n return name;\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","'use strict';\n\nimport XmlNode from './xmlNode.js';\nimport { Matcher } from 'path-expression-matcher';\n\nconst METADATA_SYMBOL = XmlNode.getMetaDataSymbol();\n\n/**\n * Helper function to strip attribute prefix from attribute map\n * @param {object} attrs - Attributes with prefix (e.g., {\"@_class\": \"code\"})\n * @param {string} prefix - Attribute prefix to remove (e.g., \"@_\")\n * @returns {object} Attributes without prefix (e.g., {\"class\": \"code\"})\n */\nfunction stripAttributePrefix(attrs, prefix) {\n if (!attrs || typeof attrs !== 'object') return {};\n if (!prefix) return attrs;\n\n const rawAttrs = {};\n for (const key in attrs) {\n if (key.startsWith(prefix)) {\n const rawName = key.substring(prefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * \n * @param {array} node \n * @param {any} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns \n */\nexport default function prettify(node, options, matcher, readonlyMatcher) {\n return compress(node, options, matcher, readonlyMatcher);\n}\n\n/**\n * @param {array} arr \n * @param {object} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns object\n */\nfunction compress(arr, options, matcher, readonlyMatcher) {\n let text;\n const compressedObj = {}; //This is intended to be a plain object\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const property = propName(tagObj);\n\n // Push current property to matcher WITH RAW ATTRIBUTES (no prefix)\n if (property !== undefined && property !== options.textNodeName) {\n const rawAttrs = stripAttributePrefix(\n tagObj[\":@\"] || {},\n options.attributeNamePrefix\n );\n matcher.push(property, rawAttrs);\n }\n\n if (property === options.textNodeName) {\n if (text === undefined) text = tagObj[property];\n else text += \"\" + tagObj[property];\n } else if (property === undefined) {\n continue;\n } else if (tagObj[property]) {\n\n let val = compress(tagObj[property], options, matcher, readonlyMatcher);\n const isLeaf = isLeafTag(val, options);\n\n if (tagObj[\":@\"]) {\n assignAttributes(val, tagObj[\":@\"], readonlyMatcher, options);\n } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {\n val = val[options.textNodeName];\n } else if (Object.keys(val).length === 0) {\n if (options.alwaysCreateTextNode) val[options.textNodeName] = \"\";\n else val = \"\";\n }\n\n if (tagObj[METADATA_SYMBOL] !== undefined && typeof val === \"object\" && val !== null) {\n val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata\n }\n\n\n if (compressedObj[property] !== undefined && Object.prototype.hasOwnProperty.call(compressedObj, property)) {\n if (!Array.isArray(compressedObj[property])) {\n compressedObj[property] = [compressedObj[property]];\n }\n compressedObj[property].push(val);\n } else {\n //TODO: if a node is not an array, then check if it should be an array\n //also determine if it is a leaf node\n\n // Pass jPath string or readonlyMatcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;\n if (options.isArray(property, jPathOrMatcher, isLeaf)) {\n compressedObj[property] = [val];\n } else {\n compressedObj[property] = val;\n }\n }\n\n // Pop property from matcher after processing\n if (property !== undefined && property !== options.textNodeName) {\n matcher.pop();\n }\n }\n\n }\n // if(text && text.length > 0) compressedObj[options.textNodeName] = text;\n if (typeof text === \"string\") {\n if (text.length > 0) compressedObj[options.textNodeName] = text;\n } else if (text !== undefined) compressedObj[options.textNodeName] = text;\n\n\n return compressedObj;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== \":@\") return key;\n }\n}\n\nfunction assignAttributes(obj, attrMap, readonlyMatcher, options) {\n if (attrMap) {\n const keys = Object.keys(attrMap);\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n const atrrName = keys[i]; // This is the PREFIXED name (e.g., \"@_class\")\n\n // Strip prefix for matcher path (for isArray callback)\n const rawAttrName = atrrName.startsWith(options.attributeNamePrefix)\n ? atrrName.substring(options.attributeNamePrefix.length)\n : atrrName;\n\n // For attributes, we need to create a temporary path\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath\n ? readonlyMatcher.toString() + \".\" + rawAttrName\n : readonlyMatcher;\n\n if (options.isArray(atrrName, jPathOrMatcher, true, true)) {\n obj[atrrName] = [attrMap[atrrName]];\n } else {\n obj[atrrName] = attrMap[atrrName];\n }\n }\n }\n}\n\nfunction isLeafTag(obj, options) {\n const { textNodeName } = options;\n const propCount = Object.keys(obj).length;\n\n if (propCount === 0) {\n return true;\n }\n\n if (\n propCount === 1 &&\n (obj[textNodeName] || typeof obj[textNodeName] === \"boolean\" || obj[textNodeName] === 0)\n ) {\n return true;\n }\n\n return false;\n}","import { buildOptions } from './OptionsBuilder.js';\nimport OrderedObjParser from './OrderedObjParser.js';\nimport prettify from './node2json.js';\nimport { validate } from \"../validator.js\";\nimport XmlNode from './xmlNode.js';\n\nexport default class XMLParser {\n\n constructor(options) {\n this.externalEntities = {};\n this.options = buildOptions(options);\n\n }\n /**\n * Parse XML dats to JS object \n * @param {string|Uint8Array} xmlData \n * @param {boolean|Object} validationOption \n */\n parse(xmlData, validationOption) {\n if (typeof xmlData !== \"string\" && xmlData.toString) {\n xmlData = xmlData.toString();\n } else if (typeof xmlData !== \"string\") {\n throw new Error(\"XML data is accepted in String or Bytes[] form.\")\n }\n\n if (validationOption) {\n if (validationOption === true) validationOption = {}; //validate with default options\n\n const result = validate(xmlData, validationOption);\n if (result !== true) {\n throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)\n }\n }\n const orderedObjParser = new OrderedObjParser(this.options);\n orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities);\n const orderedResult = orderedObjParser.parseXml(xmlData);\n if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;\n else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);\n }\n\n /**\n * Add Entity which is not by default supported by this library\n * @param {string} key \n * @param {string} value \n */\n addEntity(key, value) {\n if (value.indexOf(\"&\") !== -1) {\n throw new Error(\"Entity value can't have '&'\")\n } else if (key.indexOf(\"&\") !== -1 || key.indexOf(\";\") !== -1) {\n throw new Error(\"An entity must be set without '&' and ';'. Eg. use '#xD' for ' '\")\n } else if (value === \"&\") {\n throw new Error(\"An entity with value '&' is not permitted\");\n } else {\n this.externalEntities[key] = value;\n }\n }\n\n /**\n * Returns a Symbol that can be used to access the metadata\n * property on a node.\n * \n * If Symbol is not available in the environment, an ordinary property is used\n * and the name of the property is here returned.\n * \n * The XMLMetaData property is only present when `captureMetaData`\n * is true in the options.\n */\n static getMetaDataSymbol() {\n return XmlNode.getMetaDataSymbol();\n }\n}","import { Expression, Matcher } from 'path-expression-matcher';\n\nconst EOL = \"\\n\";\n\n/**\n * \n * @param {array} jArray \n * @param {any} options \n * @returns \n */\nexport default function toXml(jArray, options) {\n let indentation = \"\";\n if (options.format && options.indentBy.length > 0) {\n indentation = EOL;\n }\n\n // Pre-compile stopNode expressions for pattern matching\n const stopNodeExpressions = [];\n if (options.stopNodes && Array.isArray(options.stopNodes)) {\n for (let i = 0; i < options.stopNodes.length; i++) {\n const node = options.stopNodes[i];\n if (typeof node === 'string') {\n stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n stopNodeExpressions.push(node);\n }\n }\n }\n\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n\n return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions);\n}\n\nfunction arrToStr(arr, options, indentation, matcher, stopNodeExpressions) {\n let xmlStr = \"\";\n let isPreviousElementTag = false;\n\n if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n\n if (!Array.isArray(arr)) {\n // Non-array values (e.g. string tag values) should be treated as text content\n if (arr !== undefined && arr !== null) {\n let text = arr.toString();\n text = replaceEntitiesValue(text, options);\n return text;\n }\n return \"\";\n }\n\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const tagName = propName(tagObj);\n if (tagName === undefined) continue;\n\n // Extract attributes from \":@\" property\n const attrValues = extractAttributeValues(tagObj[\":@\"], options);\n\n // Push tag to matcher WITH attributes\n matcher.push(tagName, attrValues);\n\n // Check if this is a stop node using Expression matching\n const isStopNode = checkStopNode(matcher, stopNodeExpressions);\n\n if (tagName === options.textNodeName) {\n let tagText = tagObj[tagName];\n if (!isStopNode) {\n tagText = options.tagValueProcessor(tagName, tagText);\n tagText = replaceEntitiesValue(tagText, options);\n }\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n xmlStr += tagText;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.cdataPropName) {\n if (isPreviousElementTag) {\n xmlStr += indentation;\n }\n const val = tagObj[tagName][0][options.textNodeName];\n const safeVal = String(val).replace(/\\]\\]>/g, ']]]]>`;\n isPreviousElementTag = false;\n matcher.pop();\n continue;\n } else if (tagName === options.commentPropName) {\n const val = tagObj[tagName][0][options.textNodeName]\n const safeVal = String(val)\n .replace(/--/g, '- -') // -- is illegal anywhere in comment content\n .replace(/-$/, '- '); // trailing - would form -- with the closing -->\n xmlStr += indentation + ``;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n } else if (tagName[0] === \"?\") {\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tempInd = tagName === \"?xml\" ? \"\" : indentation;\n let piTextNodeName = tagObj[tagName][0][options.textNodeName];\n piTextNodeName = piTextNodeName.length !== 0 ? \" \" + piTextNodeName : \"\"; //remove extra spacing\n xmlStr += tempInd + `<${tagName}${piTextNodeName}${attStr}?>`;\n isPreviousElementTag = true;\n matcher.pop();\n continue;\n }\n\n let newIdentation = indentation;\n if (newIdentation !== \"\") {\n newIdentation += options.indentBy;\n }\n\n // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes\n const attStr = attr_to_str(tagObj[\":@\"], options, isStopNode);\n const tagStart = indentation + `<${tagName}${attStr}`;\n\n // If this is a stopNode, get raw content without processing\n let tagValue;\n if (isStopNode) {\n tagValue = getRawContent(tagObj[tagName], options);\n } else {\n\n tagValue = arrToStr(tagObj[tagName], options, newIdentation, matcher, stopNodeExpressions);\n }\n\n if (options.unpairedTags.indexOf(tagName) !== -1) {\n if (options.suppressUnpairedNode) xmlStr += tagStart + \">\";\n else xmlStr += tagStart + \"/>\";\n } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {\n xmlStr += tagStart + \"/>\";\n } else if (tagValue && tagValue.endsWith(\">\")) {\n xmlStr += tagStart + `>${tagValue}${indentation}`;\n } else {\n xmlStr += tagStart + \">\";\n if (tagValue && indentation !== \"\" && (tagValue.includes(\"/>\") || tagValue.includes(\"`;\n }\n isPreviousElementTag = true;\n\n // Pop tag from matcher\n matcher.pop();\n }\n\n return xmlStr;\n}\n\n/**\n * Extract attribute values from the \":@\" object and return as plain object\n * for passing to matcher.push()\n */\nfunction extractAttributeValues(attrMap, options) {\n if (!attrMap || options.ignoreAttributes) return null;\n\n const attrValues = {};\n let hasAttrs = false;\n\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // Remove the attribute prefix to get clean attribute name\n const cleanAttrName = attr.startsWith(options.attributeNamePrefix)\n ? attr.substr(options.attributeNamePrefix.length)\n : attr;\n attrValues[cleanAttrName] = attrMap[attr];\n hasAttrs = true;\n }\n\n return hasAttrs ? attrValues : null;\n}\n\n/**\n * Extract raw content from a stopNode without any processing\n * This preserves the content exactly as-is, including special characters\n */\nfunction getRawContent(arr, options) {\n if (!Array.isArray(arr)) {\n // Non-array values return as-is\n if (arr !== undefined && arr !== null) {\n return arr.toString();\n }\n return \"\";\n }\n\n let content = \"\";\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n const tagName = propName(item);\n\n if (tagName === options.textNodeName) {\n // Raw text content - NO processing, NO entity replacement\n content += item[tagName];\n } else if (tagName === options.cdataPropName) {\n // CDATA content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName === options.commentPropName) {\n // Comment content\n content += item[tagName][0][options.textNodeName];\n } else if (tagName && tagName[0] === \"?\") {\n // Processing instruction - skip for stopNodes\n continue;\n } else if (tagName) {\n // Nested tags within stopNode\n // Recursively get raw content and reconstruct the tag\n // For stopNodes, we don't process attributes either\n const attStr = attr_to_str_raw(item[\":@\"], options);\n const nestedContent = getRawContent(item[tagName], options);\n\n if (!nestedContent || nestedContent.length === 0) {\n content += `<${tagName}${attStr}/>`;\n } else {\n content += `<${tagName}${attStr}>${nestedContent}`;\n }\n }\n }\n return content;\n}\n\n/**\n * Build attribute string for stopNodes - NO entity replacement\n */\nfunction attr_to_str_raw(attrMap, options) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n // For stopNodes, use raw value without processing\n let attrVal = attrMap[attr];\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n if (key !== \":@\") return key;\n }\n}\n\nfunction attr_to_str(attrMap, options, isStopNode) {\n let attrStr = \"\";\n if (attrMap && !options.ignoreAttributes) {\n for (let attr in attrMap) {\n if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;\n let attrVal;\n\n if (isStopNode) {\n // For stopNodes, use raw value without any processing\n attrVal = attrMap[attr];\n } else {\n // Normal processing: apply attributeValueProcessor and entity replacement\n attrVal = options.attributeValueProcessor(attr, attrMap[attr]);\n attrVal = replaceEntitiesValue(attrVal, options);\n }\n\n if (attrVal === true && options.suppressBooleanAttributes) {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;\n } else {\n attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}=\"${attrVal}\"`;\n }\n }\n }\n return attrStr;\n}\n\nfunction checkStopNode(matcher, stopNodeExpressions) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\nfunction replaceEntitiesValue(textValue, options) {\n if (textValue && textValue.length > 0 && options.processEntities) {\n for (let i = 0; i < options.entities.length; i++) {\n const entity = options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction cdataVal(val) {\n\n}\n\nfunction commentVal(val) {\n\n}","'use strict';\n//parse Empty Node as self closing node\nimport buildFromOrderedJs from './orderedJs2Xml.js';\nimport getIgnoreAttributesFn from \"./ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\n\nconst defaultOptions = {\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n cdataPropName: false,\n format: false,\n indentBy: ' ',\n suppressEmptyNode: false,\n suppressUnpairedNode: true,\n suppressBooleanAttributes: true,\n tagValueProcessor: function (key, a) {\n return a;\n },\n attributeValueProcessor: function (attrName, a) {\n return a;\n },\n preserveOrder: false,\n commentPropName: false,\n unpairedTags: [],\n entities: [\n { regex: new RegExp(\"&\", \"g\"), val: \"&\" },//it must be on top\n { regex: new RegExp(\">\", \"g\"), val: \">\" },\n { regex: new RegExp(\"<\", \"g\"), val: \"<\" },\n { regex: new RegExp(\"\\'\", \"g\"), val: \"'\" },\n { regex: new RegExp(\"\\\"\", \"g\"), val: \""\" }\n ],\n processEntities: true,\n stopNodes: [],\n // transformTagName: false,\n // transformAttributeName: false,\n oneListGroup: false,\n maxNestedTags: 100,\n jPath: true // When true, callbacks receive string jPath; when false, receive Matcher instance\n};\n\nexport default function Builder(options) {\n this.options = Object.assign({}, defaultOptions, options);\n\n // Convert old-style stopNodes for backward compatibility\n // Old syntax: \"*.tag\" meant \"tag anywhere in tree\"\n // New syntax: \"..tag\" means \"tag anywhere in tree\"\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n this.options.stopNodes = this.options.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Convert old wildcard syntax to deep wildcard\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n\n // Pre-compile stopNode expressions for pattern matching\n this.stopNodeExpressions = [];\n if (this.options.stopNodes && Array.isArray(this.options.stopNodes)) {\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const node = this.options.stopNodes[i];\n if (typeof node === 'string') {\n this.stopNodeExpressions.push(new Expression(node));\n } else if (node instanceof Expression) {\n this.stopNodeExpressions.push(node);\n }\n }\n }\n\n if (this.options.ignoreAttributes === true || this.options.attributesGroupName) {\n this.isAttribute = function (/*a*/) {\n return false;\n };\n } else {\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.attrPrefixLen = this.options.attributeNamePrefix.length;\n this.isAttribute = isAttribute;\n }\n\n this.processTextOrObjNode = processTextOrObjNode\n\n if (this.options.format) {\n this.indentate = indentate;\n this.tagEndChar = '>\\n';\n this.newLine = '\\n';\n } else {\n this.indentate = function () {\n return '';\n };\n this.tagEndChar = '>';\n this.newLine = '';\n }\n}\n\nBuilder.prototype.build = function (jObj) {\n if (this.options.preserveOrder) {\n return buildFromOrderedJs(jObj, this.options);\n } else {\n if (Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1) {\n jObj = {\n [this.options.arrayNodeName]: jObj\n }\n }\n // Initialize matcher for path tracking\n const matcher = new Matcher();\n return this.j2x(jObj, 0, matcher).val;\n }\n};\n\nBuilder.prototype.j2x = function (jObj, level, matcher) {\n let attrStr = '';\n let val = '';\n if (this.options.maxNestedTags && matcher.getDepth() >= this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n // Get jPath based on option: string for backward compatibility, or Matcher for new features\n const jPath = this.options.jPath ? matcher.toString() : matcher;\n\n // Check if current node is a stopNode (will be used for attribute encoding)\n const isCurrentStopNode = this.checkStopNode(matcher);\n\n for (let key in jObj) {\n if (!Object.prototype.hasOwnProperty.call(jObj, key)) continue;\n if (typeof jObj[key] === 'undefined') {\n // supress undefined node only if it is not an attribute\n if (this.isAttribute(key)) {\n val += '';\n }\n } else if (jObj[key] === null) {\n // null attribute should be ignored by the attribute list, but should not cause the tag closing\n if (this.isAttribute(key)) {\n val += '';\n } else if (key === this.options.cdataPropName) {\n val += '';\n } else if (key[0] === '?') {\n val += this.indentate(level) + '<' + key + '?' + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n }\n // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar;\n } else if (jObj[key] instanceof Date) {\n val += this.buildTextValNode(jObj[key], key, '', level, matcher);\n } else if (typeof jObj[key] !== 'object') {\n //premitive type\n const attr = this.isAttribute(key);\n if (attr && !this.ignoreAttributesFn(attr, jPath)) {\n attrStr += this.buildAttrPairStr(attr, '' + jObj[key], isCurrentStopNode);\n } else if (!attr) {\n //tag value\n if (key === this.options.textNodeName) {\n let newval = this.options.tagValueProcessor(key, '' + jObj[key]);\n val += this.replaceEntitiesValue(newval);\n } else {\n // Check if this is a stopNode before building\n matcher.push(key);\n const isStopNode = this.checkStopNode(matcher);\n matcher.pop();\n\n if (isStopNode) {\n // Build as raw content without encoding\n const textValue = '' + jObj[key];\n if (textValue === '') {\n val += this.indentate(level) + '<' + key + this.closeTag(key) + this.tagEndChar;\n } else {\n val += this.indentate(level) + '<' + key + '>' + textValue + '' + textValue + '${item}`;\n } else if (typeof item === 'object' && item !== null) {\n const nestedContent = this.buildRawContent(item);\n const nestedAttrs = this.buildAttributesForStopNode(item);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n }\n }\n } else if (typeof value === 'object' && value !== null) {\n // Nested object\n const nestedContent = this.buildRawContent(value);\n const nestedAttrs = this.buildAttributesForStopNode(value);\n if (nestedContent === '') {\n content += `<${key}${nestedAttrs}/>`;\n } else {\n content += `<${key}${nestedAttrs}>${nestedContent}`;\n }\n } else {\n // Primitive value\n content += `<${key}>${value}`;\n }\n }\n\n return content;\n};\n\n// Build attribute string for stopNode (no entity encoding)\nBuilder.prototype.buildAttributesForStopNode = function (obj) {\n if (!obj || typeof obj !== 'object') return '';\n\n let attrStr = '';\n\n // Check for attributesGroupName (when attributes are grouped)\n if (this.options.attributesGroupName && obj[this.options.attributesGroupName]) {\n const attrGroup = obj[this.options.attributesGroupName];\n for (let attrKey in attrGroup) {\n if (!Object.prototype.hasOwnProperty.call(attrGroup, attrKey)) continue;\n const cleanKey = attrKey.startsWith(this.options.attributeNamePrefix)\n ? attrKey.substring(this.options.attributeNamePrefix.length)\n : attrKey;\n const val = attrGroup[attrKey];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + cleanKey;\n } else {\n attrStr += ' ' + cleanKey + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n } else {\n // Look for individual attributes\n for (let key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const attr = this.isAttribute(key);\n if (attr) {\n const val = obj[key];\n if (val === true && this.options.suppressBooleanAttributes) {\n attrStr += ' ' + attr;\n } else {\n attrStr += ' ' + attr + '=\"' + val + '\"'; // No encoding for stopNode\n }\n }\n }\n }\n\n return attrStr;\n};\n\nBuilder.prototype.buildObjectNode = function (val, key, attrStr, level) {\n if (val === \"\") {\n if (key[0] === \"?\") return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n else {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n }\n } else {\n\n let tagEndExp = '' + val + tagEndExp);\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) {\n return this.indentate(level) + `` + this.newLine;\n } else {\n return (\n this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar +\n val +\n this.indentate(level) + tagEndExp);\n }\n }\n}\n\nBuilder.prototype.closeTag = function (key) {\n let closeTag = \"\";\n if (this.options.unpairedTags.indexOf(key) !== -1) { //unpaired\n if (!this.options.suppressUnpairedNode) closeTag = \"/\"\n } else if (this.options.suppressEmptyNode) { //empty\n closeTag = \"/\";\n } else {\n closeTag = `>/g, ']]]]>` + this.newLine;\n } else if (this.options.commentPropName !== false && key === this.options.commentPropName) {\n const safeVal = String(val)\n .replace(/--/g, '- -') // -- is illegal anywhere in comment content\n .replace(/-$/, '- '); // trailing - would form -- with the closing -->\n return this.indentate(level) + `` + this.newLine;\n } else if (key[0] === \"?\") {//PI tag\n return this.indentate(level) + '<' + key + attrStr + '?' + this.tagEndChar;\n } else {\n // Normal processing: apply tagValueProcessor and entity replacement\n let textValue = this.options.tagValueProcessor(key, val);\n textValue = this.replaceEntitiesValue(textValue);\n\n if (textValue === '') {\n return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar;\n } else {\n return this.indentate(level) + '<' + key + attrStr + '>' +\n textValue +\n ' 0 && this.options.processEntities) {\n for (let i = 0; i < this.options.entities.length; i++) {\n const entity = this.options.entities[i];\n textValue = textValue.replace(entity.regex, entity.val);\n }\n }\n return textValue;\n}\n\nfunction indentate(level) {\n return this.options.indentBy.repeat(level);\n}\n\nfunction isAttribute(name /*, options*/) {\n if (name.startsWith(this.options.attributeNamePrefix) && name !== this.options.textNodeName) {\n return name.substr(this.attrPrefixLen);\n } else {\n return false;\n }\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","// Re-export from fast-xml-builder for backward compatibility\nimport XMLBuilder from 'fast-xml-builder';\nexport default XMLBuilder;\n\n// If there are any named exports you also want to re-export:\nexport * from 'fast-xml-builder';","'use strict';\n\nimport { validate } from './validator.js';\nimport XMLParser from './xmlparser/XMLParser.js';\nimport XMLBuilder from './xmlbuilder/json2xml.js';\n\nconst XMLValidator = {\n validate: validate\n}\nexport {\n XMLParser,\n XMLValidator,\n XMLBuilder\n};"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","getAllMatches","string","regex","matches","match","exec","allmatches","startIndex","lastIndex","length","len","index","push","isName","DANGEROUS_PROPERTY_NAMES","criticalProperties","defaultOptions","allowBooleanAttributes","unpairedTags","validate","xmlData","options","assign","tags","tagFound","reachedRoot","substr","i","readPI","err","isWhiteSpace","getErrorObject","getLineNumberForPosition","tagStartPos","readCommentAndCDATA","closingTag","tagName","trim","substring","validateTagName","result","readAttributeStr","attrStr","attrStrStart","isValid","validateAttributeString","code","msg","line","tagClosed","otg","pop","openPos","col","indexOf","afterAmp","validateAmpersand","JSON","stringify","map","t","replace","char","start","tagname","angleBracketsCount","doubleQuote","singleQuote","startChar","validAttrStrRegxp","attrNames","getPositionFromMatch","undefined","attrName","validateAttrName","re","validateNumberAmpersand","count","message","lineNumber","lines","split","defaultOnDangerousProperty","name","includes","preserveOrder","attributeNamePrefix","attributesGroupName","textNodeName","ignoreAttributes","removeNSPrefix","parseTagValue","parseAttributeValue","trimValues","cdataPropName","numberParseOptions","hex","leadingZeros","eNotation","tagValueProcessor","val","attributeValueProcessor","stopNodes","alwaysCreateTextNode","isArray","commentPropName","processEntities","htmlEntities","entityDecoder","ignoreDeclaration","ignorePiTags","transformTagName","transformAttributeName","updateTag","jPath","attrs","captureMetaData","maxNestedTags","strictReservedNames","onDangerousProperty","validatePropertyName","propertyName","optionName","normalized","toLowerCase","some","dangerous","Error","normalizeProcessEntities","enabled","maxEntitySize","maxExpansionDepth","maxTotalExpansions","Infinity","maxExpandedLength","maxEntityCount","allowedTags","tagFilter","appliesTo","Math","max","_value$maxEntitySize","_value$maxExpansionDe","_value$maxTotalExpans","_value$maxExpandedLen","_value$maxEntityCount","_value$allowedTags","_value$tagFilter","_value$appliesTo","METADATA_SYMBOL","buildOptions","built","_i","_propertyNameOptions","_propertyNameOptions$","unpairedTagsSet","Set","Array","node","startsWith","XmlNode","child","create","_proto","add","_this$child$push","addChild","_this$child$push2","_this$child$push3","keys","getMetaDataSymbol","DocTypeReader","suppressValidationErr","readDocType","entities","entityCount","hasBody","comment","hasSeq","entityName","_this$readEntityExp","readEntityExp","readElementExp","readNotationExp","skipWhitespace","test","validateEntityName","toUpperCase","entityValue","_this$readIdentifierV","readIdentifierVal","notationName","identifierType","publicIdentifier","systemIdentifier","_this$readIdentifierV2","_this$readIdentifierV3","_this$readIdentifierV4","type","identifierVal","elementName","contentModel","readAttlistExp","attributeName","attributeType","allowedNotations","notation","join","defaultValue","_this$readIdentifierV5","data","seq","j","hexRegex","numRegex","consider","decimalPoint","infinity","eNotationRegx","MatcherView","constructor","matcher","_matcher","separator","getCurrentTag","path","tag","getCurrentNamespace","namespace","getAttrValue","values","hasAttr","current","getPosition","position","getCounter","counter","getIndex","getDepth","toString","includeNamespace","toArray","n","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","attrValues","currentLevel","Map","siblings","siblingKey","set","updateCurrent","sep","reset","segments","hasDeepWildcard","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","segment","nextSeg","found","isCurrentNode","attrValue","String","positionValue","snapshot","restore","readOnly","Expression","pattern","_parse","_hasDeepWildcard","seg","_hasAttributeCondition","_hasPositionSelector","currentPart","_parseSegment","part","bracketContent","withoutBrackets","bracketMatch","content","slice","tagAndPosition","nsIndex","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","eqIndex","nthMatch","parseInt","hasAttributeCondition","hasPositionSelector","ExpressionSet","_byDepthAndTag","_wildcardByDepth","_deepWildcards","_patterns","_sealed","TypeError","has","depth","lastSeg","addAll","expressions","expr","size","seal","isSealed","findMatch","exactKey","exactBucket","wildcardBucket","CURRENCY","cent","pound","curren","yen","euro","dollar","fnof","inr","af","birr","peso","rub","won","yuan","cedil","XML","amp","apos","gt","lt","quot","COMMON_HTML","nbsp","copy","reg","trade","mdash","ndash","hellip","laquo","raquo","lsquo","rsquo","ldquo","rdquo","bull","para","sect","deg","frac12","frac14","frac34","SPECIAL_CHARS","ch","mergeEntityMaps","maps","out","raw","LIMIT_TIER_EXTERNAL","LIMIT_TIER_BASE","LIMIT_TIER_ALL","NCR_LEVEL","freeze","allow","leave","remove","throw","XML10_ALLOWED_C0","EntityDecoder","_limit","limit","_maxTotalExpansions","_maxExpandedLength","_postCheck","postCheck","r","_limitTiers","applyLimitsTo","_numericAllowed","numericAllowed","_baseMap","DEFAULT_XML_ENTITIES","namedEntities","_externalMap","_inputMap","_totalExpansions","_expandedLength","_removeSet","_leaveSet","ncrCfg","ncr","xmlVersion","onLevel","nullLevel","onNCR","nullNCR","parseNCRConfig","_ncrXmlVersion","_ncrOnLevel","_ncrNullLevel","setExternalEntities","addExternalEntity","addInputEntities","setXmlVersion","version","decode","str","original","chunks","last","limitExpansions","limitLength","checkLimits","charCodeAt","token","replacement","tier","ncrResult","_resolveNCR","resolved","_resolveName","_tierCounts","delta","_classifyNCR","cp","_applyNCRAction","action","fromCodePoint","padStart","second","Number","isNaN","minimum","effective","_extends","bind","e","arguments","apply","extractRawAttributes","prefixedAttrs","rawAttrs","extractNamespace","rawTagName","ns","OrderedObjParser","currentNode","tagsNodeStack","parseXml","parseTextData","resolveNameSpace","buildAttributesMap","isItStopNode","replaceEntitiesValue","readStopNodeData","saveTextToParentTag","ignoreAttributesFn","_step","_iterator","_createForOfIteratorHelperLoose","done","entityExpansionCount","currentExpandedLength","readonlyMatcher","isCurrentNodeStopNode","stopNodeExpressionsSet","stopNodesOpts","stopNodeExp","dontTrim","hasAttributes","isLeafNode","escapeEntities","jPathOrMatcher","newval","parseValue","prefix","charAt","attrsRegx","force","processedVals","hasRawAttrs","rawAttrsForMatcher","oldVal","jPathStr","hasAttrs","aName","sanitizeName","newVal","attrCollection","xmlObj","xmlNode","textData","docTypeReader","xmlLen","c1","closeIndex","findClosingIndex","lastTagName","tagData","readTagExp","attsMap","tagExp","ver","childNode","attrExpPresent","endIndex","_ref","_ref2","context","min","_transformTagName","lastTag","isSelfClosing","tagContent","_transformTagName2","entityConfig","parentNode","errMsg","closingIndex","findClosingChar","closingChar","attrBoundary","chars","closeCode0","closeCode1","fromCharCode","tagExpWithClosingIndex","separatorIndex","search","trimStart","openTagCount","xmllen","shouldParse","trimmedStr","skipLike","numStr","window","parse_int","isFinite","sign","eChar","eAdjacentToLeadingZeros","resolveEnotation","numTrimmedByZeros","decimalAdjacentToLeadingZeros","num","parsedStr","isPositive","handleInfinity","toNumber","fn","newTagName","stripAttributePrefix","prettify","compress","arr","text","compressedObj","tagObj","property","propName","isLeaf","isLeafTag","assignAttributes","attrMap","atrrName","rawAttrName","propCount","XMLParser","externalEntities","parse","validationOption","orderedObjParser","orderedResult","addEntity","toXml","jArray","indentation","format","indentBy","stopNodeExpressions","arrToStr","xmlStr","isPreviousElementTag","extractAttributeValues","isStopNode","checkStopNode","tagText","attStr","attr_to_str","tempInd","piTextNodeName","newIdentation","tagStart","tagValue","getRawContent","suppressUnpairedNode","suppressEmptyNode","endsWith","attr","item","attr_to_str_raw","nestedContent","attrVal","suppressBooleanAttributes","textValue","entity","a","oneListGroup","Builder","isAttribute","attrPrefixLen","processTextOrObjNode","indentate","tagEndChar","newLine","object","level","extractAttributes","rawContent","buildRawContent","buildAttributesForStopNode","buildObjectNode","j2x","buildTextValNode","repeat","build","jObj","buildFromOrderedJs","arrayNodeName","isCurrentStopNode","Date","buildAttrPairStr","closeTag","arrLen","listTagVal","listTagAttr","Ks","L","attrGroup","attrKey","nestedAttrs","cleanKey","tagEndExp","piClosingChar","safeVal","XMLValidator"],"sourceRoot":""} \ No newline at end of file diff --git a/node_modules/fast-xml-parser/lib/fxparser.min.js b/node_modules/fast-xml-parser/lib/fxparser.min.js index 232f7b48..762d7dee 100644 --- a/node_modules/fast-xml-parser/lib/fxparser.min.js +++ b/node_modules/fast-xml-parser/lib/fxparser.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.XMLParser=e():t.XMLParser=e()}(this,()=>(()=>{"use strict";var t={d:(e,r)=>{for(var n in r)t.o(r,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{default:()=>dt});var r=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",n=new RegExp("^["+r+"]["+r+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function i(t,e){for(var r=[],n=e.exec(t);n;){var i=[];i.startIndex=e.lastIndex-n[0].length;for(var a=n.length,s=0;s0?this.child.push(((r={})[t.tagname]=t.child,r[":@"]=t[":@"],r)):this.child.push(((n={})[t.tagname]=t.child,n)),void 0!==e&&(this.child[this.child.length-1][d]={startIndex:e})},t.getMetaDataSymbol=function(){return d},t}(),c=function(){function t(t){this.suppressValidationErr=!t,this.options=t}var e=t.prototype;return e.readDocType=function(t,e){var r=Object.create(null),n=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");e+=9;for(var i=1,a=!1,s=!1;e<"!==t[e]||s)if(">"===t[e]){if(s?"-"===t[e-1]&&"-"===t[e-2]&&(s=!1,i--):i--,0===i)break}else"["===t[e]?a=!0:t[e];else{if(a&&v(t,"!ENTITY",e)){e+=7;var o=void 0,h=void 0,l=this.readEntityExp(t,e+1,this.suppressValidationErr);if(o=l[0],h=l[1],e=l[2],-1===h.indexOf("&")){if(!1!==this.options.enabled&&null!=this.options.maxEntityCount&&n>=this.options.maxEntityCount)throw new Error("Entity count ("+(n+1)+") exceeds maximum allowed ("+this.options.maxEntityCount+")");var u=o.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");r[o]={regx:RegExp("&"+u+";","g"),val:h},n++}}else if(a&&v(t,"!ELEMENT",e))e+=8,e=this.readElementExp(t,e+1).index;else if(a&&v(t,"!ATTLIST",e))e+=8;else if(a&&v(t,"!NOTATION",e))e+=9,e=this.readNotationExp(t,e+1,this.suppressValidationErr).index;else{if(!v(t,"!--",e))throw new Error("Invalid DOCTYPE");s=!0}i++}if(0!==i)throw new Error("Unclosed DOCTYPE");return{entities:r,i:e}},e.readEntityExp=function(t,e){for(var r=e=m(t,e);ethis.options.maxEntitySize)throw new Error('Entity "'+n+'" size ('+i.length+") exceeds maximum allowed size ("+this.options.maxEntitySize+")");return[n,i,--e]},e.readNotationExp=function(t,e){for(var r=e=m(t,e);et.length)&&(e=t.length);for(var r=0,n=Array(e);r0&&(this.path[this.path.length-1].values=void 0);const n=this.path.length;this.siblingStacks[n]||(this.siblingStacks[n]=new Map);const i=this.siblingStacks[n],a=r?`${r}:${t}`:t,s=i.get(a)||0;let o=0;for(const t of i.values())o+=t;i.set(a,s+1);const h={tag:t,position:o,counter:s};null!=r&&(h.namespace=r),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0===this.path.length)return;const e=this.path[this.path.length-1];return e.values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const r=t||this.separator;return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(r)}toArray(){return this.path.map(t=>t.tag)}reset(){this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const n=t[r];if("deep-wildcard"===n.type){if(r--,r<0)return!0;const n=t[r];let i=!1;for(let t=e;t>=0;t--){const a=t===this.path.length-1;if(this._matchSegment(n,this.path[t],a)){e=t-1,r--,i=!0;break}}if(!i)return!1}else{const t=e===this.path.length-1;if(!this._matchSegment(n,this.path[e],t))return!1;e--,r--}}return r<0}_matchSegment(t,e,r){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!r)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue){const r=e.values[t.attrName];if(String(r)!==String(t.attrValue))return!1}}if(void 0!==t.position){if(!r)return!1;const n=e.counter??0;if("first"===t.position&&0!==n)return!1;if("odd"===t.position&&n%2!=1)return!1;if("even"===t.position&&n%2!=0)return!1;if("nth"===t.position&&n!==t.positionValue)return!1}return!0}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}}class S{constructor(t,e={}){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let r=0,n="";for(;r0){var r=t.substring(0,e);if("xmlns"!==r)return r}}}var P=function(t){var e;if(this.options=t,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:" "},cent:{regex:/&(cent|#162);/g,val:"¢"},pound:{regex:/&(pound|#163);/g,val:"£"},yen:{regex:/&(yen|#165);/g,val:"¥"},euro:{regex:/&(euro|#8364);/g,val:"€"},copyright:{regex:/&(copy|#169);/g,val:"©"},reg:{regex:/&(reg|#174);/g,val:"®"},inr:{regex:/&(inr|#8377);/g,val:"₹"},num_dec:{regex:/&#([0-9]{1,7});/g,val:function(t,e){return W(e,10,"&#")}},num_hex:{regex:/&#x([0-9a-fA-F]{1,6});/g,val:function(t,e){return W(e,16,"&#x")}}},this.addExternalEntities=A,this.parseXml=j,this.parseTextData=O,this.resolveNameSpace=_,this.buildAttributesMap=k,this.isItStopNode=L,this.replaceEntitiesValue=V,this.readStopNodeData=R,this.saveTextToParentTag=F,this.addChild=M,this.ignoreAttributesFn="function"==typeof(e=this.options.ignoreAttributes)?e:Array.isArray(e)?function(t){for(var r,n=function(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(r)return(r=r.call(t)).next.bind(r);if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return w(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?w(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(e);!(r=n()).done;){var i=r.value;if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:function(){return!1},this.entityExpansionCount=0,this.currentExpandedLength=0,this.matcher=new T,this.isCurrentNodeStopNode=!1,this.options.stopNodes&&this.options.stopNodes.length>0){this.stopNodeExpressions=[];for(var r=0;r0)){s||(t=this.replaceEntitiesValue(t,e,r));var o=this.options.jPath?r.toString():r,h=this.options.tagValueProcessor(e,t,o,i,a);return null==h?t:typeof h!=typeof t||h!==t?h:this.options.trimValues||t.trim()===t?Y(t,this.options.parseTagValue,this.options.numberParseOptions):t}}function _(t){if(this.options.removeNSPrefix){var e=t.split(":"),r="/"===t.charAt(0)?"/":"";if("xmlns"===e[0])return"";2===e.length&&(t=r+e[1])}return t}var D=new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?","gm");function k(t,e,r){if(!0!==this.options.ignoreAttributes&&"string"==typeof t){for(var n=i(t,D),a=n.length,s={},o={},h=0;h0&&"object"==typeof e&&e.updateCurrent&&e.updateCurrent(o);for(var d=0;d",a,"Closing Tag is not closed."),o=t.substring(a+2,s).trim();if(this.options.removeNSPrefix){var h=o.indexOf(":");-1!==h&&(o=o.substr(h+1))}o=X(this.options.transformTagName,o,"",this.options).tagName,r&&(n=this.saveTextToParentTag(n,r,this.matcher));var l=this.matcher.getCurrentTag();if(o&&-1!==this.options.unpairedTags.indexOf(o))throw new Error("Unpaired tag can not be used as closing tag: ");l&&-1!==this.options.unpairedTags.indexOf(l)&&(this.matcher.pop(),this.tagsNodeStack.pop()),this.matcher.pop(),this.isCurrentNodeStopNode=!1,r=this.tagsNodeStack.pop(),n="",a=s}else if("?"===t[a+1]){var u=$(t,a,!1,"?>");if(!u)throw new Error("Pi Tag is not closed.");if(n=this.saveTextToParentTag(n,r,this.matcher),this.options.ignoreDeclaration&&"?xml"===u.tagName||this.options.ignorePiTags);else{var p=new g(u.tagName);p.add(this.options.textNodeName,""),u.tagName!==u.tagExp&&u.attrExpPresent&&(p[":@"]=this.buildAttributesMap(u.tagExp,this.matcher,u.tagName)),this.addChild(r,p,this.matcher,a)}a=u.closeIndex+1}else if("!--"===t.substr(a+1,3)){var d=U(t,"--\x3e",a+4,"Comment is not closed.");if(this.options.commentPropName){var f,m=t.substring(a+4,d-2);n=this.saveTextToParentTag(n,r,this.matcher),r.add(this.options.commentPropName,[(f={},f[this.options.textNodeName]=m,f)])}a=d}else if("!D"===t.substr(a+1,2)){var v=i.readDocType(t,a);this.docTypeEntities=v.entities,a=v.i}else if("!["===t.substr(a+1,2)){var x=U(t,"]]>",a,"CDATA is not closed.")-2,E=t.substring(a+9,x);n=this.saveTextToParentTag(n,r,this.matcher);var b,N=this.parseTextData(E,r.tagname,this.matcher,!0,!1,!0,!0);null==N&&(N=""),this.options.cdataPropName?r.add(this.options.cdataPropName,[(b={},b[this.options.textNodeName]=E,b)]):r.add(this.options.textNodeName,N),a=x+2}else{var y=$(t,a,this.options.removeNSPrefix);if(!y){var w=t.substring(Math.max(0,a-50),Math.min(t.length,a+50));throw new Error("readTagExp returned undefined at position "+a+'. Context: "'+w+'"')}var T=y.tagName,S=y.rawTagName,P=y.tagExp,A=y.attrExpPresent,O=y.closeIndex,_=X(this.options.transformTagName,T,P,this.options);if(T=_.tagName,P=_.tagExp,this.options.strictReservedNames&&(T===this.options.commentPropName||T===this.options.cdataPropName||T===this.options.textNodeName||T===this.options.attributesGroupName))throw new Error("Invalid tag name: "+T);r&&n&&"!xml"!==r.tagname&&(n=this.saveTextToParentTag(n,r,this.matcher,!1));var D=r;D&&-1!==this.options.unpairedTags.indexOf(D.tagname)&&(r=this.tagsNodeStack.pop(),this.matcher.pop());var k=!1;P.length>0&&P.lastIndexOf("/")===P.length-1&&(k=!0,P="/"===T[T.length-1]?T=T.substr(0,T.length-1):P.substr(0,P.length-1),A=T!==P);var j,M=null;j=C(S),T!==e.tagname&&this.matcher.push(T,{},j),T!==P&&A&&(M=this.buildAttributesMap(P,this.matcher,T))&&I(M,this.options),T!==e.tagname&&(this.isCurrentNodeStopNode=this.isItStopNode(this.stopNodeExpressions,this.matcher));var V=a;if(this.isCurrentNodeStopNode){var F="";if(k)a=y.closeIndex;else if(-1!==this.options.unpairedTags.indexOf(T))a=y.closeIndex;else{var L=this.readStopNodeData(t,S,O+1);if(!L)throw new Error("Unexpected end of "+S);a=L.i,F=L.tagContent}var R=new g(T);M&&(R[":@"]=M),R.add(this.options.textNodeName,F),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(r,R,this.matcher,V)}else{if(k){var Y=X(this.options.transformTagName,T,P,this.options);T=Y.tagName,P=Y.tagExp;var W=new g(T);M&&(W[":@"]=M),this.addChild(r,W,this.matcher,V),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else{if(-1!==this.options.unpairedTags.indexOf(T)){var z=new g(T);M&&(z[":@"]=M),this.addChild(r,z,this.matcher,V),this.matcher.pop(),this.isCurrentNodeStopNode=!1,a=y.closeIndex;continue}var G=new g(T);if(this.tagsNodeStack.length>this.options.maxNestedTags)throw new Error("Maximum nested tags exceeded");this.tagsNodeStack.push(r),M&&(G[":@"]=M),this.addChild(r,G,this.matcher,V),r=G}n="",a=O}}else n+=t[a];return e.child};function M(t,e,r,n){this.options.captureMetaData||(n=void 0);var i=this.options.jPath?r.toString():r,a=this.options.updateTag(e.tagname,i,e[":@"]);!1===a||("string"==typeof a?(e.tagname=a,t.addChild(e,n)):t.addChild(e,n))}function V(t,e,r){var n=this.options.processEntities;if(!n||!n.enabled)return t;if(n.allowedTags){var i=this.options.jPath?r.toString():r;if(!(Array.isArray(n.allowedTags)?n.allowedTags.includes(e):n.allowedTags(e,i)))return t}if(n.tagFilter){var a=this.options.jPath?r.toString():r;if(!n.tagFilter(e,a))return t}for(var s=0,o=Object.keys(this.docTypeEntities);sn.maxTotalExpansions)throw new Error("Entity expansion limit exceeded: "+this.entityExpansionCount+" > "+n.maxTotalExpansions);var p=t.length;if(t=t.replace(l.regx,l.val),n.maxExpandedLength&&(this.currentExpandedLength+=t.length-p,this.currentExpandedLength>n.maxExpandedLength))throw new Error("Total expanded content size exceeded: "+this.currentExpandedLength+" > "+n.maxExpandedLength)}}for(var d=0,f=Object.keys(this.lastEntities);dn.maxTotalExpansions))throw new Error("Entity expansion limit exceeded: "+this.entityExpansionCount+" > "+n.maxTotalExpansions);t=t.replace(c.regex,c.val)}if(-1===t.indexOf("&"))return t;if(this.options.htmlEntities)for(var v=0,x=Object.keys(this.htmlEntities);vn.maxTotalExpansions))throw new Error("Entity expansion limit exceeded: "+this.entityExpansionCount+" > "+n.maxTotalExpansions);t=t.replace(b.regex,b.val)}return t.replace(this.ampEntity.regex,this.ampEntity.val)}function F(t,e,r,n){return t&&(void 0===n&&(n=0===e.child.length),void 0!==(t=this.parseTextData(t,e.tagname,r,!1,!!e[":@"]&&0!==Object.keys(e[":@"]).length,n))&&""!==t&&e.add(this.options.textNodeName,t),t=""),t}function L(t,e){if(!t||0===t.length)return!1;for(var r=0;r");var i=function(t,e,r){var n;void 0===r&&(r=">");for(var i="",a=e;a",r,e+" is not closed");if(t.substring(r+2,a).trim()===e&&0===--i)return{tagContent:t.substring(n,r),i:a};r=a}else if("?"===t[r+1])r=U(t,"?>",r+1,"StopNode is not closed.");else if("!--"===t.substr(r+1,3))r=U(t,"--\x3e",r+3,"StopNode is not closed.");else if("!["===t.substr(r+1,2))r=U(t,"]]>",r,"StopNode is not closed.")-2;else{var s=$(t,r,">");s&&((s&&s.tagName)===e&&"/"!==s.tagExp[s.tagExp.length-1]&&i++,r=s.closeIndex)}}function Y(t,e,r){if(e&&"string"==typeof t){var n=t.trim();return"true"===n||"false"!==n&&function(t,e={}){if(e=Object.assign({},N,e),!t||"string"!=typeof t)return t;let r=t.trim();if(void 0!==e.skipLike&&e.skipLike.test(r))return t;if("0"===t)return 0;if(e.hex&&E.test(r))return function(t){if(parseInt)return parseInt(t,16);if(Number.parseInt)return Number.parseInt(t,16);if(window&&window.parseInt)return window.parseInt(t,16);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}(r);if(isFinite(r)){if(r.includes("e")||r.includes("E"))return function(t,e,r){if(!r.eNotation)return t;const n=e.match(y);if(n){let i=n[1]||"";const a=-1===n[3].indexOf("e")?"E":"e",s=n[2],o=i?t[s.length+1]===a:t[s.length]===a;return s.length>1&&o?t:(1!==s.length||!n[3].startsWith(`.${a}`)&&n[3][0]!==a)&&s.length>0?r.leadingZeros&&!o?(e=(n[1]||"")+n[3],Number(e)):t:Number(e)}return t}(t,r,e);{const i=b.exec(r);if(i){const a=i[1]||"",s=i[2];let o=(n=i[3])&&-1!==n.indexOf(".")?("."===(n=n.replace(/0+$/,""))?n="0":"."===n[0]?n="0"+n:"."===n[n.length-1]&&(n=n.substring(0,n.length-1)),n):n;const h=a?"."===t[s.length+1]:"."===t[s.length];if(!e.leadingZeros&&(s.length>1||1===s.length&&!h))return t;{const n=Number(r),i=String(n);if(0===n)return n;if(-1!==i.search(/[eE]/))return e.eNotation?n:t;if(-1!==r.indexOf("."))return"0"===i||i===o||i===`${a}${o}`?n:t;let h=s?o:r;return s?h===i||a+h===i?n:t:h===i||h===a+i?n:t}}return t}}var n;return function(t,e,r){const n=e===1/0;switch(r.infinity.toLowerCase()){case"null":return null;case"infinity":return e;case"string":return n?"Infinity":"-Infinity";default:return t}}(t,Number(r),e)}(t,r)}return void 0!==t?t:""}function W(t,e,r){var n=Number.parseInt(t,e);return n>=0&&n<=1114111?String.fromCodePoint(n):r+t+";"}function X(t,e,r,n){if(t){var i=t(e);r===e&&(r=i),e=i}return{tagName:e=z(e,n),tagExp:r}}function z(t,e){if(o.includes(t))throw new Error('[SECURITY] Invalid name: "'+t+'" is a reserved JavaScript keyword that could cause prototype pollution');return s.includes(t)?e.onDangerousProperty(t):t}var G=g.getMetaDataSymbol();function B(t,e){if(!t||"object"!=typeof t)return{};if(!e)return t;var r={};for(var n in t)n.startsWith(e)?r[n.substring(e.length)]=t[n]:r[n]=t[n];return r}function Z(t,e,r){return q(t,e,r)}function q(t,e,r){for(var n,i={},a=0;a0&&(i[e.textNodeName]=n):void 0!==n&&(i[e.textNodeName]=n),i}function J(t){for(var e=Object.keys(t),r=0;r5&&"xml"===n)return ot("InvalidXml","XML declaration allowed only at the start of the document.",ut(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}}return e}function rt(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){var r=1;for(e+=8;e<"===t[e])r++;else if(">"===t[e]&&0===--r)break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}function nt(t,e){for(var r="",n="",i=!1;e"===t[e]&&""===n){i=!0;break}r+=t[e]}return""===n&&{value:r,index:e,tagClosed:i}}var it=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function at(t,e){for(var r=i(t,it),n={},a=0;a<"!==t[a]){if(tt(t[a]))continue;return ot("InvalidChar","char '"+t[a]+"' is not expected.",ut(t,a))}var s=a;if("!"===t[++a]){a=rt(t,a);continue}var o=!1;"/"===t[a]&&(o=!0,a++);for(var h="";a"!==t[a]&&" "!==t[a]&&"\t"!==t[a]&&"\n"!==t[a]&&"\r"!==t[a];a++)h+=t[a];if("/"===(h=h.trim())[h.length-1]&&(h=h.substring(0,h.length-1),a--),!lt(h))return ot("InvalidTag",0===h.trim().length?"Invalid space after '<'.":"Tag '"+h+"' is an invalid name.",ut(t,a));var l=nt(t,a);if(!1===l)return ot("InvalidAttr","Attributes for '"+h+"' have open quote.",ut(t,a));var u=l.value;if(a=l.index,"/"===u[u.length-1]){var p=a-u.length,d=at(u=u.substring(0,u.length-1),e);if(!0!==d)return ot(d.err.code,d.err.msg,ut(t,p+d.err.line));n=!0}else if(o){if(!l.tagClosed)return ot("InvalidTag","Closing tag '"+h+"' doesn't have proper closing.",ut(t,a));if(u.trim().length>0)return ot("InvalidTag","Closing tag '"+h+"' can't have attributes or invalid starting.",ut(t,s));if(0===r.length)return ot("InvalidTag","Closing tag '"+h+"' has not been opened.",ut(t,s));var f=r.pop();if(h!==f.tagName){var g=ut(t,f.tagStartPos);return ot("InvalidTag","Expected closing tag '"+f.tagName+"' (opened in line "+g.line+", col "+g.col+") instead of closing tag '"+h+"'.",ut(t,s))}0==r.length&&(i=!0)}else{var c=at(u,e);if(!0!==c)return ot(c.err.code,c.err.msg,ut(t,a-u.length+c.err.line));if(!0===i)return ot("InvalidXml","Multiple possible root nodes found.",ut(t,a));-1!==e.unpairedTags.indexOf(h)||r.push({tagName:h,tagStartPos:s}),n=!0}for(a++;a<"===t[a]){if("!"===t[a+1]){a=rt(t,++a);continue}if("?"!==t[a+1])break;if((a=et(t,++a)).err)return a}else if("&"===t[a]){var m=st(t,a);if(-1==m)return ot("InvalidChar","char '&' is not expected.",ut(t,a));a=m}else if(!0===i&&!tt(t[a]))return ot("InvalidXml","Extra text at the end",ut(t,a));"<"===t[a]&&a--}return n?1==r.length?ot("InvalidTag","Unclosed tag '"+r[0].tagName+"'.",ut(t,r[0].tagStartPos)):!(r.length>0)||ot("InvalidXml","Invalid '"+JSON.stringify(r.map(function(t){return t.tagName}),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):ot("InvalidXml","Start tag expected.",1)}(t,e);if(!0!==r)throw Error(r.err.msg+":"+r.err.line+":"+r.err.col)}var n=new P(this.options);n.addExternalEntities(this.externalEntities);var i=n.parseXml(t);return this.options.preserveOrder||void 0===i?i:Z(i,this.options,n.matcher)},e.addEntity=function(t,e){if(-1!==e.indexOf("&"))throw new Error("Entity value can't have '&'");if(-1!==t.indexOf("&")||-1!==t.indexOf(";"))throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for ' '");if("&"===e)throw new Error("An entity with value '&' is not permitted");this.externalEntities[t]=e},t.getMetaDataSymbol=function(){return g.getMetaDataSymbol()},t}();return e})()); +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.XMLParser=e():t.XMLParser=e()}(this,()=>(()=>{"use strict";var t={d:(e,r)=>{for(var n in r)t.o(r,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{default:()=>Tt});var r=":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",n=new RegExp("^["+r+"]["+r+"\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$");function i(t,e){for(var r=[],n=e.exec(t);n;){var i=[];i.startIndex=e.lastIndex-n[0].length;for(var a=n.length,s=0;s0?this.child.push(((r={})[t.tagname]=t.child,r[":@"]=t[":@"],r)):this.child.push(((n={})[t.tagname]=t.child,n)),void 0!==e&&(this.child[this.child.length-1][d]={startIndex:e})},t.getMetaDataSymbol=function(){return d},t}(),g=function(){function t(t){this.suppressValidationErr=!t,this.options=t}var e=t.prototype;return e.readDocType=function(t,e){var r=Object.create(null),n=0;if("O"!==t[e+3]||"C"!==t[e+4]||"T"!==t[e+5]||"Y"!==t[e+6]||"P"!==t[e+7]||"E"!==t[e+8])throw new Error("Invalid Tag instead of DOCTYPE");e+=9;for(var i=1,a=!1,s=!1;e<"!==t[e]||s)if(">"===t[e]){if(s?"-"===t[e-1]&&"-"===t[e-2]&&(s=!1,i--):i--,0===i)break}else"["===t[e]?a=!0:t[e];else{if(a&&v(t,"!ENTITY",e)){e+=7;var o,h=void 0,l=this.readEntityExp(t,e+1,this.suppressValidationErr);if(o=l[0],h=l[1],e=l[2],-1===h.indexOf("&")){if(!1!==this.options.enabled&&null!=this.options.maxEntityCount&&n>=this.options.maxEntityCount)throw new Error("Entity count ("+(n+1)+") exceeds maximum allowed ("+this.options.maxEntityCount+")");r[o]=h,n++}}else if(a&&v(t,"!ELEMENT",e))e+=8,e=this.readElementExp(t,e+1).index;else if(a&&v(t,"!ATTLIST",e))e+=8;else if(a&&v(t,"!NOTATION",e))e+=9,e=this.readNotationExp(t,e+1,this.suppressValidationErr).index;else{if(!v(t,"!--",e))throw new Error("Invalid DOCTYPE");s=!0}i++}if(0!==i)throw new Error("Unclosed DOCTYPE");return{entities:r,i:e}},e.readEntityExp=function(t,e){for(var r=e=m(t,e);ethis.options.maxEntitySize)throw new Error('Entity "'+n+'" size ('+i.length+") exceeds maximum allowed size ("+this.options.maxEntitySize+")");return[n,i,--e]},e.readNotationExp=function(t,e){for(var r=e=m(t,e);et.length)&&(e=t.length);for(var r=0,n=Array(e);r0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return!1;const r=e[e.length-1];return void 0!==r.values&&t in r.values}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=!0){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class S{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new _(this)}push(t,e=null,r=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const n=this.path.length;this.siblingStacks[n]||(this.siblingStacks[n]=new Map);const i=this.siblingStacks[n],a=r?`${r}:${t}`:t,s=i.get(a)||0;let o=0;for(const t of i.values())o+=t;i.set(a,s+1);const h={tag:t,position:o,counter:s};null!=r&&(h.namespace=r),null!=e&&(h.values=e),this.path.push(h)}pop(){if(0===this.path.length)return;this._pathStringCache=null;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const r=t||this.separator;if(r===this.separator&&!0===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(r);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(r)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const n=t[r];if("deep-wildcard"===n.type){if(r--,r<0)return!0;const n=t[r];let i=!1;for(let t=e;t>=0;t--)if(this._matchSegment(n,this.path[t],t===this.path.length-1)){e=t-1,r--,i=!0;break}if(!i)return!1}else{if(!this._matchSegment(n,this.path[e],e===this.path.length-1))return!1;e--,r--}}return r<0}_matchSegment(t,e,r){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!r)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return!1}if(void 0!==t.position){if(!r)return!1;const n=e.counter??0;if("first"===t.position&&0!==n)return!1;if("odd"===t.position&&n%2!=1)return!1;if("even"===t.position&&n%2!=0)return!1;if("nth"===t.position&&n!==t.positionValue)return!1}return!0}matchesAny(t){return t.matchesAny(this)}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}readOnly(){return this._view}}class T{constructor(t,e={},r){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=r,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let r=0,n="";for(;r",lt:"<",quot:'"'},P={nbsp:" ",copy:"©",reg:"®",trade:"™",mdash:"—",ndash:"–",hellip:"…",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",bull:"•",para:"¶",sect:"§",deg:"°",frac12:"½",frac14:"¼",frac34:"¾"},M=new Set("!?\\\\/[]$%{}^&*()<>|+");function D(t){if("#"===t[0])throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${t}"`);for(const e of t)if(M.has(e))throw new Error(`[EntityReplacer] Invalid character '${e}' in entity name: "${t}"`);return t}function O(...t){const e=Object.create(null);for(const r of t)if(r)for(const t of Object.keys(r)){const n=r[t];if("string"==typeof n)e[t]=n;else if(n&&"object"==typeof n&&void 0!==n.val){const r=n.val;"string"==typeof r&&(e[t]=r)}}return e}const j="external",L="base",k="all",V=Object.freeze({allow:0,leave:1,remove:2,throw:3}),F=new Set([9,10,13]);class ${constructor(t={}){var e;this._limit=t.limit||{},this._maxTotalExpansions=this._limit.maxTotalExpansions||0,this._maxExpandedLength=this._limit.maxExpandedLength||0,this._postCheck="function"==typeof t.postCheck?t.postCheck:t=>t,this._limitTiers=(e=this._limit.applyLimitsTo??j)&&e!==j?e===k?new Set([k]):e===L?new Set([L]):Array.isArray(e)?new Set(e):new Set([j]):new Set([j]),this._numericAllowed=t.numericAllowed??!0,this._baseMap=O(I,t.namedEntities||null),this._externalMap=Object.create(null),this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this._removeSet=new Set(t.remove&&Array.isArray(t.remove)?t.remove:[]),this._leaveSet=new Set(t.leave&&Array.isArray(t.leave)?t.leave:[]);const r=function(t){if(!t)return{xmlVersion:1,onLevel:V.allow,nullLevel:V.remove};const e=1.1===t.xmlVersion?1.1:1,r=V[t.onNCR]??V.allow,n=V[t.nullNCR]??V.remove;return{xmlVersion:e,onLevel:r,nullLevel:Math.max(n,V.remove)}}(t.ncr);this._ncrXmlVersion=r.xmlVersion,this._ncrOnLevel=r.onLevel,this._ncrNullLevel=r.nullLevel}setExternalEntities(t){if(t)for(const e of Object.keys(t))D(e);this._externalMap=O(t)}addExternalEntity(t,e){D(t),"string"==typeof e&&-1===e.indexOf("&")&&(this._externalMap[t]=e)}addInputEntities(t){this._totalExpansions=0,this._expandedLength=0,this._inputMap=O(t)}reset(){return this._inputMap=Object.create(null),this._totalExpansions=0,this._expandedLength=0,this}setXmlVersion(t){this._ncrXmlVersion=1.1===t?1.1:1}decode(t){if("string"!=typeof t||0===t.length)return t;const e=t,r=[],n=t.length;let i=0,a=0;const s=this._maxTotalExpansions>0,o=this._maxExpandedLength>0,h=s||o;for(;a=n||59!==t.charCodeAt(e)){a++;continue}const l=t.slice(a+1,e);if(0===l.length){a++;continue}let u,p;if(this._removeSet.has(l))u="",void 0===p&&(p=j);else{if(this._leaveSet.has(l)){a++;continue}if(35===l.charCodeAt(0)){const t=this._resolveNCR(l);if(void 0===t){a++;continue}u=t,p=L}else{const t=this._resolveName(l);u=t?.value,p=t?.tier}}if(void 0!==u){if(a>i&&r.push(t.slice(i,a)),r.push(u),i=e+1,a=i,h&&this._tierCounts(p)){if(s&&(this._totalExpansions++,this._totalExpansions>this._maxTotalExpansions))throw new Error(`[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}`);if(o){const t=u.length-(l.length+2);if(t>0&&(this._expandedLength+=t,this._expandedLength>this._maxExpandedLength))throw new Error(`[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}`)}}}else a++}i=55296&&t<=57343||1===this._ncrXmlVersion&&t>=1&&t<=31&&!F.has(t)?V.remove:-1}_applyNCRAction(t,e,r){switch(t){case V.allow:return String.fromCodePoint(r);case V.remove:return"";case V.leave:return;case V.throw:throw new Error(`[EntityDecoder] Prohibited numeric character reference &${e}; (U+${r.toString(16).toUpperCase().padStart(4,"0")})`);default:return String.fromCodePoint(r)}}_resolveNCR(t){const e=t.charCodeAt(1);let r;if(r=120===e||88===e?parseInt(t.slice(2),16):parseInt(t.slice(1),10),Number.isNaN(r)||r<0||r>1114111)return;const n=this._classifyNCR(r);if(!this._numericAllowed&&n0){var r=t.substring(0,e);if("xmlns"!==r)return r}}}var X=function(t){var e;this.options=t,this.currentNode=null,this.tagsNodeStack=[],this.parseXml=q,this.parseTextData=Y,this.resolveNameSpace=B,this.buildAttributesMap=G,this.isItStopNode=Q,this.replaceEntitiesValue=J,this.readStopNodeData=rt,this.saveTextToParentTag=K,this.addChild=Z,this.ignoreAttributesFn="function"==typeof(e=this.options.ignoreAttributes)?e:Array.isArray(e)?function(t){for(var r,n=function(t,e){var r="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(r)return(r=r.call(t)).next.bind(r);if(Array.isArray(t)||(r=function(t,e){if(t){if("string"==typeof t)return w(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?w(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){r&&(t=r);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(e);!(r=n()).done;){var i=r.value;if("string"==typeof i&&t===i)return!0;if(i instanceof RegExp&&i.test(t))return!0}}:function(){return!1},this.entityExpansionCount=0,this.currentExpandedLength=0;var r=R({},I);this.options.entityDecoder?this.entityDecoder=this.options.entityDecoder:("object"==typeof this.options.htmlEntities?r=this.options.htmlEntities:!0===this.options.htmlEntities&&(r=R({},P,A)),this.entityDecoder=new $({namedEntities:r,numericAllowed:this.options.htmlEntities,limit:{maxTotalExpansions:this.options.processEntities.maxTotalExpansions,maxExpandedLength:this.options.processEntities.maxExpandedLength,applyLimitsTo:this.options.processEntities.appliesTo}})),this.matcher=new S,this.readonlyMatcher=this.matcher.readOnly(),this.isCurrentNodeStopNode=!1,this.stopNodeExpressionsSet=new C;var n=this.options.stopNodes;if(n&&n.length>0){for(var i=0;i0)){s||(t=this.replaceEntitiesValue(t,e,r));var h=o.jPath?r.toString():r,l=o.tagValueProcessor(e,t,h,i,a);return null==l?t:typeof l!=typeof t||l!==t?l:o.trimValues||t.trim()===t?nt(t,o.parseTagValue,o.numberParseOptions):t}}function B(t){if(this.options.removeNSPrefix){var e=t.split(":"),r="/"===t.charAt(0)?"/":"";if("xmlns"===e[0])return"";2===e.length&&(t=r+e[1])}return t}var z=new RegExp("([^\\s=]+)\\s*(=\\s*(['\"])([\\s\\S]*?)\\3)?","gm");function G(t,e,r,n){void 0===n&&(n=!1);var a=this.options;if(!0===n||!0!==a.ignoreAttributes&&"string"==typeof t){for(var s=i(t,z),o=s.length,h={},l=new Array(o),u=!1,p={},d=0;d",o,"Closing Tag is not closed."),u=t.substring(o+2,l).trim();if(i.removeNSPrefix){var p=u.indexOf(":");-1!==p&&(u=u.substr(p+1))}u=it(i.transformTagName,u,"",i).tagName,r&&(n=this.saveTextToParentTag(n,r,this.readonlyMatcher));var d=this.matcher.getCurrentTag();if(u&&i.unpairedTagsSet.has(u))throw new Error("Unpaired tag can not be used as closing tag: ");d&&i.unpairedTagsSet.has(d)&&(this.matcher.pop(),this.tagsNodeStack.pop()),this.matcher.pop(),this.isCurrentNodeStopNode=!1,r=this.tagsNodeStack.pop(),n="",o=l}else if(63===h){var c=et(t,o,!1,"?>");if(!c)throw new Error("Pi Tag is not closed.");n=this.saveTextToParentTag(n,r,this.readonlyMatcher);var m=this.buildAttributesMap(c.tagExp,this.matcher,c.tagName,!0);if(m){var v=m[this.options.attributeNamePrefix+"version"];this.entityDecoder.setXmlVersion(Number(v)||1)}if(i.ignoreDeclaration&&"?xml"===c.tagName||i.ignorePiTags);else{var x=new f(c.tagName);x.add(i.textNodeName,""),c.tagName!==c.tagExp&&c.attrExpPresent&&!0!==i.ignoreAttributes&&(x[":@"]=m),this.addChild(r,x,this.readonlyMatcher,o)}o=c.closeIndex+1}else if(33===h&&45===t.charCodeAt(o+2)&&45===t.charCodeAt(o+3)){var y=H(t,"--\x3e",o+4,"Comment is not closed.");if(i.commentPropName){var E,b=t.substring(o+4,y-2);n=this.saveTextToParentTag(n,r,this.readonlyMatcher),r.add(i.commentPropName,[(E={},E[i.textNodeName]=b,E)])}o=y}else if(33===h&&68===t.charCodeAt(o+2)){var N=a.readDocType(t,o);this.entityDecoder.addInputEntities(N.entities),o=N.i}else if(33===h&&91===t.charCodeAt(o+2)){var w=H(t,"]]>",o,"CDATA is not closed.")-2,_=t.substring(o+9,w);n=this.saveTextToParentTag(n,r,this.readonlyMatcher);var S,T=this.parseTextData(_,r.tagname,this.readonlyMatcher,!0,!1,!0,!0);null==T&&(T=""),i.cdataPropName?r.add(i.cdataPropName,[(S={},S[i.textNodeName]=_,S)]):r.add(i.textNodeName,T),o=w+2}else{var C=et(t,o,i.removeNSPrefix);if(!C){var A=t.substring(Math.max(0,o-50),Math.min(s,o+50));throw new Error("readTagExp returned undefined at position "+o+'. Context: "'+A+'"')}var I=C.tagName,P=C.rawTagName,M=C.tagExp,D=C.attrExpPresent,O=C.closeIndex,j=it(i.transformTagName,I,M,i);if(I=j.tagName,M=j.tagExp,i.strictReservedNames&&(I===i.commentPropName||I===i.cdataPropName||I===i.textNodeName||I===i.attributesGroupName))throw new Error("Invalid tag name: "+I);r&&n&&"!xml"!==r.tagname&&(n=this.saveTextToParentTag(n,r,this.readonlyMatcher,!1));var L=r;L&&i.unpairedTagsSet.has(L.tagname)&&(r=this.tagsNodeStack.pop(),this.matcher.pop());var k=!1;M.length>0&&M.lastIndexOf("/")===M.length-1&&(k=!0,M="/"===I[I.length-1]?I=I.substr(0,I.length-1):M.substr(0,M.length-1),D=I!==M);var V,F=null;V=W(P),I!==e.tagname&&this.matcher.push(I,{},V),I!==M&&D&&(F=this.buildAttributesMap(M,this.matcher,I))&&U(F,i),I!==e.tagname&&(this.isCurrentNodeStopNode=this.isItStopNode());var $=o;if(this.isCurrentNodeStopNode){var R="";if(k)o=C.closeIndex;else if(i.unpairedTagsSet.has(I))o=C.closeIndex;else{var X=this.readStopNodeData(t,P,O+1);if(!X)throw new Error("Unexpected end of "+P);o=X.i,R=X.tagContent}var Y=new f(I);F&&(Y[":@"]=F),Y.add(i.textNodeName,R),this.matcher.pop(),this.isCurrentNodeStopNode=!1,this.addChild(r,Y,this.readonlyMatcher,$)}else{if(k){var B=it(i.transformTagName,I,M,i);I=B.tagName,M=B.tagExp;var z=new f(I);F&&(z[":@"]=F),this.addChild(r,z,this.readonlyMatcher,$),this.matcher.pop(),this.isCurrentNodeStopNode=!1}else{if(i.unpairedTagsSet.has(I)){var G=new f(I);F&&(G[":@"]=F),this.addChild(r,G,this.readonlyMatcher,$),this.matcher.pop(),this.isCurrentNodeStopNode=!1,o=C.closeIndex;continue}var q=new f(I);if(this.tagsNodeStack.length>i.maxNestedTags)throw new Error("Maximum nested tags exceeded");this.tagsNodeStack.push(r),F&&(q[":@"]=F),this.addChild(r,q,this.readonlyMatcher,$),r=q}n="",o=O}}}else n+=t[o];return e.child};function Z(t,e,r,n){this.options.captureMetaData||(n=void 0);var i=this.options.jPath?r.toString():r,a=this.options.updateTag(e.tagname,i,e[":@"]);!1===a||("string"==typeof a?(e.tagname=a,t.addChild(e,n)):t.addChild(e,n))}function J(t,e,r){var n=this.options.processEntities;if(!n||!n.enabled)return t;if(n.allowedTags){var i=this.options.jPath?r.toString():r;if(!(Array.isArray(n.allowedTags)?n.allowedTags.includes(e):n.allowedTags(e,i)))return t}if(n.tagFilter){var a=this.options.jPath?r.toString():r;if(!n.tagFilter(e,a))return t}return this.entityDecoder.decode(t)}function K(t,e,r,n){return t&&(void 0===n&&(n=0===e.child.length),void 0!==(t=this.parseTextData(t,e.tagname,r,!1,!!e[":@"]&&0!==Object.keys(e[":@"]).length,n))&&""!==t&&e.add(this.options.textNodeName,t),t=""),t}function Q(){return 0!==this.stopNodeExpressionsSet.size&&this.matcher.matchesAny(this.stopNodeExpressionsSet)}function H(t,e,r,n){var i=t.indexOf(e,r);if(-1===i)throw new Error(n);return i+e.length-1}function tt(t,e,r,n){var i=t.indexOf(e,r);if(-1===i)throw new Error(n);return i}function et(t,e,r,n){void 0===n&&(n=">");var i=function(t,e,r){void 0===r&&(r=">");for(var n=0,i=[],a=t.length,s=r.charCodeAt(0),o=r.length>1?r.charCodeAt(1):-1,h=e;h",r,e+" is not closed");if(t.substring(r+2,o).trim()===e&&0===--i)return{tagContent:t.substring(n,r),i:o};r=o}else if(63===s)r=H(t,"?>",r+1,"StopNode is not closed.");else if(33===s&&45===t.charCodeAt(r+2)&&45===t.charCodeAt(r+3))r=H(t,"--\x3e",r+3,"StopNode is not closed.");else if(33===s&&91===t.charCodeAt(r+2))r=H(t,"]]>",r,"StopNode is not closed.")-2;else{var h=et(t,r,">");h&&((h&&h.tagName)===e&&"/"!==h.tagExp[h.tagExp.length-1]&&i++,r=h.closeIndex)}}}function nt(t,e,r){if(e&&"string"==typeof t){var n=t.trim();return"true"===n||"false"!==n&&function(t,e={}){if(e=Object.assign({},b,e),!t||"string"!=typeof t)return t;let r=t.trim();if(0===r.length)return t;if(void 0!==e.skipLike&&e.skipLike.test(r))return t;if("0"===r)return 0;if(e.hex&&y.test(r))return function(t){if(parseInt)return parseInt(t,16);if(Number.parseInt)return Number.parseInt(t,16);if(window&&window.parseInt)return window.parseInt(t,16);throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")}(r);if(isFinite(r)){if(r.includes("e")||r.includes("E"))return function(t,e,r){if(!r.eNotation)return t;const n=e.match(N);if(n){let i=n[1]||"";const a=-1===n[3].indexOf("e")?"E":"e",s=n[2],o=i?t[s.length+1]===a:t[s.length]===a;return s.length>1&&o?t:(1!==s.length||!n[3].startsWith(`.${a}`)&&n[3][0]!==a)&&s.length>0?r.leadingZeros&&!o?(e=(n[1]||"")+n[3],Number(e)):t:Number(e)}return t}(t,r,e);{const i=E.exec(r);if(i){const a=i[1]||"",s=i[2];let o=(n=i[3])&&-1!==n.indexOf(".")?("."===(n=n.replace(/0+$/,""))?n="0":"."===n[0]?n="0"+n:"."===n[n.length-1]&&(n=n.substring(0,n.length-1)),n):n;const h=a?"."===t[s.length+1]:"."===t[s.length];if(!e.leadingZeros&&(s.length>1||1===s.length&&!h))return t;{const n=Number(r),i=String(n);if(0===n)return n;if(-1!==i.search(/[eE]/))return e.eNotation?n:t;if(-1!==r.indexOf("."))return"0"===i||i===o||i===`${a}${o}`?n:t;let h=s?o:r;return s?h===i||a+h===i?n:t:h===i||h===a+i?n:t}}return t}}var n;return function(t,e,r){const n=e===1/0;switch(r.infinity.toLowerCase()){case"null":return null;case"infinity":return e;case"string":return n?"Infinity":"-Infinity";default:return t}}(t,Number(r),e)}(t,r)}return void 0!==t?t:""}function it(t,e,r,n){if(t){var i=t(e);r===e&&(r=i),e=i}return{tagName:e=at(e,n),tagExp:r}}function at(t,e){if(o.includes(t))throw new Error('[SECURITY] Invalid name: "'+t+'" is a reserved JavaScript keyword that could cause prototype pollution');return s.includes(t)?e.onDangerousProperty(t):t}var st=f.getMetaDataSymbol();function ot(t,e){if(!t||"object"!=typeof t)return{};if(!e)return t;var r={};for(var n in t)n.startsWith(e)?r[n.substring(e.length)]=t[n]:r[n]=t[n];return r}function ht(t,e,r,n){return lt(t,e,r,n)}function lt(t,e,r,n){for(var i,a={},s=0;s0&&(a[e.textNodeName]=i):void 0!==i&&(a[e.textNodeName]=i),a}function ut(t){for(var e=Object.keys(t),r=0;r5&&"xml"===n)return bt("InvalidXml","XML declaration allowed only at the start of the document.",_t(t,e));if("?"==t[e]&&">"==t[e+1]){e++;break}}return e}function mt(t,e){if(t.length>e+5&&"-"===t[e+1]&&"-"===t[e+2]){for(e+=3;e"===t[e+2]){e+=2;break}}else if(t.length>e+8&&"D"===t[e+1]&&"O"===t[e+2]&&"C"===t[e+3]&&"T"===t[e+4]&&"Y"===t[e+5]&&"P"===t[e+6]&&"E"===t[e+7]){var r=1;for(e+=8;e<"===t[e])r++;else if(">"===t[e]&&0===--r)break}else if(t.length>e+9&&"["===t[e+1]&&"C"===t[e+2]&&"D"===t[e+3]&&"A"===t[e+4]&&"T"===t[e+5]&&"A"===t[e+6]&&"["===t[e+7])for(e+=8;e"===t[e+2]){e+=2;break}return e}function vt(t,e){for(var r="",n="",i=!1;e"===t[e]&&""===n){i=!0;break}r+=t[e]}return""===n&&{value:r,index:e,tagClosed:i}}var xt=new RegExp("(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['\"])(([\\s\\S])*?)\\5)?","g");function yt(t,e){for(var r=i(t,xt),n={},a=0;a<"!==t[a]){if(ft(t[a]))continue;return bt("InvalidChar","char '"+t[a]+"' is not expected.",_t(t,a))}var s=a;if("!"===t[++a]){a=mt(t,a);continue}var o=!1;"/"===t[a]&&(o=!0,a++);for(var h="";a"!==t[a]&&" "!==t[a]&&"\t"!==t[a]&&"\n"!==t[a]&&"\r"!==t[a];a++)h+=t[a];if("/"===(h=h.trim())[h.length-1]&&(h=h.substring(0,h.length-1),a--),!wt(h))return bt("InvalidTag",0===h.trim().length?"Invalid space after '<'.":"Tag '"+h+"' is an invalid name.",_t(t,a));var l=vt(t,a);if(!1===l)return bt("InvalidAttr","Attributes for '"+h+"' have open quote.",_t(t,a));var u=l.value;if(a=l.index,"/"===u[u.length-1]){var p=a-u.length,d=yt(u=u.substring(0,u.length-1),e);if(!0!==d)return bt(d.err.code,d.err.msg,_t(t,p+d.err.line));n=!0}else if(o){if(!l.tagClosed)return bt("InvalidTag","Closing tag '"+h+"' doesn't have proper closing.",_t(t,a));if(u.trim().length>0)return bt("InvalidTag","Closing tag '"+h+"' can't have attributes or invalid starting.",_t(t,s));if(0===r.length)return bt("InvalidTag","Closing tag '"+h+"' has not been opened.",_t(t,s));var c=r.pop();if(h!==c.tagName){var f=_t(t,c.tagStartPos);return bt("InvalidTag","Expected closing tag '"+c.tagName+"' (opened in line "+f.line+", col "+f.col+") instead of closing tag '"+h+"'.",_t(t,s))}0==r.length&&(i=!0)}else{var g=yt(u,e);if(!0!==g)return bt(g.err.code,g.err.msg,_t(t,a-u.length+g.err.line));if(!0===i)return bt("InvalidXml","Multiple possible root nodes found.",_t(t,a));-1!==e.unpairedTags.indexOf(h)||r.push({tagName:h,tagStartPos:s}),n=!0}for(a++;a<"===t[a]){if("!"===t[a+1]){a=mt(t,++a);continue}if("?"!==t[a+1])break;if((a=gt(t,++a)).err)return a}else if("&"===t[a]){var m=Et(t,a);if(-1==m)return bt("InvalidChar","char '&' is not expected.",_t(t,a));a=m}else if(!0===i&&!ft(t[a]))return bt("InvalidXml","Extra text at the end",_t(t,a));"<"===t[a]&&a--}return n?1==r.length?bt("InvalidTag","Unclosed tag '"+r[0].tagName+"'.",_t(t,r[0].tagStartPos)):!(r.length>0)||bt("InvalidXml","Invalid '"+JSON.stringify(r.map(function(t){return t.tagName}),null,4).replace(/\r?\n/g,"")+"' found.",{line:1,col:1}):bt("InvalidXml","Start tag expected.",1)}(t,e);if(!0!==r)throw Error(r.err.msg+":"+r.err.line+":"+r.err.col)}var n=new X(this.options);n.entityDecoder.setExternalEntities(this.externalEntities);var i=n.parseXml(t);return this.options.preserveOrder||void 0===i?i:ht(i,this.options,n.matcher,n.readonlyMatcher)},e.addEntity=function(t,e){if(-1!==e.indexOf("&"))throw new Error("Entity value can't have '&'");if(-1!==t.indexOf("&")||-1!==t.indexOf(";"))throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for ' '");if("&"===e)throw new Error("An entity with value '&' is not permitted");this.externalEntities[t]=e},t.getMetaDataSymbol=function(){return f.getMetaDataSymbol()},t}();return e})()); //# sourceMappingURL=fxparser.min.js.map \ No newline at end of file diff --git a/node_modules/fast-xml-parser/lib/fxparser.min.js.map b/node_modules/fast-xml-parser/lib/fxparser.min.js.map index 2fc8dd40..60fcd3a6 100644 --- a/node_modules/fast-xml-parser/lib/fxparser.min.js.map +++ b/node_modules/fast-xml-parser/lib/fxparser.min.js.map @@ -1 +1 @@ -{"version":3,"file":"./lib/fxparser.min.js","mappings":"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","sources":["webpack://XMLParser/webpack/universalModuleDefinition","webpack://XMLParser/webpack/bootstrap","webpack://XMLParser/webpack/runtime/define property getters","webpack://XMLParser/webpack/runtime/hasOwnProperty shorthand","webpack://XMLParser/webpack/runtime/make namespace object","webpack://XMLParser/./src/util.js","webpack://XMLParser/./src/xmlparser/OptionsBuilder.js","webpack://XMLParser/./src/xmlparser/xmlNode.js","webpack://XMLParser/./src/xmlparser/DocTypeReader.js","webpack://XMLParser/./node_modules/strnum/strnum.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/Matcher.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/Expression.js","webpack://XMLParser/./src/xmlparser/OrderedObjParser.js","webpack://XMLParser/./src/ignoreAttributes.js","webpack://XMLParser/./src/xmlparser/node2json.js","webpack://XMLParser/./src/validator.js","webpack://XMLParser/./src/xmlparser/XMLParser.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"XMLParser\"] = factory();\n\telse\n\t\troot[\"XMLParser\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n/**\n * Dangerous property names that could lead to prototype pollution or security issues\n */\nexport const DANGEROUS_PROPERTY_NAMES = [\n // '__proto__',\n // 'constructor',\n // 'prototype',\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__'\n];\n\nexport const criticalProperties = [\"__proto__\", \"constructor\", \"prototype\"];","import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from \"../util.js\";\n\nconst defaultOnDangerousProperty = (name) => {\n if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return \"__\" + name;\n }\n return name;\n};\n\n\nexport const defaultOptions = {\n preserveOrder: false,\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n removeNSPrefix: false, // remove NS from tag name or attribute name if true\n allowBooleanAttributes: false, //a tag can have attributes without any value\n //ignoreRootElement : false,\n parseTagValue: true,\n parseAttributeValue: false,\n trimValues: true, //Trim string values of tag and attributes\n cdataPropName: false,\n numberParseOptions: {\n hex: true,\n leadingZeros: true,\n eNotation: true\n },\n tagValueProcessor: function (tagName, val) {\n return val;\n },\n attributeValueProcessor: function (attrName, val) {\n return val;\n },\n stopNodes: [], //nested tags will not be parsed even for errors\n alwaysCreateTextNode: false,\n isArray: () => false,\n commentPropName: false,\n unpairedTags: [],\n processEntities: true,\n htmlEntities: false,\n ignoreDeclaration: false,\n ignorePiTags: false,\n transformTagName: false,\n transformAttributeName: false,\n updateTag: function (tagName, jPath, attrs) {\n return tagName\n },\n // skipEmptyListItem: false\n captureMetaData: false,\n maxNestedTags: 100,\n strictReservedNames: true,\n jPath: true, // if true, pass jPath string to callbacks; if false, pass matcher instance\n onDangerousProperty: defaultOnDangerousProperty\n};\n\n\n/**\n * Validates that a property name is safe to use\n * @param {string} propertyName - The property name to validate\n * @param {string} optionName - The option field name (for error message)\n * @throws {Error} If property name is dangerous\n */\nfunction validatePropertyName(propertyName, optionName) {\n if (typeof propertyName !== 'string') {\n return; // Only validate string property names\n }\n\n const normalized = propertyName.toLowerCase();\n if (DANGEROUS_PROPERTY_NAMES.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n\n if (criticalProperties.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n}\n\n/**\n * Normalizes processEntities option for backward compatibility\n * @param {boolean|object} value \n * @returns {object} Always returns normalized object\n */\nfunction normalizeProcessEntities(value) {\n // Boolean backward compatibility\n if (typeof value === 'boolean') {\n return {\n enabled: value, // true or false\n maxEntitySize: 10000,\n maxExpansionDepth: 10,\n maxTotalExpansions: 1000,\n maxExpandedLength: 100000,\n maxEntityCount: 100,\n allowedTags: null,\n tagFilter: null\n };\n }\n\n // Object config - merge with defaults\n if (typeof value === 'object' && value !== null) {\n return {\n enabled: value.enabled !== false,\n maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000),\n maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10),\n maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? 1000),\n maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000),\n maxEntityCount: Math.max(1, value.maxEntityCount ?? 100),\n allowedTags: value.allowedTags ?? null,\n tagFilter: value.tagFilter ?? null\n };\n }\n\n // Default to enabled with limits\n return normalizeProcessEntities(true);\n}\n\nexport const buildOptions = function (options) {\n const built = Object.assign({}, defaultOptions, options);\n\n // Validate property names to prevent prototype pollution\n const propertyNameOptions = [\n { value: built.attributeNamePrefix, name: 'attributeNamePrefix' },\n { value: built.attributesGroupName, name: 'attributesGroupName' },\n { value: built.textNodeName, name: 'textNodeName' },\n { value: built.cdataPropName, name: 'cdataPropName' },\n { value: built.commentPropName, name: 'commentPropName' }\n ];\n\n for (const { value, name } of propertyNameOptions) {\n if (value) {\n validatePropertyName(value, name);\n }\n }\n\n if (built.onDangerousProperty === null) {\n built.onDangerousProperty = defaultOnDangerousProperty;\n }\n\n // Always normalize processEntities for backward compatibility and validation\n built.processEntities = normalizeProcessEntities(built.processEntities);\n\n // Convert old-style stopNodes for backward compatibility\n if (built.stopNodes && Array.isArray(built.stopNodes)) {\n built.stopNodes = built.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Old syntax: *.tagname meant \"tagname anywhere\"\n // Convert to new syntax: ..tagname\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n //console.debug(built.processEntities)\n return built;\n};","'use strict';\n\nlet METADATA_SYMBOL;\n\nif (typeof Symbol !== \"function\") {\n METADATA_SYMBOL = \"@@xmlMetadata\";\n} else {\n METADATA_SYMBOL = Symbol(\"XML Node Metadata\");\n}\n\nexport default class XmlNode {\n constructor(tagname) {\n this.tagname = tagname;\n this.child = []; //nested tags, text, cdata, comments in order\n this[\":@\"] = Object.create(null); //attributes map\n }\n add(key, val) {\n // this.child.push( {name : key, val: val, isCdata: isCdata });\n if (key === \"__proto__\") key = \"#__proto__\";\n this.child.push({ [key]: val });\n }\n addChild(node, startIndex) {\n if (node.tagname === \"__proto__\") node.tagname = \"#__proto__\";\n if (node[\":@\"] && Object.keys(node[\":@\"]).length > 0) {\n this.child.push({ [node.tagname]: node.child, [\":@\"]: node[\":@\"] });\n } else {\n this.child.push({ [node.tagname]: node.child });\n }\n // if requested, add the startIndex\n if (startIndex !== undefined) {\n // Note: for now we just overwrite the metadata. If we had more complex metadata,\n // we might need to do an object append here: metadata = { ...metadata, startIndex }\n this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };\n }\n }\n /** symbol used for metadata */\n static getMetaDataSymbol() {\n return METADATA_SYMBOL;\n }\n}\n","import { isName } from '../util.js';\n\nexport default class DocTypeReader {\n constructor(options) {\n this.suppressValidationErr = !options;\n this.options = options;\n }\n\n readDocType(xmlData, i) {\n const entities = Object.create(null);\n let entityCount = 0;\n\n if (xmlData[i + 3] === 'O' &&\n xmlData[i + 4] === 'C' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'Y' &&\n xmlData[i + 7] === 'P' &&\n xmlData[i + 8] === 'E') {\n i = i + 9;\n let angleBracketsCount = 1;\n let hasBody = false, comment = false;\n let exp = \"\";\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === '<' && !comment) { //Determine the tag type\n if (hasBody && hasSeq(xmlData, \"!ENTITY\", i)) {\n i += 7;\n let entityName, val;\n [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);\n if (val.indexOf(\"&\") === -1) { //Parameter entities are not supported\n if (this.options.enabled !== false &&\n this.options.maxEntityCount != null &&\n entityCount >= this.options.maxEntityCount) {\n throw new Error(\n `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`\n );\n }\n //const escaped = entityName.replace(/[.\\-+*:]/g, '\\\\.');\n const escaped = entityName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n entities[entityName] = {\n regx: RegExp(`&${escaped};`, \"g\"),\n val: val\n };\n entityCount++;\n }\n }\n else if (hasBody && hasSeq(xmlData, \"!ELEMENT\", i)) {\n i += 8;//Not supported\n const { index } = this.readElementExp(xmlData, i + 1);\n i = index;\n } else if (hasBody && hasSeq(xmlData, \"!ATTLIST\", i)) {\n i += 8;//Not supported\n // const {index} = this.readAttlistExp(xmlData,i+1);\n // i = index;\n } else if (hasBody && hasSeq(xmlData, \"!NOTATION\", i)) {\n i += 9;//Not supported\n const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);\n i = index;\n } else if (hasSeq(xmlData, \"!--\", i)) comment = true;\n else throw new Error(`Invalid DOCTYPE`);\n\n angleBracketsCount++;\n exp = \"\";\n } else if (xmlData[i] === '>') { //Read tag content\n if (comment) {\n if (xmlData[i - 1] === \"-\" && xmlData[i - 2] === \"-\") {\n comment = false;\n angleBracketsCount--;\n }\n } else {\n angleBracketsCount--;\n }\n if (angleBracketsCount === 0) {\n break;\n }\n } else if (xmlData[i] === '[') {\n hasBody = true;\n } else {\n exp += xmlData[i];\n }\n }\n if (angleBracketsCount !== 0) {\n throw new Error(`Unclosed DOCTYPE`);\n }\n } else {\n throw new Error(`Invalid Tag instead of DOCTYPE`);\n }\n return { entities, i };\n }\n readEntityExp(xmlData, i) {\n //External entities are not supported\n // \n\n //Parameter entities are not supported\n // \n\n //Internal entities are supported\n // \n\n // Skip leading whitespace after this.options.maxEntitySize) {\n throw new Error(\n `Entity \"${entityName}\" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`\n );\n }\n\n i--;\n return [entityName, entityValue, i];\n }\n\n readNotationExp(xmlData, i) {\n // Skip leading whitespace after \n // \n // \n // \n // \n\n // Skip leading whitespace after {\n while (index < data.length && /\\s/.test(data[index])) {\n index++;\n }\n return index;\n};\n\n\n\nfunction hasSeq(data, seq, i) {\n for (let j = 0; j < seq.length; j++) {\n if (seq[j] !== data[i + j + 1]) return false;\n }\n return true;\n}\n\nfunction validateEntityName(name) {\n if (isName(name))\n return name;\n else\n throw new Error(`Invalid entity name ${name}`);\n}","const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;\nconst numRegex = /^([\\-\\+])?(0*)([0-9]*(\\.[0-9]*)?)$/;\n// const octRegex = /^0x[a-z0-9]+/;\n// const binRegex = /0x[a-z0-9]+/;\n\n\nconst consider = {\n hex: true,\n // oct: false,\n leadingZeros: true,\n decimalPoint: \"\\.\",\n eNotation: true,\n //skipLike: /regex/,\n infinity: \"original\", // \"null\", \"infinity\" (Infinity type), \"string\" (\"Infinity\" (the string literal))\n};\n\nexport default function toNumber(str, options = {}) {\n options = Object.assign({}, consider, options);\n if (!str || typeof str !== \"string\") return str;\n\n let trimmedStr = str.trim();\n\n if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;\n else if (str === \"0\") return 0;\n else if (options.hex && hexRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 16);\n // }else if (options.oct && octRegex.test(str)) {\n // return Number.parseInt(val, 8);\n } else if (!isFinite(trimmedStr)) { //Infinity\n return handleInfinity(str, Number(trimmedStr), options);\n } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation\n return resolveEnotation(str, trimmedStr, options);\n // }else if (options.parseBin && binRegex.test(str)) {\n // return Number.parseInt(val, 2);\n } else {\n //separate negative sign, leading zeros, and rest number\n const match = numRegex.exec(trimmedStr);\n // +00.123 => [ , '+', '00', '.123', ..\n if (match) {\n const sign = match[1] || \"\";\n const leadingZeros = match[2];\n let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros\n const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.\n str[leadingZeros.length + 1] === \".\"\n : str[leadingZeros.length] === \".\";\n\n //trim ending zeros for floating number\n if (!options.leadingZeros //leading zeros are not allowed\n && (leadingZeros.length > 1\n || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {\n // 00, 00.3, +03.24, 03, 03.24\n return str;\n }\n else {//no leading zeros or leading zeros are allowed\n const num = Number(trimmedStr);\n const parsedStr = String(num);\n\n if (num === 0) return num;\n if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation\n if (options.eNotation) return num;\n else return str;\n } else if (trimmedStr.indexOf(\".\") !== -1) { //floating number\n if (parsedStr === \"0\") return num; //0.0\n else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000\n else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;\n else return str;\n }\n\n let n = leadingZeros ? numTrimmedByZeros : trimmedStr;\n if (leadingZeros) {\n // -009 => -9\n return (n === parsedStr) || (sign + n === parsedStr) ? num : str\n } else {\n // +9\n return (n === parsedStr) || (n === sign + parsedStr) ? num : str\n }\n }\n } else { //non-numeric string\n return str;\n }\n }\n}\n\nconst eNotationRegx = /^([-+])?(0*)(\\d*(\\.\\d*)?[eE][-\\+]?\\d+)$/;\nfunction resolveEnotation(str, trimmedStr, options) {\n if (!options.eNotation) return str;\n const notation = trimmedStr.match(eNotationRegx);\n if (notation) {\n let sign = notation[1] || \"\";\n const eChar = notation[3].indexOf(\"e\") === -1 ? \"E\" : \"e\";\n const leadingZeros = notation[2];\n const eAdjacentToLeadingZeros = sign ? // 0E.\n str[leadingZeros.length + 1] === eChar\n : str[leadingZeros.length] === eChar;\n\n if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;\n else if (leadingZeros.length === 1\n && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {\n return Number(trimmedStr);\n } else if (leadingZeros.length > 0) {\n // Has leading zeros — only accept if leadingZeros option allows it\n if (options.leadingZeros && !eAdjacentToLeadingZeros) {\n trimmedStr = (notation[1] || \"\") + notation[3];\n return Number(trimmedStr);\n } else return str;\n } else {\n // No leading zeros — always valid e-notation, parse it\n return Number(trimmedStr);\n }\n } else {\n return str;\n }\n}\n\n/**\n * \n * @param {string} numStr without leading zeros\n * @returns \n */\nfunction trimZeros(numStr) {\n if (numStr && numStr.indexOf(\".\") !== -1) {//float\n numStr = numStr.replace(/0+$/, \"\"); //remove ending zeros\n if (numStr === \".\") numStr = \"0\";\n else if (numStr[0] === \".\") numStr = \"0\" + numStr;\n else if (numStr[numStr.length - 1] === \".\") numStr = numStr.substring(0, numStr.length - 1);\n return numStr;\n }\n return numStr;\n}\n\nfunction parse_int(numStr, base) {\n //polyfill\n if (parseInt) return parseInt(numStr, base);\n else if (Number.parseInt) return Number.parseInt(numStr, base);\n else if (window && window.parseInt) return window.parseInt(numStr, base);\n else throw new Error(\"parseInt, Number.parseInt, window.parseInt are not supported\")\n}\n\n/**\n * Handle infinite values based on user option\n * @param {string} str - original input string\n * @param {number} num - parsed number (Infinity or -Infinity)\n * @param {object} options - user options\n * @returns {string|number|null} based on infinity option\n */\nfunction handleInfinity(str, num, options) {\n const isPositive = num === Infinity;\n\n switch (options.infinity.toLowerCase()) {\n case \"null\":\n return null;\n case \"infinity\":\n return num; // Return Infinity or -Infinity\n case \"string\":\n return isPositive ? \"Infinity\" : \"-Infinity\";\n case \"original\":\n default:\n return str; // Return original string like \"1e1000\"\n }\n}","/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions\n * \n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n * \n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n * \n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Default path separator (default: '.')\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag: string, values: object, position: number, counter: number }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n }\n\n /**\n * Push a new tag onto the path\n * @param {string} tagName - Name of the tag\n * @param {Object} attrValues - Attribute key-value pairs for current node (optional)\n * @param {string} namespace - Namespace for the tag (optional)\n */\n push(tagName, attrValues = null, namespace = null) {\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n const prev = this.path[this.path.length - 1];\n prev.values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n // Store namespace if provided\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n // Store values only for current node\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) {\n return undefined;\n }\n\n const node = this.path.pop();\n\n // Clean up sibling tracking for levels deeper than current\n // After pop, path.length is the new depth\n // We need to clean up siblingStacks[path.length + 1] and beyond\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values\n * Useful when attributes are parsed after push\n * @param {Object} attrValues - Attribute values\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value\n * @param {string} attrName - Attribute name\n * @returns {*} Attribute value or undefined\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n const current = this.path[this.path.length - 1];\n return current.values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute\n * @param {string} attrName - Attribute name\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent)\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name)\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition for backward compatibility)\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string\n * @param {string} separator - Optional separator (uses default if not provided)\n * @param {boolean} includeNamespace - Whether to include namespace in output (default: true)\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n return this.path.map(n => {\n if (includeNamespace && n.namespace) {\n return `${n.namespace}:${n.tag}`;\n }\n return n.tag;\n }).join(sep);\n }\n\n /**\n * Get path as array of tag names\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty\n */\n reset() {\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression\n * @param {Expression} expression - The expression to match against\n * @returns {boolean} True if current path matches the expression\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n // Handle deep wildcard patterns\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n // Simple path matching (no deep wildcards)\n return this._matchSimple(segments);\n }\n\n /**\n * Match simple path (no deep wildcards)\n * @private\n */\n _matchSimple(segments) {\n // Path must be same length as segments\n if (this.path.length !== segments.length) {\n return false;\n }\n\n // Match each segment bottom-to-top\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n const node = this.path[i];\n const isCurrentNode = (i === this.path.length - 1);\n\n if (!this._matchSegment(segment, node, isCurrentNode)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match path with deep wildcards\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1; // Start from current node (bottom)\n let segIdx = segments.length - 1; // Start from last segment\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n // \"..\" matches zero or more levels\n segIdx--;\n\n if (segIdx < 0) {\n // Pattern ends with \"..\", always matches\n return true;\n }\n\n // Find where next segment matches in the path\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n const isCurrentNode = (i === this.path.length - 1);\n if (this._matchSegment(nextSeg, this.path[i], isCurrentNode)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n // Regular segment\n const isCurrentNode = (pathIdx === this.path.length - 1);\n if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n // All segments must be consumed\n return segIdx < 0;\n }\n\n /**\n * Match a single segment against a node\n * @private\n * @param {Object} segment - Segment from Expression\n * @param {Object} node - Node from path\n * @param {boolean} isCurrentNode - Whether this is the current (last) node\n * @returns {boolean}\n */\n _matchSegment(segment, node, isCurrentNode) {\n // Match tag name (* is wildcard)\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n // Match namespace if specified in segment\n if (segment.namespace !== undefined) {\n // Segment has namespace - node must match it\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n // If segment has no namespace, it matches nodes with or without namespace\n\n // Match attribute name (check if node has this attribute)\n // Can only check for current node since ancestors don't have values\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n // Can't check attributes for ancestor nodes (values not stored)\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n // Match attribute value (only possible for current node)\n if (segment.attrValue !== undefined) {\n const actualValue = node.values[segment.attrName];\n // Both should be strings\n if (String(actualValue) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n // Match position (only for current node)\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n // Can't check position for ancestor nodes\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth') {\n if (counter !== segment.positionValue) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Create a snapshot of current state\n * @returns {Object} State snapshot\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot\n * @param {Object} snapshot - State snapshot\n */\n restore(snapshot) {\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n}","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","'use strict';\n///@ts-check\n\nimport { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';\nimport xmlNode from './xmlNode.js';\nimport DocTypeReader from './DocTypeReader.js';\nimport toNumber from \"strnum\";\nimport getIgnoreAttributesFn from \"../ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\n\n// const regx =\n// '<((!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\\\/)(NAME)\\\\s*>))([^<]*)'\n// .replace(/NAME/g, util.nameRegexp);\n\n//const tagsRegx = new RegExp(\"<(\\\\/?[\\\\w:\\\\-\\._]+)([^>]*)>(\\\\s*\"+cdataRegx+\")*([^<]+)?\",\"g\");\n//const tagsRegx = new RegExp(\"<(\\\\/?)((\\\\w*:)?([\\\\w:\\\\-\\._]+))([^>]*)>([^<]*)(\"+cdataRegx+\"([^<]*))*([^<]+)?\",\"g\");\n\n// Helper functions for attribute and namespace handling\n\n/**\n * Extract raw attributes (without prefix) from prefixed attribute map\n * @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap\n * @param {object} options - Parser options containing attributeNamePrefix\n * @returns {object} Raw attributes for matcher\n */\nfunction extractRawAttributes(prefixedAttrs, options) {\n if (!prefixedAttrs) return {};\n\n // Handle attributesGroupName option\n const attrs = options.attributesGroupName\n ? prefixedAttrs[options.attributesGroupName]\n : prefixedAttrs;\n\n if (!attrs) return {};\n\n const rawAttrs = {};\n for (const key in attrs) {\n // Remove the attribute prefix to get raw name\n if (key.startsWith(options.attributeNamePrefix)) {\n const rawName = key.substring(options.attributeNamePrefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * Extract namespace from raw tag name\n * @param {string} rawTagName - Tag name possibly with namespace (e.g., \"soap:Envelope\")\n * @returns {string|undefined} Namespace or undefined\n */\nfunction extractNamespace(rawTagName) {\n if (!rawTagName || typeof rawTagName !== 'string') return undefined;\n\n const colonIndex = rawTagName.indexOf(':');\n if (colonIndex !== -1 && colonIndex > 0) {\n const ns = rawTagName.substring(0, colonIndex);\n // Don't treat xmlns as a namespace\n if (ns !== 'xmlns') {\n return ns;\n }\n }\n return undefined;\n}\n\nexport default class OrderedObjParser {\n constructor(options) {\n this.options = options;\n this.currentNode = null;\n this.tagsNodeStack = [];\n this.docTypeEntities = {};\n this.lastEntities = {\n \"apos\": { regex: /&(apos|#39|#x27);/g, val: \"'\" },\n \"gt\": { regex: /&(gt|#62|#x3E);/g, val: \">\" },\n \"lt\": { regex: /&(lt|#60|#x3C);/g, val: \"<\" },\n \"quot\": { regex: /&(quot|#34|#x22);/g, val: \"\\\"\" },\n };\n this.ampEntity = { regex: /&(amp|#38|#x26);/g, val: \"&\" };\n this.htmlEntities = {\n \"space\": { regex: /&(nbsp|#160);/g, val: \" \" },\n // \"lt\" : { regex: /&(lt|#60);/g, val: \"<\" },\n // \"gt\" : { regex: /&(gt|#62);/g, val: \">\" },\n // \"amp\" : { regex: /&(amp|#38);/g, val: \"&\" },\n // \"quot\" : { regex: /&(quot|#34);/g, val: \"\\\"\" },\n // \"apos\" : { regex: /&(apos|#39);/g, val: \"'\" },\n \"cent\": { regex: /&(cent|#162);/g, val: \"¢\" },\n \"pound\": { regex: /&(pound|#163);/g, val: \"£\" },\n \"yen\": { regex: /&(yen|#165);/g, val: \"¥\" },\n \"euro\": { regex: /&(euro|#8364);/g, val: \"€\" },\n \"copyright\": { regex: /&(copy|#169);/g, val: \"©\" },\n \"reg\": { regex: /&(reg|#174);/g, val: \"®\" },\n \"inr\": { regex: /&(inr|#8377);/g, val: \"₹\" },\n \"num_dec\": { regex: /&#([0-9]{1,7});/g, val: (_, str) => fromCodePoint(str, 10, \"&#\") },\n \"num_hex\": { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (_, str) => fromCodePoint(str, 16, \"&#x\") },\n };\n this.addExternalEntities = addExternalEntities;\n this.parseXml = parseXml;\n this.parseTextData = parseTextData;\n this.resolveNameSpace = resolveNameSpace;\n this.buildAttributesMap = buildAttributesMap;\n this.isItStopNode = isItStopNode;\n this.replaceEntitiesValue = replaceEntitiesValue;\n this.readStopNodeData = readStopNodeData;\n this.saveTextToParentTag = saveTextToParentTag;\n this.addChild = addChild;\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n\n // Initialize path matcher for path-expression-matcher\n this.matcher = new Matcher();\n\n // Flag to track if current node is a stop node (optimization)\n this.isCurrentNodeStopNode = false;\n\n // Pre-compile stopNodes expressions\n if (this.options.stopNodes && this.options.stopNodes.length > 0) {\n this.stopNodeExpressions = [];\n for (let i = 0; i < this.options.stopNodes.length; i++) {\n const stopNodeExp = this.options.stopNodes[i];\n if (typeof stopNodeExp === 'string') {\n // Convert string to Expression object\n this.stopNodeExpressions.push(new Expression(stopNodeExp));\n } else if (stopNodeExp instanceof Expression) {\n // Already an Expression object\n this.stopNodeExpressions.push(stopNodeExp);\n }\n }\n }\n }\n\n}\n\nfunction addExternalEntities(externalEntities) {\n const entKeys = Object.keys(externalEntities);\n for (let i = 0; i < entKeys.length; i++) {\n const ent = entKeys[i];\n const escaped = ent.replace(/[.\\-+*:]/g, '\\\\.');\n this.lastEntities[ent] = {\n regex: new RegExp(\"&\" + escaped + \";\", \"g\"),\n val: externalEntities[ent]\n }\n }\n}\n\n/**\n * @param {string} val\n * @param {string} tagName\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n * @param {boolean} dontTrim\n * @param {boolean} hasAttributes\n * @param {boolean} isLeafNode\n * @param {boolean} escapeEntities\n */\nfunction parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {\n if (val !== undefined) {\n if (this.options.trimValues && !dontTrim) {\n val = val.trim();\n }\n if (val.length > 0) {\n if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const newval = this.options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);\n if (newval === null || newval === undefined) {\n //don't parse\n return val;\n } else if (typeof newval !== typeof val || newval !== val) {\n //overwrite\n return newval;\n } else if (this.options.trimValues) {\n return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);\n } else {\n const trimmedVal = val.trim();\n if (trimmedVal === val) {\n return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions);\n } else {\n return val;\n }\n }\n }\n }\n}\n\nfunction resolveNameSpace(tagname) {\n if (this.options.removeNSPrefix) {\n const tags = tagname.split(':');\n const prefix = tagname.charAt(0) === '/' ? '/' : '';\n if (tags[0] === 'xmlns') {\n return '';\n }\n if (tags.length === 2) {\n tagname = prefix + tags[1];\n }\n }\n return tagname;\n}\n\n//TODO: change regex to capture NS\n//const attrsRegx = new RegExp(\"([\\\\w\\\\-\\\\.\\\\:]+)\\\\s*=\\\\s*(['\\\"])((.|\\n)*?)\\\\2\",\"gm\");\nconst attrsRegx = new RegExp('([^\\\\s=]+)\\\\s*(=\\\\s*([\\'\"])([\\\\s\\\\S]*?)\\\\3)?', 'gm');\n\nfunction buildAttributesMap(attrStr, jPath, tagName) {\n if (this.options.ignoreAttributes !== true && typeof attrStr === 'string') {\n // attrStr = attrStr.replace(/\\r?\\n/g, ' ');\n //attrStr = attrStr || attrStr.trim();\n\n const matches = getAllMatches(attrStr, attrsRegx);\n const len = matches.length; //don't make it inline\n const attrs = {};\n\n // First pass: parse all attributes and update matcher with raw values\n // This ensures the matcher has all attribute values when processors run\n const rawAttrsForMatcher = {};\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n const oldVal = matches[i][4];\n\n if (attrName.length && oldVal !== undefined) {\n let parsedVal = oldVal;\n if (this.options.trimValues) {\n parsedVal = parsedVal.trim();\n }\n parsedVal = this.replaceEntitiesValue(parsedVal, tagName, jPath);\n rawAttrsForMatcher[attrName] = parsedVal;\n }\n }\n\n // Update matcher with raw attribute values BEFORE running processors\n if (Object.keys(rawAttrsForMatcher).length > 0 && typeof jPath === 'object' && jPath.updateCurrent) {\n jPath.updateCurrent(rawAttrsForMatcher);\n }\n\n // Second pass: now process attributes with matcher having full attribute context\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n\n // Convert jPath to string if needed for ignoreAttributesFn\n const jPathStr = this.options.jPath ? jPath.toString() : jPath;\n if (this.ignoreAttributesFn(attrName, jPathStr)) {\n continue\n }\n\n let oldVal = matches[i][4];\n let aName = this.options.attributeNamePrefix + attrName;\n\n if (attrName.length) {\n if (this.options.transformAttributeName) {\n aName = this.options.transformAttributeName(aName);\n }\n //if (aName === \"__proto__\") aName = \"#__proto__\";\n aName = sanitizeName(aName, this.options);\n\n if (oldVal !== undefined) {\n if (this.options.trimValues) {\n oldVal = oldVal.trim();\n }\n oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPathOrMatcher);\n if (newVal === null || newVal === undefined) {\n //don't parse\n attrs[aName] = oldVal;\n } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {\n //overwrite\n attrs[aName] = newVal;\n } else {\n //parse\n attrs[aName] = parseValue(\n oldVal,\n this.options.parseAttributeValue,\n this.options.numberParseOptions\n );\n }\n } else if (this.options.allowBooleanAttributes) {\n attrs[aName] = true;\n }\n }\n }\n\n if (!Object.keys(attrs).length) {\n return;\n }\n if (this.options.attributesGroupName) {\n const attrCollection = {};\n attrCollection[this.options.attributesGroupName] = attrs;\n return attrCollection;\n }\n return attrs\n }\n}\n\nconst parseXml = function (xmlData) {\n xmlData = xmlData.replace(/\\r\\n?/g, \"\\n\"); //TODO: remove this line\n const xmlObj = new xmlNode('!xml');\n let currentNode = xmlObj;\n let textData = \"\";\n\n // Reset matcher for new document\n this.matcher.reset();\n\n // Reset entity expansion counters for this document\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n\n const docTypeReader = new DocTypeReader(this.options.processEntities);\n for (let i = 0; i < xmlData.length; i++) {//for each char in XML data\n const ch = xmlData[i];\n if (ch === '<') {\n // const nextIndex = i+1;\n // const _2ndChar = xmlData[nextIndex];\n if (xmlData[i + 1] === '/') {//Closing Tag\n const closeIndex = findClosingIndex(xmlData, \">\", i, \"Closing Tag is not closed.\")\n let tagName = xmlData.substring(i + 2, closeIndex).trim();\n\n if (this.options.removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n }\n }\n\n tagName = transformTagName(this.options.transformTagName, tagName, \"\", this.options).tagName;\n\n if (currentNode) {\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n }\n\n //check if last tag of nested tag was unpaired tag\n const lastTagName = this.matcher.getCurrentTag();\n if (tagName && this.options.unpairedTags.indexOf(tagName) !== -1) {\n throw new Error(`Unpaired tag can not be used as closing tag: `);\n }\n if (lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1) {\n // Pop the unpaired tag\n this.matcher.pop();\n this.tagsNodeStack.pop();\n }\n // Pop the closing tag\n this.matcher.pop();\n this.isCurrentNodeStopNode = false; // Reset flag when closing tag\n\n currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope\n textData = \"\";\n i = closeIndex;\n } else if (xmlData[i + 1] === '?') {\n\n let tagData = readTagExp(xmlData, i, false, \"?>\");\n if (!tagData) throw new Error(\"Pi Tag is not closed.\");\n\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n if ((this.options.ignoreDeclaration && tagData.tagName === \"?xml\") || this.options.ignorePiTags) {\n //do nothing\n } else {\n\n const childNode = new xmlNode(tagData.tagName);\n childNode.add(this.options.textNodeName, \"\");\n\n if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) {\n childNode[\":@\"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName);\n }\n this.addChild(currentNode, childNode, this.matcher, i);\n }\n\n\n i = tagData.closeIndex + 1;\n } else if (xmlData.substr(i + 1, 3) === '!--') {\n const endIndex = findClosingIndex(xmlData, \"-->\", i + 4, \"Comment is not closed.\")\n if (this.options.commentPropName) {\n const comment = xmlData.substring(i + 4, endIndex - 2);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n\n currentNode.add(this.options.commentPropName, [{ [this.options.textNodeName]: comment }]);\n }\n i = endIndex;\n } else if (xmlData.substr(i + 1, 2) === '!D') {\n const result = docTypeReader.readDocType(xmlData, i);\n this.docTypeEntities = result.entities;\n i = result.i;\n } else if (xmlData.substr(i + 1, 2) === '![') {\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"CDATA is not closed.\") - 2;\n const tagExp = xmlData.substring(i + 9, closeIndex);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher);\n\n let val = this.parseTextData(tagExp, currentNode.tagname, this.matcher, true, false, true, true);\n if (val == undefined) val = \"\";\n\n //cdata should be set even if it is 0 length string\n if (this.options.cdataPropName) {\n currentNode.add(this.options.cdataPropName, [{ [this.options.textNodeName]: tagExp }]);\n } else {\n currentNode.add(this.options.textNodeName, val);\n }\n\n i = closeIndex + 2;\n } else {//Opening tag\n let result = readTagExp(xmlData, i, this.options.removeNSPrefix);\n\n // Safety check: readTagExp can return undefined\n if (!result) {\n // Log context for debugging\n const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlData.length, i + 50));\n throw new Error(`readTagExp returned undefined at position ${i}. Context: \"${context}\"`);\n }\n\n let tagName = result.tagName;\n const rawTagName = result.rawTagName;\n let tagExp = result.tagExp;\n let attrExpPresent = result.attrExpPresent;\n let closeIndex = result.closeIndex;\n\n ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));\n\n if (this.options.strictReservedNames &&\n (tagName === this.options.commentPropName\n || tagName === this.options.cdataPropName\n || tagName === this.options.textNodeName\n || tagName === this.options.attributesGroupName\n )) {\n throw new Error(`Invalid tag name: ${tagName}`);\n }\n\n //save text as child node\n if (currentNode && textData) {\n if (currentNode.tagname !== '!xml') {\n //when nested tag is found\n textData = this.saveTextToParentTag(textData, currentNode, this.matcher, false);\n }\n }\n\n //check if last tag was unpaired tag\n const lastTag = currentNode;\n if (lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1) {\n currentNode = this.tagsNodeStack.pop();\n this.matcher.pop();\n }\n\n // Clean up self-closing syntax BEFORE processing attributes\n // This is where tagExp gets the trailing / removed\n let isSelfClosing = false;\n if (tagExp.length > 0 && tagExp.lastIndexOf(\"/\") === tagExp.length - 1) {\n isSelfClosing = true;\n if (tagName[tagName.length - 1] === \"/\") {\n tagName = tagName.substr(0, tagName.length - 1);\n tagExp = tagName;\n } else {\n tagExp = tagExp.substr(0, tagExp.length - 1);\n }\n\n // Re-check attrExpPresent after cleaning\n attrExpPresent = (tagName !== tagExp);\n }\n\n // Now process attributes with CLEAN tagExp (no trailing /)\n let prefixedAttrs = null;\n let rawAttrs = {};\n let namespace = undefined;\n\n // Extract namespace from rawTagName\n namespace = extractNamespace(rawTagName);\n\n // Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path\n if (tagName !== xmlObj.tagname) {\n this.matcher.push(tagName, {}, namespace);\n }\n\n // Now build attributes - callbacks will see correct matcher state\n if (tagName !== tagExp && attrExpPresent) {\n // Build attributes (returns prefixed attributes for the tree)\n // Note: buildAttributesMap now internally updates the matcher with raw attributes\n prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);\n\n if (prefixedAttrs) {\n // Extract raw attributes (without prefix) for our use\n rawAttrs = extractRawAttributes(prefixedAttrs, this.options);\n }\n }\n\n // Now check if this is a stop node (after attributes are set)\n if (tagName !== xmlObj.tagname) {\n this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher);\n }\n\n const startIndex = i;\n if (this.isCurrentNodeStopNode) {\n let tagContent = \"\";\n\n // For self-closing tags, content is empty\n if (isSelfClosing) {\n i = result.closeIndex;\n }\n //unpaired tag\n else if (this.options.unpairedTags.indexOf(tagName) !== -1) {\n i = result.closeIndex;\n }\n //normal tag\n else {\n //read until closing tag is found\n const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);\n if (!result) throw new Error(`Unexpected end of ${rawTagName}`);\n i = result.i;\n tagContent = result.tagContent;\n }\n\n const childNode = new xmlNode(tagName);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n\n // For stop nodes, store raw content as-is without any processing\n childNode.add(this.options.textNodeName, tagContent);\n\n this.matcher.pop(); // Pop the stop node tag\n this.isCurrentNodeStopNode = false; // Reset flag\n\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n } else {\n //selfClosing tag\n if (isSelfClosing) {\n ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options));\n\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n this.matcher.pop(); // Pop self-closing tag\n this.isCurrentNodeStopNode = false; // Reset flag\n }\n else if (this.options.unpairedTags.indexOf(tagName) !== -1) {//unpaired tag\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n this.matcher.pop(); // Pop unpaired tag\n this.isCurrentNodeStopNode = false; // Reset flag\n i = result.closeIndex;\n // Continue to next iteration without changing currentNode\n continue;\n }\n //opening tag\n else {\n const childNode = new xmlNode(tagName);\n if (this.tagsNodeStack.length > this.options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n this.tagsNodeStack.push(currentNode);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.matcher, startIndex);\n currentNode = childNode;\n }\n textData = \"\";\n i = closeIndex;\n }\n }\n } else {\n textData += xmlData[i];\n }\n }\n return xmlObj.child;\n}\n\nfunction addChild(currentNode, childNode, matcher, startIndex) {\n // unset startIndex if not requested\n if (!this.options.captureMetaData) startIndex = undefined;\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;\n const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[\":@\"])\n if (result === false) {\n //do nothing\n } else if (typeof result === \"string\") {\n childNode.tagname = result\n currentNode.addChild(childNode, startIndex);\n } else {\n currentNode.addChild(childNode, startIndex);\n }\n}\n\n/**\n * @param {object} val - Entity object with regex and val properties\n * @param {string} tagName - Tag name\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n */\nfunction replaceEntitiesValue(val, tagName, jPath) {\n const entityConfig = this.options.processEntities;\n\n if (!entityConfig || !entityConfig.enabled) {\n return val;\n }\n\n // Check if tag is allowed to contain entities\n if (entityConfig.allowedTags) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const allowed = Array.isArray(entityConfig.allowedTags)\n ? entityConfig.allowedTags.includes(tagName)\n : entityConfig.allowedTags(tagName, jPathOrMatcher);\n\n if (!allowed) {\n return val;\n }\n }\n\n // Apply custom tag filter if provided\n if (entityConfig.tagFilter) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {\n return val; // Skip based on custom filter\n }\n }\n\n // Replace DOCTYPE entities\n for (const entityName of Object.keys(this.docTypeEntities)) {\n const entity = this.docTypeEntities[entityName];\n const matches = val.match(entity.regx);\n\n if (matches) {\n // Track expansions\n this.entityExpansionCount += matches.length;\n\n // Check expansion limit\n if (entityConfig.maxTotalExpansions &&\n this.entityExpansionCount > entityConfig.maxTotalExpansions) {\n throw new Error(\n `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`\n );\n }\n\n // Store length before replacement\n const lengthBefore = val.length;\n val = val.replace(entity.regx, entity.val);\n\n // Check expanded length immediately after replacement\n if (entityConfig.maxExpandedLength) {\n this.currentExpandedLength += (val.length - lengthBefore);\n\n if (this.currentExpandedLength > entityConfig.maxExpandedLength) {\n throw new Error(\n `Total expanded content size exceeded: ${this.currentExpandedLength} > ${entityConfig.maxExpandedLength}`\n );\n }\n }\n }\n }\n // Replace standard entities\n for (const entityName of Object.keys(this.lastEntities)) {\n const entity = this.lastEntities[entityName];\n const matches = val.match(entity.regex);\n if (matches) {\n this.entityExpansionCount += matches.length;\n if (entityConfig.maxTotalExpansions &&\n this.entityExpansionCount > entityConfig.maxTotalExpansions) {\n throw new Error(\n `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`\n );\n }\n }\n val = val.replace(entity.regex, entity.val);\n }\n if (val.indexOf('&') === -1) return val;\n\n // Replace HTML entities if enabled\n if (this.options.htmlEntities) {\n for (const entityName of Object.keys(this.htmlEntities)) {\n const entity = this.htmlEntities[entityName];\n const matches = val.match(entity.regex);\n if (matches) {\n //console.log(matches);\n this.entityExpansionCount += matches.length;\n if (entityConfig.maxTotalExpansions &&\n this.entityExpansionCount > entityConfig.maxTotalExpansions) {\n throw new Error(\n `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}`\n );\n }\n }\n val = val.replace(entity.regex, entity.val);\n }\n }\n\n // Replace ampersand entity last\n val = val.replace(this.ampEntity.regex, this.ampEntity.val);\n\n return val;\n}\n\n\nfunction saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {\n if (textData) { //store previously collected data as textNode\n if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0\n\n textData = this.parseTextData(textData,\n parentNode.tagname,\n matcher,\n false,\n parentNode[\":@\"] ? Object.keys(parentNode[\":@\"]).length !== 0 : false,\n isLeafNode);\n\n if (textData !== undefined && textData !== \"\")\n parentNode.add(this.options.textNodeName, textData);\n textData = \"\";\n }\n return textData;\n}\n\n//TODO: use jPath to simplify the logic\n/**\n * @param {Array} stopNodeExpressions - Array of compiled Expression objects\n * @param {Matcher} matcher - Current path matcher\n */\nfunction isItStopNode(stopNodeExpressions, matcher) {\n if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;\n\n for (let i = 0; i < stopNodeExpressions.length; i++) {\n if (matcher.matches(stopNodeExpressions[i])) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Returns the tag Expression and where it is ending handling single-double quotes situation\n * @param {string} xmlData \n * @param {number} i starting index\n * @returns \n */\nfunction tagExpWithClosingIndex(xmlData, i, closingChar = \">\") {\n let attrBoundary;\n let tagExp = \"\";\n for (let index = i; index < xmlData.length; index++) {\n let ch = xmlData[index];\n if (attrBoundary) {\n if (ch === attrBoundary) attrBoundary = \"\";//reset\n } else if (ch === '\"' || ch === \"'\") {\n attrBoundary = ch;\n } else if (ch === closingChar[0]) {\n if (closingChar[1]) {\n if (xmlData[index + 1] === closingChar[1]) {\n return {\n data: tagExp,\n index: index\n }\n }\n } else {\n return {\n data: tagExp,\n index: index\n }\n }\n } else if (ch === '\\t') {\n ch = \" \"\n }\n tagExp += ch;\n }\n}\n\nfunction findClosingIndex(xmlData, str, i, errMsg) {\n const closingIndex = xmlData.indexOf(str, i);\n if (closingIndex === -1) {\n throw new Error(errMsg)\n } else {\n return closingIndex + str.length - 1;\n }\n}\n\nfunction readTagExp(xmlData, i, removeNSPrefix, closingChar = \">\") {\n const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);\n if (!result) return;\n let tagExp = result.data;\n const closeIndex = result.index;\n const separatorIndex = tagExp.search(/\\s/);\n let tagName = tagExp;\n let attrExpPresent = true;\n if (separatorIndex !== -1) {//separate tag name and attributes expression\n tagName = tagExp.substring(0, separatorIndex);\n tagExp = tagExp.substring(separatorIndex + 1).trimStart();\n }\n\n const rawTagName = tagName;\n if (removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n attrExpPresent = tagName !== result.data.substr(colonIndex + 1);\n }\n }\n\n return {\n tagName: tagName,\n tagExp: tagExp,\n closeIndex: closeIndex,\n attrExpPresent: attrExpPresent,\n rawTagName: rawTagName,\n }\n}\n/**\n * find paired tag for a stop node\n * @param {string} xmlData \n * @param {string} tagName \n * @param {number} i \n */\nfunction readStopNodeData(xmlData, tagName, i) {\n const startIndex = i;\n // Starting at 1 since we already have an open tag\n let openTagCount = 1;\n\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === \"<\") {\n if (xmlData[i + 1] === \"/\") {//close tag\n const closeIndex = findClosingIndex(xmlData, \">\", i, `${tagName} is not closed`);\n let closeTagName = xmlData.substring(i + 2, closeIndex).trim();\n if (closeTagName === tagName) {\n openTagCount--;\n if (openTagCount === 0) {\n return {\n tagContent: xmlData.substring(startIndex, i),\n i: closeIndex\n }\n }\n }\n i = closeIndex;\n } else if (xmlData[i + 1] === '?') {\n const closeIndex = findClosingIndex(xmlData, \"?>\", i + 1, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (xmlData.substr(i + 1, 3) === '!--') {\n const closeIndex = findClosingIndex(xmlData, \"-->\", i + 3, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (xmlData.substr(i + 1, 2) === '![') {\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"StopNode is not closed.\") - 2;\n i = closeIndex;\n } else {\n const tagData = readTagExp(xmlData, i, '>')\n\n if (tagData) {\n const openTagName = tagData && tagData.tagName;\n if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== \"/\") {\n openTagCount++;\n }\n i = tagData.closeIndex;\n }\n }\n }\n }//end for loop\n}\n\nfunction parseValue(val, shouldParse, options) {\n if (shouldParse && typeof val === 'string') {\n //console.log(options)\n const newval = val.trim();\n if (newval === 'true') return true;\n else if (newval === 'false') return false;\n else return toNumber(val, options);\n } else {\n if (isExist(val)) {\n return val;\n } else {\n return '';\n }\n }\n}\n\nfunction fromCodePoint(str, base, prefix) {\n const codePoint = Number.parseInt(str, base);\n\n if (codePoint >= 0 && codePoint <= 0x10FFFF) {\n return String.fromCodePoint(codePoint);\n } else {\n return prefix + str + \";\";\n }\n}\n\nfunction transformTagName(fn, tagName, tagExp, options) {\n if (fn) {\n const newTagName = fn(tagName);\n if (tagExp === tagName) {\n tagExp = newTagName\n }\n tagName = newTagName;\n }\n tagName = sanitizeName(tagName, options);\n return { tagName, tagExp };\n}\n\n\n\nfunction sanitizeName(name, options) {\n if (criticalProperties.includes(name)) {\n throw new Error(`[SECURITY] Invalid name: \"${name}\" is a reserved JavaScript keyword that could cause prototype pollution`);\n } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return options.onDangerousProperty(name);\n }\n return name;\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","'use strict';\n\nimport XmlNode from './xmlNode.js';\nimport { Matcher } from 'path-expression-matcher';\n\nconst METADATA_SYMBOL = XmlNode.getMetaDataSymbol();\n\n/**\n * Helper function to strip attribute prefix from attribute map\n * @param {object} attrs - Attributes with prefix (e.g., {\"@_class\": \"code\"})\n * @param {string} prefix - Attribute prefix to remove (e.g., \"@_\")\n * @returns {object} Attributes without prefix (e.g., {\"class\": \"code\"})\n */\nfunction stripAttributePrefix(attrs, prefix) {\n if (!attrs || typeof attrs !== 'object') return {};\n if (!prefix) return attrs;\n\n const rawAttrs = {};\n for (const key in attrs) {\n if (key.startsWith(prefix)) {\n const rawName = key.substring(prefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * \n * @param {array} node \n * @param {any} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns \n */\nexport default function prettify(node, options, matcher) {\n return compress(node, options, matcher);\n}\n\n/**\n * \n * @param {array} arr \n * @param {object} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns object\n */\nfunction compress(arr, options, matcher) {\n let text;\n const compressedObj = {}; //This is intended to be a plain object\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const property = propName(tagObj);\n\n // Push current property to matcher WITH RAW ATTRIBUTES (no prefix)\n if (property !== undefined && property !== options.textNodeName) {\n const rawAttrs = stripAttributePrefix(\n tagObj[\":@\"] || {},\n options.attributeNamePrefix\n );\n matcher.push(property, rawAttrs);\n }\n\n if (property === options.textNodeName) {\n if (text === undefined) text = tagObj[property];\n else text += \"\" + tagObj[property];\n } else if (property === undefined) {\n continue;\n } else if (tagObj[property]) {\n\n let val = compress(tagObj[property], options, matcher);\n const isLeaf = isLeafTag(val, options);\n\n if (tagObj[\":@\"]) {\n assignAttributes(val, tagObj[\":@\"], matcher, options);\n } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {\n val = val[options.textNodeName];\n } else if (Object.keys(val).length === 0) {\n if (options.alwaysCreateTextNode) val[options.textNodeName] = \"\";\n else val = \"\";\n }\n\n if (tagObj[METADATA_SYMBOL] !== undefined && typeof val === \"object\" && val !== null) {\n val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata\n }\n\n\n if (compressedObj[property] !== undefined && Object.prototype.hasOwnProperty.call(compressedObj, property)) {\n if (!Array.isArray(compressedObj[property])) {\n compressedObj[property] = [compressedObj[property]];\n }\n compressedObj[property].push(val);\n } else {\n //TODO: if a node is not an array, then check if it should be an array\n //also determine if it is a leaf node\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? matcher.toString() : matcher;\n if (options.isArray(property, jPathOrMatcher, isLeaf)) {\n compressedObj[property] = [val];\n } else {\n compressedObj[property] = val;\n }\n }\n\n // Pop property from matcher after processing\n if (property !== undefined && property !== options.textNodeName) {\n matcher.pop();\n }\n }\n\n }\n // if(text && text.length > 0) compressedObj[options.textNodeName] = text;\n if (typeof text === \"string\") {\n if (text.length > 0) compressedObj[options.textNodeName] = text;\n } else if (text !== undefined) compressedObj[options.textNodeName] = text;\n\n\n return compressedObj;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== \":@\") return key;\n }\n}\n\nfunction assignAttributes(obj, attrMap, matcher, options) {\n if (attrMap) {\n const keys = Object.keys(attrMap);\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n const atrrName = keys[i]; // This is the PREFIXED name (e.g., \"@_class\")\n\n // Strip prefix for matcher path (for isArray callback)\n const rawAttrName = atrrName.startsWith(options.attributeNamePrefix)\n ? atrrName.substring(options.attributeNamePrefix.length)\n : atrrName;\n\n // For attributes, we need to create a temporary path\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath\n ? matcher.toString() + \".\" + rawAttrName\n : matcher;\n\n if (options.isArray(atrrName, jPathOrMatcher, true, true)) {\n obj[atrrName] = [attrMap[atrrName]];\n } else {\n obj[atrrName] = attrMap[atrrName];\n }\n }\n }\n}\n\nfunction isLeafTag(obj, options) {\n const { textNodeName } = options;\n const propCount = Object.keys(obj).length;\n\n if (propCount === 0) {\n return true;\n }\n\n if (\n propCount === 1 &&\n (obj[textNodeName] || typeof obj[textNodeName] === \"boolean\" || obj[textNodeName] === 0)\n ) {\n return true;\n }\n\n return false;\n}","'use strict';\n\nimport { getAllMatches, isName } from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/()/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n\n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i + 1] === '?') {\n i += 2;\n i = readPI(xmlData, i);\n if (i.err) return i;\n } else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n\n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\" + tagName + \"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\" + tagName + \"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\" + otg.tagName + \"' (opened in line \" + openPos.line + \", col \" + openPos.col + \") instead of closing tag '\" + tagName + \"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if (options.unpairedTags.indexOf(tagName) !== -1) {\n //don't push into stack\n } else {\n tags.push({ tagName, tagStartPos });\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i + 1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else {\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n } else {\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if (isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\" + xmlData[i] + \"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n } else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\" + tags[0].tagName + \"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n } else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\" +\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '') +\n \"' found.\", { line: 1, col: 1 });\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char) {\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Select all the attributes whether valid or invalid.\n */\nconst validAttrStrRegxp = new RegExp('(\\\\s*)([^\\\\s=]+)(\\\\s*=)?(\\\\s*([\\'\"])(([\\\\s\\\\S])*?)\\\\5)?', 'g');\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = getAllMatches(attrStr, validAttrStrRegxp);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\" + matches[i][2] + \"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}\n","import { buildOptions } from './OptionsBuilder.js';\nimport OrderedObjParser from './OrderedObjParser.js';\nimport prettify from './node2json.js';\nimport { validate } from \"../validator.js\";\nimport XmlNode from './xmlNode.js';\n\nexport default class XMLParser {\n\n constructor(options) {\n this.externalEntities = {};\n this.options = buildOptions(options);\n\n }\n /**\n * Parse XML dats to JS object \n * @param {string|Uint8Array} xmlData \n * @param {boolean|Object} validationOption \n */\n parse(xmlData, validationOption) {\n if (typeof xmlData !== \"string\" && xmlData.toString) {\n xmlData = xmlData.toString();\n } else if (typeof xmlData !== \"string\") {\n throw new Error(\"XML data is accepted in String or Bytes[] form.\")\n }\n\n if (validationOption) {\n if (validationOption === true) validationOption = {}; //validate with default options\n\n const result = validate(xmlData, validationOption);\n if (result !== true) {\n throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)\n }\n }\n const orderedObjParser = new OrderedObjParser(this.options);\n orderedObjParser.addExternalEntities(this.externalEntities);\n const orderedResult = orderedObjParser.parseXml(xmlData);\n if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;\n else return prettify(orderedResult, this.options, orderedObjParser.matcher);\n }\n\n /**\n * Add Entity which is not by default supported by this library\n * @param {string} key \n * @param {string} value \n */\n addEntity(key, value) {\n if (value.indexOf(\"&\") !== -1) {\n throw new Error(\"Entity value can't have '&'\")\n } else if (key.indexOf(\"&\") !== -1 || key.indexOf(\";\") !== -1) {\n throw new Error(\"An entity must be set without '&' and ';'. Eg. use '#xD' for ' '\")\n } else if (value === \"&\") {\n throw new Error(\"An entity with value '&' is not permitted\");\n } else {\n this.externalEntities[key] = value;\n }\n }\n\n /**\n * Returns a Symbol that can be used to access the metadata\n * property on a node.\n * \n * If Symbol is not available in the environment, an ordinary property is used\n * and the name of the property is here returned.\n * \n * The XMLMetaData property is only present when `captureMetaData`\n * is true in the options.\n */\n static getMetaDataSymbol() {\n return XmlNode.getMetaDataSymbol();\n }\n}\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","getAllMatches","string","regex","matches","match","exec","allmatches","startIndex","lastIndex","length","len","index","push","isName","DANGEROUS_PROPERTY_NAMES","criticalProperties","defaultOnDangerousProperty","name","includes","defaultOptions","preserveOrder","attributeNamePrefix","attributesGroupName","textNodeName","ignoreAttributes","removeNSPrefix","allowBooleanAttributes","parseTagValue","parseAttributeValue","trimValues","cdataPropName","numberParseOptions","hex","leadingZeros","eNotation","tagValueProcessor","tagName","val","attributeValueProcessor","attrName","stopNodes","alwaysCreateTextNode","isArray","commentPropName","unpairedTags","processEntities","htmlEntities","ignoreDeclaration","ignorePiTags","transformTagName","transformAttributeName","updateTag","jPath","attrs","captureMetaData","maxNestedTags","strictReservedNames","onDangerousProperty","validatePropertyName","propertyName","optionName","normalized","toLowerCase","some","dangerous","Error","normalizeProcessEntities","enabled","maxEntitySize","maxExpansionDepth","maxTotalExpansions","maxExpandedLength","maxEntityCount","allowedTags","tagFilter","Math","max","_value$maxEntitySize","_value$maxExpansionDe","_value$maxTotalExpans","_value$maxExpandedLen","_value$maxEntityCount","_value$allowedTags","_value$tagFilter","METADATA_SYMBOL","buildOptions","options","built","assign","_i","_propertyNameOptions","_propertyNameOptions$","Array","map","node","startsWith","substring","XmlNode","tagname","child","create","_proto","add","_this$child$push","addChild","_this$child$push2","_this$child$push3","keys","undefined","getMetaDataSymbol","DocTypeReader","suppressValidationErr","readDocType","xmlData","i","entities","entityCount","angleBracketsCount","hasBody","comment","hasSeq","entityName","_this$readEntityExp","readEntityExp","indexOf","escaped","replace","regx","readElementExp","readNotationExp","skipWhitespace","test","validateEntityName","toUpperCase","entityValue","_this$readIdentifierV","readIdentifierVal","notationName","identifierType","publicIdentifier","systemIdentifier","_this$readIdentifierV2","_this$readIdentifierV3","_this$readIdentifierV4","type","identifierVal","startChar","elementName","contentModel","trim","readAttlistExp","attributeName","attributeType","allowedNotations","notation","join","defaultValue","_this$readIdentifierV5","data","seq","j","hexRegex","numRegex","consider","decimalPoint","infinity","eNotationRegx","Matcher","constructor","separator","path","siblingStacks","attrValues","namespace","values","currentLevel","Map","siblings","siblingKey","counter","position","count","set","tag","pop","updateCurrent","current","getCurrentTag","getCurrentNamespace","getAttrValue","hasAttr","getPosition","getCounter","getIndex","getDepth","toString","includeNamespace","sep","n","toArray","reset","expression","segments","hasDeepWildcard","_matchWithDeepWildcard","_matchSimple","segment","isCurrentNode","_matchSegment","pathIdx","segIdx","nextSeg","found","attrValue","actualValue","String","positionValue","snapshot","restore","Expression","pattern","_parse","_hasDeepWildcard","seg","_hasAttributeCondition","_hasPositionSelector","currentPart","_parseSegment","part","bracketContent","withoutBrackets","bracketMatch","content","slice","tagAndPosition","nsIndex","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","eqIndex","nthMatch","parseInt","hasAttributeCondition","hasPositionSelector","extractRawAttributes","prefixedAttrs","rawAttrs","extractNamespace","rawTagName","ns","OrderedObjParser","currentNode","tagsNodeStack","docTypeEntities","lastEntities","ampEntity","_","str","fromCodePoint","addExternalEntities","parseXml","parseTextData","resolveNameSpace","buildAttributesMap","isItStopNode","replaceEntitiesValue","readStopNodeData","saveTextToParentTag","ignoreAttributesFn","_step","_iterator","_createForOfIteratorHelperLoose","done","entityExpansionCount","currentExpandedLength","matcher","isCurrentNodeStopNode","stopNodeExpressions","stopNodeExp","externalEntities","entKeys","ent","dontTrim","hasAttributes","isLeafNode","escapeEntities","jPathOrMatcher","newval","parseValue","tags","split","prefix","charAt","attrsRegx","attrStr","rawAttrsForMatcher","oldVal","parsedVal","jPathStr","aName","sanitizeName","newVal","attrCollection","xmlObj","xmlNode","textData","docTypeReader","closeIndex","findClosingIndex","substr","lastTagName","tagData","readTagExp","childNode","tagExp","attrExpPresent","endIndex","_ref","result","_ref2","context","min","_transformTagName","lastTag","isSelfClosing","tagContent","_transformTagName2","entityConfig","_i2","_Object$keys","entity","lengthBefore","_i3","_Object$keys2","_i4","_Object$keys3","parentNode","errMsg","closingIndex","closingChar","attrBoundary","ch","tagExpWithClosingIndex","separatorIndex","search","trimStart","openTagCount","shouldParse","trimmedStr","skipLike","numStr","Number","window","parse_int","isFinite","sign","eChar","eAdjacentToLeadingZeros","resolveEnotation","numTrimmedByZeros","decimalAdjacentToLeadingZeros","num","parsedStr","isPositive","Infinity","handleInfinity","toNumber","base","codePoint","fn","newTagName","stripAttributePrefix","prettify","compress","arr","text","compressedObj","tagObj","property","propName","isLeaf","isLeafTag","assignAttributes","attrMap","atrrName","rawAttrName","propCount","isWhiteSpace","char","readPI","start","getErrorObject","getLineNumberForPosition","readCommentAndCDATA","readAttributeStr","tagClosed","validAttrStrRegxp","validateAttributeString","attrNames","getPositionFromMatch","validateAttrName","validateAmpersand","re","validateNumberAmpersand","code","message","lineNumber","err","msg","line","col","validateTagName","lines","XMLParser","parse","validationOption","tagFound","reachedRoot","tagStartPos","closingTag","attrStrStart","isValid","otg","openPos","afterAmp","JSON","stringify","t","validate","orderedObjParser","orderedResult","addEntity"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"./lib/fxparser.min.js","mappings":"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","sources":["webpack://XMLParser/webpack/universalModuleDefinition","webpack://XMLParser/webpack/bootstrap","webpack://XMLParser/webpack/runtime/define property getters","webpack://XMLParser/webpack/runtime/hasOwnProperty shorthand","webpack://XMLParser/webpack/runtime/make namespace object","webpack://XMLParser/./src/util.js","webpack://XMLParser/./src/xmlparser/OptionsBuilder.js","webpack://XMLParser/./src/xmlparser/xmlNode.js","webpack://XMLParser/./src/xmlparser/DocTypeReader.js","webpack://XMLParser/./node_modules/strnum/strnum.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/Matcher.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/Expression.js","webpack://XMLParser/./node_modules/path-expression-matcher/src/ExpressionSet.js","webpack://XMLParser/./node_modules/@nodable/entities/src/entities.js","webpack://XMLParser/./node_modules/@nodable/entities/src/EntityDecoder.js","webpack://XMLParser/./src/xmlparser/OrderedObjParser.js","webpack://XMLParser/./src/ignoreAttributes.js","webpack://XMLParser/./src/xmlparser/node2json.js","webpack://XMLParser/./src/validator.js","webpack://XMLParser/./src/xmlparser/XMLParser.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"XMLParser\"] = factory();\n\telse\n\t\troot[\"XMLParser\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","'use strict';\n\nconst nameStartChar = ':A-Za-z_\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\nconst nameChar = nameStartChar + '\\\\-.\\\\d\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040';\nexport const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';\nconst regexName = new RegExp('^' + nameRegexp + '$');\n\nexport function getAllMatches(string, regex) {\n const matches = [];\n let match = regex.exec(string);\n while (match) {\n const allmatches = [];\n allmatches.startIndex = regex.lastIndex - match[0].length;\n const len = match.length;\n for (let index = 0; index < len; index++) {\n allmatches.push(match[index]);\n }\n matches.push(allmatches);\n match = regex.exec(string);\n }\n return matches;\n}\n\nexport const isName = function (string) {\n const match = regexName.exec(string);\n return !(match === null || typeof match === 'undefined');\n}\n\nexport function isExist(v) {\n return typeof v !== 'undefined';\n}\n\nexport function isEmptyObject(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function getValue(v) {\n if (exports.isExist(v)) {\n return v;\n } else {\n return '';\n }\n}\n\n/**\n * Dangerous property names that could lead to prototype pollution or security issues\n */\nexport const DANGEROUS_PROPERTY_NAMES = [\n // '__proto__',\n // 'constructor',\n // 'prototype',\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n '__defineGetter__',\n '__defineSetter__',\n '__lookupGetter__',\n '__lookupSetter__'\n];\n\nexport const criticalProperties = [\"__proto__\", \"constructor\", \"prototype\"];","import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from \"../util.js\";\nimport { COMMON_HTML, CURRENCY } from '@nodable/entities';\n\nconst defaultOnDangerousProperty = (name) => {\n if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return \"__\" + name;\n }\n return name;\n};\n\n\nexport const defaultOptions = {\n preserveOrder: false,\n attributeNamePrefix: '@_',\n attributesGroupName: false,\n textNodeName: '#text',\n ignoreAttributes: true,\n removeNSPrefix: false, // remove NS from tag name or attribute name if true\n allowBooleanAttributes: false, //a tag can have attributes without any value\n //ignoreRootElement : false,\n parseTagValue: true,\n parseAttributeValue: false,\n trimValues: true, //Trim string values of tag and attributes\n cdataPropName: false,\n numberParseOptions: {\n hex: true,\n leadingZeros: true,\n eNotation: true\n },\n tagValueProcessor: function (tagName, val) {\n return val;\n },\n attributeValueProcessor: function (attrName, val) {\n return val;\n },\n stopNodes: [], //nested tags will not be parsed even for errors\n alwaysCreateTextNode: false,\n isArray: () => false,\n commentPropName: false,\n unpairedTags: [],\n processEntities: true,\n htmlEntities: false,\n entityDecoder: null,\n ignoreDeclaration: false,\n ignorePiTags: false,\n transformTagName: false,\n transformAttributeName: false,\n updateTag: function (tagName, jPath, attrs) {\n return tagName\n },\n // skipEmptyListItem: false\n captureMetaData: false,\n maxNestedTags: 100,\n strictReservedNames: true,\n jPath: true, // if true, pass jPath string to callbacks; if false, pass matcher instance\n onDangerousProperty: defaultOnDangerousProperty\n};\n\n\n/**\n * Validates that a property name is safe to use\n * @param {string} propertyName - The property name to validate\n * @param {string} optionName - The option field name (for error message)\n * @throws {Error} If property name is dangerous\n */\nfunction validatePropertyName(propertyName, optionName) {\n if (typeof propertyName !== 'string') {\n return; // Only validate string property names\n }\n\n const normalized = propertyName.toLowerCase();\n if (DANGEROUS_PROPERTY_NAMES.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n\n if (criticalProperties.some(dangerous => normalized === dangerous.toLowerCase())) {\n throw new Error(\n `[SECURITY] Invalid ${optionName}: \"${propertyName}\" is a reserved JavaScript keyword that could cause prototype pollution`\n );\n }\n}\n\n/**\n * Normalizes processEntities option for backward compatibility\n * @param {boolean|object} value \n * @returns {object} Always returns normalized object\n */\nfunction normalizeProcessEntities(value, htmlEntities) {\n // Boolean backward compatibility\n if (typeof value === 'boolean') {\n return {\n enabled: value, // true or false\n maxEntitySize: 10000,\n maxExpansionDepth: 10000,\n maxTotalExpansions: Infinity,\n maxExpandedLength: 100000,\n maxEntityCount: 1000,\n allowedTags: null,\n tagFilter: null,\n appliesTo: \"all\",\n };\n }\n\n // Object config - merge with defaults\n if (typeof value === 'object' && value !== null) {\n return {\n enabled: value.enabled !== false,\n maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000),\n maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10000),\n maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),\n maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000),\n maxEntityCount: Math.max(1, value.maxEntityCount ?? 1000),\n allowedTags: value.allowedTags ?? null,\n tagFilter: value.tagFilter ?? null,\n appliesTo: value.appliesTo ?? \"all\",\n };\n }\n\n // Default to enabled with limits\n return normalizeProcessEntities(true);\n}\n\nexport const buildOptions = function (options) {\n const built = Object.assign({}, defaultOptions, options);\n\n // Validate property names to prevent prototype pollution\n const propertyNameOptions = [\n { value: built.attributeNamePrefix, name: 'attributeNamePrefix' },\n { value: built.attributesGroupName, name: 'attributesGroupName' },\n { value: built.textNodeName, name: 'textNodeName' },\n { value: built.cdataPropName, name: 'cdataPropName' },\n { value: built.commentPropName, name: 'commentPropName' }\n ];\n\n for (const { value, name } of propertyNameOptions) {\n if (value) {\n validatePropertyName(value, name);\n }\n }\n\n if (built.onDangerousProperty === null) {\n built.onDangerousProperty = defaultOnDangerousProperty;\n }\n\n // Always normalize processEntities for backward compatibility and validation\n built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities);\n built.unpairedTagsSet = new Set(built.unpairedTags);\n // Convert old-style stopNodes for backward compatibility\n if (built.stopNodes && Array.isArray(built.stopNodes)) {\n built.stopNodes = built.stopNodes.map(node => {\n if (typeof node === 'string' && node.startsWith('*.')) {\n // Old syntax: *.tagname meant \"tagname anywhere\"\n // Convert to new syntax: ..tagname\n return '..' + node.substring(2);\n }\n return node;\n });\n }\n //console.debug(built.processEntities)\n return built;\n};","'use strict';\n\nlet METADATA_SYMBOL;\n\nif (typeof Symbol !== \"function\") {\n METADATA_SYMBOL = \"@@xmlMetadata\";\n} else {\n METADATA_SYMBOL = Symbol(\"XML Node Metadata\");\n}\n\nexport default class XmlNode {\n constructor(tagname) {\n this.tagname = tagname;\n this.child = []; //nested tags, text, cdata, comments in order\n this[\":@\"] = Object.create(null); //attributes map\n }\n add(key, val) {\n // this.child.push( {name : key, val: val, isCdata: isCdata });\n if (key === \"__proto__\") key = \"#__proto__\";\n this.child.push({ [key]: val });\n }\n addChild(node, startIndex) {\n if (node.tagname === \"__proto__\") node.tagname = \"#__proto__\";\n if (node[\":@\"] && Object.keys(node[\":@\"]).length > 0) {\n this.child.push({ [node.tagname]: node.child, [\":@\"]: node[\":@\"] });\n } else {\n this.child.push({ [node.tagname]: node.child });\n }\n // if requested, add the startIndex\n if (startIndex !== undefined) {\n // Note: for now we just overwrite the metadata. If we had more complex metadata,\n // we might need to do an object append here: metadata = { ...metadata, startIndex }\n this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };\n }\n }\n /** symbol used for metadata */\n static getMetaDataSymbol() {\n return METADATA_SYMBOL;\n }\n}\n","import { isName } from '../util.js';\n\nexport default class DocTypeReader {\n constructor(options) {\n this.suppressValidationErr = !options;\n this.options = options;\n }\n\n readDocType(xmlData, i) {\n const entities = Object.create(null);\n let entityCount = 0;\n\n if (xmlData[i + 3] === 'O' &&\n xmlData[i + 4] === 'C' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'Y' &&\n xmlData[i + 7] === 'P' &&\n xmlData[i + 8] === 'E') {\n i = i + 9;\n let angleBracketsCount = 1;\n let hasBody = false, comment = false;\n let exp = \"\";\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === '<' && !comment) { //Determine the tag type\n if (hasBody && hasSeq(xmlData, \"!ENTITY\", i)) {\n i += 7;\n let entityName, val;\n [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);\n if (val.indexOf(\"&\") === -1) { //Parameter entities are not supported\n if (this.options.enabled !== false &&\n this.options.maxEntityCount != null &&\n entityCount >= this.options.maxEntityCount) {\n throw new Error(\n `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`\n );\n }\n //const escaped = entityName.replace(/[.\\-+*:]/g, '\\\\.');\n //const escaped = entityName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n entities[entityName] = val;\n entityCount++;\n }\n }\n else if (hasBody && hasSeq(xmlData, \"!ELEMENT\", i)) {\n i += 8;//Not supported\n const { index } = this.readElementExp(xmlData, i + 1);\n i = index;\n } else if (hasBody && hasSeq(xmlData, \"!ATTLIST\", i)) {\n i += 8;//Not supported\n // const {index} = this.readAttlistExp(xmlData,i+1);\n // i = index;\n } else if (hasBody && hasSeq(xmlData, \"!NOTATION\", i)) {\n i += 9;//Not supported\n const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);\n i = index;\n } else if (hasSeq(xmlData, \"!--\", i)) comment = true;\n else throw new Error(`Invalid DOCTYPE`);\n\n angleBracketsCount++;\n exp = \"\";\n } else if (xmlData[i] === '>') { //Read tag content\n if (comment) {\n if (xmlData[i - 1] === \"-\" && xmlData[i - 2] === \"-\") {\n comment = false;\n angleBracketsCount--;\n }\n } else {\n angleBracketsCount--;\n }\n if (angleBracketsCount === 0) {\n break;\n }\n } else if (xmlData[i] === '[') {\n hasBody = true;\n } else {\n exp += xmlData[i];\n }\n }\n if (angleBracketsCount !== 0) {\n throw new Error(`Unclosed DOCTYPE`);\n }\n } else {\n throw new Error(`Invalid Tag instead of DOCTYPE`);\n }\n return { entities, i };\n }\n readEntityExp(xmlData, i) {\n //External entities are not supported\n // \n\n //Parameter entities are not supported\n // \n\n //Internal entities are supported\n // \n\n // Skip leading whitespace after this.options.maxEntitySize) {\n throw new Error(\n `Entity \"${entityName}\" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`\n );\n }\n\n i--;\n return [entityName, entityValue, i];\n }\n\n readNotationExp(xmlData, i) {\n // Skip leading whitespace after \n // \n // \n // \n // \n\n // Skip leading whitespace after {\n while (index < data.length && /\\s/.test(data[index])) {\n index++;\n }\n return index;\n};\n\n\n\nfunction hasSeq(data, seq, i) {\n for (let j = 0; j < seq.length; j++) {\n if (seq[j] !== data[i + j + 1]) return false;\n }\n return true;\n}\n\nfunction validateEntityName(name) {\n if (isName(name))\n return name;\n else\n throw new Error(`Invalid entity name ${name}`);\n}","const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;\nconst numRegex = /^([\\-\\+])?(0*)([0-9]*(\\.[0-9]*)?)$/;\n// const octRegex = /^0x[a-z0-9]+/;\n// const binRegex = /0x[a-z0-9]+/;\n\n\nconst consider = {\n hex: true,\n // oct: false,\n leadingZeros: true,\n decimalPoint: \"\\.\",\n eNotation: true,\n //skipLike: /regex/,\n infinity: \"original\", // \"null\", \"infinity\" (Infinity type), \"string\" (\"Infinity\" (the string literal))\n};\n\nexport default function toNumber(str, options = {}) {\n options = Object.assign({}, consider, options);\n if (!str || typeof str !== \"string\") return str;\n\n let trimmedStr = str.trim();\n\n if (trimmedStr.length === 0) return str;\n else if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;\n else if (trimmedStr === \"0\") return 0;\n else if (options.hex && hexRegex.test(trimmedStr)) {\n return parse_int(trimmedStr, 16);\n // }else if (options.oct && octRegex.test(str)) {\n // return Number.parseInt(val, 8);\n } else if (!isFinite(trimmedStr)) { //Infinity\n return handleInfinity(str, Number(trimmedStr), options);\n } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation\n return resolveEnotation(str, trimmedStr, options);\n // }else if (options.parseBin && binRegex.test(str)) {\n // return Number.parseInt(val, 2);\n } else {\n //separate negative sign, leading zeros, and rest number\n const match = numRegex.exec(trimmedStr);\n // +00.123 => [ , '+', '00', '.123', ..\n if (match) {\n const sign = match[1] || \"\";\n const leadingZeros = match[2];\n let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros\n const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.\n str[leadingZeros.length + 1] === \".\"\n : str[leadingZeros.length] === \".\";\n\n //trim ending zeros for floating number\n if (!options.leadingZeros //leading zeros are not allowed\n && (leadingZeros.length > 1\n || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {\n // 00, 00.3, +03.24, 03, 03.24\n return str;\n }\n else {//no leading zeros or leading zeros are allowed\n const num = Number(trimmedStr);\n const parsedStr = String(num);\n\n if (num === 0) return num;\n if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation\n if (options.eNotation) return num;\n else return str;\n } else if (trimmedStr.indexOf(\".\") !== -1) { //floating number\n if (parsedStr === \"0\") return num; //0.0\n else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000\n else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;\n else return str;\n }\n\n let n = leadingZeros ? numTrimmedByZeros : trimmedStr;\n if (leadingZeros) {\n // -009 => -9\n return (n === parsedStr) || (sign + n === parsedStr) ? num : str\n } else {\n // +9\n return (n === parsedStr) || (n === sign + parsedStr) ? num : str\n }\n }\n } else { //non-numeric string\n return str;\n }\n }\n}\n\nconst eNotationRegx = /^([-+])?(0*)(\\d*(\\.\\d*)?[eE][-\\+]?\\d+)$/;\nfunction resolveEnotation(str, trimmedStr, options) {\n if (!options.eNotation) return str;\n const notation = trimmedStr.match(eNotationRegx);\n if (notation) {\n let sign = notation[1] || \"\";\n const eChar = notation[3].indexOf(\"e\") === -1 ? \"E\" : \"e\";\n const leadingZeros = notation[2];\n const eAdjacentToLeadingZeros = sign ? // 0E.\n str[leadingZeros.length + 1] === eChar\n : str[leadingZeros.length] === eChar;\n\n if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;\n else if (leadingZeros.length === 1\n && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {\n return Number(trimmedStr);\n } else if (leadingZeros.length > 0) {\n // Has leading zeros — only accept if leadingZeros option allows it\n if (options.leadingZeros && !eAdjacentToLeadingZeros) {\n trimmedStr = (notation[1] || \"\") + notation[3];\n return Number(trimmedStr);\n } else return str;\n } else {\n // No leading zeros — always valid e-notation, parse it\n return Number(trimmedStr);\n }\n } else {\n return str;\n }\n}\n\n/**\n * \n * @param {string} numStr without leading zeros\n * @returns \n */\nfunction trimZeros(numStr) {\n if (numStr && numStr.indexOf(\".\") !== -1) {//float\n numStr = numStr.replace(/0+$/, \"\"); //remove ending zeros\n if (numStr === \".\") numStr = \"0\";\n else if (numStr[0] === \".\") numStr = \"0\" + numStr;\n else if (numStr[numStr.length - 1] === \".\") numStr = numStr.substring(0, numStr.length - 1);\n return numStr;\n }\n return numStr;\n}\n\nfunction parse_int(numStr, base) {\n //polyfill\n if (parseInt) return parseInt(numStr, base);\n else if (Number.parseInt) return Number.parseInt(numStr, base);\n else if (window && window.parseInt) return window.parseInt(numStr, base);\n else throw new Error(\"parseInt, Number.parseInt, window.parseInt are not supported\")\n}\n\n/**\n * Handle infinite values based on user option\n * @param {string} str - original input string\n * @param {number} num - parsed number (Infinity or -Infinity)\n * @param {object} options - user options\n * @returns {string|number|null} based on infinity option\n */\nfunction handleInfinity(str, num, options) {\n const isPositive = num === Infinity;\n\n switch (options.infinity.toLowerCase()) {\n case \"null\":\n return null;\n case \"infinity\":\n return num; // Return Infinity or -Infinity\n case \"string\":\n return isPositive ? \"Infinity\" : \"-Infinity\";\n case \"original\":\n default:\n return str; // Return original string like \"1e1000\"\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n */\n push(tagName, attrValues = null, namespace = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","/**\n * ExpressionSet - An indexed collection of Expressions for efficient bulk matching\n *\n * Instead of iterating all expressions on every tag, ExpressionSet pre-indexes\n * them at insertion time by depth and terminal tag name. At match time, only\n * the relevant bucket is evaluated — typically reducing checks from O(E) to O(1)\n * lookup plus O(small bucket) matches.\n *\n * Three buckets are maintained:\n * - `_byDepthAndTag` — exact depth + exact tag name (tightest, used first)\n * - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only)\n * - `_deepWildcards` — expressions containing `..` (cannot be depth-indexed)\n *\n * @example\n * import { Expression, ExpressionSet } from 'fast-xml-tagger';\n *\n * // Build once at config time\n * const stopNodes = new ExpressionSet();\n * stopNodes.add(new Expression('root.users.user'));\n * stopNodes.add(new Expression('root.config.setting'));\n * stopNodes.add(new Expression('..script'));\n *\n * // Query on every tag — hot path\n * if (stopNodes.matchesAny(matcher)) { ... }\n */\nexport default class ExpressionSet {\n constructor() {\n /** @type {Map} depth:tag → expressions */\n this._byDepthAndTag = new Map();\n\n /** @type {Map} depth → wildcard-tag expressions */\n this._wildcardByDepth = new Map();\n\n /** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */\n this._deepWildcards = [];\n\n /** @type {Set} pattern strings already added — used for deduplication */\n this._patterns = new Set();\n\n /** @type {boolean} whether the set is sealed against further additions */\n this._sealed = false;\n }\n\n /**\n * Add an Expression to the set.\n * Duplicate patterns (same pattern string) are silently ignored.\n *\n * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance\n * @returns {this} for chaining\n * @throws {TypeError} if called after seal()\n *\n * @example\n * set.add(new Expression('root.users.user'));\n * set.add(new Expression('..script'));\n */\n add(expression) {\n if (this._sealed) {\n throw new TypeError(\n 'ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.'\n );\n }\n\n // Deduplicate by pattern string\n if (this._patterns.has(expression.pattern)) return this;\n this._patterns.add(expression.pattern);\n\n if (expression.hasDeepWildcard()) {\n this._deepWildcards.push(expression);\n return this;\n }\n\n const depth = expression.length;\n const lastSeg = expression.segments[expression.segments.length - 1];\n const tag = lastSeg?.tag;\n\n if (!tag || tag === '*') {\n // Can index by depth but not by tag\n if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);\n this._wildcardByDepth.get(depth).push(expression);\n } else {\n // Tightest bucket: depth + tag\n const key = `${depth}:${tag}`;\n if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);\n this._byDepthAndTag.get(key).push(expression);\n }\n\n return this;\n }\n\n /**\n * Add multiple expressions at once.\n *\n * @param {import('./Expression.js').default[]} expressions - Array of Expression instances\n * @returns {this} for chaining\n *\n * @example\n * set.addAll([\n * new Expression('root.users.user'),\n * new Expression('root.config.setting'),\n * ]);\n */\n addAll(expressions) {\n for (const expr of expressions) this.add(expr);\n return this;\n }\n\n /**\n * Check whether a pattern string is already present in the set.\n *\n * @param {import('./Expression.js').default} expression\n * @returns {boolean}\n */\n has(expression) {\n return this._patterns.has(expression.pattern);\n }\n\n /**\n * Number of expressions in the set.\n * @type {number}\n */\n get size() {\n return this._patterns.size;\n }\n\n /**\n * Seal the set against further modifications.\n * Useful to prevent accidental mutations after config is built.\n * Calling add() or addAll() on a sealed set throws a TypeError.\n *\n * @returns {this}\n */\n seal() {\n this._sealed = true;\n return this;\n }\n\n /**\n * Whether the set has been sealed.\n * @type {boolean}\n */\n get isSealed() {\n return this._sealed;\n }\n\n /**\n * Test whether the matcher's current path matches any expression in the set.\n *\n * Evaluation order (cheapest → most expensive):\n * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions\n * 2. Depth-only wildcard bucket — O(1) lookup, rare\n * 3. Deep-wildcard list — always checked, but usually small\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {boolean} true if any expression matches the current path\n *\n * @example\n * if (stopNodes.matchesAny(matcher)) {\n * // handle stop node\n * }\n */\n matchesAny(matcher) {\n return this.findMatch(matcher) !== null;\n }\n /**\n * Find and return the first Expression that matches the matcher's current path.\n *\n * Uses the same evaluation order as matchesAny (cheapest → most expensive):\n * 1. Exact depth + tag bucket\n * 2. Depth-only wildcard bucket\n * 3. Deep-wildcard list\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {import('./Expression.js').default | null} the first matching Expression, or null\n *\n * @example\n * const expr = stopNodes.findMatch(matcher);\n * if (expr) {\n * // access expr.config, expr.pattern, etc.\n * }\n */\n findMatch(matcher) {\n const depth = matcher.getDepth();\n const tag = matcher.getCurrentTag();\n\n // 1. Tightest bucket — most expressions live here\n const exactKey = `${depth}:${tag}`;\n const exactBucket = this._byDepthAndTag.get(exactKey);\n if (exactBucket) {\n for (let i = 0; i < exactBucket.length; i++) {\n if (matcher.matches(exactBucket[i])) return exactBucket[i];\n }\n }\n\n // 2. Depth-matched wildcard-tag expressions\n const wildcardBucket = this._wildcardByDepth.get(depth);\n if (wildcardBucket) {\n for (let i = 0; i < wildcardBucket.length; i++) {\n if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];\n }\n }\n\n // 3. Deep wildcards — cannot be pre-filtered by depth or tag\n for (let i = 0; i < this._deepWildcards.length; i++) {\n if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];\n }\n\n return null;\n }\n}\n","// ---------------------------------------------------------------------------\n// Complete HTML5 named entity reference\n// Organized by logical categories for easy maintenance and selective importing\n// ---------------------------------------------------------------------------\n\n/**\n * Basic Latin & Special Characters\n * @type {Record}\n */\nexport const BASIC_LATIN = {\n amp: '&',\n AMP: '&',\n lt: '<',\n LT: '<',\n gt: '>',\n GT: '>',\n quot: '\"',\n QUOT: '\"',\n apos: \"'\",\n lsquo: '‘',\n rsquo: '’',\n ldquo: '“',\n rdquo: '”',\n lsquor: '‚',\n rsquor: '’',\n ldquor: '„',\n bdquo: '„',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n excl: '!',\n quest: '?',\n num: '#',\n dollar: '$',\n percent: '%',\n amp: '&',\n ast: '*',\n commat: '@',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n sol: '/',\n bsol: '\\\\',\n lbrace: '{',\n rbrace: '}',\n lbrack: '[',\n rbrack: ']',\n lpar: '(',\n rpar: ')',\n nbsp: '\\u00a0',\n iexcl: '¡',\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n COPY: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n REG: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n half: '½',\n frac34: '¾',\n iquest: '¿',\n times: '×',\n div: '÷',\n divide: '÷',\n};\n\n/**\n * Latin Extended & Accented Letters (A-Z)\n * @type {Record}\n */\nexport const LATIN_ACCENTS = {\n Agrave: 'À',\n agrave: 'à',\n Aacute: 'Á',\n aacute: 'á',\n Acirc: 'Â',\n acirc: 'â',\n Atilde: 'Ã',\n atilde: 'ã',\n Auml: 'Ä',\n auml: 'ä',\n Aring: 'Å',\n aring: 'å',\n AElig: 'Æ',\n aelig: 'æ',\n Ccedil: 'Ç',\n ccedil: 'ç',\n Egrave: 'È',\n egrave: 'è',\n Eacute: 'É',\n eacute: 'é',\n Ecirc: 'Ê',\n ecirc: 'ê',\n Euml: 'Ë',\n euml: 'ë',\n Igrave: 'Ì',\n igrave: 'ì',\n Iacute: 'Í',\n iacute: 'í',\n Icirc: 'Î',\n icirc: 'î',\n Iuml: 'Ï',\n iuml: 'ï',\n ETH: 'Ð',\n eth: 'ð',\n Ntilde: 'Ñ',\n ntilde: 'ñ',\n Ograve: 'Ò',\n ograve: 'ò',\n Oacute: 'Ó',\n oacute: 'ó',\n Ocirc: 'Ô',\n ocirc: 'ô',\n Otilde: 'Õ',\n otilde: 'õ',\n Ouml: 'Ö',\n ouml: 'ö',\n Oslash: 'Ø',\n oslash: 'ø',\n Ugrave: 'Ù',\n ugrave: 'ù',\n Uacute: 'Ú',\n uacute: 'ú',\n Ucirc: 'Û',\n ucirc: 'û',\n Uuml: 'Ü',\n uuml: 'ü',\n Yacute: 'Ý',\n yacute: 'ý',\n THORN: 'Þ',\n thorn: 'þ',\n szlig: 'ß',\n yuml: 'ÿ',\n Yuml: 'Ÿ',\n};\n\n/**\n * Latin Extended (Letters with diacritics)\n * @type {Record}\n */\nexport const LATIN_EXTENDED = {\n Amacr: 'Ā',\n amacr: 'ā',\n Abreve: 'Ă',\n abreve: 'ă',\n Aogon: 'Ą',\n aogon: 'ą',\n Cacute: 'Ć',\n cacute: 'ć',\n Ccirc: 'Ĉ',\n ccirc: 'ĉ',\n Cdot: 'Ċ',\n cdot: 'ċ',\n Ccaron: 'Č',\n ccaron: 'č',\n Dcaron: 'Ď',\n dcaron: 'ď',\n Dstrok: 'Đ',\n dstrok: 'đ',\n Emacr: 'Ē',\n emacr: 'ē',\n Ecaron: 'Ě',\n ecaron: 'ě',\n Edot: 'Ė',\n edot: 'ė',\n Eogon: 'Ę',\n eogon: 'ę',\n Gcirc: 'Ĝ',\n gcirc: 'ĝ',\n Gbreve: 'Ğ',\n gbreve: 'ğ',\n Gdot: 'Ġ',\n gdot: 'ġ',\n Gcedil: 'Ģ',\n Hcirc: 'Ĥ',\n hcirc: 'ĥ',\n Hstrok: 'Ħ',\n hstrok: 'ħ',\n Itilde: 'Ĩ',\n itilde: 'ĩ',\n Imacr: 'Ī',\n imacr: 'ī',\n Iogon: 'Į',\n iogon: 'į',\n Idot: 'İ',\n IJlig: 'IJ',\n ijlig: 'ij',\n Jcirc: 'Ĵ',\n jcirc: 'ĵ',\n Kcedil: 'Ķ',\n kcedil: 'ķ',\n kgreen: 'ĸ',\n Lacute: 'Ĺ',\n lacute: 'ĺ',\n Lcedil: 'Ļ',\n lcedil: 'ļ',\n Lcaron: 'Ľ',\n lcaron: 'ľ',\n Lmidot: 'Ŀ',\n lmidot: 'ŀ',\n Lstrok: 'Ł',\n lstrok: 'ł',\n Nacute: 'Ń',\n nacute: 'ń',\n Ncaron: 'Ň',\n ncaron: 'ň',\n Ncedil: 'Ņ',\n ncedil: 'ņ',\n ENG: 'Ŋ',\n eng: 'ŋ',\n Omacr: 'Ō',\n omacr: 'ō',\n Odblac: 'Ő',\n odblac: 'ő',\n OElig: 'Œ',\n oelig: 'œ',\n Racute: 'Ŕ',\n racute: 'ŕ',\n Rcaron: 'Ř',\n rcaron: 'ř',\n Rcedil: 'Ŗ',\n rcedil: 'ŗ',\n Sacute: 'Ś',\n sacute: 'ś',\n Scirc: 'Ŝ',\n scirc: 'ŝ',\n Scedil: 'Ş',\n scedil: 'ş',\n Scaron: 'Š',\n scaron: 'š',\n Tcedil: 'Ţ',\n tcedil: 'ţ',\n Tcaron: 'Ť',\n tcaron: 'ť',\n Tstrok: 'Ŧ',\n tstrok: 'ŧ',\n Utilde: 'Ũ',\n utilde: 'ũ',\n Umacr: 'Ū',\n umacr: 'ū',\n Ubreve: 'Ŭ',\n ubreve: 'ŭ',\n Uring: 'Ů',\n uring: 'ů',\n Udblac: 'Ű',\n udblac: 'ű',\n Uogon: 'Ų',\n uogon: 'ų',\n Wcirc: 'Ŵ',\n wcirc: 'ŵ',\n Ycirc: 'Ŷ',\n ycirc: 'ŷ',\n Zacute: 'Ź',\n zacute: 'ź',\n Zdot: 'Ż',\n zdot: 'ż',\n Zcaron: 'Ž',\n zcaron: 'ž',\n};\n\n/**\n * Greek Letters\n * @type {Record}\n */\nexport const GREEK = {\n Alpha: 'Α',\n alpha: 'α',\n Beta: 'Β',\n beta: 'β',\n Gamma: 'Γ',\n gamma: 'γ',\n Delta: 'Δ',\n delta: 'δ',\n Epsilon: 'Ε',\n epsilon: 'ε',\n epsiv: 'ϵ',\n varepsilon: 'ϵ',\n Zeta: 'Ζ',\n zeta: 'ζ',\n Eta: 'Η',\n eta: 'η',\n Theta: 'Θ',\n theta: 'θ',\n thetasym: 'ϑ',\n vartheta: 'ϑ',\n Iota: 'Ι',\n iota: 'ι',\n Kappa: 'Κ',\n kappa: 'κ',\n kappav: 'ϰ',\n varkappa: 'ϰ',\n Lambda: 'Λ',\n lambda: 'λ',\n Mu: 'Μ',\n mu: 'μ',\n Nu: 'Ν',\n nu: 'ν',\n Xi: 'Ξ',\n xi: 'ξ',\n Omicron: 'Ο',\n omicron: 'ο',\n Pi: 'Π',\n pi: 'π',\n piv: 'ϖ',\n varpi: 'ϖ',\n Rho: 'Ρ',\n rho: 'ρ',\n rhov: 'ϱ',\n varrho: 'ϱ',\n Sigma: 'Σ',\n sigma: 'σ',\n sigmaf: 'ς',\n sigmav: 'ς',\n varsigma: 'ς',\n Tau: 'Τ',\n tau: 'τ',\n Upsilon: 'Υ',\n upsilon: 'υ',\n upsi: 'υ',\n Upsi: 'ϒ',\n upsih: 'ϒ',\n Phi: 'Φ',\n phi: 'φ',\n phiv: 'ϕ',\n varphi: 'ϕ',\n Chi: 'Χ',\n chi: 'χ',\n Psi: 'Ψ',\n psi: 'ψ',\n Omega: 'Ω',\n omega: 'ω',\n ohm: 'Ω',\n Gammad: 'Ϝ',\n gammad: 'ϝ',\n digamma: 'ϝ',\n};\n\n/**\n * Cyrillic Letters\n * @type {Record}\n */\nexport const CYRILLIC = {\n Afr: '𝔄',\n afr: '𝔞',\n Acy: 'А',\n acy: 'а',\n Bcy: 'Б',\n bcy: 'б',\n Vcy: 'В',\n vcy: 'в',\n Gcy: 'Г',\n gcy: 'г',\n Dcy: 'Д',\n dcy: 'д',\n IEcy: 'Е',\n iecy: 'е',\n IOcy: 'Ё',\n iocy: 'ё',\n ZHcy: 'Ж',\n zhcy: 'ж',\n Zcy: 'З',\n zcy: 'з',\n Icy: 'И',\n icy: 'и',\n Jcy: 'Й',\n jcy: 'й',\n Kcy: 'К',\n kcy: 'к',\n Lcy: 'Л',\n lcy: 'л',\n Mcy: 'М',\n mcy: 'м',\n Ncy: 'Н',\n ncy: 'н',\n Ocy: 'О',\n ocy: 'о',\n Pcy: 'П',\n pcy: 'п',\n Rcy: 'Р',\n rcy: 'р',\n Scy: 'С',\n scy: 'с',\n Tcy: 'Т',\n tcy: 'т',\n Ucy: 'У',\n ucy: 'у',\n Fcy: 'Ф',\n fcy: 'ф',\n KHcy: 'Х',\n khcy: 'х',\n TScy: 'Ц',\n tscy: 'ц',\n CHcy: 'Ч',\n chcy: 'ч',\n SHcy: 'Ш',\n shcy: 'ш',\n SHCHcy: 'Щ',\n shchcy: 'щ',\n HARDcy: 'Ъ',\n hardcy: 'ъ',\n Ycy: 'Ы',\n ycy: 'ы',\n SOFTcy: 'Ь',\n softcy: 'ь',\n Ecy: 'Э',\n ecy: 'э',\n YUcy: 'Ю',\n yucy: 'ю',\n YAcy: 'Я',\n yacy: 'я',\n DJcy: 'Ђ',\n djcy: 'ђ',\n GJcy: 'Ѓ',\n gjcy: 'ѓ',\n Jukcy: 'Є',\n jukcy: 'є',\n DScy: 'Ѕ',\n dscy: 'ѕ',\n Iukcy: 'І',\n iukcy: 'і',\n YIcy: 'Ї',\n yicy: 'ї',\n Jsercy: 'Ј',\n jsercy: 'ј',\n LJcy: 'Љ',\n ljcy: 'љ',\n NJcy: 'Њ',\n njcy: 'њ',\n TSHcy: 'Ћ',\n tshcy: 'ћ',\n KJcy: 'Ќ',\n kjcy: 'ќ',\n Ubrcy: 'Ў',\n ubrcy: 'ў',\n DZcy: 'Џ',\n dzcy: 'џ',\n};\n\n/**\n * Mathematical Operators & Relations\n * @type {Record}\n */\nexport const MATH = {\n plus: '+',\n minus: '−',\n mnplus: '∓',\n mp: '∓',\n pm: '±',\n times: '×',\n div: '÷',\n divide: '÷',\n sdot: '⋅',\n star: '☆',\n starf: '★',\n bigstar: '★',\n lowast: '∗',\n ast: '*',\n midast: '*',\n compfn: '∘',\n smallcircle: '∘',\n bullet: '•',\n bull: '•',\n nbsp: '\\u00a0',\n hellip: '…',\n mldr: '…',\n prime: '′',\n Prime: '″',\n tprime: '‴',\n bprime: '‵',\n backprime: '‵',\n minus: '−',\n minusd: '∸',\n dotminus: '∸',\n plusdo: '∔',\n dotplus: '∔',\n plusmn: '±',\n minusplus: '∓',\n mnplus: '∓',\n mp: '∓',\n setminus: '∖',\n smallsetminus: '∖',\n Backslash: '∖',\n setmn: '∖',\n ssetmn: '∖',\n lowbar: '_',\n verbar: '|',\n vert: '|',\n VerticalLine: '|',\n colon: ':',\n Colon: '∷',\n Proportion: '∷',\n ratio: '∶',\n equals: '=',\n ne: '≠',\n nequiv: '≢',\n equiv: '≡',\n Congruent: '≡',\n sim: '∼',\n thicksim: '∼',\n thksim: '∼',\n sime: '≃',\n simeq: '≃',\n TildeEqual: '≃',\n asymp: '≈',\n approx: '≈',\n thickapprox: '≈',\n thkap: '≈',\n TildeTilde: '≈',\n ncong: '≇',\n cong: '≅',\n TildeFullEqual: '≅',\n asympeq: '≍',\n CupCap: '≍',\n bump: '≎',\n Bumpeq: '≎',\n HumpDownHump: '≎',\n bumpe: '≏',\n bumpeq: '≏',\n HumpEqual: '≏',\n dotminus: '∸',\n minusd: '∸',\n plusdo: '∔',\n dotplus: '∔',\n le: '≤',\n LessEqual: '≤',\n ge: '≥',\n GreaterEqual: '≥',\n lesseqgtr: '⋚',\n lesseqqgtr: '⪋',\n greater: '>',\n less: '<',\n};\n\n/**\n * Mathematical Operators (Advanced)\n * @type {Record}\n */\nexport const MATH_ADVANCED = {\n alefsym: 'ℵ',\n aleph: 'ℵ',\n beth: 'ℶ',\n gimel: 'ℷ',\n daleth: 'ℸ',\n forall: '∀',\n ForAll: '∀',\n part: '∂',\n PartialD: '∂',\n exist: '∃',\n Exists: '∃',\n nexist: '∄',\n nexists: '∄',\n empty: '∅',\n emptyset: '∅',\n emptyv: '∅',\n varnothing: '∅',\n nabla: '∇',\n Del: '∇',\n isin: '∈',\n isinv: '∈',\n in: '∈',\n Element: '∈',\n notin: '∉',\n notinva: '∉',\n ni: '∋',\n niv: '∋',\n SuchThat: '∋',\n ReverseElement: '∋',\n notni: '∌',\n notniva: '∌',\n prod: '∏',\n Product: '∏',\n coprod: '∐',\n Coproduct: '∐',\n sum: '∑',\n Sum: '∑',\n minus: '−',\n mp: '∓',\n plusdo: '∔',\n dotplus: '∔',\n setminus: '∖',\n lowast: '∗',\n radic: '√',\n Sqrt: '√',\n prop: '∝',\n propto: '∝',\n Proportional: '∝',\n varpropto: '∝',\n infin: '∞',\n infintie: '⧝',\n ang: '∠',\n angle: '∠',\n angmsd: '∡',\n measuredangle: '∡',\n angsph: '∢',\n mid: '∣',\n VerticalBar: '∣',\n nmid: '∤',\n nsmid: '∤',\n npar: '∦',\n parallel: '∥',\n spar: '∥',\n nparallel: '∦',\n nspar: '∦',\n and: '∧',\n wedge: '∧',\n or: '∨',\n vee: '∨',\n cap: '∩',\n cup: '∪',\n int: '∫',\n Integral: '∫',\n conint: '∮',\n ContourIntegral: '∮',\n Conint: '∯',\n DoubleContourIntegral: '∯',\n Cconint: '∰',\n there4: '∴',\n therefore: '∴',\n Therefore: '∴',\n becaus: '∵',\n because: '∵',\n Because: '∵',\n ratio: '∶',\n Proportion: '∷',\n minusd: '∸',\n dotminus: '∸',\n mDDot: '∺',\n homtht: '∻',\n sim: '∼',\n bsimg: '∽',\n backsim: '∽',\n ac: '∾',\n mstpos: '∾',\n acd: '∿',\n VerticalTilde: '≀',\n wr: '≀',\n wreath: '≀',\n nsime: '≄',\n nsimeq: '≄',\n nsimeq: '≄',\n ncong: '≇',\n simne: '≆',\n ncongdot: '⩭̸',\n ngsim: '≵',\n nsim: '≁',\n napprox: '≉',\n nap: '≉',\n ngeq: '≱',\n nge: '≱',\n nleq: '≰',\n nle: '≰',\n ngtr: '≯',\n ngt: '≯',\n nless: '≮',\n nlt: '≮',\n nprec: '⊀',\n npr: '⊀',\n nsucc: '⊁',\n nsc: '⊁',\n};\n\n/**\n * Arrows\n * @type {Record}\n */\nexport const ARROWS = {\n larr: '←',\n leftarrow: '←',\n LeftArrow: '←',\n uarr: '↑',\n uparrow: '↑',\n UpArrow: '↑',\n rarr: '→',\n rightarrow: '→',\n RightArrow: '→',\n darr: '↓',\n downarrow: '↓',\n DownArrow: '↓',\n harr: '↔',\n leftrightarrow: '↔',\n LeftRightArrow: '↔',\n varr: '↕',\n updownarrow: '↕',\n UpDownArrow: '↕',\n nwarr: '↖',\n nwarrow: '↖',\n UpperLeftArrow: '↖',\n nearr: '↗',\n nearrow: '↗',\n UpperRightArrow: '↗',\n searr: '↘',\n searrow: '↘',\n LowerRightArrow: '↘',\n swarr: '↙',\n swarrow: '↙',\n LowerLeftArrow: '↙',\n lArr: '⇐',\n Leftarrow: '⇐',\n uArr: '⇑',\n Uparrow: '⇑',\n rArr: '⇒',\n Rightarrow: '⇒',\n dArr: '⇓',\n Downarrow: '⇓',\n hArr: '⇔',\n Leftrightarrow: '⇔',\n iff: '⇔',\n vArr: '⇕',\n Updownarrow: '⇕',\n lAarr: '⇚',\n Lleftarrow: '⇚',\n rAarr: '⇛',\n Rrightarrow: '⇛',\n lrarr: '⇆',\n leftrightarrows: '⇆',\n rlarr: '⇄',\n rightleftarrows: '⇄',\n lrhar: '⇋',\n leftrightharpoons: '⇋',\n ReverseEquilibrium: '⇋',\n rlhar: '⇌',\n rightleftharpoons: '⇌',\n Equilibrium: '⇌',\n udarr: '⇅',\n UpArrowDownArrow: '⇅',\n duarr: '⇵',\n DownArrowUpArrow: '⇵',\n llarr: '⇇',\n leftleftarrows: '⇇',\n rrarr: '⇉',\n rightrightarrows: '⇉',\n ddarr: '⇊',\n downdownarrows: '⇊',\n har: '↽',\n lhard: '↽',\n leftharpoondown: '↽',\n lharu: '↼',\n leftharpoonup: '↼',\n rhard: '⇁',\n rightharpoondown: '⇁',\n rharu: '⇀',\n rightharpoonup: '⇀',\n lsh: '↰',\n Lsh: '↰',\n rsh: '↱',\n Rsh: '↱',\n ldsh: '↲',\n rdsh: '↳',\n hookleftarrow: '↩',\n hookrightarrow: '↪',\n mapstoleft: '↤',\n mapstoup: '↥',\n map: '↦',\n mapsto: '↦',\n mapstodown: '↧',\n crarr: '↵',\n nwarrow: '↖',\n nearrow: '↗',\n searrow: '↘',\n swarrow: '↙',\n nleftarrow: '↚',\n nleftrightarrow: '↮',\n nrightarrow: '↛',\n nrarr: '↛',\n larrtl: '↢',\n rarrtl: '↣',\n leftarrowtail: '↢',\n rightarrowtail: '↣',\n twoheadleftarrow: '↞',\n twoheadrightarrow: '↠',\n Larr: '↞',\n Rarr: '↠',\n larrhk: '↩',\n rarrhk: '↪',\n larrlp: '↫',\n looparrowleft: '↫',\n rarrlp: '↬',\n looparrowright: '↬',\n harrw: '↭',\n leftrightsquigarrow: '↭',\n nrarrw: '↝̸',\n rarrw: '↝',\n rightsquigarrow: '↝',\n larrbfs: '⤟',\n rarrbfs: '⤠',\n nvHarr: '⤄',\n nvlArr: '⤂',\n nvrArr: '⤃',\n larrfs: '⤝',\n rarrfs: '⤞',\n Map: '⤅',\n larrsim: '⥳',\n rarrsim: '⥴',\n harrcir: '⥈',\n Uarrocir: '⥉',\n lurdshar: '⥊',\n ldrdhar: '⥧',\n ldrushar: '⥋',\n rdldhar: '⥩',\n lrhard: '⥭',\n rlhar: '⇌',\n uharr: '↾',\n uharl: '↿',\n dharr: '⇂',\n dharl: '⇃',\n Uarr: '↟',\n Darr: '↡',\n zigrarr: '⇝',\n nwArr: '⇖',\n neArr: '⇗',\n seArr: '⇘',\n swArr: '⇙',\n nharr: '↮',\n nhArr: '⇎',\n nlarr: '↚',\n nlArr: '⇍',\n nrarr: '↛',\n nrArr: '⇏',\n larrb: '⇤',\n LeftArrowBar: '⇤',\n rarrb: '⇥',\n RightArrowBar: '⇥',\n};\n\n/**\n * Geometric Shapes\n * @type {Record}\n */\nexport const SHAPES = {\n square: '□',\n Square: '□',\n squ: '□',\n squf: '▪',\n squarf: '▪',\n blacksquar: '▪',\n blacksquare: '▪',\n FilledVerySmallSquare: '▪',\n blk34: '▓',\n blk12: '▒',\n blk14: '░',\n block: '█',\n srect: '▭',\n rect: '▭',\n sdot: '⋅',\n sdotb: '⊡',\n dotsquare: '⊡',\n triangle: '▵',\n tri: '▵',\n trine: '▵',\n utri: '▵',\n triangledown: '▿',\n dtri: '▿',\n tridown: '▿',\n triangleleft: '◃',\n ltri: '◃',\n triangleright: '▹',\n rtri: '▹',\n blacktriangle: '▴',\n utrif: '▴',\n blacktriangledown: '▾',\n dtrif: '▾',\n blacktriangleleft: '◂',\n ltrif: '◂',\n blacktriangleright: '▸',\n rtrif: '▸',\n loz: '◊',\n lozenge: '◊',\n blacklozenge: '⧫',\n lozf: '⧫',\n bigcirc: '◯',\n xcirc: '◯',\n circ: 'ˆ',\n Circle: '○',\n cir: '○',\n o: '○',\n bullet: '•',\n bull: '•',\n hellip: '…',\n mldr: '…',\n nldr: '‥',\n boxh: '─',\n HorizontalLine: '─',\n boxv: '│',\n boxdr: '┌',\n boxdl: '┐',\n boxur: '└',\n boxul: '┘',\n boxvr: '├',\n boxvl: '┤',\n boxhd: '┬',\n boxhu: '┴',\n boxvh: '┼',\n boxH: '═',\n boxV: '║',\n boxdR: '╒',\n boxDr: '╓',\n boxDR: '╔',\n boxDl: '╕',\n boxdL: '╖',\n boxDL: '╗',\n boxuR: '╘',\n boxUr: '╙',\n boxUR: '╚',\n boxUl: '╜',\n boxuL: '╛',\n boxUL: '╝',\n boxvR: '╞',\n boxVr: '╟',\n boxVR: '╠',\n boxVl: '╢',\n boxvL: '╡',\n boxVL: '╣',\n boxHd: '╤',\n boxhD: '╥',\n boxHD: '╦',\n boxHu: '╧',\n boxhU: '╨',\n boxHU: '╩',\n boxvH: '╪',\n boxVh: '╫',\n boxVH: '╬',\n};\n\n/**\n * Punctuation & Diacritics\n * @type {Record}\n */\nexport const PUNCTUATION = {\n excl: '!',\n iexcl: '¡',\n brvbar: '¦',\n sect: '§',\n uml: '¨',\n copy: '©',\n ordf: 'ª',\n laquo: '«',\n not: '¬',\n shy: '\\u00ad',\n reg: '®',\n macr: '¯',\n deg: '°',\n plusmn: '±',\n sup2: '²',\n sup3: '³',\n acute: '´',\n micro: 'µ',\n para: '¶',\n middot: '·',\n cedil: '¸',\n sup1: '¹',\n ordm: 'º',\n raquo: '»',\n frac14: '¼',\n frac12: '½',\n frac34: '¾',\n iquest: '¿',\n nbsp: '\\u00a0',\n comma: ',',\n period: '.',\n colon: ':',\n semi: ';',\n vert: '|',\n Verbar: '‖',\n verbar: '|',\n dblac: '˝',\n circ: 'ˆ',\n caron: 'ˇ',\n breve: '˘',\n dot: '˙',\n ring: '˚',\n ogon: '˛',\n tilde: '˜',\n DiacriticalGrave: '`',\n DiacriticalAcute: '´',\n DiacriticalTilde: '˜',\n DiacriticalDot: '˙',\n DiacriticalDoubleAcute: '˝',\n grave: '`',\n acute: '´',\n};\n\n/**\n * Currency Symbols\n * @type {Record}\n */\nexport const CURRENCY = {\n cent: '¢',\n pound: '£',\n curren: '¤',\n yen: '¥',\n euro: '€',\n dollar: '$',\n euro: '€',\n fnof: 'ƒ',\n inr: '₹',\n af: '؋',\n birr: 'ብር',\n peso: '₱',\n rub: '₽',\n won: '₩',\n yuan: '¥',\n cedil: '¸',\n};\n\n/**\n * Fractions\n * @type {Record}\n */\nexport const FRACTIONS = {\n frac12: '½',\n half: '½',\n frac13: '⅓',\n frac14: '¼',\n frac15: '⅕',\n frac16: '⅙',\n frac18: '⅛',\n frac23: '⅔',\n frac25: '⅖',\n frac34: '¾',\n frac35: '⅗',\n frac38: '⅜',\n frac45: '⅘',\n frac56: '⅚',\n frac58: '⅝',\n frac78: '⅞',\n frasl: '⁄',\n};\n\n/**\n * Miscellaneous Symbols\n * @type {Record}\n */\nexport const MISC_SYMBOLS = {\n trade: '™',\n TRADE: '™',\n telrec: '⌕',\n target: '⌖',\n ulcorn: '⌜',\n ulcorner: '⌜',\n urcorn: '⌝',\n urcorner: '⌝',\n dlcorn: '⌞',\n llcorner: '⌞',\n drcorn: '⌟',\n lrcorner: '⌟',\n intercal: '⊺',\n intcal: '⊺',\n oplus: '⊕',\n CirclePlus: '⊕',\n ominus: '⊖',\n CircleMinus: '⊖',\n otimes: '⊗',\n CircleTimes: '⊗',\n osol: '⊘',\n odot: '⊙',\n CircleDot: '⊙',\n oast: '⊛',\n circledast: '⊛',\n odash: '⊝',\n circleddash: '⊝',\n ocirc: '⊚',\n circledcirc: '⊚',\n boxplus: '⊞',\n plusb: '⊞',\n boxminus: '⊟',\n minusb: '⊟',\n boxtimes: '⊠',\n timesb: '⊠',\n boxdot: '⊡',\n sdotb: '⊡',\n veebar: '⊻',\n vee: '∨',\n barvee: '⊽',\n and: '∧',\n wedge: '∧',\n Cap: '⋒',\n Cup: '⋓',\n Fork: '⋔',\n pitchfork: '⋔',\n epar: '⋕',\n ltlarr: '⥶',\n nvap: '≍⃒',\n nvsim: '∼⃒',\n nvge: '≥⃒',\n nvle: '≤⃒',\n nvlt: '<⃒',\n nvgt: '>⃒',\n nvltrie: '⊴⃒',\n nvrtrie: '⊵⃒',\n Vdash: '⊩',\n dashv: '⊣',\n vDash: '⊨',\n Vdash: '⊩',\n Vvdash: '⊪',\n nvdash: '⊬',\n nvDash: '⊭',\n nVdash: '⊮',\n nVDash: '⊯',\n};\n\n/**\n * All entities combined (if you need everything)\n * @type {Record}\n */\nexport const ALL_ENTITIES = {\n ...BASIC_LATIN,\n ...LATIN_ACCENTS,\n ...LATIN_EXTENDED,\n ...GREEK,\n ...CYRILLIC,\n ...MATH,\n ...MATH_ADVANCED,\n ...ARROWS,\n ...SHAPES,\n ...PUNCTUATION,\n ...CURRENCY,\n ...FRACTIONS,\n ...MISC_SYMBOLS,\n};\n\nexport const XML = {\n amp: \"&\",\n apos: \"'\",\n gt: \">\",\n lt: \"<\",\n quot: \"\\\"\"\n}\nexport const COMMON_HTML = {\n nbsp: '\\u00a0',\n copy: '\\u00a9',\n reg: '\\u00ae',\n trade: '\\u2122',\n mdash: '\\u2014',\n ndash: '\\u2013',\n hellip: '\\u2026',\n laquo: '\\u00ab',\n raquo: '\\u00bb',\n lsquo: '\\u2018',\n rsquo: '\\u2019',\n ldquo: '\\u201c',\n rdquo: '\\u201d',\n bull: '\\u2022',\n para: '\\u00b6',\n sect: '\\u00a7',\n deg: '\\u00b0',\n frac12: '\\u00bd',\n frac14: '\\u00bc',\n frac34: '\\u00be',\n}\n// ---------------------------------------------------------------------------\n// Note: NUMERIC_ENTITIES (&#NNN; / &#xHH;) are handled by the scanner directly\n// via String.fromCodePoint() without any map lookup.\n// ---------------------------------------------------------------------------","// ---------------------------------------------------------------------------\n// Built-in named entity map (name → replacement string)\n// No regex, no {regex,val} objects — just flat key/value pairs.\n// ---------------------------------------------------------------------------\n\nimport { XML as DEFAULT_XML_ENTITIES } from \"./entities.js\"\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst SPECIAL_CHARS = new Set('!?\\\\\\\\/[]$%{}^&*()<>|+');\n\n/**\n * Validate that an entity name contains no dangerous characters.\n * @param {string} name\n * @returns {string} the name, unchanged\n * @throws {Error} on invalid characters\n */\nfunction validateEntityName(name) {\n if (name[0] === '#') {\n throw new Error(`[EntityReplacer] Invalid character '#' in entity name: \"${name}\"`);\n }\n for (const ch of name) {\n if (SPECIAL_CHARS.has(ch)) {\n throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: \"${name}\"`);\n }\n }\n return name;\n}\n\n/**\n * Merge one or more entity maps into a flat name→string map.\n * Accepts either:\n * - plain string values: { amp: '&' }\n * - legacy {regex,val} / {regx,val}: { lt: { regex: /.../, val: '<' } }\n *\n * Values containing '&' are skipped (recursive expansion risk).\n *\n * @param {...object} maps\n * @returns {Record}\n */\nfunction mergeEntityMaps(...maps) {\n const out = Object.create(null);\n for (const map of maps) {\n if (!map) continue;\n for (const key of Object.keys(map)) {\n const raw = map[key];\n if (typeof raw === 'string') {\n out[key] = raw;\n } else if (raw && typeof raw === 'object' && raw.val !== undefined) {\n // Legacy {regex,val} or {regx,val} — extract the string val only\n const val = raw.val;\n if (typeof val === 'string') {\n out[key] = val;\n }\n // function vals are not supported in the scanner — skip\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// applyLimitsTo helpers\n// ---------------------------------------------------------------------------\n\nconst LIMIT_TIER_EXTERNAL = 'external'; // input/runtime + persistent external maps\nconst LIMIT_TIER_BASE = 'base'; // DEFAULT_XML_ENTITIES + namedEntities (system) maps\nconst LIMIT_TIER_ALL = 'all'; // every entity regardless of tier\n\n/**\n * Resolve `applyLimitsTo` option into a normalised Set of tier strings.\n * Accepted values: 'external' | 'base' | 'all' | string[]\n * Default: 'external' (only untrusted injected entities are counted).\n * @param {string|string[]|undefined} raw\n * @returns {Set}\n */\nfunction parseLimitTiers(raw) {\n if (!raw || raw === LIMIT_TIER_EXTERNAL) return new Set([LIMIT_TIER_EXTERNAL]);\n if (raw === LIMIT_TIER_ALL) return new Set([LIMIT_TIER_ALL]);\n if (raw === LIMIT_TIER_BASE) return new Set([LIMIT_TIER_BASE]);\n if (Array.isArray(raw)) return new Set(raw);\n return new Set([LIMIT_TIER_EXTERNAL]); // safe default for unrecognised values\n}\n\n// ---------------------------------------------------------------------------\n// NCR (Numeric Character Reference) classification\n// ---------------------------------------------------------------------------\n\n// Severity order — higher number = stricter action.\n// Used to enforce minimum action levels for specific codepoint ranges.\nconst NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 });\n\n// XML 1.0 §2.2: allowed chars are #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n// Restricted C0: U+0001–U+001F excluding U+0009, U+000A, U+000D\nconst XML10_ALLOWED_C0 = new Set([0x09, 0x0A, 0x0D]);\n\n/**\n * Parse the `ncr` constructor option into flat, hot-path-friendly fields.\n * @param {object|undefined} ncr\n * @returns {{ xmlVersion: number, onLevel: number, nullLevel: number }}\n */\nfunction parseNCRConfig(ncr) {\n if (!ncr) {\n return { xmlVersion: 1.0, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove };\n }\n const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1.0;\n const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow;\n const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove;\n // 'allow' is not meaningful for null — clamp to at least 'remove'\n const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove);\n return { xmlVersion, onLevel, nullLevel: clampedNull };\n}\n\n// ---------------------------------------------------------------------------\n// EntityReplacer\n// ---------------------------------------------------------------------------\n\n/**\n * Single-pass, zero-regex entity replacer for XML/HTML content.\n *\n * Algorithm: scan the string once for '&', read to ';', resolve via map\n * or direct codepoint conversion, build output chunks, join once at the end.\n *\n * Entity lookup priority (highest → lowest):\n * 1. input / runtime (DOCTYPE entities for current document)\n * 2. persistent external (survive across documents)\n * 3. base named map (DEFAULT_XML_ENTITIES + user-supplied namedEntities)\n *\n * Both input and external resolve as the 'external' tier for limit purposes.\n * Base map entities resolve as the 'base' tier.\n *\n * Numeric / hex references (&#NNN; / &#xHH;) are resolved directly via\n * String.fromCodePoint() — no map needed. They count as 'base' tier.\n *\n * @example\n * const replacer = new EntityReplacer({ namedEntities: COMMON_HTML });\n * replacer.setExternalEntities({ brand: 'Acme' });\n *\n * const instance = replacer.reset();\n * instance.addInputEntities({ version: '1.0' });\n * instance.encode('&brand; v&version; <'); // 'Acme v1.0 <'\n */\nexport default class EntityDecoder {\n /**\n * @param {object} [options]\n * @param {object|null} [options.namedEntities] — extra named entities merged into base map\n * @param {object} [options.limit] — security limits\n * @param {number} [options.limit.maxTotalExpansions=0] — 0 = unlimited\n * @param {number} [options.limit.maxExpandedLength=0] — 0 = unlimited\n * @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external']\n * Which entity tiers count against the security limits:\n * - 'external' (default) — only input/runtime + persistent external entities\n * - 'base' — only DEFAULT_XML_ENTITIES + namedEntities\n * - 'all' — every entity regardless of tier\n * - string[] — explicit combination, e.g. ['external', 'base']\n * @param {((resolved: string, original: string) => string)|null} [options.postCheck=null]\n * @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string)\n * @param {string[]} [options.leave=[]] — entity names to keep as literal (unchanged in output)\n * @param {object} [options.ncr] — Numeric Character Reference controls\n * @param {1.0|1.1} [options.ncr.xmlVersion=1.0]\n * XML version governing which codepoint ranges are restricted:\n * - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited\n * - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is\n * @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow']\n * Base action for numeric references. Severity order: allow < leave < remove < throw.\n * For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove),\n * the effective action is max(onNCR, rangeMinimum).\n * @param {'remove'|'throw'} [options.ncr.nullNCR='remove']\n * Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe.\n */\n constructor(options = {}) {\n this._limit = options.limit || {};\n this._maxTotalExpansions = this._limit.maxTotalExpansions || 0;\n this._maxExpandedLength = this._limit.maxExpandedLength || 0;\n this._postCheck = typeof options.postCheck === 'function' ? options.postCheck : r => r;\n this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL);\n this._numericAllowed = options.numericAllowed ?? true;\n // Base map: DEFAULT_XML_ENTITIES + user-supplied extras. Immutable after construction.\n this._baseMap = mergeEntityMaps(DEFAULT_XML_ENTITIES, options.namedEntities || null);\n\n // Persistent external entities — survive across documents.\n // Stored as a separate map so reset() never touches them.\n /** @type {Record} */\n this._externalMap = Object.create(null);\n\n // Input / runtime entities — current document only, wiped on reset().\n /** @type {Record} */\n this._inputMap = Object.create(null);\n\n // Per-document counters\n this._totalExpansions = 0;\n this._expandedLength = 0;\n\n // --- New: remove / leave sets ---\n /** @type {Set} */\n this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []);\n /** @type {Set} */\n this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []);\n\n // --- NCR config (parsed into flat fields for hot-path speed) ---\n const ncrCfg = parseNCRConfig(options.ncr);\n this._ncrXmlVersion = ncrCfg.xmlVersion;\n this._ncrOnLevel = ncrCfg.onLevel;\n this._ncrNullLevel = ncrCfg.nullLevel;\n }\n\n // -------------------------------------------------------------------------\n // Persistent external entity registration\n // -------------------------------------------------------------------------\n\n /**\n * Replace the full set of persistent external entities.\n * All keys are validated — throws on invalid characters.\n * @param {Record} map\n */\n setExternalEntities(map) {\n if (map) {\n for (const key of Object.keys(map)) {\n validateEntityName(key);\n }\n }\n this._externalMap = mergeEntityMaps(map);\n }\n\n /**\n * Add a single persistent external entity.\n * @param {string} key\n * @param {string} value\n */\n addExternalEntity(key, value) {\n validateEntityName(key);\n if (typeof value === 'string' && value.indexOf('&') === -1) {\n this._externalMap[key] = value;\n }\n }\n\n // -------------------------------------------------------------------------\n // Input / runtime entity registration (per document)\n // -------------------------------------------------------------------------\n\n /**\n * Inject DOCTYPE entities for the current document.\n * Also resets per-document expansion counters.\n * @param {Record} map\n */\n addInputEntities(map) {\n this._totalExpansions = 0;\n this._expandedLength = 0;\n this._inputMap = mergeEntityMaps(map);\n }\n\n // -------------------------------------------------------------------------\n // Per-document reset\n // -------------------------------------------------------------------------\n\n /**\n * Wipe input/runtime entities and reset counters.\n * Call this before processing each new document.\n * @returns {this}\n */\n reset() {\n this._inputMap = Object.create(null);\n this._totalExpansions = 0;\n this._expandedLength = 0;\n return this;\n }\n\n // -------------------------------------------------------------------------\n // XML version (can be set after construction, e.g. once parser reads )\n // -------------------------------------------------------------------------\n\n /**\n * Update the XML version used for NCR classification.\n * Call this as soon as the document's `` declaration is parsed.\n * @param {1.0|1.1|number} version\n */\n setXmlVersion(version) {\n this._ncrXmlVersion = version === 1.1 ? 1.1 : 1.0;\n }\n\n // -------------------------------------------------------------------------\n // Primary API\n // -------------------------------------------------------------------------\n\n /**\n * Replace all entity references in `str` in a single pass.\n *\n * @param {string} str\n * @returns {string}\n */\n decode(str) {\n if (typeof str !== 'string' || str.length === 0) return str;\n //TODO: check if needed\n //if (str.indexOf('&') === -1) return str; // fast path — no entities at all\n\n const original = str;\n const chunks = [];\n const len = str.length;\n let last = 0; // start of next unprocessed literal chunk\n let i = 0;\n\n const limitExpansions = this._maxTotalExpansions > 0;\n const limitLength = this._maxExpandedLength > 0;\n const checkLimits = limitExpansions || limitLength;\n\n while (i < len) {\n // Scan forward to next '&'\n if (str.charCodeAt(i) !== 38 /* '&' */) { i++; continue; }\n\n // --- Found '&' at position i ---\n\n // Scan forward to ';'\n let j = i + 1;\n while (j < len && str.charCodeAt(j) !== 59 /* ';' */ && (j - i) <= 32) j++;\n\n if (j >= len || str.charCodeAt(j) !== 59) {\n // No closing ';' within window — treat '&' as literal\n i++;\n continue;\n }\n\n // Raw token between '&' and ';' (exclusive)\n const token = str.slice(i + 1, j);\n if (token.length === 0) { i++; continue; }\n\n let replacement;\n let tier; // which limit tier this entity belongs to\n\n if (this._removeSet.has(token)) {\n // Remove entity: replace with empty string\n replacement = '';\n // If entity was unknown (replacement undefined), we still need a tier for limits.\n // Treat as external tier because it's user-directed removal of an unknown reference.\n if (tier === undefined) {\n tier = LIMIT_TIER_EXTERNAL;\n }\n } else if (this._leaveSet.has(token)) {\n // Do not replace — keep original &token; as literal\n i++;\n continue;\n } else if (token.charCodeAt(0) === 35 /* '#' */) {\n // ---- Numeric / NCR reference ----\n // NCR classification always runs first — prohibited codepoints must be\n // caught regardless of numericAllowed.\n const ncrResult = this._resolveNCR(token);\n if (ncrResult === undefined) {\n // 'leave' action — keep original &token; as-is\n i++;\n continue;\n }\n replacement = ncrResult; // '' for remove, char string for allow\n tier = LIMIT_TIER_BASE;\n } else {\n // ---- Named reference ----\n const resolved = this._resolveName(token);\n replacement = resolved?.value;\n tier = resolved?.tier;\n }\n\n if (replacement === undefined) {\n // Unknown entity — leave as-is, advance past '&' only\n i++;\n continue;\n }\n\n // Flush literal chunk before this entity\n if (i > last) chunks.push(str.slice(last, i));\n chunks.push(replacement);\n last = j + 1; // skip past ';'\n i = last;\n\n // Apply expansion limits only if this tier is being tracked\n if (checkLimits && this._tierCounts(tier)) {\n if (limitExpansions) {\n this._totalExpansions++;\n if (this._totalExpansions > this._maxTotalExpansions) {\n throw new Error(\n `[EntityReplacer] Entity expansion count limit exceeded: ` +\n `${this._totalExpansions} > ${this._maxTotalExpansions}`\n );\n }\n }\n if (limitLength) {\n // delta: replacement.length minus the raw &token; length (token.length + 2 for '&' and ';')\n const delta = replacement.length - (token.length + 2);\n if (delta > 0) {\n this._expandedLength += delta;\n if (this._expandedLength > this._maxExpandedLength) {\n throw new Error(\n `[EntityReplacer] Expanded content length limit exceeded: ` +\n `${this._expandedLength} > ${this._maxExpandedLength}`\n );\n }\n }\n }\n }\n }\n\n // Flush trailing literal\n if (last < len) chunks.push(str.slice(last));\n\n // If nothing was replaced, chunks is empty — return original\n const result = chunks.length === 0 ? str : chunks.join('');\n\n return this._postCheck(result, original);\n }\n\n // -------------------------------------------------------------------------\n // Private: limit tier check\n // -------------------------------------------------------------------------\n\n /**\n * Returns true if a resolved entity of the given tier should count\n * against the expansion/length limits.\n * @param {string} tier — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE\n * @returns {boolean}\n */\n _tierCounts(tier) {\n if (this._limitTiers.has(LIMIT_TIER_ALL)) return true;\n return this._limitTiers.has(tier);\n }\n\n // -------------------------------------------------------------------------\n // Private: entity resolution\n // -------------------------------------------------------------------------\n\n /**\n * Resolve a named entity token (without & and ;).\n * Priority: inputMap > externalMap > baseMap\n * Returns the resolved value tagged with its limit tier.\n *\n * @param {string} name\n * @returns {{ value: string, tier: string }|undefined}\n */\n _resolveName(name) {\n // input and external both count as 'external' tier for limit purposes —\n // they are injected at runtime and are the untrusted surface.\n if (name in this._inputMap) return { value: this._inputMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._externalMap) return { value: this._externalMap[name], tier: LIMIT_TIER_EXTERNAL };\n if (name in this._baseMap) return { value: this._baseMap[name], tier: LIMIT_TIER_BASE };\n return undefined;\n }\n\n /**\n * Classify a codepoint and return the minimum action level that must be applied.\n * Returns -1 when no minimum is imposed (normal allow path).\n *\n * Ranges checked (in priority order):\n * 1. U+0000 — null, governed by nullNCR (always ≥ remove)\n * 2. U+D800–U+DFFF — surrogates, always prohibited (min: remove)\n * 3. U+0001–U+001F \\ {0x09,0x0A,0x0D} — XML 1.0 restricted C0 (min: remove)\n * (skipped in XML 1.1 — C0 controls are allowed when written as NCRs)\n *\n * @param {number} cp — codepoint\n * @returns {number} — minimum NCR_LEVEL value, or -1 for no restriction\n */\n _classifyNCR(cp) {\n // 1. Null\n if (cp === 0) return this._ncrNullLevel;\n\n // 2. Surrogates — always prohibited, minimum 'remove'\n if (cp >= 0xD800 && cp <= 0xDFFF) return NCR_LEVEL.remove;\n\n // 3. XML 1.0 restricted C0 controls\n if (this._ncrXmlVersion === 1.0) {\n if (cp >= 0x01 && cp <= 0x1F && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove;\n }\n\n return -1; // no restriction\n }\n\n /**\n * Execute a resolved NCR action.\n *\n * @param {number} action — NCR_LEVEL value\n * @param {string} token — raw token (e.g. '#38') for error messages\n * @param {number} cp — codepoint, used only for error messages\n * @returns {string|undefined}\n * - decoded character string → 'allow'\n * - '' → 'remove'\n * - undefined → 'leave' (caller must skip past '&' only)\n * - throws Error → 'throw'\n */\n _applyNCRAction(action, token, cp) {\n switch (action) {\n case NCR_LEVEL.allow: return String.fromCodePoint(cp);\n case NCR_LEVEL.remove: return '';\n case NCR_LEVEL.leave: return undefined; // signal: keep literal\n case NCR_LEVEL.throw:\n throw new Error(\n `[EntityDecoder] Prohibited numeric character reference ` +\n `&${token}; (U+${cp.toString(16).toUpperCase().padStart(4, '0')})`\n );\n default: return String.fromCodePoint(cp);\n }\n }\n\n /**\n * Full NCR resolution pipeline for a numeric token.\n *\n * Steps:\n * 1. Parse the codepoint (decimal or hex).\n * 2. Validate the raw codepoint range (NaN, <0, >0x10FFFF).\n * 3. If numericAllowed is false and no minimum restriction applies → leave as-is.\n * 4. Classify the codepoint to find the minimum required action level.\n * 5. Resolve effective action = max(onNCR, minimum).\n * 6. Apply and return.\n *\n * @param {string} token — e.g. '#38', '#x26', '#X26'\n * @returns {string|undefined}\n * - string (incl. '') — replacement ('' = remove)\n * - undefined — leave original &token; as-is\n */\n _resolveNCR(token) {\n // Step 1: parse codepoint\n const second = token.charCodeAt(1);\n let cp;\n if (second === 120 /* x */ || second === 88 /* X */) {\n cp = parseInt(token.slice(2), 16);\n } else {\n cp = parseInt(token.slice(1), 10);\n }\n\n // Step 2: out-of-range → leave as-is unconditionally\n if (Number.isNaN(cp) || cp < 0 || cp > 0x10FFFF) return undefined;\n\n // Step 3: classify to get minimum action level\n const minimum = this._classifyNCR(cp);\n\n // Step 4: if numericAllowed is false and no hard minimum → leave\n if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return undefined;\n\n // Step 5: effective action = max(configured onNCR, range minimum)\n const effective = minimum === -1\n ? this._ncrOnLevel\n : Math.max(this._ncrOnLevel, minimum);\n\n // Step 6: apply\n return this._applyNCRAction(effective, token, cp);\n }\n}","'use strict';\n///@ts-check\n\nimport { getAllMatches, isExist, DANGEROUS_PROPERTY_NAMES, criticalProperties } from '../util.js';\nimport xmlNode from './xmlNode.js';\nimport DocTypeReader from './DocTypeReader.js';\nimport toNumber from \"strnum\";\nimport getIgnoreAttributesFn from \"../ignoreAttributes.js\";\nimport { Expression, Matcher } from 'path-expression-matcher';\nimport { ExpressionSet } from 'path-expression-matcher';\nimport { EntityDecoder, XML, CURRENCY, COMMON_HTML } from '@nodable/entities';\n\n// const regx =\n// '<((!\\\\[CDATA\\\\[([\\\\s\\\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\\\/)(NAME)\\\\s*>))([^<]*)'\n// .replace(/NAME/g, util.nameRegexp);\n\n//const tagsRegx = new RegExp(\"<(\\\\/?[\\\\w:\\\\-\\._]+)([^>]*)>(\\\\s*\"+cdataRegx+\")*([^<]+)?\",\"g\");\n//const tagsRegx = new RegExp(\"<(\\\\/?)((\\\\w*:)?([\\\\w:\\\\-\\._]+))([^>]*)>([^<]*)(\"+cdataRegx+\"([^<]*))*([^<]+)?\",\"g\");\n\n// Helper functions for attribute and namespace handling\n\n/**\n * Extract raw attributes (without prefix) from prefixed attribute map\n * @param {object} prefixedAttrs - Attributes with prefix from buildAttributesMap\n * @param {object} options - Parser options containing attributeNamePrefix\n * @returns {object} Raw attributes for matcher\n */\nfunction extractRawAttributes(prefixedAttrs, options) {\n if (!prefixedAttrs) return {};\n\n // Handle attributesGroupName option\n const attrs = options.attributesGroupName\n ? prefixedAttrs[options.attributesGroupName]\n : prefixedAttrs;\n\n if (!attrs) return {};\n\n const rawAttrs = {};\n for (const key in attrs) {\n // Remove the attribute prefix to get raw name\n if (key.startsWith(options.attributeNamePrefix)) {\n const rawName = key.substring(options.attributeNamePrefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * Extract namespace from raw tag name\n * @param {string} rawTagName - Tag name possibly with namespace (e.g., \"soap:Envelope\")\n * @returns {string|undefined} Namespace or undefined\n */\nfunction extractNamespace(rawTagName) {\n if (!rawTagName || typeof rawTagName !== 'string') return undefined;\n\n const colonIndex = rawTagName.indexOf(':');\n if (colonIndex !== -1 && colonIndex > 0) {\n const ns = rawTagName.substring(0, colonIndex);\n // Don't treat xmlns as a namespace\n if (ns !== 'xmlns') {\n return ns;\n }\n }\n return undefined;\n}\n\nexport default class OrderedObjParser {\n constructor(options) {\n this.options = options;\n this.currentNode = null;\n this.tagsNodeStack = [];\n this.parseXml = parseXml;\n this.parseTextData = parseTextData;\n this.resolveNameSpace = resolveNameSpace;\n this.buildAttributesMap = buildAttributesMap;\n this.isItStopNode = isItStopNode;\n this.replaceEntitiesValue = replaceEntitiesValue;\n this.readStopNodeData = readStopNodeData;\n this.saveTextToParentTag = saveTextToParentTag;\n this.addChild = addChild;\n this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes)\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n let namedEntities = { ...XML };\n if (this.options.entityDecoder) {\n this.entityDecoder = this.options.entityDecoder\n } else {\n if (typeof this.options.htmlEntities === \"object\") namedEntities = this.options.htmlEntities;\n else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };\n this.entityDecoder = new EntityDecoder({\n namedEntities: namedEntities,\n numericAllowed: this.options.htmlEntities,\n limit: {\n maxTotalExpansions: this.options.processEntities.maxTotalExpansions,\n maxExpandedLength: this.options.processEntities.maxExpandedLength,\n applyLimitsTo: this.options.processEntities.appliesTo,\n }\n //postCheck: resolved => resolved\n });\n }\n\n // Initialize path matcher for path-expression-matcher\n this.matcher = new Matcher();\n\n // Live read-only proxy of matcher — PEM creates and caches this internally.\n // All user callbacks receive this instead of the mutable matcher.\n this.readonlyMatcher = this.matcher.readOnly();\n\n // Flag to track if current node is a stop node (optimization)\n this.isCurrentNodeStopNode = false;\n\n // Pre-compile stopNodes expressions\n this.stopNodeExpressionsSet = new ExpressionSet();\n const stopNodesOpts = this.options.stopNodes;\n if (stopNodesOpts && stopNodesOpts.length > 0) {\n for (let i = 0; i < stopNodesOpts.length; i++) {\n const stopNodeExp = stopNodesOpts[i];\n if (typeof stopNodeExp === 'string') {\n // Convert string to Expression object\n this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));\n } else if (stopNodeExp instanceof Expression) {\n // Already an Expression object\n this.stopNodeExpressionsSet.add(stopNodeExp);\n }\n }\n this.stopNodeExpressionsSet.seal();\n }\n }\n\n}\n\n\n/**\n * @param {string} val\n * @param {string} tagName\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n * @param {boolean} dontTrim\n * @param {boolean} hasAttributes\n * @param {boolean} isLeafNode\n * @param {boolean} escapeEntities\n */\nfunction parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {\n const options = this.options;\n if (val !== undefined) {\n if (options.trimValues && !dontTrim) {\n val = val.trim();\n }\n if (val.length > 0) {\n if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;\n const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);\n if (newval === null || newval === undefined) {\n //don't parse\n return val;\n } else if (typeof newval !== typeof val || newval !== val) {\n //overwrite\n return newval;\n } else if (options.trimValues) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n const trimmedVal = val.trim();\n if (trimmedVal === val) {\n return parseValue(val, options.parseTagValue, options.numberParseOptions);\n } else {\n return val;\n }\n }\n }\n }\n}\n\nfunction resolveNameSpace(tagname) {\n if (this.options.removeNSPrefix) {\n const tags = tagname.split(':');\n const prefix = tagname.charAt(0) === '/' ? '/' : '';\n if (tags[0] === 'xmlns') {\n return '';\n }\n if (tags.length === 2) {\n tagname = prefix + tags[1];\n }\n }\n return tagname;\n}\n\n//TODO: change regex to capture NS\n//const attrsRegx = new RegExp(\"([\\\\w\\\\-\\\\.\\\\:]+)\\\\s*=\\\\s*(['\\\"])((.|\\n)*?)\\\\2\",\"gm\");\nconst attrsRegx = new RegExp('([^\\\\s=]+)\\\\s*(=\\\\s*([\\'\"])([\\\\s\\\\S]*?)\\\\3)?', 'gm');\n\nfunction buildAttributesMap(attrStr, jPath, tagName, force = false) {\n const options = this.options;\n if (force === true || (options.ignoreAttributes !== true && typeof attrStr === 'string')) {\n // attrStr = attrStr.replace(/\\r?\\n/g, ' ');\n //attrStr = attrStr || attrStr.trim();\n\n const matches = getAllMatches(attrStr, attrsRegx);\n const len = matches.length; //don't make it inline\n const attrs = {};\n\n // Pre-process values once: trim + entity replacement\n // Reused in both matcher update and second pass\n const processedVals = new Array(len);\n let hasRawAttrs = false;\n const rawAttrsForMatcher = {};\n\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n const oldVal = matches[i][4];\n\n if (attrName.length && oldVal !== undefined) {\n let val = oldVal;\n if (options.trimValues) val = val.trim();\n val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);\n processedVals[i] = val;\n\n rawAttrsForMatcher[attrName] = val;\n hasRawAttrs = true;\n }\n }\n\n // Update matcher ONCE before second pass, if applicable\n if (hasRawAttrs && typeof jPath === 'object' && jPath.updateCurrent) {\n jPath.updateCurrent(rawAttrsForMatcher);\n }\n\n // Hoist toString() once — path doesn't change during attribute processing\n const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;\n\n // Second pass: apply processors, build final attrs\n let hasAttrs = false;\n for (let i = 0; i < len; i++) {\n const attrName = this.resolveNameSpace(matches[i][1]);\n\n if (this.ignoreAttributesFn(attrName, jPathStr)) continue;\n\n let aName = options.attributeNamePrefix + attrName;\n\n if (attrName.length) {\n if (options.transformAttributeName) {\n aName = options.transformAttributeName(aName);\n }\n aName = sanitizeName(aName, options);\n\n if (matches[i][4] !== undefined) {\n // Reuse already-processed value — no double entity replacement\n const oldVal = processedVals[i];\n\n const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);\n if (newVal === null || newVal === undefined) {\n attrs[aName] = oldVal;\n } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {\n attrs[aName] = newVal;\n } else {\n attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);\n }\n hasAttrs = true;\n } else if (options.allowBooleanAttributes) {\n attrs[aName] = true;\n hasAttrs = true;\n }\n }\n }\n\n if (!hasAttrs) return;\n\n if (options.attributesGroupName) {\n const attrCollection = {};\n attrCollection[options.attributesGroupName] = attrs;\n return attrCollection;\n }\n return attrs;\n }\n}\nconst parseXml = function (xmlData) {\n xmlData = xmlData.replace(/\\r\\n?/g, \"\\n\"); //TODO: remove this line\n const xmlObj = new xmlNode('!xml');\n let currentNode = xmlObj;\n let textData = \"\";\n\n // Reset matcher for new document\n this.matcher.reset();\n this.entityDecoder.reset();\n\n // Reset entity expansion counters for this document\n this.entityExpansionCount = 0;\n this.currentExpandedLength = 0;\n const options = this.options;\n const docTypeReader = new DocTypeReader(options.processEntities);\n const xmlLen = xmlData.length;\n for (let i = 0; i < xmlLen; i++) {//for each char in XML data\n const ch = xmlData[i];\n if (ch === '<') {\n // const nextIndex = i+1;\n // const _2ndChar = xmlData[nextIndex];\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//Closing Tag '/'\n const closeIndex = findClosingIndex(xmlData, \">\", i, \"Closing Tag is not closed.\")\n let tagName = xmlData.substring(i + 2, closeIndex).trim();\n\n if (options.removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n }\n }\n\n tagName = transformTagName(options.transformTagName, tagName, \"\", options).tagName;\n\n if (currentNode) {\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n }\n\n //check if last tag of nested tag was unpaired tag\n const lastTagName = this.matcher.getCurrentTag();\n if (tagName && options.unpairedTagsSet.has(tagName)) {\n throw new Error(`Unpaired tag can not be used as closing tag: `);\n }\n if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {\n // Pop the unpaired tag\n this.matcher.pop();\n this.tagsNodeStack.pop();\n }\n // Pop the closing tag\n this.matcher.pop();\n this.isCurrentNodeStopNode = false; // Reset flag when closing tag\n\n currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope\n textData = \"\";\n i = closeIndex;\n } else if (c1 === 63) { //'?'\n\n let tagData = readTagExp(xmlData, i, false, \"?>\");\n if (!tagData) throw new Error(\"Pi Tag is not closed.\");\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);\n if (attsMap) {\n const ver = attsMap[this.options.attributeNamePrefix + \"version\"];\n this.entityDecoder.setXmlVersion(Number(ver) || 1.0);\n }\n if ((options.ignoreDeclaration && tagData.tagName === \"?xml\") || options.ignorePiTags) {\n //do nothing\n } else {\n\n const childNode = new xmlNode(tagData.tagName);\n childNode.add(options.textNodeName, \"\");\n\n if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) {\n childNode[\":@\"] = attsMap\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, i);\n }\n\n\n i = tagData.closeIndex + 1;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { //'!--'\n const endIndex = findClosingIndex(xmlData, \"-->\", i + 4, \"Comment is not closed.\")\n if (options.commentPropName) {\n const comment = xmlData.substring(i + 4, endIndex - 2);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);\n }\n i = endIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 68) { //'!D'\n const result = docTypeReader.readDocType(xmlData, i);\n this.entityDecoder.addInputEntities(result.entities);\n i = result.i;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"CDATA is not closed.\") - 2;\n const tagExp = xmlData.substring(i + 9, closeIndex);\n\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);\n\n let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);\n if (val == undefined) val = \"\";\n\n //cdata should be set even if it is 0 length string\n if (options.cdataPropName) {\n currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);\n } else {\n currentNode.add(options.textNodeName, val);\n }\n\n i = closeIndex + 2;\n } else {//Opening tag\n let result = readTagExp(xmlData, i, options.removeNSPrefix);\n\n // Safety check: readTagExp can return undefined\n if (!result) {\n // Log context for debugging\n const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));\n throw new Error(`readTagExp returned undefined at position ${i}. Context: \"${context}\"`);\n }\n\n let tagName = result.tagName;\n const rawTagName = result.rawTagName;\n let tagExp = result.tagExp;\n let attrExpPresent = result.attrExpPresent;\n let closeIndex = result.closeIndex;\n\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n if (options.strictReservedNames &&\n (tagName === options.commentPropName\n || tagName === options.cdataPropName\n || tagName === options.textNodeName\n || tagName === options.attributesGroupName\n )) {\n throw new Error(`Invalid tag name: ${tagName}`);\n }\n\n //save text as child node\n if (currentNode && textData) {\n if (currentNode.tagname !== '!xml') {\n //when nested tag is found\n textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);\n }\n }\n\n //check if last tag was unpaired tag\n const lastTag = currentNode;\n if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {\n currentNode = this.tagsNodeStack.pop();\n this.matcher.pop();\n }\n\n // Clean up self-closing syntax BEFORE processing attributes\n // This is where tagExp gets the trailing / removed\n let isSelfClosing = false;\n if (tagExp.length > 0 && tagExp.lastIndexOf(\"/\") === tagExp.length - 1) {\n isSelfClosing = true;\n if (tagName[tagName.length - 1] === \"/\") {\n tagName = tagName.substr(0, tagName.length - 1);\n tagExp = tagName;\n } else {\n tagExp = tagExp.substr(0, tagExp.length - 1);\n }\n\n // Re-check attrExpPresent after cleaning\n attrExpPresent = (tagName !== tagExp);\n }\n\n // Now process attributes with CLEAN tagExp (no trailing /)\n let prefixedAttrs = null;\n let rawAttrs = {};\n let namespace = undefined;\n\n // Extract namespace from rawTagName\n namespace = extractNamespace(rawTagName);\n\n // Push tag to matcher FIRST (with empty attrs for now) so callbacks see correct path\n if (tagName !== xmlObj.tagname) {\n this.matcher.push(tagName, {}, namespace);\n }\n\n // Now build attributes - callbacks will see correct matcher state\n if (tagName !== tagExp && attrExpPresent) {\n // Build attributes (returns prefixed attributes for the tree)\n // Note: buildAttributesMap now internally updates the matcher with raw attributes\n prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);\n\n if (prefixedAttrs) {\n // Extract raw attributes (without prefix) for our use\n //TODO: seems a performance overhead\n rawAttrs = extractRawAttributes(prefixedAttrs, options);\n }\n }\n\n // Now check if this is a stop node (after attributes are set)\n if (tagName !== xmlObj.tagname) {\n this.isCurrentNodeStopNode = this.isItStopNode();\n }\n\n const startIndex = i;\n if (this.isCurrentNodeStopNode) {\n let tagContent = \"\";\n\n // For self-closing tags, content is empty\n if (isSelfClosing) {\n i = result.closeIndex;\n }\n //unpaired tag\n else if (options.unpairedTagsSet.has(tagName)) {\n i = result.closeIndex;\n }\n //normal tag\n else {\n //read until closing tag is found\n const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);\n if (!result) throw new Error(`Unexpected end of ${rawTagName}`);\n i = result.i;\n tagContent = result.tagContent;\n }\n\n const childNode = new xmlNode(tagName);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n\n // For stop nodes, store raw content as-is without any processing\n childNode.add(options.textNodeName, tagContent);\n\n this.matcher.pop(); // Pop the stop node tag\n this.isCurrentNodeStopNode = false; // Reset flag\n\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n } else {\n //selfClosing tag\n if (isSelfClosing) {\n ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));\n\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n this.matcher.pop(); // Pop self-closing tag\n this.isCurrentNodeStopNode = false; // Reset flag\n }\n else if (options.unpairedTagsSet.has(tagName)) {//unpaired tag\n const childNode = new xmlNode(tagName);\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n this.matcher.pop(); // Pop unpaired tag\n this.isCurrentNodeStopNode = false; // Reset flag\n i = result.closeIndex;\n // Continue to next iteration without changing currentNode\n continue;\n }\n //opening tag\n else {\n const childNode = new xmlNode(tagName);\n if (this.tagsNodeStack.length > options.maxNestedTags) {\n throw new Error(\"Maximum nested tags exceeded\");\n }\n this.tagsNodeStack.push(currentNode);\n\n if (prefixedAttrs) {\n childNode[\":@\"] = prefixedAttrs;\n }\n this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);\n currentNode = childNode;\n }\n textData = \"\";\n i = closeIndex;\n }\n }\n } else {\n textData += xmlData[i];\n }\n }\n return xmlObj.child;\n}\n\nfunction addChild(currentNode, childNode, matcher, startIndex) {\n // unset startIndex if not requested\n if (!this.options.captureMetaData) startIndex = undefined;\n\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;\n const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[\":@\"])\n if (result === false) {\n //do nothing\n } else if (typeof result === \"string\") {\n childNode.tagname = result\n currentNode.addChild(childNode, startIndex);\n } else {\n currentNode.addChild(childNode, startIndex);\n }\n}\n\n/**\n * @param {object} val - Entity object with regex and val properties\n * @param {string} tagName - Tag name\n * @param {string|Matcher} jPath - jPath string or Matcher instance based on options.jPath\n */\nfunction replaceEntitiesValue(val, tagName, jPath) {\n const entityConfig = this.options.processEntities;\n\n if (!entityConfig || !entityConfig.enabled) {\n return val;\n }\n\n // Check if tag is allowed to contain entities\n if (entityConfig.allowedTags) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n const allowed = Array.isArray(entityConfig.allowedTags)\n ? entityConfig.allowedTags.includes(tagName)\n : entityConfig.allowedTags(tagName, jPathOrMatcher);\n\n if (!allowed) {\n return val;\n }\n }\n\n // Apply custom tag filter if provided\n if (entityConfig.tagFilter) {\n const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;\n if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {\n return val; // Skip based on custom filter\n }\n }\n\n return this.entityDecoder.decode(val);\n}\n\n\nfunction saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {\n if (textData) { //store previously collected data as textNode\n if (isLeafNode === undefined) isLeafNode = parentNode.child.length === 0\n\n textData = this.parseTextData(textData,\n parentNode.tagname,\n matcher,\n false,\n parentNode[\":@\"] ? Object.keys(parentNode[\":@\"]).length !== 0 : false,\n isLeafNode);\n\n if (textData !== undefined && textData !== \"\")\n parentNode.add(this.options.textNodeName, textData);\n textData = \"\";\n }\n return textData;\n}\n\n/**\n * @param {Array} stopNodeExpressions - Array of compiled Expression objects\n * @param {Matcher} matcher - Current path matcher\n */\nfunction isItStopNode() {\n if (this.stopNodeExpressionsSet.size === 0) return false;\n\n return this.matcher.matchesAny(this.stopNodeExpressionsSet);\n}\n\n/**\n * Returns the tag Expression and where it is ending handling single-double quotes situation\n * @param {string} xmlData \n * @param {number} i starting index\n * @returns \n */\nfunction tagExpWithClosingIndex(xmlData, i, closingChar = \">\") {\n let attrBoundary = 0;\n const chars = [];\n const len = xmlData.length;\n const closeCode0 = closingChar.charCodeAt(0);\n const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;\n\n for (let index = i; index < len; index++) {\n const code = xmlData.charCodeAt(index);\n\n if (attrBoundary) {\n if (code === attrBoundary) attrBoundary = 0;\n } else if (code === 34 || code === 39) { // \" or '\n attrBoundary = code;\n } else if (code === closeCode0) {\n if (closeCode1 !== -1) {\n if (xmlData.charCodeAt(index + 1) === closeCode1) {\n return { data: String.fromCharCode(...chars), index };\n }\n } else {\n return { data: String.fromCharCode(...chars), index };\n }\n } else if (code === 9) { // \\t\n chars.push(32); // space\n continue;\n }\n\n chars.push(code);\n }\n}\n\nfunction findClosingIndex(xmlData, str, i, errMsg) {\n const closingIndex = xmlData.indexOf(str, i);\n if (closingIndex === -1) {\n throw new Error(errMsg)\n } else {\n return closingIndex + str.length - 1;\n }\n}\n\nfunction findClosingChar(xmlData, char, i, errMsg) {\n const closingIndex = xmlData.indexOf(char, i);\n if (closingIndex === -1) throw new Error(errMsg);\n return closingIndex; // no offset needed\n}\n\nfunction readTagExp(xmlData, i, removeNSPrefix, closingChar = \">\") {\n const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);\n if (!result) return;\n let tagExp = result.data;\n const closeIndex = result.index;\n const separatorIndex = tagExp.search(/\\s/);\n let tagName = tagExp;\n let attrExpPresent = true;\n if (separatorIndex !== -1) {//separate tag name and attributes expression\n tagName = tagExp.substring(0, separatorIndex);\n tagExp = tagExp.substring(separatorIndex + 1).trimStart();\n }\n\n const rawTagName = tagName;\n if (removeNSPrefix) {\n const colonIndex = tagName.indexOf(\":\");\n if (colonIndex !== -1) {\n tagName = tagName.substr(colonIndex + 1);\n attrExpPresent = tagName !== result.data.substr(colonIndex + 1);\n }\n }\n\n return {\n tagName: tagName,\n tagExp: tagExp,\n closeIndex: closeIndex,\n attrExpPresent: attrExpPresent,\n rawTagName: rawTagName,\n }\n}\n/**\n * find paired tag for a stop node\n * @param {string} xmlData \n * @param {string} tagName \n * @param {number} i \n */\nfunction readStopNodeData(xmlData, tagName, i) {\n const startIndex = i;\n // Starting at 1 since we already have an open tag\n let openTagCount = 1;\n\n const xmllen = xmlData.length;\n for (; i < xmllen; i++) {\n if (xmlData[i] === \"<\") {\n const c1 = xmlData.charCodeAt(i + 1);\n if (c1 === 47) {//close tag '/'\n const closeIndex = findClosingChar(xmlData, \">\", i, `${tagName} is not closed`);\n let closeTagName = xmlData.substring(i + 2, closeIndex).trim();\n if (closeTagName === tagName) {\n openTagCount--;\n if (openTagCount === 0) {\n return {\n tagContent: xmlData.substring(startIndex, i),\n i: closeIndex\n }\n }\n }\n i = closeIndex;\n } else if (c1 === 63) { //?\n const closeIndex = findClosingIndex(xmlData, \"?>\", i + 1, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 45\n && xmlData.charCodeAt(i + 3) === 45) { // '!--'\n const closeIndex = findClosingIndex(xmlData, \"-->\", i + 3, \"StopNode is not closed.\")\n i = closeIndex;\n } else if (c1 === 33\n && xmlData.charCodeAt(i + 2) === 91) { // '!['\n const closeIndex = findClosingIndex(xmlData, \"]]>\", i, \"StopNode is not closed.\") - 2;\n i = closeIndex;\n } else {\n const tagData = readTagExp(xmlData, i, '>')\n\n if (tagData) {\n const openTagName = tagData && tagData.tagName;\n if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== \"/\") {\n openTagCount++;\n }\n i = tagData.closeIndex;\n }\n }\n }\n }//end for loop\n}\n\nfunction parseValue(val, shouldParse, options) {\n if (shouldParse && typeof val === 'string') {\n //console.log(options)\n const newval = val.trim();\n if (newval === 'true') return true;\n else if (newval === 'false') return false;\n else return toNumber(val, options);\n } else {\n if (isExist(val)) {\n return val;\n } else {\n return '';\n }\n }\n}\n\nfunction fromCodePoint(str, base, prefix) {\n const codePoint = Number.parseInt(str, base);\n\n if (codePoint >= 0 && codePoint <= 0x10FFFF) {\n return String.fromCodePoint(codePoint);\n } else {\n return prefix + str + \";\";\n }\n}\n\nfunction transformTagName(fn, tagName, tagExp, options) {\n if (fn) {\n const newTagName = fn(tagName);\n if (tagExp === tagName) {\n tagExp = newTagName\n }\n tagName = newTagName;\n }\n tagName = sanitizeName(tagName, options);\n return { tagName, tagExp };\n}\n\n\n\nfunction sanitizeName(name, options) {\n if (criticalProperties.includes(name)) {\n throw new Error(`[SECURITY] Invalid name: \"${name}\" is a reserved JavaScript keyword that could cause prototype pollution`);\n } else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {\n return options.onDangerousProperty(name);\n }\n return name;\n}","export default function getIgnoreAttributesFn(ignoreAttributes) {\n if (typeof ignoreAttributes === 'function') {\n return ignoreAttributes\n }\n if (Array.isArray(ignoreAttributes)) {\n return (attrName) => {\n for (const pattern of ignoreAttributes) {\n if (typeof pattern === 'string' && attrName === pattern) {\n return true\n }\n if (pattern instanceof RegExp && pattern.test(attrName)) {\n return true\n }\n }\n }\n }\n return () => false\n}","'use strict';\n\nimport XmlNode from './xmlNode.js';\nimport { Matcher } from 'path-expression-matcher';\n\nconst METADATA_SYMBOL = XmlNode.getMetaDataSymbol();\n\n/**\n * Helper function to strip attribute prefix from attribute map\n * @param {object} attrs - Attributes with prefix (e.g., {\"@_class\": \"code\"})\n * @param {string} prefix - Attribute prefix to remove (e.g., \"@_\")\n * @returns {object} Attributes without prefix (e.g., {\"class\": \"code\"})\n */\nfunction stripAttributePrefix(attrs, prefix) {\n if (!attrs || typeof attrs !== 'object') return {};\n if (!prefix) return attrs;\n\n const rawAttrs = {};\n for (const key in attrs) {\n if (key.startsWith(prefix)) {\n const rawName = key.substring(prefix.length);\n rawAttrs[rawName] = attrs[key];\n } else {\n // Attribute without prefix (shouldn't normally happen, but be safe)\n rawAttrs[key] = attrs[key];\n }\n }\n return rawAttrs;\n}\n\n/**\n * \n * @param {array} node \n * @param {any} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns \n */\nexport default function prettify(node, options, matcher, readonlyMatcher) {\n return compress(node, options, matcher, readonlyMatcher);\n}\n\n/**\n * @param {array} arr \n * @param {object} options \n * @param {Matcher} matcher - Path matcher instance\n * @returns object\n */\nfunction compress(arr, options, matcher, readonlyMatcher) {\n let text;\n const compressedObj = {}; //This is intended to be a plain object\n for (let i = 0; i < arr.length; i++) {\n const tagObj = arr[i];\n const property = propName(tagObj);\n\n // Push current property to matcher WITH RAW ATTRIBUTES (no prefix)\n if (property !== undefined && property !== options.textNodeName) {\n const rawAttrs = stripAttributePrefix(\n tagObj[\":@\"] || {},\n options.attributeNamePrefix\n );\n matcher.push(property, rawAttrs);\n }\n\n if (property === options.textNodeName) {\n if (text === undefined) text = tagObj[property];\n else text += \"\" + tagObj[property];\n } else if (property === undefined) {\n continue;\n } else if (tagObj[property]) {\n\n let val = compress(tagObj[property], options, matcher, readonlyMatcher);\n const isLeaf = isLeafTag(val, options);\n\n if (tagObj[\":@\"]) {\n assignAttributes(val, tagObj[\":@\"], readonlyMatcher, options);\n } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {\n val = val[options.textNodeName];\n } else if (Object.keys(val).length === 0) {\n if (options.alwaysCreateTextNode) val[options.textNodeName] = \"\";\n else val = \"\";\n }\n\n if (tagObj[METADATA_SYMBOL] !== undefined && typeof val === \"object\" && val !== null) {\n val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata\n }\n\n\n if (compressedObj[property] !== undefined && Object.prototype.hasOwnProperty.call(compressedObj, property)) {\n if (!Array.isArray(compressedObj[property])) {\n compressedObj[property] = [compressedObj[property]];\n }\n compressedObj[property].push(val);\n } else {\n //TODO: if a node is not an array, then check if it should be an array\n //also determine if it is a leaf node\n\n // Pass jPath string or readonlyMatcher based on options.jPath setting\n const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;\n if (options.isArray(property, jPathOrMatcher, isLeaf)) {\n compressedObj[property] = [val];\n } else {\n compressedObj[property] = val;\n }\n }\n\n // Pop property from matcher after processing\n if (property !== undefined && property !== options.textNodeName) {\n matcher.pop();\n }\n }\n\n }\n // if(text && text.length > 0) compressedObj[options.textNodeName] = text;\n if (typeof text === \"string\") {\n if (text.length > 0) compressedObj[options.textNodeName] = text;\n } else if (text !== undefined) compressedObj[options.textNodeName] = text;\n\n\n return compressedObj;\n}\n\nfunction propName(obj) {\n const keys = Object.keys(obj);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (key !== \":@\") return key;\n }\n}\n\nfunction assignAttributes(obj, attrMap, readonlyMatcher, options) {\n if (attrMap) {\n const keys = Object.keys(attrMap);\n const len = keys.length; //don't make it inline\n for (let i = 0; i < len; i++) {\n const atrrName = keys[i]; // This is the PREFIXED name (e.g., \"@_class\")\n\n // Strip prefix for matcher path (for isArray callback)\n const rawAttrName = atrrName.startsWith(options.attributeNamePrefix)\n ? atrrName.substring(options.attributeNamePrefix.length)\n : atrrName;\n\n // For attributes, we need to create a temporary path\n // Pass jPath string or matcher based on options.jPath setting\n const jPathOrMatcher = options.jPath\n ? readonlyMatcher.toString() + \".\" + rawAttrName\n : readonlyMatcher;\n\n if (options.isArray(atrrName, jPathOrMatcher, true, true)) {\n obj[atrrName] = [attrMap[atrrName]];\n } else {\n obj[atrrName] = attrMap[atrrName];\n }\n }\n }\n}\n\nfunction isLeafTag(obj, options) {\n const { textNodeName } = options;\n const propCount = Object.keys(obj).length;\n\n if (propCount === 0) {\n return true;\n }\n\n if (\n propCount === 1 &&\n (obj[textNodeName] || typeof obj[textNodeName] === \"boolean\" || obj[textNodeName] === 0)\n ) {\n return true;\n }\n\n return false;\n}","'use strict';\n\nimport { getAllMatches, isName } from './util.js';\n\nconst defaultOptions = {\n allowBooleanAttributes: false, //A tag can have attributes without any value\n unpairedTags: []\n};\n\n//const tagsPattern = new RegExp(\"<\\\\/?([\\\\w:\\\\-_\\.]+)\\\\s*\\/?>\",\"g\");\nexport function validate(xmlData, options) {\n options = Object.assign({}, defaultOptions, options);\n\n //xmlData = xmlData.replace(/(\\r\\n|\\n|\\r)/gm,\"\");//make it single line\n //xmlData = xmlData.replace(/(^\\s*<\\?xml.*?\\?>)/g,\"\");//Remove XML starting tag\n //xmlData = xmlData.replace(/()/g,\"\");//Remove DOCTYPE\n const tags = [];\n let tagFound = false;\n\n //indicates that the root tag has been closed (aka. depth 0 has been reached)\n let reachedRoot = false;\n\n if (xmlData[0] === '\\ufeff') {\n // check for byte order mark (BOM)\n xmlData = xmlData.substr(1);\n }\n\n for (let i = 0; i < xmlData.length; i++) {\n\n if (xmlData[i] === '<' && xmlData[i + 1] === '?') {\n i += 2;\n i = readPI(xmlData, i);\n if (i.err) return i;\n } else if (xmlData[i] === '<') {\n //starting of tag\n //read until you reach to '>' avoiding any '>' in attribute value\n let tagStartPos = i;\n i++;\n\n if (xmlData[i] === '!') {\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else {\n let closingTag = false;\n if (xmlData[i] === '/') {\n //closing tag\n closingTag = true;\n i++;\n }\n //read tagname\n let tagName = '';\n for (; i < xmlData.length &&\n xmlData[i] !== '>' &&\n xmlData[i] !== ' ' &&\n xmlData[i] !== '\\t' &&\n xmlData[i] !== '\\n' &&\n xmlData[i] !== '\\r'; i++\n ) {\n tagName += xmlData[i];\n }\n tagName = tagName.trim();\n //console.log(tagName);\n\n if (tagName[tagName.length - 1] === '/') {\n //self closing tag without attributes\n tagName = tagName.substring(0, tagName.length - 1);\n //continue;\n i--;\n }\n if (!validateTagName(tagName)) {\n let msg;\n if (tagName.trim().length === 0) {\n msg = \"Invalid space after '<'.\";\n } else {\n msg = \"Tag '\" + tagName + \"' is an invalid name.\";\n }\n return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i));\n }\n\n const result = readAttributeStr(xmlData, i);\n if (result === false) {\n return getErrorObject('InvalidAttr', \"Attributes for '\" + tagName + \"' have open quote.\", getLineNumberForPosition(xmlData, i));\n }\n let attrStr = result.value;\n i = result.index;\n\n if (attrStr[attrStr.length - 1] === '/') {\n //self closing tag\n const attrStrStart = i - attrStr.length;\n attrStr = attrStr.substring(0, attrStr.length - 1);\n const isValid = validateAttributeString(attrStr, options);\n if (isValid === true) {\n tagFound = true;\n //continue; //text may presents after self closing tag\n } else {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));\n }\n } else if (closingTag) {\n if (!result.tagClosed) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' doesn't have proper closing.\", getLineNumberForPosition(xmlData, i));\n } else if (attrStr.trim().length > 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' can't have attributes or invalid starting.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else if (tags.length === 0) {\n return getErrorObject('InvalidTag', \"Closing tag '\" + tagName + \"' has not been opened.\", getLineNumberForPosition(xmlData, tagStartPos));\n } else {\n const otg = tags.pop();\n if (tagName !== otg.tagName) {\n let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);\n return getErrorObject('InvalidTag',\n \"Expected closing tag '\" + otg.tagName + \"' (opened in line \" + openPos.line + \", col \" + openPos.col + \") instead of closing tag '\" + tagName + \"'.\",\n getLineNumberForPosition(xmlData, tagStartPos));\n }\n\n //when there are no more tags, we reached the root level.\n if (tags.length == 0) {\n reachedRoot = true;\n }\n }\n } else {\n const isValid = validateAttributeString(attrStr, options);\n if (isValid !== true) {\n //the result from the nested function returns the position of the error within the attribute\n //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute\n //this gives us the absolute index in the entire xml, which we can use to find the line at last\n return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));\n }\n\n //if the root level has been reached before ...\n if (reachedRoot === true) {\n return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i));\n } else if (options.unpairedTags.indexOf(tagName) !== -1) {\n //don't push into stack\n } else {\n tags.push({ tagName, tagStartPos });\n }\n tagFound = true;\n }\n\n //skip tag text value\n //It may include comments and CDATA value\n for (i++; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n if (xmlData[i + 1] === '!') {\n //comment or CADATA\n i++;\n i = readCommentAndCDATA(xmlData, i);\n continue;\n } else if (xmlData[i + 1] === '?') {\n i = readPI(xmlData, ++i);\n if (i.err) return i;\n } else {\n break;\n }\n } else if (xmlData[i] === '&') {\n const afterAmp = validateAmpersand(xmlData, i);\n if (afterAmp == -1)\n return getErrorObject('InvalidChar', \"char '&' is not expected.\", getLineNumberForPosition(xmlData, i));\n i = afterAmp;\n } else {\n if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {\n return getErrorObject('InvalidXml', \"Extra text at the end\", getLineNumberForPosition(xmlData, i));\n }\n }\n } //end of reading tag text value\n if (xmlData[i] === '<') {\n i--;\n }\n }\n } else {\n if (isWhiteSpace(xmlData[i])) {\n continue;\n }\n return getErrorObject('InvalidChar', \"char '\" + xmlData[i] + \"' is not expected.\", getLineNumberForPosition(xmlData, i));\n }\n }\n\n if (!tagFound) {\n return getErrorObject('InvalidXml', 'Start tag expected.', 1);\n } else if (tags.length == 1) {\n return getErrorObject('InvalidTag', \"Unclosed tag '\" + tags[0].tagName + \"'.\", getLineNumberForPosition(xmlData, tags[0].tagStartPos));\n } else if (tags.length > 0) {\n return getErrorObject('InvalidXml', \"Invalid '\" +\n JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\\r?\\n/g, '') +\n \"' found.\", { line: 1, col: 1 });\n }\n\n return true;\n};\n\nfunction isWhiteSpace(char) {\n return char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n}\n/**\n * Read Processing insstructions and skip\n * @param {*} xmlData\n * @param {*} i\n */\nfunction readPI(xmlData, i) {\n const start = i;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] == '?' || xmlData[i] == ' ') {\n //tagname\n const tagname = xmlData.substr(start, i - start);\n if (i > 5 && tagname === 'xml') {\n return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i));\n } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') {\n //check if valid attribut string\n i++;\n break;\n } else {\n continue;\n }\n }\n }\n return i;\n}\n\nfunction readCommentAndCDATA(xmlData, i) {\n if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') {\n //comment\n for (i += 3; i < xmlData.length; i++) {\n if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n } else if (\n xmlData.length > i + 8 &&\n xmlData[i + 1] === 'D' &&\n xmlData[i + 2] === 'O' &&\n xmlData[i + 3] === 'C' &&\n xmlData[i + 4] === 'T' &&\n xmlData[i + 5] === 'Y' &&\n xmlData[i + 6] === 'P' &&\n xmlData[i + 7] === 'E'\n ) {\n let angleBracketsCount = 1;\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === '<') {\n angleBracketsCount++;\n } else if (xmlData[i] === '>') {\n angleBracketsCount--;\n if (angleBracketsCount === 0) {\n break;\n }\n }\n }\n } else if (\n xmlData.length > i + 9 &&\n xmlData[i + 1] === '[' &&\n xmlData[i + 2] === 'C' &&\n xmlData[i + 3] === 'D' &&\n xmlData[i + 4] === 'A' &&\n xmlData[i + 5] === 'T' &&\n xmlData[i + 6] === 'A' &&\n xmlData[i + 7] === '['\n ) {\n for (i += 8; i < xmlData.length; i++) {\n if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') {\n i += 2;\n break;\n }\n }\n }\n\n return i;\n}\n\nconst doubleQuote = '\"';\nconst singleQuote = \"'\";\n\n/**\n * Keep reading xmlData until '<' is found outside the attribute value.\n * @param {string} xmlData\n * @param {number} i\n */\nfunction readAttributeStr(xmlData, i) {\n let attrStr = '';\n let startChar = '';\n let tagClosed = false;\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {\n if (startChar === '') {\n startChar = xmlData[i];\n } else if (startChar !== xmlData[i]) {\n //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa\n } else {\n startChar = '';\n }\n } else if (xmlData[i] === '>') {\n if (startChar === '') {\n tagClosed = true;\n break;\n }\n }\n attrStr += xmlData[i];\n }\n if (startChar !== '') {\n return false;\n }\n\n return {\n value: attrStr,\n index: i,\n tagClosed: tagClosed\n };\n}\n\n/**\n * Select all the attributes whether valid or invalid.\n */\nconst validAttrStrRegxp = new RegExp('(\\\\s*)([^\\\\s=]+)(\\\\s*=)?(\\\\s*([\\'\"])(([\\\\s\\\\S])*?)\\\\5)?', 'g');\n\n//attr, =\"sd\", a=\"amit's\", a=\"sd\"b=\"saf\", ab cd=\"\"\n\nfunction validateAttributeString(attrStr, options) {\n //console.log(\"start:\"+attrStr+\":end\");\n\n //if(attrStr.trim().length === 0) return true; //empty string\n\n const matches = getAllMatches(attrStr, validAttrStrRegxp);\n const attrNames = {};\n\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][1].length === 0) {\n //nospace before attribute name: a=\"sd\"b=\"saf\"\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' has no space in starting.\", getPositionFromMatch(matches[i]))\n } else if (matches[i][3] !== undefined && matches[i][4] === undefined) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + matches[i][2] + \"' is without value.\", getPositionFromMatch(matches[i]));\n } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) {\n //independent attribute: ab\n return getErrorObject('InvalidAttr', \"boolean attribute '\" + matches[i][2] + \"' is not allowed.\", getPositionFromMatch(matches[i]));\n }\n /* else if(matches[i][6] === undefined){//attribute without value: ab=\n return { err: { code:\"InvalidAttr\",msg:\"attribute \" + matches[i][2] + \" has no value assigned.\"}};\n } */\n const attrName = matches[i][2];\n if (!validateAttrName(attrName)) {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is an invalid name.\", getPositionFromMatch(matches[i]));\n }\n if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {\n //check for duplicate attribute.\n attrNames[attrName] = 1;\n } else {\n return getErrorObject('InvalidAttr', \"Attribute '\" + attrName + \"' is repeated.\", getPositionFromMatch(matches[i]));\n }\n }\n\n return true;\n}\n\nfunction validateNumberAmpersand(xmlData, i) {\n let re = /\\d/;\n if (xmlData[i] === 'x') {\n i++;\n re = /[\\da-fA-F]/;\n }\n for (; i < xmlData.length; i++) {\n if (xmlData[i] === ';')\n return i;\n if (!xmlData[i].match(re))\n break;\n }\n return -1;\n}\n\nfunction validateAmpersand(xmlData, i) {\n // https://www.w3.org/TR/xml/#dt-charref\n i++;\n if (xmlData[i] === ';')\n return -1;\n if (xmlData[i] === '#') {\n i++;\n return validateNumberAmpersand(xmlData, i);\n }\n let count = 0;\n for (; i < xmlData.length; i++, count++) {\n if (xmlData[i].match(/\\w/) && count < 20)\n continue;\n if (xmlData[i] === ';')\n break;\n return -1;\n }\n return i;\n}\n\nfunction getErrorObject(code, message, lineNumber) {\n return {\n err: {\n code: code,\n msg: message,\n line: lineNumber.line || lineNumber,\n col: lineNumber.col,\n },\n };\n}\n\nfunction validateAttrName(attrName) {\n return isName(attrName);\n}\n\n// const startsWithXML = /^xml/i;\n\nfunction validateTagName(tagname) {\n return isName(tagname) /* && !tagname.match(startsWithXML) */;\n}\n\n//this function returns the line number for the character at the given index\nfunction getLineNumberForPosition(xmlData, index) {\n const lines = xmlData.substring(0, index).split(/\\r?\\n/);\n return {\n line: lines.length,\n\n // column number is last line's length + 1, because column numbering starts at 1:\n col: lines[lines.length - 1].length + 1\n };\n}\n\n//this function returns the position of the first character of match within attrStr\nfunction getPositionFromMatch(match) {\n return match.startIndex + match[1].length;\n}\n","import { buildOptions } from './OptionsBuilder.js';\nimport OrderedObjParser from './OrderedObjParser.js';\nimport prettify from './node2json.js';\nimport { validate } from \"../validator.js\";\nimport XmlNode from './xmlNode.js';\n\nexport default class XMLParser {\n\n constructor(options) {\n this.externalEntities = {};\n this.options = buildOptions(options);\n\n }\n /**\n * Parse XML dats to JS object \n * @param {string|Uint8Array} xmlData \n * @param {boolean|Object} validationOption \n */\n parse(xmlData, validationOption) {\n if (typeof xmlData !== \"string\" && xmlData.toString) {\n xmlData = xmlData.toString();\n } else if (typeof xmlData !== \"string\") {\n throw new Error(\"XML data is accepted in String or Bytes[] form.\")\n }\n\n if (validationOption) {\n if (validationOption === true) validationOption = {}; //validate with default options\n\n const result = validate(xmlData, validationOption);\n if (result !== true) {\n throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`)\n }\n }\n const orderedObjParser = new OrderedObjParser(this.options);\n orderedObjParser.entityDecoder.setExternalEntities(this.externalEntities);\n const orderedResult = orderedObjParser.parseXml(xmlData);\n if (this.options.preserveOrder || orderedResult === undefined) return orderedResult;\n else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);\n }\n\n /**\n * Add Entity which is not by default supported by this library\n * @param {string} key \n * @param {string} value \n */\n addEntity(key, value) {\n if (value.indexOf(\"&\") !== -1) {\n throw new Error(\"Entity value can't have '&'\")\n } else if (key.indexOf(\"&\") !== -1 || key.indexOf(\";\") !== -1) {\n throw new Error(\"An entity must be set without '&' and ';'. Eg. use '#xD' for ' '\")\n } else if (value === \"&\") {\n throw new Error(\"An entity with value '&' is not permitted\");\n } else {\n this.externalEntities[key] = value;\n }\n }\n\n /**\n * Returns a Symbol that can be used to access the metadata\n * property on a node.\n * \n * If Symbol is not available in the environment, an ordinary property is used\n * and the name of the property is here returned.\n * \n * The XMLMetaData property is only present when `captureMetaData`\n * is true in the options.\n */\n static getMetaDataSymbol() {\n return XmlNode.getMetaDataSymbol();\n }\n}"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","nameStartChar","regexName","RegExp","getAllMatches","string","regex","matches","match","exec","allmatches","startIndex","lastIndex","length","len","index","push","isName","DANGEROUS_PROPERTY_NAMES","criticalProperties","defaultOnDangerousProperty","name","includes","defaultOptions","preserveOrder","attributeNamePrefix","attributesGroupName","textNodeName","ignoreAttributes","removeNSPrefix","allowBooleanAttributes","parseTagValue","parseAttributeValue","trimValues","cdataPropName","numberParseOptions","hex","leadingZeros","eNotation","tagValueProcessor","tagName","val","attributeValueProcessor","attrName","stopNodes","alwaysCreateTextNode","isArray","commentPropName","unpairedTags","processEntities","htmlEntities","entityDecoder","ignoreDeclaration","ignorePiTags","transformTagName","transformAttributeName","updateTag","jPath","attrs","captureMetaData","maxNestedTags","strictReservedNames","onDangerousProperty","validatePropertyName","propertyName","optionName","normalized","toLowerCase","some","dangerous","Error","normalizeProcessEntities","enabled","maxEntitySize","maxExpansionDepth","maxTotalExpansions","Infinity","maxExpandedLength","maxEntityCount","allowedTags","tagFilter","appliesTo","Math","max","_value$maxEntitySize","_value$maxExpansionDe","_value$maxTotalExpans","_value$maxExpandedLen","_value$maxEntityCount","_value$allowedTags","_value$tagFilter","_value$appliesTo","METADATA_SYMBOL","buildOptions","options","built","assign","_i","_propertyNameOptions","_propertyNameOptions$","unpairedTagsSet","Set","Array","map","node","startsWith","substring","XmlNode","tagname","child","create","_proto","add","_this$child$push","addChild","_this$child$push2","_this$child$push3","keys","undefined","getMetaDataSymbol","DocTypeReader","suppressValidationErr","readDocType","xmlData","i","entities","entityCount","angleBracketsCount","hasBody","comment","hasSeq","entityName","_this$readEntityExp","readEntityExp","indexOf","readElementExp","readNotationExp","skipWhitespace","test","validateEntityName","toUpperCase","entityValue","_this$readIdentifierV","readIdentifierVal","notationName","identifierType","publicIdentifier","systemIdentifier","_this$readIdentifierV2","_this$readIdentifierV3","_this$readIdentifierV4","type","identifierVal","startChar","elementName","contentModel","trim","readAttlistExp","attributeName","attributeType","allowedNotations","notation","join","defaultValue","_this$readIdentifierV5","data","seq","j","hexRegex","numRegex","consider","decimalPoint","infinity","eNotationRegx","MatcherView","constructor","matcher","_matcher","separator","getCurrentTag","path","tag","getCurrentNamespace","namespace","getAttrValue","values","hasAttr","current","getPosition","position","getCounter","counter","getIndex","getDepth","toString","includeNamespace","toArray","n","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","attrValues","currentLevel","Map","siblings","siblingKey","count","set","pop","updateCurrent","sep","result","reset","segments","hasDeepWildcard","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","segment","nextSeg","found","isCurrentNode","attrValue","String","positionValue","snapshot","restore","readOnly","Expression","pattern","_parse","_hasDeepWildcard","seg","_hasAttributeCondition","_hasPositionSelector","currentPart","_parseSegment","part","bracketContent","withoutBrackets","bracketMatch","content","slice","tagAndPosition","nsIndex","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","eqIndex","nthMatch","parseInt","hasAttributeCondition","hasPositionSelector","ExpressionSet","_byDepthAndTag","_wildcardByDepth","_deepWildcards","_patterns","_sealed","TypeError","has","depth","lastSeg","addAll","expressions","expr","size","seal","isSealed","findMatch","exactKey","exactBucket","wildcardBucket","CURRENCY","cent","pound","curren","yen","euro","dollar","fnof","inr","af","birr","peso","rub","won","yuan","cedil","XML","amp","apos","gt","lt","quot","COMMON_HTML","nbsp","copy","reg","trade","mdash","ndash","hellip","laquo","raquo","lsquo","rsquo","ldquo","rdquo","bull","para","sect","deg","frac12","frac14","frac34","SPECIAL_CHARS","ch","mergeEntityMaps","maps","out","raw","LIMIT_TIER_EXTERNAL","LIMIT_TIER_BASE","LIMIT_TIER_ALL","NCR_LEVEL","freeze","allow","leave","remove","throw","XML10_ALLOWED_C0","EntityDecoder","_limit","limit","_maxTotalExpansions","_maxExpandedLength","_postCheck","postCheck","r","_limitTiers","applyLimitsTo","_numericAllowed","numericAllowed","_baseMap","DEFAULT_XML_ENTITIES","namedEntities","_externalMap","_inputMap","_totalExpansions","_expandedLength","_removeSet","_leaveSet","ncrCfg","ncr","xmlVersion","onLevel","nullLevel","onNCR","nullNCR","parseNCRConfig","_ncrXmlVersion","_ncrOnLevel","_ncrNullLevel","setExternalEntities","addExternalEntity","addInputEntities","setXmlVersion","version","decode","str","original","chunks","last","limitExpansions","limitLength","checkLimits","charCodeAt","token","replacement","tier","ncrResult","_resolveNCR","resolved","_resolveName","_tierCounts","delta","_classifyNCR","cp","_applyNCRAction","action","fromCodePoint","padStart","second","Number","isNaN","minimum","effective","_extends","bind","e","arguments","t","apply","extractRawAttributes","prefixedAttrs","rawAttrs","extractNamespace","rawTagName","ns","OrderedObjParser","currentNode","tagsNodeStack","parseXml","parseTextData","resolveNameSpace","buildAttributesMap","isItStopNode","replaceEntitiesValue","readStopNodeData","saveTextToParentTag","ignoreAttributesFn","_step","_iterator","_createForOfIteratorHelperLoose","done","entityExpansionCount","currentExpandedLength","readonlyMatcher","isCurrentNodeStopNode","stopNodeExpressionsSet","stopNodesOpts","stopNodeExp","dontTrim","hasAttributes","isLeafNode","escapeEntities","jPathOrMatcher","newval","parseValue","tags","split","prefix","charAt","attrsRegx","attrStr","force","processedVals","hasRawAttrs","rawAttrsForMatcher","oldVal","jPathStr","hasAttrs","aName","sanitizeName","newVal","attrCollection","replace","xmlObj","xmlNode","textData","docTypeReader","xmlLen","c1","closeIndex","findClosingIndex","substr","lastTagName","tagData","readTagExp","attsMap","tagExp","ver","childNode","attrExpPresent","endIndex","_ref","_ref2","context","min","_transformTagName","lastTag","isSelfClosing","tagContent","_transformTagName2","entityConfig","parentNode","errMsg","closingIndex","findClosingChar","char","closingChar","attrBoundary","chars","closeCode0","closeCode1","code","fromCharCode","tagExpWithClosingIndex","separatorIndex","search","trimStart","openTagCount","xmllen","shouldParse","trimmedStr","skipLike","numStr","window","parse_int","isFinite","sign","eChar","eAdjacentToLeadingZeros","resolveEnotation","numTrimmedByZeros","decimalAdjacentToLeadingZeros","num","parsedStr","isPositive","handleInfinity","toNumber","fn","newTagName","stripAttributePrefix","prettify","compress","arr","text","compressedObj","tagObj","property","propName","isLeaf","isLeafTag","assignAttributes","attrMap","atrrName","rawAttrName","propCount","isWhiteSpace","readPI","start","getErrorObject","getLineNumberForPosition","readCommentAndCDATA","readAttributeStr","tagClosed","validAttrStrRegxp","validateAttributeString","attrNames","getPositionFromMatch","validateAttrName","validateAmpersand","re","validateNumberAmpersand","message","lineNumber","err","msg","line","col","validateTagName","lines","XMLParser","externalEntities","parse","validationOption","tagFound","reachedRoot","tagStartPos","closingTag","attrStrStart","isValid","otg","openPos","afterAmp","JSON","stringify","validate","orderedObjParser","orderedResult","addEntity"],"sourceRoot":""} \ No newline at end of file diff --git a/node_modules/fast-xml-parser/package.json b/node_modules/fast-xml-parser/package.json index 0596745c..ded1d5f0 100644 --- a/node_modules/fast-xml-parser/package.json +++ b/node_modules/fast-xml-parser/package.json @@ -1,6 +1,6 @@ { "name": "fast-xml-parser", - "version": "5.5.7", + "version": "5.7.1", "description": "Validate XML, Parse XML, Build XML without C/C++ based libraries", "main": "./lib/fxp.cjs", "type": "module", @@ -87,8 +87,9 @@ } ], "dependencies": { - "fast-xml-builder": "^1.1.4", - "path-expression-matcher": "^1.1.3", - "strnum": "^2.2.0" + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" } } \ No newline at end of file diff --git a/node_modules/fast-xml-parser/src/fxp.d.ts b/node_modules/fast-xml-parser/src/fxp.d.ts index 4724d48c..e9798118 100644 --- a/node_modules/fast-xml-parser/src/fxp.d.ts +++ b/node_modules/fast-xml-parser/src/fxp.d.ts @@ -1,7 +1,152 @@ -//import type { Matcher, Expression } from 'path-expression-matcher'; +/** + * Types copied from path-expression-matcher + * @version + * @updated + * + * Update this file when path-expression-matcher releases a new version. + * Source: https://github.com/NaturalIntelligence/path-expression-matcher + */ + +/** + * Options for creating an Expression + */ +export interface ExpressionOptions { + /** + * Path separator character + * @default '.' + */ + separator?: string; +} + +/** + * Parsed segment from an expression pattern + */ +export interface Segment { + type: 'tag' | 'deep-wildcard'; + tag?: string; + namespace?: string; + attrName?: string; + attrValue?: string; + position?: 'first' | 'last' | 'odd' | 'even' | 'nth'; + positionValue?: number; +} + +/** + * Expression - Parses and stores a tag pattern expression. + * Patterns are parsed once and stored in an optimized structure for fast matching. + * + * @example + * ```typescript + * const expr = new Expression("root.users.user"); + * const expr2 = new Expression("..user[id]:first"); + * const expr3 = new Expression("root/users/user", { separator: '/' }); + * ``` + * + * Pattern Syntax: + * - `root.users.user` — Match exact path + * - `..user` — Match "user" at any depth (deep wildcard) + * - `user[id]` — Match user tag with "id" attribute + * - `user[id=123]` — Match user tag where id="123" + * - `user:first` — Match first occurrence of user tag + * - `ns::user` — Match user tag with namespace "ns" + * - `ns::user[id]:first` — Combine namespace, attribute, and position + */ +export class Expression { + readonly pattern: string; + readonly separator: string; + readonly segments: Segment[]; + + constructor(pattern: string, options?: ExpressionOptions); + + get length(): number; + hasDeepWildcard(): boolean; + hasAttributeCondition(): boolean; + hasPositionSelector(): boolean; + toString(): string; +} + +// --------------------------------------------------------------------------- +// MatcherView +// --------------------------------------------------------------------------- + +/** + * A lightweight, live read-only view of a Matcher instance. + * + * Returned by `Matcher.readOnly()`. The same instance is reused across every + * callback invocation — no allocation overhead per call. Reads directly from + * the parent Matcher's internal state so it always reflects the current parser + * position with no copying or freezing. + * + * Mutation methods (`push`, `pop`, `reset`, `updateCurrent`, `restore`) are + * simply absent — misuse is caught at compile time by TypeScript. + * + * This is the type received by all FXP user callbacks when `jPath: false`. + */ +export class MatcherView { + readonly separator: string; + + /** Check if current path matches an Expression. */ + matches(expression: Expression): boolean; + + /** Get current tag name, or `undefined` if path is empty. */ + getCurrentTag(): string | undefined; -type Matcher = unknown; -type Expression = unknown; + /** Get current namespace, or `undefined` if not present. */ + getCurrentNamespace(): string | undefined; + + /** Get attribute value of the current node. */ + getAttrValue(attrName: string): any; + + /** Check if the current node has a given attribute. */ + hasAttr(attrName: string): boolean; + + /** Sibling position of the current node (child index in parent). */ + getPosition(): number; + + /** Occurrence counter of the current tag name at this level. */ + getCounter(): number; + + /** Number of nodes in the current path. */ + getDepth(): number; + + /** Current path as a string (e.g. `"root.users.user"`). */ + toString(separator?: string, includeNamespace?: boolean): string; + + /** Current path as an array of tag names. */ + toArray(): string[]; +} + +/** + * @deprecated Use {@link MatcherView} instead. + * Alias kept for backward compatibility. + */ +export type ReadonlyMatcher = MatcherView; + +/** Internal node structure — exposed via snapshot only. */ +export interface PathNode { + tag: string; + namespace?: string; + position: number; + counter: number; + values?: Record; +} + +/** Snapshot of matcher state returned by `snapshot()` and `readOnly().snapshot()`. */ +export interface MatcherSnapshot { + path: PathNode[]; + siblingStacks: Map[]; +} + +/********************************************************************** + * + * END of path-expression-matcher relevant typings + * + **********************************************************************/ + +// jPath: true → string +// jPath: false → MatcherView +type JPathOrMatcher = string | MatcherView; +type JPathOrExpression = string | Expression; export type ProcessEntitiesOptions = { /** @@ -63,9 +208,17 @@ export type ProcessEntitiesOptions = { * * Defaults to `null` */ - tagFilter?: ((tagName: string, jPathOrMatcher: string | Matcher) => boolean) | null; + tagFilter?: ((tagName: string, jPathOrMatcher: JPathOrMatcher) => boolean) | null; }; +export type EntityDecoderOptions = { + setExternalEntities: (entities: Record) => void; + addInputEntities: (entities: Record) => void; + reset: () => void; + decode: (text: string) => string; + setXmlVersion: (version: string) => void; +} + export type X2jOptions = { /** * Preserve the order of tags in resulting JS object @@ -108,7 +261,7 @@ export type X2jOptions = { * * Defaults to `true` */ - ignoreAttributes?: boolean | (string | RegExp)[] | ((attrName: string, jPathOrMatcher: string | Matcher) => boolean); + ignoreAttributes?: boolean | (string | RegExp)[] | ((attrName: string, jPathOrMatcher: JPathOrMatcher) => boolean); /** * Whether to remove namespace string from tag and attribute names @@ -175,7 +328,7 @@ export type X2jOptions = { * * Defaults to `(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode) => val` */ - tagValueProcessor?: (tagName: string, tagValue: string, jPathOrMatcher: string | Matcher, hasAttributes: boolean, isLeafNode: boolean) => unknown; + tagValueProcessor?: (tagName: string, tagValue: string, jPathOrMatcher: JPathOrMatcher, hasAttributes: boolean, isLeafNode: boolean) => unknown; /** * Control how attribute value should be parsed @@ -188,7 +341,7 @@ export type X2jOptions = { * * Defaults to `(attrName, val, jPathOrMatcher) => val` */ - attributeValueProcessor?: (attrName: string, attrValue: string, jPathOrMatcher: string | Matcher) => unknown; + attributeValueProcessor?: (attrName: string, attrValue: string, jPathOrMatcher: JPathOrMatcher) => unknown; /** * Options to pass to `strnum` for parsing numbers @@ -206,7 +359,7 @@ export type X2jOptions = { * * Defaults to `[]` */ - stopNodes?: (string | Expression)[]; + stopNodes?: JPathOrExpression[]; /** * List of tags without closing tags @@ -233,7 +386,7 @@ export type X2jOptions = { * * Defaults to `() => false` */ - isArray?: (tagName: string, jPathOrMatcher: string | Matcher, isLeafNode: boolean, isAttribute: boolean) => boolean; + isArray?: (tagName: string, jPathOrMatcher: JPathOrMatcher, isLeafNode: boolean, isAttribute: boolean) => boolean; /** * Whether to process default and DOCTYPE entities @@ -252,9 +405,14 @@ export type X2jOptions = { * Whether to process HTML entities * * Defaults to `false` + * @deprecated Use `entityDecoder` instead */ htmlEntities?: boolean; + /** + * Custom entity decoder + */ + entityDecoder?: EntityDecoderOptions; /** * Whether to ignore the declaration tag from output * @@ -295,7 +453,7 @@ export type X2jOptions = { * * Defaults to `(tagName, jPathOrMatcher, attrs) => tagName` */ - updateTag?: (tagName: string, jPathOrMatcher: string | Matcher, attrs: { [k: string]: string }) => string | boolean; + updateTag?: (tagName: string, jPathOrMatcher: JPathOrMatcher, attrs: { [k: string]: string }) => string | boolean; /** * If true, adds a Symbol to all object nodes, accessible by {@link XMLParser.getMetaDataSymbol} with @@ -479,7 +637,7 @@ export type XmlBuilderOptions = { * * Defaults to `[]` */ - stopNodes?: (string | Expression)[]; + stopNodes?: JPathOrExpression[]; /** * Control how tag value should be parsed. Called only if tag value is not empty @@ -562,6 +720,9 @@ export class XMLParser { export class XMLValidator { static validate(xmlData: string, options?: validationOptions): true | ValidationError; } +/** + * @deprecated Use npm package 'fast-xml-builder' instead + */ export class XMLBuilder { constructor(options?: XmlBuilderOptions); build(jObj: any): string; diff --git a/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js b/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js index 18dc3105..8b1ceb92 100644 --- a/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js +++ b/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js @@ -35,11 +35,8 @@ export default class DocTypeReader { ); } //const escaped = entityName.replace(/[.\-+*:]/g, '\\.'); - const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - entities[entityName] = { - regx: RegExp(`&${escaped};`, "g"), - val: val - }; + //const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + entities[entityName] = val; entityCount++; } } diff --git a/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js b/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js index baf6f9c2..ea3fff8a 100644 --- a/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +++ b/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js @@ -1,4 +1,5 @@ import { DANGEROUS_PROPERTY_NAMES, criticalProperties } from "../util.js"; +import { COMMON_HTML, CURRENCY } from '@nodable/entities'; const defaultOnDangerousProperty = (name) => { if (DANGEROUS_PROPERTY_NAMES.includes(name)) { @@ -39,6 +40,7 @@ export const defaultOptions = { unpairedTags: [], processEntities: true, htmlEntities: false, + entityDecoder: null, ignoreDeclaration: false, ignorePiTags: false, transformTagName: false, @@ -85,18 +87,19 @@ function validatePropertyName(propertyName, optionName) { * @param {boolean|object} value * @returns {object} Always returns normalized object */ -function normalizeProcessEntities(value) { +function normalizeProcessEntities(value, htmlEntities) { // Boolean backward compatibility if (typeof value === 'boolean') { return { enabled: value, // true or false maxEntitySize: 10000, - maxExpansionDepth: 10, - maxTotalExpansions: 1000, + maxExpansionDepth: 10000, + maxTotalExpansions: Infinity, maxExpandedLength: 100000, - maxEntityCount: 100, + maxEntityCount: 1000, allowedTags: null, - tagFilter: null + tagFilter: null, + appliesTo: "all", }; } @@ -105,12 +108,13 @@ function normalizeProcessEntities(value) { return { enabled: value.enabled !== false, maxEntitySize: Math.max(1, value.maxEntitySize ?? 10000), - maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10), - maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? 1000), + maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 10000), + maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity), maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 100000), - maxEntityCount: Math.max(1, value.maxEntityCount ?? 100), + maxEntityCount: Math.max(1, value.maxEntityCount ?? 1000), allowedTags: value.allowedTags ?? null, - tagFilter: value.tagFilter ?? null + tagFilter: value.tagFilter ?? null, + appliesTo: value.appliesTo ?? "all", }; } @@ -141,8 +145,8 @@ export const buildOptions = function (options) { } // Always normalize processEntities for backward compatibility and validation - built.processEntities = normalizeProcessEntities(built.processEntities); - + built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities); + built.unpairedTagsSet = new Set(built.unpairedTags); // Convert old-style stopNodes for backward compatibility if (built.stopNodes && Array.isArray(built.stopNodes)) { built.stopNodes = built.stopNodes.map(node => { diff --git a/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js b/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js index dce04c94..c8da90b8 100644 --- a/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js +++ b/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js @@ -7,6 +7,8 @@ import DocTypeReader from './DocTypeReader.js'; import toNumber from "strnum"; import getIgnoreAttributesFn from "../ignoreAttributes.js"; import { Expression, Matcher } from 'path-expression-matcher'; +import { ExpressionSet } from 'path-expression-matcher'; +import { EntityDecoder, XML, CURRENCY, COMMON_HTML } from '@nodable/entities'; // const regx = // '<((!\\[CDATA\\[([\\s\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\/)(NAME)\\s*>))([^<]*)' @@ -71,32 +73,6 @@ export default class OrderedObjParser { 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: "¢" }, - "pound": { regex: /&(pound|#163);/g, val: "£" }, - "yen": { regex: /&(yen|#165);/g, val: "¥" }, - "euro": { regex: /&(euro|#8364);/g, val: "€" }, - "copyright": { regex: /&(copy|#169);/g, val: "©" }, - "reg": { regex: /&(reg|#174);/g, val: "®" }, - "inr": { regex: /&(inr|#8377);/g, val: "₹" }, - "num_dec": { regex: /&#([0-9]{1,7});/g, val: (_, str) => fromCodePoint(str, 10, "&#") }, - "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val: (_, str) => fromCodePoint(str, 16, "&#x") }, - }; - this.addExternalEntities = addExternalEntities; this.parseXml = parseXml; this.parseTextData = parseTextData; this.resolveNameSpace = resolveNameSpace; @@ -109,42 +85,54 @@ export default class OrderedObjParser { 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: namedEntities, + numericAllowed: this.options.htmlEntities, + limit: { + maxTotalExpansions: this.options.processEntities.maxTotalExpansions, + maxExpandedLength: this.options.processEntities.maxExpandedLength, + applyLimitsTo: this.options.processEntities.appliesTo, + } + //postCheck: resolved => resolved + }); + } // Initialize path matcher for path-expression-matcher this.matcher = new Matcher(); + // Live read-only proxy of matcher — PEM creates and caches this internally. + // All user callbacks receive this instead of the mutable matcher. + this.readonlyMatcher = this.matcher.readOnly(); + // Flag to track if current node is a stop node (optimization) this.isCurrentNodeStopNode = false; // Pre-compile stopNodes expressions - 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') { // Convert string to Expression object - this.stopNodeExpressions.push(new Expression(stopNodeExp)); + this.stopNodeExpressionsSet.add(new Expression(stopNodeExp)); } else if (stopNodeExp instanceof Expression) { // Already an Expression object - 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] - } - } -} /** * @param {string} val @@ -156,28 +144,29 @@ function addExternalEntities(externalEntities) { * @param {boolean} escapeEntities */ function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) { + const options = this.options; if (val !== undefined) { - if (this.options.trimValues && !dontTrim) { + if (options.trimValues && !dontTrim) { val = val.trim(); } if (val.length > 0) { if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath); // Pass jPath string or matcher based on options.jPath setting - 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 === undefined) { //don't parse return val; } else if (typeof newval !== typeof val || newval !== val) { //overwrite 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; } @@ -204,8 +193,9 @@ function resolveNameSpace(tagname) { //const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm"); const 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')) { // attrStr = attrStr.replace(/\r?\n/g, ' '); //attrStr = attrStr || attrStr.trim(); @@ -213,89 +203,80 @@ function buildAttributesMap(attrStr, jPath, tagName) { const len = matches.length; //don't make it inline const attrs = {}; - // First pass: parse all attributes and update matcher with raw values - // This ensures the matcher has all attribute values when processors run + // Pre-process values once: trim + entity replacement + // Reused in both matcher update and second pass + const processedVals = new Array(len); + let hasRawAttrs = false; const rawAttrsForMatcher = {}; + for (let i = 0; i < len; i++) { const attrName = this.resolveNameSpace(matches[i][1]); const oldVal = matches[i][4]; if (attrName.length && oldVal !== undefined) { - let parsedVal = oldVal; - if (this.options.trimValues) { - parsedVal = parsedVal.trim(); - } - parsedVal = this.replaceEntitiesValue(parsedVal, tagName, jPath); - rawAttrsForMatcher[attrName] = parsedVal; + let val = oldVal; + if (options.trimValues) val = val.trim(); + val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher); + processedVals[i] = val; + + rawAttrsForMatcher[attrName] = val; + hasRawAttrs = true; } } - // Update matcher with raw attribute values BEFORE running processors - if (Object.keys(rawAttrsForMatcher).length > 0 && typeof jPath === 'object' && jPath.updateCurrent) { + // Update matcher ONCE before second pass, if applicable + if (hasRawAttrs && typeof jPath === 'object' && jPath.updateCurrent) { jPath.updateCurrent(rawAttrsForMatcher); } - // Second pass: now process attributes with matcher having full attribute context + // Hoist toString() once — path doesn't change during attribute processing + const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher; + + // Second pass: apply processors, build final attrs + let hasAttrs = false; for (let i = 0; i < len; i++) { const attrName = this.resolveNameSpace(matches[i][1]); - // Convert jPath to string if needed for ignoreAttributesFn - const jPathStr = this.options.jPath ? jPath.toString() : jPath; - if (this.ignoreAttributesFn(attrName, jPathStr)) { - continue - } + if (this.ignoreAttributesFn(attrName, jPathStr)) continue; - let oldVal = matches[i][4]; - 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); } - //if (aName === "__proto__") aName = "#__proto__"; - aName = sanitizeName(aName, this.options); + aName = sanitizeName(aName, options); - if (oldVal !== undefined) { - if (this.options.trimValues) { - oldVal = oldVal.trim(); - } - oldVal = this.replaceEntitiesValue(oldVal, tagName, jPath); + if (matches[i][4] !== undefined) { + // Reuse already-processed value — no double entity replacement + const oldVal = processedVals[i]; - // Pass jPath string or matcher based on options.jPath setting - const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath; - const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPathOrMatcher); + const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr); if (newVal === null || newVal === undefined) { - //don't parse attrs[aName] = oldVal; } else if (typeof newVal !== typeof oldVal || newVal !== oldVal) { - //overwrite attrs[aName] = newVal; } else { - //parse - attrs[aName] = parseValue( - oldVal, - this.options.parseAttributeValue, - this.options.numberParseOptions - ); + attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions); } - } else if (this.options.allowBooleanAttributes) { + hasAttrs = true; + } else if (options.allowBooleanAttributes) { attrs[aName] = true; + hasAttrs = true; } } } - if (!Object.keys(attrs).length) { - return; - } - if (this.options.attributesGroupName) { + if (!hasAttrs) return; + + if (options.attributesGroupName) { const attrCollection = {}; - attrCollection[this.options.attributesGroupName] = attrs; + attrCollection[options.attributesGroupName] = attrs; return attrCollection; } - return attrs + return attrs; } } - const parseXml = function (xmlData) { xmlData = xmlData.replace(/\r\n?/g, "\n"); //TODO: remove this line const xmlObj = new xmlNode('!xml'); @@ -304,40 +285,43 @@ const parseXml = function (xmlData) { // Reset matcher for new document this.matcher.reset(); + this.entityDecoder.reset(); // Reset entity expansion counters for this document this.entityExpansionCount = 0; this.currentExpandedLength = 0; - - const docTypeReader = new DocTypeReader(this.options.processEntities); - for (let i = 0; i < xmlData.length; i++) {//for each char in XML data + const options = this.options; + const docTypeReader = new DocTypeReader(options.processEntities); + const xmlLen = xmlData.length; + for (let i = 0; i < xmlLen; i++) {//for each char in XML data const ch = xmlData[i]; if (ch === '<') { // const nextIndex = i+1; // const _2ndChar = xmlData[nextIndex]; - if (xmlData[i + 1] === '/') {//Closing Tag + const c1 = xmlData.charCodeAt(i + 1); + if (c1 === 47) {//Closing Tag '/' 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.matcher); + textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); } //check if last tag of nested tag was unpaired tag 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)) { // Pop the unpaired tag this.matcher.pop(); this.tagsNodeStack.pop(); @@ -349,65 +333,74 @@ const parseXml = function (xmlData) { currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope 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.matcher); - if ((this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags) { + textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); + 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.0); + } + if ((options.ignoreDeclaration && tagData.tagName === "?xml") || options.ignorePiTags) { //do nothing } else { const childNode = new xmlNode(tagData.tagName); - childNode.add(this.options.textNodeName, ""); + childNode.add(options.textNodeName, ""); - if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent) { - childNode[":@"] = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName); + if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) { + childNode[":@"] = attsMap } - this.addChild(currentNode, childNode, this.matcher, i); + 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.matcher); + 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) { //'!D' 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.matcher); + textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher); - let val = this.parseTextData(tagExp, currentNode.tagname, this.matcher, true, false, true, true); + let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true); if (val == undefined) val = ""; //cdata should be set even if it is 0 length string - 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 {//Opening tag - let result = readTagExp(xmlData, i, this.options.removeNSPrefix); + let result = readTagExp(xmlData, i, options.removeNSPrefix); // Safety check: readTagExp can return undefined if (!result) { // Log context for debugging - const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlData.length, i + 50)); + const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50)); throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context}"`); } @@ -417,13 +410,13 @@ const parseXml = function (xmlData) { let attrExpPresent = result.attrExpPresent; let closeIndex = result.closeIndex; - ({ tagName, tagExp } = transformTagName(this.options.transformTagName, tagName, tagExp, this.options)); + ({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options)); - if (this.options.strictReservedNames && - (tagName === this.options.commentPropName - || tagName === this.options.cdataPropName - || tagName === this.options.textNodeName - || tagName === this.options.attributesGroupName + if (options.strictReservedNames && + (tagName === options.commentPropName + || tagName === options.cdataPropName + || tagName === options.textNodeName + || tagName === options.attributesGroupName )) { throw new Error(`Invalid tag name: ${tagName}`); } @@ -432,13 +425,13 @@ const parseXml = function (xmlData) { if (currentNode && textData) { if (currentNode.tagname !== '!xml') { //when nested tag is found - textData = this.saveTextToParentTag(textData, currentNode, this.matcher, false); + textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false); } } //check if last tag was unpaired tag 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(); } @@ -480,13 +473,14 @@ const parseXml = function (xmlData) { if (prefixedAttrs) { // Extract raw attributes (without prefix) for our use - rawAttrs = extractRawAttributes(prefixedAttrs, this.options); + //TODO: seems a performance overhead + rawAttrs = extractRawAttributes(prefixedAttrs, options); } } // Now check if this is a stop node (after attributes are set) if (tagName !== xmlObj.tagname) { - this.isCurrentNodeStopNode = this.isItStopNode(this.stopNodeExpressions, this.matcher); + this.isCurrentNodeStopNode = this.isItStopNode(); } const startIndex = i; @@ -498,7 +492,7 @@ const parseXml = function (xmlData) { i = result.closeIndex; } //unpaired tag - else if (this.options.unpairedTags.indexOf(tagName) !== -1) { + else if (options.unpairedTagsSet.has(tagName)) { i = result.closeIndex; } //normal tag @@ -517,31 +511,31 @@ const parseXml = function (xmlData) { } // For stop nodes, store raw content as-is without any processing - childNode.add(this.options.textNodeName, tagContent); + childNode.add(options.textNodeName, tagContent); this.matcher.pop(); // Pop the stop node tag this.isCurrentNodeStopNode = false; // Reset flag - this.addChild(currentNode, childNode, this.matcher, startIndex); + this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex); } else { //selfClosing tag 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; } - this.addChild(currentNode, childNode, this.matcher, startIndex); + this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex); this.matcher.pop(); // Pop self-closing tag this.isCurrentNodeStopNode = false; // Reset flag } - else if (this.options.unpairedTags.indexOf(tagName) !== -1) {//unpaired tag + else if (options.unpairedTagsSet.has(tagName)) {//unpaired tag const childNode = new xmlNode(tagName); if (prefixedAttrs) { childNode[":@"] = prefixedAttrs; } - this.addChild(currentNode, childNode, this.matcher, startIndex); + this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex); this.matcher.pop(); // Pop unpaired tag this.isCurrentNodeStopNode = false; // Reset flag i = result.closeIndex; @@ -551,7 +545,7 @@ const parseXml = function (xmlData) { //opening tag 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); @@ -559,7 +553,7 @@ const parseXml = function (xmlData) { if (prefixedAttrs) { childNode[":@"] = prefixedAttrs; } - this.addChild(currentNode, childNode, this.matcher, startIndex); + this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex); currentNode = childNode; } textData = ""; @@ -622,79 +616,7 @@ function replaceEntitiesValue(val, tagName, jPath) { } } - // Replace DOCTYPE entities - for (const entityName of Object.keys(this.docTypeEntities)) { - const entity = this.docTypeEntities[entityName]; - const matches = val.match(entity.regx); - - if (matches) { - // Track expansions - this.entityExpansionCount += matches.length; - - // Check expansion limit - if (entityConfig.maxTotalExpansions && - this.entityExpansionCount > entityConfig.maxTotalExpansions) { - throw new Error( - `Entity expansion limit exceeded: ${this.entityExpansionCount} > ${entityConfig.maxTotalExpansions}` - ); - } - - // Store length before replacement - const lengthBefore = val.length; - val = val.replace(entity.regx, entity.val); - - // Check expanded length immediately after replacement - 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}` - ); - } - } - } - } - // Replace standard entities - 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; - - // Replace HTML entities if enabled - 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) { - //console.log(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); - } - } - - // Replace ampersand entity last - val = val.replace(this.ampEntity.regex, this.ampEntity.val); - - return val; + return this.entityDecoder.decode(val); } @@ -716,20 +638,14 @@ function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) { return textData; } -//TODO: use jPath to simplify the logic /** * @param {Array} stopNodeExpressions - Array of compiled Expression objects * @param {Matcher} matcher - Current path matcher */ -function isItStopNode(stopNodeExpressions, matcher) { - if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false; +function isItStopNode() { + if (this.stopNodeExpressionsSet.size === 0) return false; - for (let i = 0; i < stopNodeExpressions.length; i++) { - if (matcher.matches(stopNodeExpressions[i])) { - return true; - } - } - return false; + return this.matcher.matchesAny(this.stopNodeExpressionsSet); } /** @@ -739,32 +655,33 @@ function isItStopNode(stopNodeExpressions, matcher) { * @returns */ 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 = "";//reset - } else if (ch === '"' || ch === "'") { - attrBoundary = ch; - } else if (ch === closingChar[0]) { - if (closingChar[1]) { - if (xmlData[index + 1] === closingChar[1]) { - return { - data: tagExp, - index: index - } + if (code === attrBoundary) attrBoundary = 0; + } else if (code === 34 || code === 39) { // " or ' + 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: index - } + return { data: String.fromCharCode(...chars), index }; } - } else if (ch === '\t') { - ch = " " + } else if (code === 9) { // \t + chars.push(32); // space + continue; } - tagExp += ch; + + chars.push(code); } } @@ -777,6 +694,12 @@ function findClosingIndex(xmlData, str, i, errMsg) { } } +function findClosingChar(xmlData, char, i, errMsg) { + const closingIndex = xmlData.indexOf(char, i); + if (closingIndex === -1) throw new Error(errMsg); + return closingIndex; // no offset needed +} + function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") { const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar); if (!result) return; @@ -818,10 +741,12 @@ function readStopNodeData(xmlData, tagName, i) { // Starting at 1 since we already have an open tag let openTagCount = 1; - for (; i < xmlData.length; i++) { + const xmllen = xmlData.length; + for (; i < xmllen; i++) { if (xmlData[i] === "<") { - if (xmlData[i + 1] === "/") {//close tag - const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`); + const c1 = xmlData.charCodeAt(i + 1); + if (c1 === 47) {//close tag '/' + const closeIndex = findClosingChar(xmlData, ">", i, `${tagName} is not closed`); let closeTagName = xmlData.substring(i + 2, closeIndex).trim(); if (closeTagName === tagName) { openTagCount--; @@ -833,13 +758,16 @@ 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 { diff --git a/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js b/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js index 4a4d8d6f..292efa1e 100644 --- a/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js +++ b/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js @@ -32,10 +32,10 @@ export default class XMLParser { } } 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 === undefined) return orderedResult; - else return prettify(orderedResult, this.options, orderedObjParser.matcher); + else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher); } /** @@ -68,4 +68,4 @@ export default class XMLParser { static getMetaDataSymbol() { return XmlNode.getMetaDataSymbol(); } -} +} \ No newline at end of file diff --git a/node_modules/fast-xml-parser/src/xmlparser/node2json.js b/node_modules/fast-xml-parser/src/xmlparser/node2json.js index a7992929..c31968a0 100644 --- a/node_modules/fast-xml-parser/src/xmlparser/node2json.js +++ b/node_modules/fast-xml-parser/src/xmlparser/node2json.js @@ -35,18 +35,17 @@ function stripAttributePrefix(attrs, prefix) { * @param {Matcher} matcher - Path matcher instance * @returns */ -export default function prettify(node, options, matcher) { - return compress(node, options, matcher); +export default function prettify(node, options, matcher, readonlyMatcher) { + return compress(node, options, matcher, readonlyMatcher); } /** - * * @param {array} arr * @param {object} options * @param {Matcher} matcher - Path matcher instance * @returns object */ -function compress(arr, options, matcher) { +function compress(arr, options, matcher, readonlyMatcher) { let text; const compressedObj = {}; //This is intended to be a plain object for (let i = 0; i < arr.length; i++) { @@ -69,11 +68,11 @@ function compress(arr, options, matcher) { continue; } else if (tagObj[property]) { - let val = compress(tagObj[property], options, matcher); + let val = compress(tagObj[property], options, matcher, readonlyMatcher); const isLeaf = isLeafTag(val, options); if (tagObj[":@"]) { - assignAttributes(val, tagObj[":@"], matcher, options); + assignAttributes(val, tagObj[":@"], readonlyMatcher, options); } else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) { val = val[options.textNodeName]; } else if (Object.keys(val).length === 0) { @@ -95,8 +94,8 @@ function compress(arr, options, matcher) { //TODO: if a node is not an array, then check if it should be an array //also determine if it is a leaf node - // Pass jPath string or matcher based on options.jPath setting - const jPathOrMatcher = options.jPath ? matcher.toString() : matcher; + // Pass jPath string or readonlyMatcher based on options.jPath setting + const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher; if (options.isArray(property, jPathOrMatcher, isLeaf)) { compressedObj[property] = [val]; } else { @@ -128,7 +127,7 @@ function propName(obj) { } } -function assignAttributes(obj, attrMap, matcher, options) { +function assignAttributes(obj, attrMap, readonlyMatcher, options) { if (attrMap) { const keys = Object.keys(attrMap); const len = keys.length; //don't make it inline @@ -143,8 +142,8 @@ function assignAttributes(obj, attrMap, matcher, options) { // For attributes, we need to create a temporary path // Pass jPath string or matcher based on options.jPath setting const jPathOrMatcher = options.jPath - ? matcher.toString() + "." + rawAttrName - : matcher; + ? readonlyMatcher.toString() + "." + rawAttrName + : readonlyMatcher; if (options.isArray(atrrName, jPathOrMatcher, true, true)) { obj[atrrName] = [attrMap[atrrName]]; diff --git a/node_modules/filesize/README.md b/node_modules/filesize/README.md index 9828da3f..9391eaa8 100644 --- a/node_modules/filesize/README.md +++ b/node_modules/filesize/README.md @@ -212,15 +212,6 @@ filesize.js/ 2. Avoid locale formatting in performance-critical code 3. Use `object` output for fastest structured data access -## Browser Usage - -```html - - -``` - ## Contributing We welcome contributions! Please see our [Contributing Guidelines](https://github.com/avoidwork/filesize.js/blob/master/CONTRIBUTING.md) for details. diff --git a/node_modules/filesize/dist/filesize.cjs b/node_modules/filesize/dist/filesize.cjs index b28dce92..a7775e4e 100644 --- a/node_modules/filesize/dist/filesize.cjs +++ b/node_modules/filesize/dist/filesize.cjs @@ -3,7 +3,7 @@ * * @copyright 2026 Jason Mulligan * @license BSD-3-Clause - * @version 11.0.15 + * @version 11.0.17 */ 'use strict'; @@ -141,7 +141,12 @@ function handleZeroValue( spacer, symbol, ) { - const value = precision > 0 ? (0).toPrecision(precision) : 0; + let value; + if (precision > 0) { + value = (0).toPrecision(precision); + } else { + value = 0; + } if (output === EXPONENT) { return 0; @@ -161,7 +166,16 @@ function handleZeroValue( // Apply full form if (full) { - symbol = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + if (fullforms[0]) { + symbol = fullforms[0]; + } else { + symbol = STRINGS.fullform[actualStandard][0]; + if (bits) { + symbol += BIT; + } else { + symbol += BYTE; + } + } } // Return in requested format @@ -187,7 +201,12 @@ function handleZeroValue( * @returns {Object} Object with result and e properties */ function calculateOptimizedValue(num, e, isDecimal, bits, ceil, autoExponent = true) { - const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let d; + if (isDecimal) { + d = DECIMAL_POWERS[e]; + } else { + d = BINARY_POWERS[e]; + } let result = num / d; if (bits) { @@ -228,6 +247,10 @@ function applyPrecisionHandling( round, exponent, ) { + if (typeof value === "string") { + value = parseFloat(value); + } + let result = value.toPrecision(precision); const autoExponent = exponent === -1 || isNaN(exponent); @@ -236,10 +259,19 @@ function applyPrecisionHandling( if (result.includes(E) && e < 8 && autoExponent) { e++; const { result: valueResult } = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - const p = round > 0 ? Math.pow(10, round) : 1; - result = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision( - precision, - ); + let p; + if (round > 0) { + p = Math.pow(10, round); + } else { + p = 1; + } + let computed; + if (p === 1) { + computed = roundingFunc(valueResult); + } else { + computed = roundingFunc(valueResult * p) / p; + } + result = computed.toPrecision(precision); } return { value: result, e }; @@ -283,6 +315,198 @@ function applyNumberFormatting(value, locale, localeOptions, separator, pad, rou return result; } +/** + * Calculates exponent from the input value using pre-computed log values and clamps to supported range + * Also adjusts precision when exponent exceeds the lookup table bounds + * @param {number} num - Input file size in bytes + * @param {number} e - Current exponent value + * @param {number} exponent - Original user-provided exponent option (-1 for auto) + * @param {boolean} isDecimal - Whether to use decimal (SI) base + * @param {number} precision - Current precision value (modified when e > 8) + * @returns {Object} Object with computed e value and possibly adjusted precision + */ +function calculateExponent(num, e, exponent, isDecimal, precision) { + if (e === -1 || isNaN(e)) { + if (isDecimal) { + e = Math.floor(Math.log(num) / LOG_10_1000); + } else { + e = Math.floor(Math.log(num) / LOG_2_1024); + } + if (e < 0) { + e = 0; + } + } + + if (e > 8) { + if (precision > 0) { + precision += 8 - e; + } + return { e: 8, precision }; + } + + return { e, precision }; +} + +/** + * Applies rounding to the raw calculated value and handles auto-increment ceiling + * @param {number} val - Raw value before rounding + * @param {number} ceil - Ceiling threshold (1000 for SI, 1024 for IEC) + * @param {number} e - Current exponent value + * @param {number} round - Number of decimal places + * @param {Function} roundingFunc - Rounding method (Math.round, Math.floor, Math.ceil) + * @param {boolean} autoExponent - Whether exponent is auto-calculated (-1 or NaN) + * @returns {Object} Object with rounded value and possibly incremented exponent + */ +function applyRounding(val, ceil, e, round, roundingFunc, autoExponent) { + let p; + if (e > 0 && round > 0) { + p = Math.pow(10, round); + } else { + p = 1; + } + let r; + if (p === 1) { + r = roundingFunc(val); + } else { + r = roundingFunc(val * p) / p; + } + + if (r === ceil && e < 8 && autoExponent) { + r = 1; + e++; + } + + return { value: r, e }; +} + +/** + * Resolves the unit symbol for the given standard, bits mode, and exponent + * Handles SI standard special case where exponent 1 always uses "kB" or "kbit" + * @param {string} actualStandard - The resolved standard (iec, jedec) + * @param {boolean} bits - Whether formatting bit values + * @param {number} e - Current exponent index + * @param {boolean} isDecimal - Whether using decimal (SI) base + * @returns {string} The resolved unit symbol string + */ +function resolveSymbol(actualStandard, bits, e, isDecimal) { + const symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES]; + let result; + if (isDecimal && e === 1) { + if (bits) { + result = SI_KBIT; + } else { + result = SI_KBYTE; + } + } else { + result = symbolTable[e]; + } + return result; +} + +/** + * Decorates the result: applies negation, custom symbols, number formatting, and full form names + * Mutates the result array in-place for both value (index 0) and symbol (index 1) + * @param {Array} result - Result array with numeric value at [0] and string symbol at [1] + * @param {boolean} neg - Whether the original input was negative + * @param {Object} symbols - Custom symbol override map + * @param {string|boolean} locale - Locale string for formatting + * @param {Object} localeOptions - Additional locale formatting options + * @param {string} separator - Custom decimal separator + * @param {boolean} pad - Whether zero-pad decimals + * @param {number} round - Target decimal count for padding + * @param {boolean} full - Whether to use full unit names + * @param {Array} fullforms - Custom full unit name overrides + * @param {string} actualStandard - Unit standard for full form lookup + * @param {number} e - Current exponent index + * @param {boolean} bits - Whether formatting bit values + * @returns {void} Mutates result array in place + */ +function decorateResult( + result, + neg, + symbols, + locale, + localeOptions, + separator, + pad, + round, + full, + fullforms, + actualStandard, + e, + bits, +) { + if (neg) { + result[0] = -result[0]; + } + + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); + + if (full) { + let unit; + if (bits) { + unit = BIT; + } else { + unit = BYTE; + } + let val; + if (typeof result[0] === "string") { + val = parseFloat(result[0]); + } else { + val = result[0]; + } + // Determine singular/plural suffix + let suffix; + if (val === 1) { + suffix = EMPTY; + } else { + suffix = S; + } + // Determine symbol — custom fullforms are the complete name, defaults get unit+suffix + if (fullforms[e]) { + result[1] = fullforms[e]; + } else { + result[1] = STRINGS.fullform[actualStandard][e] + unit + suffix; + } + } +} + +/** + * Formats the computed result array into the requested output type + * @param {Array} result - Result array with formatted value at [0] and symbol at [1] + * @param {number} e - Current exponent + * @param {string} u - Original resolved symbol (before custom override) + * @param {string} output - Output type (ARRAY, OBJECT, STRING) + * @param {string} spacer - String separator between value and unit + * @returns {string|Array|Object|number} Formatted result in requested type + */ +function formatOutput(result, e, u, output, spacer) { + if (output === ARRAY) { + return result; + } + + if (output === OBJECT) { + return { + value: result[0], + symbol: result[1], + exponent: e, + unit: u, + }; + } + + let formatted; + if (spacer === SPACE) { + formatted = `${result[0]} ${result[1]}`; + } else { + formatted = result.join(spacer); + } + return formatted; +} + /** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert @@ -332,32 +556,39 @@ function filesize( } = {}, ) { let e = exponent, - num = Number(arg), + num, result = [], val = 0, u = EMPTY; - // Optimized base & standard configuration lookup + if (typeof arg === "bigint") { + num = Number(arg); + } else { + num = Number(arg); + + if (isNaN(arg)) { + throw new TypeError(INVALID_NUMBER); + } + + if (!isFinite(num)) { + throw new TypeError(INVALID_NUMBER); + } + } + const { isDecimal, ceil, actualStandard } = getBaseConfiguration(standard, base); const full = fullform === true, neg = num < 0, roundingFunc = Math[roundingMethod]; - if (typeof arg !== "bigint" && isNaN(arg)) { - throw new TypeError(INVALID_NUMBER); - } - if (typeof roundingFunc !== FUNCTION) { throw new TypeError(INVALID_ROUND); } - // Flipping a negative number to determine the size if (neg) { num = -num; } - // Fast path for zero if (num === 0) { return handleZeroValue( precision, @@ -371,31 +602,21 @@ function filesize( ); } - // Optimized exponent calculation using pre-computed log values - if (e === -1 || isNaN(e)) { - e = isDecimal - ? Math.floor(Math.log(num) / LOG_10_1000) - : Math.floor(Math.log(num) / LOG_2_1024); - if (e < 0) { - e = 0; - } - } - - // Exceeding supported length, time to reduce & multiply - if (e > 8) { - if (precision > 0) { - precision += 8 - e; - } - e = 8; - } - + // Exponent calculation + clamp + precision adjustment + const { e: calculatedE, precision: precisionAdjusted } = calculateExponent( + num, + e, + exponent, + isDecimal, + precision, + ); + e = calculatedE; const autoExponent = exponent === -1 || isNaN(exponent); if (output === EXPONENT) { return e; } - // Calculate value with optimized lookup and bits handling const { result: valueResult, e: valueExponent } = calculateOptimizedValue( num, e, @@ -407,20 +628,16 @@ function filesize( val = valueResult; e = valueExponent; - // Optimize rounding calculation - const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; - result[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p; + // Rounding + auto-increment ceiling + const rounded = applyRounding(val, ceil, e, round, roundingFunc, autoExponent); + result[0] = rounded.value; + e = rounded.e; - if (result[0] === ceil && e < 8 && autoExponent) { - result[0] = 1; - e++; - } - - // Apply precision handling - if (precision > 0) { + // Precision handling + if (precisionAdjusted > 0) { const precisionResult = applyPrecisionHandling( result[0], - precision, + precisionAdjusted, e, num, isDecimal, @@ -434,44 +651,26 @@ function filesize( e = precisionResult.e; } - // Cache symbol lookup - const symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES]; - u = result[1] = isDecimal && e === 1 ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e]; - - // Decorating a 'diff' - if (neg) { - result[0] = -result[0]; - } - - // Applying custom symbol - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - // Apply locale, separator, and padding formatting - result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); - - if (full) { - result[1] = - fullforms[e] || - STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S); - } - - // Optimized return logic - if (output === ARRAY) { - return result; - } - - if (output === OBJECT) { - return { - value: result[0], - symbol: result[1], - exponent: e, - unit: u, - }; - } + u = resolveSymbol(actualStandard, bits, e, isDecimal); + result[1] = u; + + decorateResult( + result, + neg, + symbols, + locale, + localeOptions, + separator, + pad, + round, + full, + fullforms, + actualStandard, + e, + bits, + ); - return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); + return formatOutput(result, e, u, output, spacer); } /** @@ -506,18 +705,24 @@ function partial({ base = -1, round = 2, locale = EMPTY, - localeOptions = {}, separator = EMPTY, spacer = SPACE, - symbols = {}, standard = EMPTY, output = STRING, fullform = false, - fullforms = [], exponent = -1, roundingMethod = ROUND, precision = 0, + localeOptions = {}, + symbols = {}, + fullforms = [], } = {}) { + const cloned = { + localeOptions: JSON.parse(JSON.stringify(localeOptions)), + symbols: JSON.parse(JSON.stringify(symbols)), + fullforms: JSON.parse(JSON.stringify(fullforms)), + }; + return (arg) => filesize(arg, { bits, @@ -525,14 +730,14 @@ function partial({ base, round, locale, - localeOptions, + localeOptions: cloned.localeOptions, separator, spacer, - symbols, + symbols: cloned.symbols, standard, output, fullform, - fullforms, + fullforms: cloned.fullforms, exponent, roundingMethod, precision, diff --git a/node_modules/filesize/dist/filesize.js b/node_modules/filesize/dist/filesize.js index 4ccd262b..9273c959 100644 --- a/node_modules/filesize/dist/filesize.js +++ b/node_modules/filesize/dist/filesize.js @@ -3,7 +3,7 @@ * * @copyright 2026 Jason Mulligan * @license BSD-3-Clause - * @version 11.0.15 + * @version 11.0.17 */ // Error Messages const INVALID_NUMBER = "Invalid number"; @@ -137,7 +137,12 @@ function handleZeroValue( spacer, symbol, ) { - const value = precision > 0 ? (0).toPrecision(precision) : 0; + let value; + if (precision > 0) { + value = (0).toPrecision(precision); + } else { + value = 0; + } if (output === EXPONENT) { return 0; @@ -157,7 +162,16 @@ function handleZeroValue( // Apply full form if (full) { - symbol = fullforms[0] || STRINGS.fullform[actualStandard][0] + (bits ? BIT : BYTE); + if (fullforms[0]) { + symbol = fullforms[0]; + } else { + symbol = STRINGS.fullform[actualStandard][0]; + if (bits) { + symbol += BIT; + } else { + symbol += BYTE; + } + } } // Return in requested format @@ -183,7 +197,12 @@ function handleZeroValue( * @returns {Object} Object with result and e properties */ function calculateOptimizedValue(num, e, isDecimal, bits, ceil, autoExponent = true) { - const d = isDecimal ? DECIMAL_POWERS[e] : BINARY_POWERS[e]; + let d; + if (isDecimal) { + d = DECIMAL_POWERS[e]; + } else { + d = BINARY_POWERS[e]; + } let result = num / d; if (bits) { @@ -224,6 +243,10 @@ function applyPrecisionHandling( round, exponent, ) { + if (typeof value === "string") { + value = parseFloat(value); + } + let result = value.toPrecision(precision); const autoExponent = exponent === -1 || isNaN(exponent); @@ -232,10 +255,19 @@ function applyPrecisionHandling( if (result.includes(E) && e < 8 && autoExponent) { e++; const { result: valueResult } = calculateOptimizedValue(num, e, isDecimal, bits, ceil); - const p = round > 0 ? Math.pow(10, round) : 1; - result = (p === 1 ? roundingFunc(valueResult) : roundingFunc(valueResult * p) / p).toPrecision( - precision, - ); + let p; + if (round > 0) { + p = Math.pow(10, round); + } else { + p = 1; + } + let computed; + if (p === 1) { + computed = roundingFunc(valueResult); + } else { + computed = roundingFunc(valueResult * p) / p; + } + result = computed.toPrecision(precision); } return { value: result, e }; @@ -277,6 +309,198 @@ function applyNumberFormatting(value, locale, localeOptions, separator, pad, rou } return result; +} + +/** + * Calculates exponent from the input value using pre-computed log values and clamps to supported range + * Also adjusts precision when exponent exceeds the lookup table bounds + * @param {number} num - Input file size in bytes + * @param {number} e - Current exponent value + * @param {number} exponent - Original user-provided exponent option (-1 for auto) + * @param {boolean} isDecimal - Whether to use decimal (SI) base + * @param {number} precision - Current precision value (modified when e > 8) + * @returns {Object} Object with computed e value and possibly adjusted precision + */ +function calculateExponent(num, e, exponent, isDecimal, precision) { + if (e === -1 || isNaN(e)) { + if (isDecimal) { + e = Math.floor(Math.log(num) / LOG_10_1000); + } else { + e = Math.floor(Math.log(num) / LOG_2_1024); + } + if (e < 0) { + e = 0; + } + } + + if (e > 8) { + if (precision > 0) { + precision += 8 - e; + } + return { e: 8, precision }; + } + + return { e, precision }; +} + +/** + * Applies rounding to the raw calculated value and handles auto-increment ceiling + * @param {number} val - Raw value before rounding + * @param {number} ceil - Ceiling threshold (1000 for SI, 1024 for IEC) + * @param {number} e - Current exponent value + * @param {number} round - Number of decimal places + * @param {Function} roundingFunc - Rounding method (Math.round, Math.floor, Math.ceil) + * @param {boolean} autoExponent - Whether exponent is auto-calculated (-1 or NaN) + * @returns {Object} Object with rounded value and possibly incremented exponent + */ +function applyRounding(val, ceil, e, round, roundingFunc, autoExponent) { + let p; + if (e > 0 && round > 0) { + p = Math.pow(10, round); + } else { + p = 1; + } + let r; + if (p === 1) { + r = roundingFunc(val); + } else { + r = roundingFunc(val * p) / p; + } + + if (r === ceil && e < 8 && autoExponent) { + r = 1; + e++; + } + + return { value: r, e }; +} + +/** + * Resolves the unit symbol for the given standard, bits mode, and exponent + * Handles SI standard special case where exponent 1 always uses "kB" or "kbit" + * @param {string} actualStandard - The resolved standard (iec, jedec) + * @param {boolean} bits - Whether formatting bit values + * @param {number} e - Current exponent index + * @param {boolean} isDecimal - Whether using decimal (SI) base + * @returns {string} The resolved unit symbol string + */ +function resolveSymbol(actualStandard, bits, e, isDecimal) { + const symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES]; + let result; + if (isDecimal && e === 1) { + if (bits) { + result = SI_KBIT; + } else { + result = SI_KBYTE; + } + } else { + result = symbolTable[e]; + } + return result; +} + +/** + * Decorates the result: applies negation, custom symbols, number formatting, and full form names + * Mutates the result array in-place for both value (index 0) and symbol (index 1) + * @param {Array} result - Result array with numeric value at [0] and string symbol at [1] + * @param {boolean} neg - Whether the original input was negative + * @param {Object} symbols - Custom symbol override map + * @param {string|boolean} locale - Locale string for formatting + * @param {Object} localeOptions - Additional locale formatting options + * @param {string} separator - Custom decimal separator + * @param {boolean} pad - Whether zero-pad decimals + * @param {number} round - Target decimal count for padding + * @param {boolean} full - Whether to use full unit names + * @param {Array} fullforms - Custom full unit name overrides + * @param {string} actualStandard - Unit standard for full form lookup + * @param {number} e - Current exponent index + * @param {boolean} bits - Whether formatting bit values + * @returns {void} Mutates result array in place + */ +function decorateResult( + result, + neg, + symbols, + locale, + localeOptions, + separator, + pad, + round, + full, + fullforms, + actualStandard, + e, + bits, +) { + if (neg) { + result[0] = -result[0]; + } + + if (symbols[result[1]]) { + result[1] = symbols[result[1]]; + } + + result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); + + if (full) { + let unit; + if (bits) { + unit = BIT; + } else { + unit = BYTE; + } + let val; + if (typeof result[0] === "string") { + val = parseFloat(result[0]); + } else { + val = result[0]; + } + // Determine singular/plural suffix + let suffix; + if (val === 1) { + suffix = EMPTY; + } else { + suffix = S; + } + // Determine symbol — custom fullforms are the complete name, defaults get unit+suffix + if (fullforms[e]) { + result[1] = fullforms[e]; + } else { + result[1] = STRINGS.fullform[actualStandard][e] + unit + suffix; + } + } +} + +/** + * Formats the computed result array into the requested output type + * @param {Array} result - Result array with formatted value at [0] and symbol at [1] + * @param {number} e - Current exponent + * @param {string} u - Original resolved symbol (before custom override) + * @param {string} output - Output type (ARRAY, OBJECT, STRING) + * @param {string} spacer - String separator between value and unit + * @returns {string|Array|Object|number} Formatted result in requested type + */ +function formatOutput(result, e, u, output, spacer) { + if (output === ARRAY) { + return result; + } + + if (output === OBJECT) { + return { + value: result[0], + symbol: result[1], + exponent: e, + unit: u, + }; + } + + let formatted; + if (spacer === SPACE) { + formatted = `${result[0]} ${result[1]}`; + } else { + formatted = result.join(spacer); + } + return formatted; }/** * Converts a file size in bytes to a human-readable string with appropriate units * @param {number|string|bigint} arg - The file size in bytes to convert @@ -326,32 +550,39 @@ function filesize( } = {}, ) { let e = exponent, - num = Number(arg), + num, result = [], val = 0, u = EMPTY; - // Optimized base & standard configuration lookup + if (typeof arg === "bigint") { + num = Number(arg); + } else { + num = Number(arg); + + if (isNaN(arg)) { + throw new TypeError(INVALID_NUMBER); + } + + if (!isFinite(num)) { + throw new TypeError(INVALID_NUMBER); + } + } + const { isDecimal, ceil, actualStandard } = getBaseConfiguration(standard, base); const full = fullform === true, neg = num < 0, roundingFunc = Math[roundingMethod]; - if (typeof arg !== "bigint" && isNaN(arg)) { - throw new TypeError(INVALID_NUMBER); - } - if (typeof roundingFunc !== FUNCTION) { throw new TypeError(INVALID_ROUND); } - // Flipping a negative number to determine the size if (neg) { num = -num; } - // Fast path for zero if (num === 0) { return handleZeroValue( precision, @@ -365,31 +596,21 @@ function filesize( ); } - // Optimized exponent calculation using pre-computed log values - if (e === -1 || isNaN(e)) { - e = isDecimal - ? Math.floor(Math.log(num) / LOG_10_1000) - : Math.floor(Math.log(num) / LOG_2_1024); - if (e < 0) { - e = 0; - } - } - - // Exceeding supported length, time to reduce & multiply - if (e > 8) { - if (precision > 0) { - precision += 8 - e; - } - e = 8; - } - + // Exponent calculation + clamp + precision adjustment + const { e: calculatedE, precision: precisionAdjusted } = calculateExponent( + num, + e, + exponent, + isDecimal, + precision, + ); + e = calculatedE; const autoExponent = exponent === -1 || isNaN(exponent); if (output === EXPONENT) { return e; } - // Calculate value with optimized lookup and bits handling const { result: valueResult, e: valueExponent } = calculateOptimizedValue( num, e, @@ -401,20 +622,16 @@ function filesize( val = valueResult; e = valueExponent; - // Optimize rounding calculation - const p = e > 0 && round > 0 ? Math.pow(10, round) : 1; - result[0] = p === 1 ? roundingFunc(val) : roundingFunc(val * p) / p; + // Rounding + auto-increment ceiling + const rounded = applyRounding(val, ceil, e, round, roundingFunc, autoExponent); + result[0] = rounded.value; + e = rounded.e; - if (result[0] === ceil && e < 8 && autoExponent) { - result[0] = 1; - e++; - } - - // Apply precision handling - if (precision > 0) { + // Precision handling + if (precisionAdjusted > 0) { const precisionResult = applyPrecisionHandling( result[0], - precision, + precisionAdjusted, e, num, isDecimal, @@ -428,44 +645,26 @@ function filesize( e = precisionResult.e; } - // Cache symbol lookup - const symbolTable = STRINGS.symbol[actualStandard][bits ? BITS : BYTES]; - u = result[1] = isDecimal && e === 1 ? (bits ? SI_KBIT : SI_KBYTE) : symbolTable[e]; - - // Decorating a 'diff' - if (neg) { - result[0] = -result[0]; - } - - // Applying custom symbol - if (symbols[result[1]]) { - result[1] = symbols[result[1]]; - } - - // Apply locale, separator, and padding formatting - result[0] = applyNumberFormatting(result[0], locale, localeOptions, separator, pad, round); - - if (full) { - result[1] = - fullforms[e] || - STRINGS.fullform[actualStandard][e] + (bits ? BIT : BYTE) + (result[0] === 1 ? EMPTY : S); - } - - // Optimized return logic - if (output === ARRAY) { - return result; - } - - if (output === OBJECT) { - return { - value: result[0], - symbol: result[1], - exponent: e, - unit: u, - }; - } + u = resolveSymbol(actualStandard, bits, e, isDecimal); + result[1] = u; + + decorateResult( + result, + neg, + symbols, + locale, + localeOptions, + separator, + pad, + round, + full, + fullforms, + actualStandard, + e, + bits, + ); - return spacer === SPACE ? `${result[0]} ${result[1]}` : result.join(spacer); + return formatOutput(result, e, u, output, spacer); } /** @@ -500,18 +699,24 @@ function partial({ base = -1, round = 2, locale = EMPTY, - localeOptions = {}, separator = EMPTY, spacer = SPACE, - symbols = {}, standard = EMPTY, output = STRING, fullform = false, - fullforms = [], exponent = -1, roundingMethod = ROUND, precision = 0, + localeOptions = {}, + symbols = {}, + fullforms = [], } = {}) { + const cloned = { + localeOptions: JSON.parse(JSON.stringify(localeOptions)), + symbols: JSON.parse(JSON.stringify(symbols)), + fullforms: JSON.parse(JSON.stringify(fullforms)), + }; + return (arg) => filesize(arg, { bits, @@ -519,14 +724,14 @@ function partial({ base, round, locale, - localeOptions, + localeOptions: cloned.localeOptions, separator, spacer, - symbols, + symbols: cloned.symbols, standard, output, fullform, - fullforms, + fullforms: cloned.fullforms, exponent, roundingMethod, precision, diff --git a/node_modules/filesize/package.json b/node_modules/filesize/package.json index 127722b7..7c1af06b 100644 --- a/node_modules/filesize/package.json +++ b/node_modules/filesize/package.json @@ -1,7 +1,7 @@ { "name": "filesize", - "description": "JavaScript library to generate a human readable String describing the file size", - "version": "11.0.15", + "description": "Lightweight, zero-dependency JavaScript utility to convert bytes to human-readable strings with localization support", + "version": "11.0.17", "homepage": "https://filesizejs.com", "author": "Jason Mulligan ", "repository": { @@ -57,7 +57,7 @@ "@rollup/plugin-terser": "^1.0.0", "auto-changelog": "^2.5.0", "husky": "^9.1.7", - "oxfmt": "^0.42.0", + "oxfmt": "^0.46.0", "oxlint": "^1.57.0", "rollup": "^4.52.0" }, diff --git a/node_modules/path-expression-matcher/README.md b/node_modules/path-expression-matcher/README.md index 4af53aa3..3f655baf 100644 --- a/node_modules/path-expression-matcher/README.md +++ b/node_modules/path-expression-matcher/README.md @@ -4,10 +4,11 @@ Efficient path tracking and pattern matching for XML, JSON, YAML or any other pa ## 🎯 Purpose -`path-expression-matcher` provides two core classes for tracking and matching paths: +`path-expression-matcher` provides three core classes for tracking and matching paths: - **`Expression`**: Parses and stores pattern expressions (e.g., `"root.users.user[id]"`) - **`Matcher`**: Tracks current path during parsing and matches against expressions +- **`MatcherView`**: A lightweight read-only view of a `Matcher`, safe to pass to callbacks Compatible with [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) and similar tools. @@ -138,7 +139,7 @@ console.log(matcher.toString()); // "soap:Envelope.soap:Body.ns:UserId" #### Constructor ```javascript -new Expression(pattern, options) +new Expression(pattern, options = {}, data) ``` **Parameters:** @@ -149,6 +150,8 @@ new Expression(pattern, options) ```javascript const expr1 = new Expression("root.users.user"); const expr2 = new Expression("root/users/user", { separator: '/' }); +const expr3 = new Expression("root/users/user", { separator: '/' }, { extra: "data"}); +console.log(expr3.data) // { extra: "data" } ``` #### Methods @@ -240,6 +243,22 @@ if (matcher.matches(expr)) { } ``` +#### `matchesAny(exprSet)` → `boolean` + +Please check `ExpressionSet` class for more details. + +```javascript +const matcher = new Matcher(); +const exprSet = new ExpressionSet(); +exprSet.add(new Expression("root.users.user")); +exprSet.add(new Expression("root.config.*")); +exprSet.seal(); + +if (matcher.matchesAny(exprSet)) { + // Current path matches any expression in the set +} +``` + ##### `getCurrentTag()` Get current tag name. @@ -346,6 +365,57 @@ Restore from a snapshot. matcher.restore(snapshot); ``` +#### Read-Only Access + +##### `readOnly()` + +Returns a **`MatcherView`** — a lightweight, live read-only view of the matcher. All query and inspection methods work normally and always reflect the current state of the underlying matcher. Mutation methods (`push`, `pop`, `reset`, `updateCurrent`, `restore`) simply don't exist on `MatcherView`, so misuse is caught at **compile time** by TypeScript rather than at runtime. + +The **same instance** is returned on every call — no allocation occurs per invocation. This is the recommended way to share the matcher with callbacks, plugins, or any external code that only needs to inspect the current path. + +```javascript +const view = matcher.readOnly(); +// Same reference every time — safe to cache +view === matcher.readOnly(); // true +``` + +**What works on the view:** + +```javascript +view.matches(expr) // ✓ pattern matching +view.getCurrentTag() // ✓ current tag name +view.getCurrentNamespace() // ✓ current namespace +view.getAttrValue("id") // ✓ attribute value +view.hasAttr("id") // ✓ attribute presence check +view.getPosition() // ✓ sibling position +view.getCounter() // ✓ occurrence counter +view.getDepth() // ✓ path depth +view.toString() // ✓ path as string +view.toArray() // ✓ path as array +``` + +**What doesn't exist (compile-time error in TypeScript):** + +```javascript +view.push("child", {}) // ✗ Property 'push' does not exist on type 'MatcherView' +view.pop() // ✗ Property 'pop' does not exist on type 'MatcherView' +view.reset() // ✗ Property 'reset' does not exist on type 'MatcherView' +view.updateCurrent({}) // ✗ Property 'updateCurrent' does not exist on type 'MatcherView' +view.restore(snapshot) // ✗ Property 'restore' does not exist on type 'MatcherView' +``` + +**The view is live** — it always reflects the current state of the underlying matcher. + +```javascript +const matcher = new Matcher(); +const view = matcher.readOnly(); + +matcher.push("root"); +view.getDepth(); // 1 — immediately reflects the push +matcher.push("users"); +view.getDepth(); // 2 — still live +``` + ## 💡 Usage Examples ### Example 1: XML Parser with stopNodes @@ -481,7 +551,39 @@ const expr = new Expression("root.item:first"); console.log(matcher.matches(expr)); // false (counter=1, not 0) ``` -### Example 7: Namespace Support (XML/SOAP) +### Example 8: Passing a Read-Only View to External Consumers + +When passing the matcher into callbacks, plugins, or other code you don't control, use `readOnly()` to get a `MatcherView` — it can inspect but never mutate parser state. + +```javascript +import { Expression, Matcher } from 'path-expression-matcher'; + +const matcher = new Matcher(); + +const adminExpr = new Expression("..user[type=admin]"); + +function parseTag(tagName, attrs, onTag) { + matcher.push(tagName, attrs); + + // Pass MatcherView — consumer can inspect but not mutate + onTag(matcher.readOnly()); + + matcher.pop(); +} + +// Safe consumer — can only read +function myPlugin(view) { + if (view.matches(adminExpr)) { + console.log("Admin at path:", view.toString()); + console.log("Depth:", view.getDepth()); + console.log("ID:", view.getAttrValue("id")); + } +} + +// view.push(...) or view.reset() don't exist on MatcherView — +// TypeScript catches misuse at compile time. +parseTag("user", { id: "1", type: "admin" }, myPlugin); +``` ```javascript const matcher = new Matcher(); @@ -577,21 +679,168 @@ for (let i = 0; i < 1000; i++) { } ``` -### Batch Pattern Checking +### Batch Pattern Checking with ExpressionSet (Recommended) + +For checking multiple patterns on every tag, use `ExpressionSet` instead of a manual loop. +It pre-indexes expressions at build time so each call to `matchesAny()` does an O(1) bucket +lookup rather than a full O(N) scan: ```javascript -// For multiple patterns, check all at once -const patterns = [ - new Expression("..user"), - new Expression("..post"), - new Expression("..comment"), -]; +import { Expression, ExpressionSet, Matcher } from 'path-expression-matcher'; -function matchesAny(matcher, patterns) { - return patterns.some(expr => matcher.matches(expr)); +// Build once at config/startup time +const stopNodes = new ExpressionSet(); +stopNodes + .add(new Expression('root.users.user')) + .add(new Expression('root.config.*')) + .add(new Expression('..script')) + .seal(); // prevent accidental mutation during parsing + +// Per-tag — hot path +if (stopNodes.matchesAny(matcher)) { + // handle stop node +} +``` + +This replaces the manual loop pattern: + +```javascript +// ❌ Before — O(N) per tag +function isStopNode(expressions, matcher) { + for (let i = 0; i < expressions.length; i++) { + if (matcher.matches(expressions[i])) return true; + } + return false; } + +// ✅ After — O(1) lookup per tag +const stopNodes = new ExpressionSet(); +stopNodes.addAll(expressions); +stopNodes.matchesAny(matcher); +//or matcher.matchesAny(stopNodes) ``` +--- + +## 📦 ExpressionSet API + +`ExpressionSet` is an indexed collection of `Expression` objects designed for efficient +bulk matching. Build it once from your config, then call `matchesAny()` on every tag. + +### Constructor + +```javascript +const set = new ExpressionSet(); +``` + +### `add(expression)` → `this` + +Add a single `Expression`. Duplicate patterns (same pattern string) are silently ignored. +Returns `this` for chaining. Throws `TypeError` if the set is sealed. + +```javascript +set.add(new Expression('root.users.user')); +set.add(new Expression('..script')); +``` + +### `addAll(expressions)` → `this` + +Add an array of `Expression` objects at once. Returns `this` for chaining. + +```javascript +set.addAll(config.stopNodes.map(p => new Expression(p))); +``` + +### `has(expression)` → `boolean` + +Check whether an expression with the same pattern is already present. + +```javascript +set.has(new Expression('root.users.user')); // true / false +``` + +### `seal()` → `this` + +Prevent further additions. Any subsequent call to `add()` or `addAll()` throws a `TypeError`. +Useful to guard against accidental mutation once parsing has started. + +```javascript +const stopNodes = new ExpressionSet(); +stopNodes.addAll(patterns).seal(); + +stopNodes.add(new Expression('root.extra')); // ❌ TypeError: ExpressionSet is sealed +``` + +### `size` → `number` + +Number of distinct expressions in the set. + +```javascript +set.size; // 3 +``` + +### `isSealed` → `boolean` + +Whether `seal()` has been called. + +### `matchesAny(matcher)` → `boolean` + +Returns `true` if the matcher's current path matches **any** expression in the set. +Accepts both a `Matcher` instance and a `MatcherView`. + +```javascript +if (stopNodes.matchesAny(matcher)) { /* ... */ } +if (stopNodes.matchesAny(matcher.readOnly())) { /* ... */ } // also works +``` + +**How indexing works:** expressions are bucketed at `add()` time, not at match time. + +| Expression type | Bucket | Lookup cost | +|---|---|---| +| Fixed path, concrete tag (`root.users.user`) | `depth:tag` map | O(1) | +| Fixed path, wildcard tag (`root.config.*`) | `depth` map | O(1) | +| Deep wildcard (`..script`) | flat list | O(D) — always scanned | + +In practice, deep-wildcard expressions are rare in configs, so the list stays small. + +### `findMatch(matcher)` → `Expression` + +Returns the Expression instance that matched the current path. Accepts both a `Matcher` instance and a `MatcherView`. + +```javascript +const node = stopNodes.findMatch(matcher); +``` + + +### Example 7: ExpressionSet in a real parser loop + +```javascript +import { XMLParser } from 'fast-xml-parser'; +import { Expression, ExpressionSet, Matcher } from 'path-expression-matcher'; + +// Config-time setup +const stopNodes = new ExpressionSet(); +stopNodes + .addAll(['script', 'style'].map(t => new Expression(`..${t}`))) + .seal(); + +const matcher = new Matcher(); + +const parser = new XMLParser({ + onOpenTag(tagName, attrs) { + matcher.push(tagName, attrs); + if (stopNodes.matchesAny(matcher)) { + // treat as stop node + } + }, + onCloseTag() { + matcher.pop(); + }, +}); +``` + + + ## 🔗 Integration with fast-xml-parser **Basic integration:** @@ -614,22 +863,10 @@ const parser = new XMLParser({ }); ``` -## 🧪 Testing - -```bash -npm test -``` - -All 77 tests covering: -- Pattern parsing (exact, wildcards, attributes, position) -- Path tracking (push, pop, update) -- Pattern matching (all combinations) -- Edge cases and error conditions - ## 📄 License MIT ## 🤝 Contributing -Issues and PRs welcome! This package is designed to be used by XML/JSON parsers like fast-xml-parser. \ No newline at end of file +Issues and PRs welcome! This package is designed to be used by XML/JSON parsers like fast-xml-parser. But can be used with any formar parser. \ No newline at end of file diff --git a/node_modules/path-expression-matcher/lib/pem.cjs b/node_modules/path-expression-matcher/lib/pem.cjs index 189e599f..4be499fe 100644 --- a/node_modules/path-expression-matcher/lib/pem.cjs +++ b/node_modules/path-expression-matcher/lib/pem.cjs @@ -1 +1 @@ -(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Expression:()=>s,Matcher:()=>i,default:()=>n});class s{constructor(t,e={}){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let s=0,i="";for(;s0&&(this.path[this.path.length-1].values=void 0);const i=this.path.length;this.siblingStacks[i]||(this.siblingStacks[i]=new Map);const n=this.siblingStacks[i],r=s?`${s}:${t}`:t,a=n.get(r)||0;let h=0;for(const t of n.values())h+=t;n.set(r,a+1);const o={tag:t,position:h,counter:a};null!=s&&(o.namespace=s),null!=e&&(o.values=e),this.path.push(o)}pop(){if(0===this.path.length)return;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0===this.path.length)return;const e=this.path[this.path.length-1];return e.values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const s=t||this.separator;return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(s)}toArray(){return this.path.map(t=>t.tag)}reset(){this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const i=t[s];if("deep-wildcard"===i.type){if(s--,s<0)return!0;const i=t[s];let n=!1;for(let t=e;t>=0;t--){const r=t===this.path.length-1;if(this._matchSegment(i,this.path[t],r)){e=t-1,s--,n=!0;break}}if(!n)return!1}else{const t=e===this.path.length-1;if(!this._matchSegment(i,this.path[e],t))return!1;e--,s--}}return s<0}_matchSegment(t,e,s){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!s)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue){const s=e.values[t.attrName];if(String(s)!==String(t.attrValue))return!1}}if(void 0!==t.position){if(!s)return!1;const i=e.counter??0;if("first"===t.position&&0!==i)return!1;if("odd"===t.position&&i%2!=1)return!1;if("even"===t.position&&i%2!=0)return!1;if("nth"===t.position&&i!==t.positionValue)return!1}return!0}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}}const n={Expression:s,Matcher:i};module.exports=e})(); \ No newline at end of file +(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Expression:()=>s,ExpressionSet:()=>n,Matcher:()=>h,default:()=>r});class s{constructor(t,e={},s){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=s,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let s=0,i="";for(;s0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return!1;const s=e[e.length-1];return void 0!==s.values&&t in s.values}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=!0){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class h{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new i(this)}push(t,e=null,s=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const i=this.path.length;this.siblingStacks[i]||(this.siblingStacks[i]=new Map);const h=this.siblingStacks[i],n=s?`${s}:${t}`:t,r=h.get(n)||0;let a=0;for(const t of h.values())a+=t;h.set(n,r+1);const p={tag:t,position:a,counter:r};null!=s&&(p.namespace=s),null!=e&&(p.values=e),this.path.push(p)}pop(){if(0===this.path.length)return;this._pathStringCache=null;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const s=t||this.separator;if(s===this.separator&&!0===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(s);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(s)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const i=t[s];if("deep-wildcard"===i.type){if(s--,s<0)return!0;const i=t[s];let h=!1;for(let t=e;t>=0;t--)if(this._matchSegment(i,this.path[t],t===this.path.length-1)){e=t-1,s--,h=!0;break}if(!h)return!1}else{if(!this._matchSegment(i,this.path[e],e===this.path.length-1))return!1;e--,s--}}return s<0}_matchSegment(t,e,s){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!s)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return!1}if(void 0!==t.position){if(!s)return!1;const i=e.counter??0;if("first"===t.position&&0!==i)return!1;if("odd"===t.position&&i%2!=1)return!1;if("even"===t.position&&i%2!=0)return!1;if("nth"===t.position&&i!==t.positionValue)return!1}return!0}matchesAny(t){return t.matchesAny(this)}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}readOnly(){return this._view}}class n{constructor(){this._byDepthAndTag=new Map,this._wildcardByDepth=new Map,this._deepWildcards=[],this._patterns=new Set,this._sealed=!1}add(t){if(this._sealed)throw new TypeError("ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.");if(this._patterns.has(t.pattern))return this;if(this._patterns.add(t.pattern),t.hasDeepWildcard())return this._deepWildcards.push(t),this;const e=t.length,s=t.segments[t.segments.length-1],i=s?.tag;if(i&&"*"!==i){const s=`${e}:${i}`;this._byDepthAndTag.has(s)||this._byDepthAndTag.set(s,[]),this._byDepthAndTag.get(s).push(t)}else this._wildcardByDepth.has(e)||this._wildcardByDepth.set(e,[]),this._wildcardByDepth.get(e).push(t);return this}addAll(t){for(const e of t)this.add(e);return this}has(t){return this._patterns.has(t.pattern)}get size(){return this._patterns.size}seal(){return this._sealed=!0,this}get isSealed(){return this._sealed}matchesAny(t){return null!==this.findMatch(t)}findMatch(t){const e=t.getDepth(),s=`${e}:${t.getCurrentTag()}`,i=this._byDepthAndTag.get(s);if(i)for(let e=0;e[]; } +/** + * ReadOnlyMatcher - A safe, read-only view over a {@link Matcher} instance. + * + * Returned by {@link Matcher.readOnly}. Exposes all query and inspection + * methods but **throws a `TypeError`** if any state-mutating method is called + * (`push`, `pop`, `reset`, `updateCurrent`, `restore`). Direct property + * writes are also blocked. + * + * Pass this to consumers that only need to inspect or match the current path + * so they cannot accidentally corrupt the parser state. + * + * @example + * ```javascript + * const matcher = new Matcher(); + * matcher.push("root", {}); + * matcher.push("users", {}); + * matcher.push("user", { id: "123" }); + * + * const ro: ReadOnlyMatcher = matcher.readOnly(); + * + * ro.matches(expr); // ✓ works + * ro.getCurrentTag(); // ✓ "user" + * ro.getDepth(); // ✓ 3 + * ro.push("child", {}); // ✗ TypeError: Cannot call 'push' on a read-only Matcher + * ro.reset(); // ✗ TypeError: Cannot call 'reset' on a read-only Matcher + * ``` + */ +declare interface ReadOnlyMatcher { + /** + * Default path separator (read-only) + */ + readonly separator: string; + + /** + * Current path stack (each node is a frozen copy) + */ + readonly path: ReadonlyArray>; + + // ── Query methods ─────────────────────────────────────────────────────────── + + /** + * Get current tag name + * @returns Current tag name or undefined if path is empty + */ + getCurrentTag(): string | undefined; + + /** + * Get current namespace + * @returns Current namespace or undefined if not present or path is empty + */ + getCurrentNamespace(): string | undefined; + + /** + * Get current node's attribute value + * @param attrName - Attribute name + * @returns Attribute value or undefined + */ + getAttrValue(attrName: string): any; + + /** + * Check if current node has an attribute + * @param attrName - Attribute name + */ + hasAttr(attrName: string): boolean; + + /** + * Get current node's sibling position (child index in parent) + * @returns Position index or -1 if path is empty + */ + getPosition(): number; + + /** + * Get current node's repeat counter (occurrence count of this tag name) + * @returns Counter value or -1 if path is empty + */ + getCounter(): number; + + /** + * Get current node's sibling index (alias for getPosition for backward compatibility) + * @returns Index or -1 if path is empty + * @deprecated Use getPosition() or getCounter() instead + */ + getIndex(): number; + + /** + * Get current path depth + * @returns Number of nodes in the path + */ + getDepth(): number; + + /** + * Get path as string + * @param separator - Optional separator (uses default if not provided) + * @param includeNamespace - Whether to include namespace in output + * @returns Path string (e.g., "root.users.user" or "ns:root.ns:users.user") + */ + toString(separator?: string, includeNamespace?: boolean): string; + + /** + * Get path as array of tag names + * @returns Array of tag names + */ + toArray(): string[]; + + /** + * Match current path against an Expression + * @param expression - The expression to match against + * @returns True if current path matches the expression + */ + matches(expression: Expression): boolean; + + /** + * Test whether the matcher's current path matches **any** expression in the set. + * + * @param exprSet - A `ExpressionSet` instance + * @returns `true` if at least one expression matches the current path + */ + matchesAny(exprSet: ExpressionSet): boolean; + /** + * Create a snapshot of current state + * @returns State snapshot that can be restored later + */ + snapshot(): MatcherSnapshot; + + // ── Blocked mutating methods ──────────────────────────────────────────────── + // These are present in the type so callers get a compile-time error with a + // helpful message instead of a silent "property does not exist" error. + + /** + * @throws {TypeError} Always – mutation is not allowed on a read-only view. + */ + push(tagName: string, attrValues?: Record | null, namespace?: string | null): never; + + /** + * @throws {TypeError} Always – mutation is not allowed on a read-only view. + */ + pop(): never; + + /** + * @throws {TypeError} Always – mutation is not allowed on a read-only view. + */ + updateCurrent(attrValues: Record): never; + + /** + * @throws {TypeError} Always – mutation is not allowed on a read-only view. + */ + reset(): never; + + /** + * @throws {TypeError} Always – mutation is not allowed on a read-only view. + */ + restore(snapshot: MatcherSnapshot): never; +} + /** * Matcher - Tracks current path in XML/JSON tree and matches against Expressions * @@ -191,6 +356,12 @@ declare interface MatcherSnapshot { * matcher.push("root", {}); * matcher.push("users", {}); * matcher.push("user", { id: "123", type: "admin" }); + * + * const expr = new Expression("root.users.user"); + * matcher.matches(expr); // true + * + * matcher.pop(); + * matcher.matches(expr); // false * ``` */ declare class Matcher { @@ -215,6 +386,13 @@ declare class Matcher { * @param tagName - Name of the tag * @param attrValues - Attribute key-value pairs for current node (optional) * @param namespace - Namespace for the tag (optional) + * + * @example + * ```javascript + * matcher.push("user", { id: "123", type: "admin" }); + * matcher.push("user", { id: "456" }, "ns"); + * matcher.push("container", null); + * ``` */ push(tagName: string, attrValues?: Record | null, namespace?: string | null): void; @@ -304,9 +482,46 @@ declare class Matcher { * Match current path against an Expression * @param expression - The expression to match against * @returns True if current path matches the expression + * + * @example + * ```javascript + * const expr = new Expression("root.users.user[id]"); + * const matcher = new Matcher(); + * + * matcher.push("root"); + * matcher.push("users"); + * matcher.push("user", { id: "123" }); + * + * matcher.matches(expr); // true + * ``` */ matches(expression: Expression): boolean; + + /** + * Test whether the matcher's current path matches **any** expression in the set. + * + * Uses the pre-built index to evaluate only the relevant bucket(s): + * 1. Exact depth + tag — O(1) lookup + * 2. Depth-matched wildcard tag — O(1) lookup + * 3. Deep-wildcard expressions — always scanned (typically a small list) + * + * @param exprSet - A `ExpressionSet` instance + * @returns `true` if at least one expression matches the current path + * + * @example + * ```typescript + * // Replaces: + * // for (const expr of stopNodeExpressions) { + * // if (matcher.matches(expr)) return true; + * // } + * + * if (matcher.matchesAny(stopNodes)) { + * // current tag is a stop node + * } + * ``` + */ + matchesAny(exprSet: ExpressionSet): boolean; /** * Create a snapshot of current state * @returns State snapshot that can be restored later @@ -318,12 +533,96 @@ declare class Matcher { * @param snapshot - State snapshot from previous snapshot() call */ restore(snapshot: MatcherSnapshot): void; + + /** + * Return a read-only view of this matcher. + */ + readOnly(): ReadOnlyMatcher; +} + +/** + * ExpressionSet - An indexed collection of Expressions for efficient bulk matching + * + * Pre-indexes expressions at insertion time by depth and terminal tag name so + * that `matchesAny()` performs an O(1) bucket lookup rather than a full O(E) + * linear scan on every tag. + * + * @example + * ```javascript + * const { Expression, ExpressionSet, Matcher } = require('path-expression-matcher'); + * + * // Build once at config time + * const stopNodes = new ExpressionSet(); + * stopNodes + * .add(new Expression('root.users.user')) + * .add(new Expression('root.config.*')) + * .add(new Expression('..script')) + * .seal(); + * + * // Per-tag — hot path + * if (stopNodes.matchesAny(matcher)) { ... } + * ``` + */ +declare class ExpressionSet { + constructor(); + + /** Number of expressions currently in the set. */ + readonly size: number; + + /** Whether the set has been sealed against further modifications. */ + readonly isSealed: boolean; + + /** + * Add a single Expression. Duplicate patterns are silently ignored. + * @throws {TypeError} if the set has been sealed + */ + add(expression: Expression): this; + + /** + * Add multiple expressions at once. + * @throws {TypeError} if the set has been sealed + */ + addAll(expressions: Expression[]): this; + + /** Check whether an expression with the same pattern is already present. */ + has(expression: Expression): boolean; + + /** + * Seal the set against further modifications. + * Any subsequent call to add() or addAll() will throw a TypeError. + */ + seal(): this; + + /** + * Test whether the matcher's current path matches any expression in the set. + * Accepts both a Matcher instance and a ReadOnlyMatcher view. + * + * + * @param matcher - A `Matcher` instance or a `ReadOnlyMatcher` view + * @returns Expression if at least one expression matches the current path + */ + matchesAny(matcher: Matcher | ReadOnlyMatcher): boolean; + + /** + * Find the first expression in the set that matches the matcher's current path. + + * + * @param matcher - A `Matcher` instance or a `ReadOnlyMatcher` view + * @returns Expression if at least one expression matches the current path + * + * @example + * ```typescript + * const node = stopNodes.findMatch(matcher); + * ``` + */ + findMatch(matcher: Matcher | ReadOnlyMatcher): Expression; } declare namespace pathExpressionMatcher { export { Expression, Matcher, + ExpressionSet, ExpressionOptions, MatcherOptions, Segment, diff --git a/node_modules/path-expression-matcher/lib/pem.min.js b/node_modules/path-expression-matcher/lib/pem.min.js index 30dc591f..67b9f39d 100644 --- a/node_modules/path-expression-matcher/lib/pem.min.js +++ b/node_modules/path-expression-matcher/lib/pem.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.pem=e():t.pem=e()}(this,()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Expression:()=>s,Matcher:()=>i,default:()=>n});class s{constructor(t,e={}){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let s=0,i="";for(;s0&&(this.path[this.path.length-1].values=void 0);const i=this.path.length;this.siblingStacks[i]||(this.siblingStacks[i]=new Map);const n=this.siblingStacks[i],r=s?`${s}:${t}`:t,a=n.get(r)||0;let h=0;for(const t of n.values())h+=t;n.set(r,a+1);const o={tag:t,position:h,counter:a};null!=s&&(o.namespace=s),null!=e&&(o.values=e),this.path.push(o)}pop(){if(0===this.path.length)return;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0===this.path.length)return;const e=this.path[this.path.length-1];return e.values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const s=t||this.separator;return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(s)}toArray(){return this.path.map(t=>t.tag)}reset(){this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const i=t[s];if("deep-wildcard"===i.type){if(s--,s<0)return!0;const i=t[s];let n=!1;for(let t=e;t>=0;t--){const r=t===this.path.length-1;if(this._matchSegment(i,this.path[t],r)){e=t-1,s--,n=!0;break}}if(!n)return!1}else{const t=e===this.path.length-1;if(!this._matchSegment(i,this.path[e],t))return!1;e--,s--}}return s<0}_matchSegment(t,e,s){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!s)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue){const s=e.values[t.attrName];if(String(s)!==String(t.attrValue))return!1}}if(void 0!==t.position){if(!s)return!1;const i=e.counter??0;if("first"===t.position&&0!==i)return!1;if("odd"===t.position&&i%2!=1)return!1;if("even"===t.position&&i%2!=0)return!1;if("nth"===t.position&&i!==t.positionValue)return!1}return!0}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}}const n={Expression:s,Matcher:i};return e})()); +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.pem=e():t.pem=e()}(this,()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Expression:()=>s,ExpressionSet:()=>r,Matcher:()=>n,default:()=>h});class s{constructor(t,e={},s){this.pattern=t,this.separator=e.separator||".",this.segments=this._parse(t),this.data=s,this._hasDeepWildcard=this.segments.some(t=>"deep-wildcard"===t.type),this._hasAttributeCondition=this.segments.some(t=>void 0!==t.attrName),this._hasPositionSelector=this.segments.some(t=>void 0!==t.position)}_parse(t){const e=[];let s=0,i="";for(;s0?t[t.length-1].tag:void 0}getCurrentNamespace(){const t=this._matcher.path;return t.length>0?t[t.length-1].namespace:void 0}getAttrValue(t){const e=this._matcher.path;if(0!==e.length)return e[e.length-1].values?.[t]}hasAttr(t){const e=this._matcher.path;if(0===e.length)return!1;const s=e[e.length-1];return void 0!==s.values&&t in s.values}getPosition(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].position??0}getCounter(){const t=this._matcher.path;return 0===t.length?-1:t[t.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this._matcher.path.length}toString(t,e=!0){return this._matcher.toString(t,e)}toArray(){return this._matcher.path.map(t=>t.tag)}matches(t){return this._matcher.matches(t)}matchesAny(t){return t.matchesAny(this._matcher)}}class n{constructor(t={}){this.separator=t.separator||".",this.path=[],this.siblingStacks=[],this._pathStringCache=null,this._view=new i(this)}push(t,e=null,s=null){this._pathStringCache=null,this.path.length>0&&(this.path[this.path.length-1].values=void 0);const i=this.path.length;this.siblingStacks[i]||(this.siblingStacks[i]=new Map);const n=this.siblingStacks[i],r=s?`${s}:${t}`:t,h=n.get(r)||0;let a=0;for(const t of n.values())a+=t;n.set(r,h+1);const p={tag:t,position:a,counter:h};null!=s&&(p.namespace=s),null!=e&&(p.values=e),this.path.push(p)}pop(){if(0===this.path.length)return;this._pathStringCache=null;const t=this.path.pop();return this.siblingStacks.length>this.path.length+1&&(this.siblingStacks.length=this.path.length+1),t}updateCurrent(t){if(this.path.length>0){const e=this.path[this.path.length-1];null!=t&&(e.values=t)}}getCurrentTag(){return this.path.length>0?this.path[this.path.length-1].tag:void 0}getCurrentNamespace(){return this.path.length>0?this.path[this.path.length-1].namespace:void 0}getAttrValue(t){if(0!==this.path.length)return this.path[this.path.length-1].values?.[t]}hasAttr(t){if(0===this.path.length)return!1;const e=this.path[this.path.length-1];return void 0!==e.values&&t in e.values}getPosition(){return 0===this.path.length?-1:this.path[this.path.length-1].position??0}getCounter(){return 0===this.path.length?-1:this.path[this.path.length-1].counter??0}getIndex(){return this.getPosition()}getDepth(){return this.path.length}toString(t,e=!0){const s=t||this.separator;if(s===this.separator&&!0===e){if(null!==this._pathStringCache)return this._pathStringCache;const t=this.path.map(t=>t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(s);return this._pathStringCache=t,t}return this.path.map(t=>e&&t.namespace?`${t.namespace}:${t.tag}`:t.tag).join(s)}toArray(){return this.path.map(t=>t.tag)}reset(){this._pathStringCache=null,this.path=[],this.siblingStacks=[]}matches(t){const e=t.segments;return 0!==e.length&&(t.hasDeepWildcard()?this._matchWithDeepWildcard(e):this._matchSimple(e))}_matchSimple(t){if(this.path.length!==t.length)return!1;for(let e=0;e=0&&e>=0;){const i=t[s];if("deep-wildcard"===i.type){if(s--,s<0)return!0;const i=t[s];let n=!1;for(let t=e;t>=0;t--)if(this._matchSegment(i,this.path[t],t===this.path.length-1)){e=t-1,s--,n=!0;break}if(!n)return!1}else{if(!this._matchSegment(i,this.path[e],e===this.path.length-1))return!1;e--,s--}}return s<0}_matchSegment(t,e,s){if("*"!==t.tag&&t.tag!==e.tag)return!1;if(void 0!==t.namespace&&"*"!==t.namespace&&t.namespace!==e.namespace)return!1;if(void 0!==t.attrName){if(!s)return!1;if(!e.values||!(t.attrName in e.values))return!1;if(void 0!==t.attrValue&&String(e.values[t.attrName])!==String(t.attrValue))return!1}if(void 0!==t.position){if(!s)return!1;const i=e.counter??0;if("first"===t.position&&0!==i)return!1;if("odd"===t.position&&i%2!=1)return!1;if("even"===t.position&&i%2!=0)return!1;if("nth"===t.position&&i!==t.positionValue)return!1}return!0}matchesAny(t){return t.matchesAny(this)}snapshot(){return{path:this.path.map(t=>({...t})),siblingStacks:this.siblingStacks.map(t=>new Map(t))}}restore(t){this._pathStringCache=null,this.path=t.path.map(t=>({...t})),this.siblingStacks=t.siblingStacks.map(t=>new Map(t))}readOnly(){return this._view}}class r{constructor(){this._byDepthAndTag=new Map,this._wildcardByDepth=new Map,this._deepWildcards=[],this._patterns=new Set,this._sealed=!1}add(t){if(this._sealed)throw new TypeError("ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.");if(this._patterns.has(t.pattern))return this;if(this._patterns.add(t.pattern),t.hasDeepWildcard())return this._deepWildcards.push(t),this;const e=t.length,s=t.segments[t.segments.length-1],i=s?.tag;if(i&&"*"!==i){const s=`${e}:${i}`;this._byDepthAndTag.has(s)||this._byDepthAndTag.set(s,[]),this._byDepthAndTag.get(s).push(t)}else this._wildcardByDepth.has(e)||this._wildcardByDepth.set(e,[]),this._wildcardByDepth.get(e).push(t);return this}addAll(t){for(const e of t)this.add(e);return this}has(t){return this._patterns.has(t.pattern)}get size(){return this._patterns.size}seal(){return this._sealed=!0,this}get isSealed(){return this._sealed}matchesAny(t){return null!==this.findMatch(t)}findMatch(t){const e=t.getDepth(),s=`${e}:${t.getCurrentTag()}`,i=this._byDepthAndTag.get(s);if(i)for(let e=0;e {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions\n * \n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n * \n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n * \n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Default path separator (default: '.')\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag: string, values: object, position: number, counter: number }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n }\n\n /**\n * Push a new tag onto the path\n * @param {string} tagName - Name of the tag\n * @param {Object} attrValues - Attribute key-value pairs for current node (optional)\n * @param {string} namespace - Namespace for the tag (optional)\n */\n push(tagName, attrValues = null, namespace = null) {\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n const prev = this.path[this.path.length - 1];\n prev.values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n // Store namespace if provided\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n // Store values only for current node\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) {\n return undefined;\n }\n\n const node = this.path.pop();\n\n // Clean up sibling tracking for levels deeper than current\n // After pop, path.length is the new depth\n // We need to clean up siblingStacks[path.length + 1] and beyond\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values\n * Useful when attributes are parsed after push\n * @param {Object} attrValues - Attribute values\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value\n * @param {string} attrName - Attribute name\n * @returns {*} Attribute value or undefined\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n const current = this.path[this.path.length - 1];\n return current.values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute\n * @param {string} attrName - Attribute name\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent)\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name)\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition for backward compatibility)\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string\n * @param {string} separator - Optional separator (uses default if not provided)\n * @param {boolean} includeNamespace - Whether to include namespace in output (default: true)\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n return this.path.map(n => {\n if (includeNamespace && n.namespace) {\n return `${n.namespace}:${n.tag}`;\n }\n return n.tag;\n }).join(sep);\n }\n\n /**\n * Get path as array of tag names\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty\n */\n reset() {\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression\n * @param {Expression} expression - The expression to match against\n * @returns {boolean} True if current path matches the expression\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n // Handle deep wildcard patterns\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n // Simple path matching (no deep wildcards)\n return this._matchSimple(segments);\n }\n\n /**\n * Match simple path (no deep wildcards)\n * @private\n */\n _matchSimple(segments) {\n // Path must be same length as segments\n if (this.path.length !== segments.length) {\n return false;\n }\n\n // Match each segment bottom-to-top\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n const node = this.path[i];\n const isCurrentNode = (i === this.path.length - 1);\n\n if (!this._matchSegment(segment, node, isCurrentNode)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match path with deep wildcards\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1; // Start from current node (bottom)\n let segIdx = segments.length - 1; // Start from last segment\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n // \"..\" matches zero or more levels\n segIdx--;\n\n if (segIdx < 0) {\n // Pattern ends with \"..\", always matches\n return true;\n }\n\n // Find where next segment matches in the path\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n const isCurrentNode = (i === this.path.length - 1);\n if (this._matchSegment(nextSeg, this.path[i], isCurrentNode)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n // Regular segment\n const isCurrentNode = (pathIdx === this.path.length - 1);\n if (!this._matchSegment(segment, this.path[pathIdx], isCurrentNode)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n // All segments must be consumed\n return segIdx < 0;\n }\n\n /**\n * Match a single segment against a node\n * @private\n * @param {Object} segment - Segment from Expression\n * @param {Object} node - Node from path\n * @param {boolean} isCurrentNode - Whether this is the current (last) node\n * @returns {boolean}\n */\n _matchSegment(segment, node, isCurrentNode) {\n // Match tag name (* is wildcard)\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n // Match namespace if specified in segment\n if (segment.namespace !== undefined) {\n // Segment has namespace - node must match it\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n // If segment has no namespace, it matches nodes with or without namespace\n\n // Match attribute name (check if node has this attribute)\n // Can only check for current node since ancestors don't have values\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n // Can't check attributes for ancestor nodes (values not stored)\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n // Match attribute value (only possible for current node)\n if (segment.attrValue !== undefined) {\n const actualValue = node.values[segment.attrName];\n // Both should be strings\n if (String(actualValue) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n // Match position (only for current node)\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n // Can't check position for ancestor nodes\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth') {\n if (counter !== segment.positionValue) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Create a snapshot of current state\n * @returns {Object} State snapshot\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot\n * @param {Object} snapshot - State snapshot\n */\n restore(snapshot) {\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n}","/**\n * fast-xml-tagger - XML/JSON path matching library\n * \n * Provides efficient path tracking and pattern matching for XML/JSON parsers.\n * \n * @example\n * import { Expression, Matcher } from 'fast-xml-tagger';\n * \n * // Create expression (parse once)\n * const expr = new Expression(\"root.users.user[id]\");\n * \n * // Create matcher (track path)\n * const matcher = new Matcher();\n * matcher.push(\"root\", [], {}, 0);\n * matcher.push(\"users\", [], {}, 0);\n * matcher.push(\"user\", [\"id\", \"type\"], { id: \"123\", type: \"admin\" }, 0);\n * \n * // Match\n * if (matcher.matches(expr)) {\n * console.log(\"Match found!\");\n * }\n */\n\nimport Expression from './Expression.js';\nimport Matcher from './Matcher.js';\n\nexport { Expression, Matcher };\nexport default { Expression, Matcher };\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Expression","constructor","pattern","options","separator","segments","_parse","_hasDeepWildcard","some","seg","type","_hasAttributeCondition","undefined","attrName","_hasPositionSelector","position","i","currentPart","length","trim","push","_parseSegment","part","segment","bracketContent","withoutBrackets","bracketMatch","match","content","slice","namespace","tag","tagAndPosition","includes","nsIndex","indexOf","substring","Error","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","test","eqIndex","attrValue","nthMatch","positionValue","parseInt","hasDeepWildcard","hasAttributeCondition","hasPositionSelector","toString","Matcher","path","siblingStacks","tagName","attrValues","values","currentLevel","Map","siblings","siblingKey","counter","count","set","node","pop","updateCurrent","current","getCurrentTag","getCurrentNamespace","getAttrValue","hasAttr","getPosition","getCounter","getIndex","getDepth","includeNamespace","sep","map","n","join","toArray","reset","matches","expression","_matchWithDeepWildcard","_matchSimple","isCurrentNode","_matchSegment","pathIdx","segIdx","nextSeg","found","actualValue","String","snapshot","restore"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"./lib/pem.min.js","mappings":"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","sources":["webpack://pem/webpack/universalModuleDefinition","webpack://pem/webpack/bootstrap","webpack://pem/webpack/runtime/define property getters","webpack://pem/webpack/runtime/hasOwnProperty shorthand","webpack://pem/webpack/runtime/make namespace object","webpack://pem/./src/Expression.js","webpack://pem/./src/Matcher.js","webpack://pem/./src/ExpressionSet.js","webpack://pem/./src/index.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"pem\"] = factory();\n\telse\n\t\troot[\"pem\"] = factory();\n})(this, () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * Expression - Parses and stores a tag pattern expression\n * \n * Patterns are parsed once and stored in an optimized structure for fast matching.\n * \n * @example\n * const expr = new Expression(\"root.users.user\");\n * const expr2 = new Expression(\"..user[id]:first\");\n * const expr3 = new Expression(\"root/users/user\", { separator: '/' });\n */\nexport default class Expression {\n /**\n * Create a new Expression\n * @param {string} pattern - Pattern string (e.g., \"root.users.user\", \"..user[id]\")\n * @param {Object} options - Configuration options\n * @param {string} options.separator - Path separator (default: '.')\n */\n constructor(pattern, options = {}, data) {\n this.pattern = pattern;\n this.separator = options.separator || '.';\n this.segments = this._parse(pattern);\n this.data = data;\n // Cache expensive checks for performance (O(1) instead of O(n))\n this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard');\n this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined);\n this._hasPositionSelector = this.segments.some(seg => seg.position !== undefined);\n }\n\n /**\n * Parse pattern string into segments\n * @private\n * @param {string} pattern - Pattern to parse\n * @returns {Array} Array of segment objects\n */\n _parse(pattern) {\n const segments = [];\n\n // Split by separator but handle \"..\" specially\n let i = 0;\n let currentPart = '';\n\n while (i < pattern.length) {\n if (pattern[i] === this.separator) {\n // Check if next char is also separator (deep wildcard)\n if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {\n // Flush current part if any\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n currentPart = '';\n }\n // Add deep wildcard\n segments.push({ type: 'deep-wildcard' });\n i += 2; // Skip both separators\n } else {\n // Regular separator\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n currentPart = '';\n i++;\n }\n } else {\n currentPart += pattern[i];\n i++;\n }\n }\n\n // Flush remaining part\n if (currentPart.trim()) {\n segments.push(this._parseSegment(currentPart.trim()));\n }\n\n return segments;\n }\n\n /**\n * Parse a single segment\n * @private\n * @param {string} part - Segment string (e.g., \"user\", \"ns::user\", \"user[id]\", \"ns::user:first\")\n * @returns {Object} Segment object\n */\n _parseSegment(part) {\n const segment = { type: 'tag' };\n\n // NEW NAMESPACE SYNTAX (v2.0):\n // ============================\n // Namespace uses DOUBLE colon (::)\n // Position uses SINGLE colon (:)\n // \n // Examples:\n // \"user\" → tag\n // \"user:first\" → tag + position\n // \"user[id]\" → tag + attribute\n // \"user[id]:first\" → tag + attribute + position\n // \"ns::user\" → namespace + tag\n // \"ns::user:first\" → namespace + tag + position\n // \"ns::user[id]\" → namespace + tag + attribute\n // \"ns::user[id]:first\" → namespace + tag + attribute + position\n // \"ns::first\" → namespace + tag named \"first\" (NO ambiguity!)\n //\n // This eliminates all ambiguity:\n // :: = namespace separator\n // : = position selector\n // [] = attributes\n\n // Step 1: Extract brackets [attr] or [attr=value]\n let bracketContent = null;\n let withoutBrackets = part;\n\n const bracketMatch = part.match(/^([^\\[]+)(\\[[^\\]]*\\])(.*)$/);\n if (bracketMatch) {\n withoutBrackets = bracketMatch[1] + bracketMatch[3];\n if (bracketMatch[2]) {\n const content = bracketMatch[2].slice(1, -1);\n if (content) {\n bracketContent = content;\n }\n }\n }\n\n // Step 2: Check for namespace (double colon ::)\n let namespace = undefined;\n let tagAndPosition = withoutBrackets;\n\n if (withoutBrackets.includes('::')) {\n const nsIndex = withoutBrackets.indexOf('::');\n namespace = withoutBrackets.substring(0, nsIndex).trim();\n tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim(); // Skip ::\n\n if (!namespace) {\n throw new Error(`Invalid namespace in pattern: ${part}`);\n }\n }\n\n // Step 3: Parse tag and position (single colon :)\n let tag = undefined;\n let positionMatch = null;\n\n if (tagAndPosition.includes(':')) {\n const colonIndex = tagAndPosition.lastIndexOf(':'); // Use last colon for position\n const tagPart = tagAndPosition.substring(0, colonIndex).trim();\n const posPart = tagAndPosition.substring(colonIndex + 1).trim();\n\n // Verify position is a valid keyword\n const isPositionKeyword = ['first', 'last', 'odd', 'even'].includes(posPart) ||\n /^nth\\(\\d+\\)$/.test(posPart);\n\n if (isPositionKeyword) {\n tag = tagPart;\n positionMatch = posPart;\n } else {\n // Not a valid position keyword, treat whole thing as tag\n tag = tagAndPosition;\n }\n } else {\n tag = tagAndPosition;\n }\n\n if (!tag) {\n throw new Error(`Invalid segment pattern: ${part}`);\n }\n\n segment.tag = tag;\n if (namespace) {\n segment.namespace = namespace;\n }\n\n // Step 4: Parse attributes\n if (bracketContent) {\n if (bracketContent.includes('=')) {\n const eqIndex = bracketContent.indexOf('=');\n segment.attrName = bracketContent.substring(0, eqIndex).trim();\n segment.attrValue = bracketContent.substring(eqIndex + 1).trim();\n } else {\n segment.attrName = bracketContent.trim();\n }\n }\n\n // Step 5: Parse position selector\n if (positionMatch) {\n const nthMatch = positionMatch.match(/^nth\\((\\d+)\\)$/);\n if (nthMatch) {\n segment.position = 'nth';\n segment.positionValue = parseInt(nthMatch[1], 10);\n } else {\n segment.position = positionMatch;\n }\n }\n\n return segment;\n }\n\n /**\n * Get the number of segments\n * @returns {number}\n */\n get length() {\n return this.segments.length;\n }\n\n /**\n * Check if expression contains deep wildcard\n * @returns {boolean}\n */\n hasDeepWildcard() {\n return this._hasDeepWildcard;\n }\n\n /**\n * Check if expression has attribute conditions\n * @returns {boolean}\n */\n hasAttributeCondition() {\n return this._hasAttributeCondition;\n }\n\n /**\n * Check if expression has position selectors\n * @returns {boolean}\n */\n hasPositionSelector() {\n return this._hasPositionSelector;\n }\n\n /**\n * Get string representation\n * @returns {string}\n */\n toString() {\n return this.pattern;\n }\n}","import ExpressionSet from \"./ExpressionSet.js\";\n\n/**\n * MatcherView - A lightweight read-only view over a Matcher's internal state.\n *\n * Created once by Matcher and reused across all callbacks. Holds a direct\n * reference to the parent Matcher so it always reflects current parser state\n * with zero copying or freezing overhead.\n *\n * Users receive this via {@link Matcher#readOnly} or directly from parser\n * callbacks. It exposes all query and matching methods but has no mutation\n * methods — misuse is caught at the TypeScript level rather than at runtime.\n *\n * @example\n * const matcher = new Matcher();\n * const view = matcher.readOnly();\n *\n * matcher.push(\"root\", {});\n * view.getCurrentTag(); // \"root\"\n * view.getDepth(); // 1\n */\nexport class MatcherView {\n /**\n * @param {Matcher} matcher - The parent Matcher instance to read from.\n */\n constructor(matcher) {\n this._matcher = matcher;\n }\n\n /**\n * Get the path separator used by the parent matcher.\n * @returns {string}\n */\n get separator() {\n return this._matcher.separator;\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n const path = this._matcher.path;\n return path.length > 0 ? path[path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return undefined;\n return path[path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n const path = this._matcher.path;\n if (path.length === 0) return false;\n const current = path[path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n const path = this._matcher.path;\n if (path.length === 0) return -1;\n return path[path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this._matcher.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n return this._matcher.toString(separator, includeNamespace);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this._matcher.path.map(n => n.tag);\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n return this._matcher.matches(expression);\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this._matcher);\n }\n}\n\n/**\n * Matcher - Tracks current path in XML/JSON tree and matches against Expressions.\n *\n * The matcher maintains a stack of nodes representing the current path from root to\n * current tag. It only stores attribute values for the current (top) node to minimize\n * memory usage. Sibling tracking is used to auto-calculate position and counter.\n *\n * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to\n * user callbacks — it always reflects current state with no Proxy overhead.\n *\n * @example\n * const matcher = new Matcher();\n * matcher.push(\"root\", {});\n * matcher.push(\"users\", {});\n * matcher.push(\"user\", { id: \"123\", type: \"admin\" });\n *\n * const expr = new Expression(\"root.users.user\");\n * matcher.matches(expr); // true\n */\nexport default class Matcher {\n /**\n * Create a new Matcher.\n * @param {Object} [options={}]\n * @param {string} [options.separator='.'] - Default path separator\n */\n constructor(options = {}) {\n this.separator = options.separator || '.';\n this.path = [];\n this.siblingStacks = [];\n // Each path node: { tag, values, position, counter, namespace? }\n // values only present for current (last) node\n // Each siblingStacks entry: Map tracking occurrences at each level\n this._pathStringCache = null;\n this._view = new MatcherView(this);\n }\n\n /**\n * Push a new tag onto the path.\n * @param {string} tagName\n * @param {Object|null} [attrValues=null]\n * @param {string|null} [namespace=null]\n */\n push(tagName, attrValues = null, namespace = null) {\n this._pathStringCache = null;\n\n // Remove values from previous current node (now becoming ancestor)\n if (this.path.length > 0) {\n this.path[this.path.length - 1].values = undefined;\n }\n\n // Get or create sibling tracking for current level\n const currentLevel = this.path.length;\n if (!this.siblingStacks[currentLevel]) {\n this.siblingStacks[currentLevel] = new Map();\n }\n\n const siblings = this.siblingStacks[currentLevel];\n\n // Create a unique key for sibling tracking that includes namespace\n const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;\n\n // Calculate counter (how many times this tag appeared at this level)\n const counter = siblings.get(siblingKey) || 0;\n\n // Calculate position (total children at this level so far)\n let position = 0;\n for (const count of siblings.values()) {\n position += count;\n }\n\n // Update sibling count for this tag\n siblings.set(siblingKey, counter + 1);\n\n // Create new node\n const node = {\n tag: tagName,\n position: position,\n counter: counter\n };\n\n if (namespace !== null && namespace !== undefined) {\n node.namespace = namespace;\n }\n\n if (attrValues !== null && attrValues !== undefined) {\n node.values = attrValues;\n }\n\n this.path.push(node);\n }\n\n /**\n * Pop the last tag from the path.\n * @returns {Object|undefined} The popped node\n */\n pop() {\n if (this.path.length === 0) return undefined;\n this._pathStringCache = null;\n\n const node = this.path.pop();\n\n if (this.siblingStacks.length > this.path.length + 1) {\n this.siblingStacks.length = this.path.length + 1;\n }\n\n return node;\n }\n\n /**\n * Update current node's attribute values.\n * Useful when attributes are parsed after push.\n * @param {Object} attrValues\n */\n updateCurrent(attrValues) {\n if (this.path.length > 0) {\n const current = this.path[this.path.length - 1];\n if (attrValues !== null && attrValues !== undefined) {\n current.values = attrValues;\n }\n }\n }\n\n /**\n * Get current tag name.\n * @returns {string|undefined}\n */\n getCurrentTag() {\n return this.path.length > 0 ? this.path[this.path.length - 1].tag : undefined;\n }\n\n /**\n * Get current namespace.\n * @returns {string|undefined}\n */\n getCurrentNamespace() {\n return this.path.length > 0 ? this.path[this.path.length - 1].namespace : undefined;\n }\n\n /**\n * Get current node's attribute value.\n * @param {string} attrName\n * @returns {*}\n */\n getAttrValue(attrName) {\n if (this.path.length === 0) return undefined;\n return this.path[this.path.length - 1].values?.[attrName];\n }\n\n /**\n * Check if current node has an attribute.\n * @param {string} attrName\n * @returns {boolean}\n */\n hasAttr(attrName) {\n if (this.path.length === 0) return false;\n const current = this.path[this.path.length - 1];\n return current.values !== undefined && attrName in current.values;\n }\n\n /**\n * Get current node's sibling position (child index in parent).\n * @returns {number}\n */\n getPosition() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].position ?? 0;\n }\n\n /**\n * Get current node's repeat counter (occurrence count of this tag name).\n * @returns {number}\n */\n getCounter() {\n if (this.path.length === 0) return -1;\n return this.path[this.path.length - 1].counter ?? 0;\n }\n\n /**\n * Get current node's sibling index (alias for getPosition).\n * @returns {number}\n * @deprecated Use getPosition() or getCounter() instead\n */\n getIndex() {\n return this.getPosition();\n }\n\n /**\n * Get current path depth.\n * @returns {number}\n */\n getDepth() {\n return this.path.length;\n }\n\n /**\n * Get path as string.\n * @param {string} [separator] - Optional separator (uses default if not provided)\n * @param {boolean} [includeNamespace=true]\n * @returns {string}\n */\n toString(separator, includeNamespace = true) {\n const sep = separator || this.separator;\n const isDefault = (sep === this.separator && includeNamespace === true);\n\n if (isDefault) {\n if (this._pathStringCache !== null) {\n return this._pathStringCache;\n }\n const result = this.path.map(n =>\n (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n this._pathStringCache = result;\n return result;\n }\n\n return this.path.map(n =>\n (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag\n ).join(sep);\n }\n\n /**\n * Get path as array of tag names.\n * @returns {string[]}\n */\n toArray() {\n return this.path.map(n => n.tag);\n }\n\n /**\n * Reset the path to empty.\n */\n reset() {\n this._pathStringCache = null;\n this.path = [];\n this.siblingStacks = [];\n }\n\n /**\n * Match current path against an Expression.\n * @param {Expression} expression\n * @returns {boolean}\n */\n matches(expression) {\n const segments = expression.segments;\n\n if (segments.length === 0) {\n return false;\n }\n\n if (expression.hasDeepWildcard()) {\n return this._matchWithDeepWildcard(segments);\n }\n\n return this._matchSimple(segments);\n }\n\n /**\n * @private\n */\n _matchSimple(segments) {\n if (this.path.length !== segments.length) {\n return false;\n }\n\n for (let i = 0; i < segments.length; i++) {\n if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * @private\n */\n _matchWithDeepWildcard(segments) {\n let pathIdx = this.path.length - 1;\n let segIdx = segments.length - 1;\n\n while (segIdx >= 0 && pathIdx >= 0) {\n const segment = segments[segIdx];\n\n if (segment.type === 'deep-wildcard') {\n segIdx--;\n\n if (segIdx < 0) {\n return true;\n }\n\n const nextSeg = segments[segIdx];\n let found = false;\n\n for (let i = pathIdx; i >= 0; i--) {\n if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {\n pathIdx = i - 1;\n segIdx--;\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n } else {\n if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {\n return false;\n }\n pathIdx--;\n segIdx--;\n }\n }\n\n return segIdx < 0;\n }\n\n /**\n * @private\n */\n _matchSegment(segment, node, isCurrentNode) {\n if (segment.tag !== '*' && segment.tag !== node.tag) {\n return false;\n }\n\n if (segment.namespace !== undefined) {\n if (segment.namespace !== '*' && segment.namespace !== node.namespace) {\n return false;\n }\n }\n\n if (segment.attrName !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n if (!node.values || !(segment.attrName in node.values)) {\n return false;\n }\n\n if (segment.attrValue !== undefined) {\n if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {\n return false;\n }\n }\n }\n\n if (segment.position !== undefined) {\n if (!isCurrentNode) {\n return false;\n }\n\n const counter = node.counter ?? 0;\n\n if (segment.position === 'first' && counter !== 0) {\n return false;\n } else if (segment.position === 'odd' && counter % 2 !== 1) {\n return false;\n } else if (segment.position === 'even' && counter % 2 !== 0) {\n return false;\n } else if (segment.position === 'nth' && counter !== segment.positionValue) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Match any expression in the given set against the current path.\n * @param {ExpressionSet} exprSet\n * @returns {boolean}\n */\n matchesAny(exprSet) {\n return exprSet.matchesAny(this);\n }\n\n /**\n * Create a snapshot of current state.\n * @returns {Object}\n */\n snapshot() {\n return {\n path: this.path.map(node => ({ ...node })),\n siblingStacks: this.siblingStacks.map(map => new Map(map))\n };\n }\n\n /**\n * Restore state from snapshot.\n * @param {Object} snapshot\n */\n restore(snapshot) {\n this._pathStringCache = null;\n this.path = snapshot.path.map(node => ({ ...node }));\n this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map));\n }\n\n /**\n * Return the read-only {@link MatcherView} for this matcher.\n *\n * The same instance is returned on every call — no allocation occurs.\n * It always reflects the current parser state and is safe to pass to\n * user callbacks without risk of accidental mutation.\n *\n * @returns {MatcherView}\n *\n * @example\n * const view = matcher.readOnly();\n * // pass view to callbacks — it stays in sync automatically\n * view.matches(expr); // ✓\n * view.getCurrentTag(); // ✓\n * // view.push(...) // ✗ method does not exist — caught by TypeScript\n */\n readOnly() {\n return this._view;\n }\n}","/**\n * ExpressionSet - An indexed collection of Expressions for efficient bulk matching\n *\n * Instead of iterating all expressions on every tag, ExpressionSet pre-indexes\n * them at insertion time by depth and terminal tag name. At match time, only\n * the relevant bucket is evaluated — typically reducing checks from O(E) to O(1)\n * lookup plus O(small bucket) matches.\n *\n * Three buckets are maintained:\n * - `_byDepthAndTag` — exact depth + exact tag name (tightest, used first)\n * - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only)\n * - `_deepWildcards` — expressions containing `..` (cannot be depth-indexed)\n *\n * @example\n * import { Expression, ExpressionSet } from 'fast-xml-tagger';\n *\n * // Build once at config time\n * const stopNodes = new ExpressionSet();\n * stopNodes.add(new Expression('root.users.user'));\n * stopNodes.add(new Expression('root.config.setting'));\n * stopNodes.add(new Expression('..script'));\n *\n * // Query on every tag — hot path\n * if (stopNodes.matchesAny(matcher)) { ... }\n */\nexport default class ExpressionSet {\n constructor() {\n /** @type {Map} depth:tag → expressions */\n this._byDepthAndTag = new Map();\n\n /** @type {Map} depth → wildcard-tag expressions */\n this._wildcardByDepth = new Map();\n\n /** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */\n this._deepWildcards = [];\n\n /** @type {Set} pattern strings already added — used for deduplication */\n this._patterns = new Set();\n\n /** @type {boolean} whether the set is sealed against further additions */\n this._sealed = false;\n }\n\n /**\n * Add an Expression to the set.\n * Duplicate patterns (same pattern string) are silently ignored.\n *\n * @param {import('./Expression.js').default} expression - A pre-constructed Expression instance\n * @returns {this} for chaining\n * @throws {TypeError} if called after seal()\n *\n * @example\n * set.add(new Expression('root.users.user'));\n * set.add(new Expression('..script'));\n */\n add(expression) {\n if (this._sealed) {\n throw new TypeError(\n 'ExpressionSet is sealed. Create a new ExpressionSet to add more expressions.'\n );\n }\n\n // Deduplicate by pattern string\n if (this._patterns.has(expression.pattern)) return this;\n this._patterns.add(expression.pattern);\n\n if (expression.hasDeepWildcard()) {\n this._deepWildcards.push(expression);\n return this;\n }\n\n const depth = expression.length;\n const lastSeg = expression.segments[expression.segments.length - 1];\n const tag = lastSeg?.tag;\n\n if (!tag || tag === '*') {\n // Can index by depth but not by tag\n if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);\n this._wildcardByDepth.get(depth).push(expression);\n } else {\n // Tightest bucket: depth + tag\n const key = `${depth}:${tag}`;\n if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);\n this._byDepthAndTag.get(key).push(expression);\n }\n\n return this;\n }\n\n /**\n * Add multiple expressions at once.\n *\n * @param {import('./Expression.js').default[]} expressions - Array of Expression instances\n * @returns {this} for chaining\n *\n * @example\n * set.addAll([\n * new Expression('root.users.user'),\n * new Expression('root.config.setting'),\n * ]);\n */\n addAll(expressions) {\n for (const expr of expressions) this.add(expr);\n return this;\n }\n\n /**\n * Check whether a pattern string is already present in the set.\n *\n * @param {import('./Expression.js').default} expression\n * @returns {boolean}\n */\n has(expression) {\n return this._patterns.has(expression.pattern);\n }\n\n /**\n * Number of expressions in the set.\n * @type {number}\n */\n get size() {\n return this._patterns.size;\n }\n\n /**\n * Seal the set against further modifications.\n * Useful to prevent accidental mutations after config is built.\n * Calling add() or addAll() on a sealed set throws a TypeError.\n *\n * @returns {this}\n */\n seal() {\n this._sealed = true;\n return this;\n }\n\n /**\n * Whether the set has been sealed.\n * @type {boolean}\n */\n get isSealed() {\n return this._sealed;\n }\n\n /**\n * Test whether the matcher's current path matches any expression in the set.\n *\n * Evaluation order (cheapest → most expensive):\n * 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions\n * 2. Depth-only wildcard bucket — O(1) lookup, rare\n * 3. Deep-wildcard list — always checked, but usually small\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {boolean} true if any expression matches the current path\n *\n * @example\n * if (stopNodes.matchesAny(matcher)) {\n * // handle stop node\n * }\n */\n matchesAny(matcher) {\n return this.findMatch(matcher) !== null;\n }\n /**\n * Find and return the first Expression that matches the matcher's current path.\n *\n * Uses the same evaluation order as matchesAny (cheapest → most expensive):\n * 1. Exact depth + tag bucket\n * 2. Depth-only wildcard bucket\n * 3. Deep-wildcard list\n *\n * @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)\n * @returns {import('./Expression.js').default | null} the first matching Expression, or null\n *\n * @example\n * const expr = stopNodes.findMatch(matcher);\n * if (expr) {\n * // access expr.config, expr.pattern, etc.\n * }\n */\n findMatch(matcher) {\n const depth = matcher.getDepth();\n const tag = matcher.getCurrentTag();\n\n // 1. Tightest bucket — most expressions live here\n const exactKey = `${depth}:${tag}`;\n const exactBucket = this._byDepthAndTag.get(exactKey);\n if (exactBucket) {\n for (let i = 0; i < exactBucket.length; i++) {\n if (matcher.matches(exactBucket[i])) return exactBucket[i];\n }\n }\n\n // 2. Depth-matched wildcard-tag expressions\n const wildcardBucket = this._wildcardByDepth.get(depth);\n if (wildcardBucket) {\n for (let i = 0; i < wildcardBucket.length; i++) {\n if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];\n }\n }\n\n // 3. Deep wildcards — cannot be pre-filtered by depth or tag\n for (let i = 0; i < this._deepWildcards.length; i++) {\n if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];\n }\n\n return null;\n }\n}\n","/**\n * fast-xml-tagger - XML/JSON path matching library\n * \n * Provides efficient path tracking and pattern matching for XML/JSON parsers.\n * \n * @example\n * import { Expression, Matcher } from 'fast-xml-tagger';\n * \n * // Create expression (parse once)\n * const expr = new Expression(\"root.users.user[id]\");\n * \n * // Create matcher (track path)\n * const matcher = new Matcher();\n * matcher.push(\"root\", [], {}, 0);\n * matcher.push(\"users\", [], {}, 0);\n * matcher.push(\"user\", [\"id\", \"type\"], { id: \"123\", type: \"admin\" }, 0);\n * \n * // Match\n * if (matcher.matches(expr)) {\n * console.log(\"Match found!\");\n * }\n */\n\nimport Expression from './Expression.js';\nimport Matcher from './Matcher.js';\nimport ExpressionSet from './ExpressionSet.js';\n\nexport { Expression, Matcher, ExpressionSet };\nexport default { Expression, Matcher, ExpressionSet };\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","Expression","constructor","pattern","options","data","separator","segments","_parse","_hasDeepWildcard","some","seg","type","_hasAttributeCondition","undefined","attrName","_hasPositionSelector","position","i","currentPart","length","trim","push","_parseSegment","part","segment","bracketContent","withoutBrackets","bracketMatch","match","content","slice","namespace","tag","tagAndPosition","includes","nsIndex","indexOf","substring","Error","positionMatch","colonIndex","lastIndexOf","tagPart","posPart","test","eqIndex","attrValue","nthMatch","positionValue","parseInt","hasDeepWildcard","hasAttributeCondition","hasPositionSelector","toString","MatcherView","matcher","_matcher","getCurrentTag","path","getCurrentNamespace","getAttrValue","values","hasAttr","current","getPosition","getCounter","counter","getIndex","getDepth","includeNamespace","toArray","map","n","matches","expression","matchesAny","exprSet","Matcher","siblingStacks","_pathStringCache","_view","tagName","attrValues","currentLevel","Map","siblings","siblingKey","count","set","node","pop","updateCurrent","sep","result","join","reset","_matchWithDeepWildcard","_matchSimple","_matchSegment","pathIdx","segIdx","nextSeg","found","isCurrentNode","String","snapshot","restore","readOnly","ExpressionSet","_byDepthAndTag","_wildcardByDepth","_deepWildcards","_patterns","Set","_sealed","add","TypeError","has","depth","lastSeg","addAll","expressions","expr","size","seal","isSealed","findMatch","exactKey","exactBucket","wildcardBucket"],"sourceRoot":""} \ No newline at end of file diff --git a/node_modules/path-expression-matcher/package.json b/node_modules/path-expression-matcher/package.json index f6c83894..a54cead5 100644 --- a/node_modules/path-expression-matcher/package.json +++ b/node_modules/path-expression-matcher/package.json @@ -1,6 +1,6 @@ { "name": "path-expression-matcher", - "version": "1.1.3", + "version": "1.5.0", "description": "Efficient path tracking and pattern matching for XML/JSON parsers", "main": "./lib/pem.cjs", "type": "module", @@ -20,7 +20,7 @@ } }, "scripts": { - "test": "c8 --reporter=lcov --reporter=text node test/namespace_test.js && c8 --reporter=lcov --reporter=text node test/test.js", + "test": "c8 --reporter=lcov --reporter=text node test/*test.js", "bundle": "webpack --config webpack.cjs.config.js" }, "keywords": [ diff --git a/node_modules/path-expression-matcher/src/Expression.js b/node_modules/path-expression-matcher/src/Expression.js index 6cf24d54..0fbcea37 100644 --- a/node_modules/path-expression-matcher/src/Expression.js +++ b/node_modules/path-expression-matcher/src/Expression.js @@ -15,11 +15,11 @@ export default class Expression { * @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; // Cache expensive checks for performance (O(1) instead of O(n)) this._hasDeepWildcard = this.segments.some(seg => seg.type === 'deep-wildcard'); this._hasAttributeCondition = this.segments.some(seg => seg.attrName !== undefined); diff --git a/node_modules/path-expression-matcher/src/ExpressionSet.js b/node_modules/path-expression-matcher/src/ExpressionSet.js new file mode 100644 index 00000000..51b8888b --- /dev/null +++ b/node_modules/path-expression-matcher/src/ExpressionSet.js @@ -0,0 +1,209 @@ +/** + * ExpressionSet - An indexed collection of Expressions for efficient bulk matching + * + * Instead of iterating all expressions on every tag, ExpressionSet pre-indexes + * them at insertion time by depth and terminal tag name. At match time, only + * the relevant bucket is evaluated — typically reducing checks from O(E) to O(1) + * lookup plus O(small bucket) matches. + * + * Three buckets are maintained: + * - `_byDepthAndTag` — exact depth + exact tag name (tightest, used first) + * - `_wildcardByDepth` — exact depth + wildcard tag `*` (depth-matched only) + * - `_deepWildcards` — expressions containing `..` (cannot be depth-indexed) + * + * @example + * import { Expression, ExpressionSet } from 'fast-xml-tagger'; + * + * // Build once at config time + * const stopNodes = new ExpressionSet(); + * stopNodes.add(new Expression('root.users.user')); + * stopNodes.add(new Expression('root.config.setting')); + * stopNodes.add(new Expression('..script')); + * + * // Query on every tag — hot path + * if (stopNodes.matchesAny(matcher)) { ... } + */ +export default class ExpressionSet { + constructor() { + /** @type {Map} depth:tag → expressions */ + this._byDepthAndTag = new Map(); + + /** @type {Map} depth → wildcard-tag expressions */ + this._wildcardByDepth = new Map(); + + /** @type {import('./Expression.js').default[]} expressions containing deep wildcard (..) */ + this._deepWildcards = []; + + /** @type {Set} pattern strings already added — used for deduplication */ + this._patterns = new Set(); + + /** @type {boolean} whether the set is sealed against further additions */ + 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.' + ); + } + + // Deduplicate by pattern string + 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 === '*') { + // Can index by depth but not by tag + if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []); + this._wildcardByDepth.get(depth).push(expression); + } else { + // Tightest bucket: depth + tag + 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(); + + // 1. Tightest bucket — most expressions live here + 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]; + } + } + + // 2. Depth-matched wildcard-tag expressions + const wildcardBucket = this._wildcardByDepth.get(depth); + if (wildcardBucket) { + for (let i = 0; i < wildcardBucket.length; i++) { + if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i]; + } + } + + // 3. Deep wildcards — cannot be pre-filtered by depth or tag + for (let i = 0; i < this._deepWildcards.length; i++) { + if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i]; + } + + return null; + } +} diff --git a/node_modules/path-expression-matcher/src/Matcher.js b/node_modules/path-expression-matcher/src/Matcher.js index d3df66f8..cbb8fffe 100644 --- a/node_modules/path-expression-matcher/src/Matcher.js +++ b/node_modules/path-expression-matcher/src/Matcher.js @@ -1,45 +1,203 @@ +import ExpressionSet from "./ExpressionSet.js"; + +/** + * MatcherView - A lightweight read-only view over a Matcher's internal state. + * + * Created once by Matcher and reused across all callbacks. Holds a direct + * reference to the parent Matcher so it always reflects current parser state + * with zero copying or freezing overhead. + * + * Users receive this via {@link Matcher#readOnly} or directly from parser + * callbacks. It exposes all query and matching methods but has no mutation + * methods — misuse is caught at the TypeScript level rather than at runtime. + * + * @example + * const matcher = new Matcher(); + * const view = matcher.readOnly(); + * + * matcher.push("root", {}); + * view.getCurrentTag(); // "root" + * view.getDepth(); // 1 + */ +export class MatcherView { + /** + * @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 path = this._matcher.path; + return path.length > 0 ? path[path.length - 1].tag : undefined; + } + + /** + * Get current namespace. + * @returns {string|undefined} + */ + getCurrentNamespace() { + const path = this._matcher.path; + return path.length > 0 ? path[path.length - 1].namespace : undefined; + } + + /** + * Get current node's attribute value. + * @param {string} attrName + * @returns {*} + */ + getAttrValue(attrName) { + const path = this._matcher.path; + if (path.length === 0) return undefined; + return path[path.length - 1].values?.[attrName]; + } + + /** + * Check if current node has an attribute. + * @param {string} attrName + * @returns {boolean} + */ + hasAttr(attrName) { + const path = this._matcher.path; + if (path.length === 0) return false; + const current = path[path.length - 1]; + return current.values !== undefined && attrName in current.values; + } + + /** + * Get current node's sibling position (child index in parent). + * @returns {number} + */ + getPosition() { + const path = this._matcher.path; + if (path.length === 0) return -1; + return path[path.length - 1].position ?? 0; + } + + /** + * Get current node's repeat counter (occurrence count of this tag name). + * @returns {number} + */ + getCounter() { + const path = this._matcher.path; + if (path.length === 0) return -1; + return path[path.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(n => n.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); + } +} + /** - * Matcher - Tracks current path in XML/JSON tree and matches against Expressions - * + * Matcher - Tracks current path in XML/JSON tree and matches against Expressions. + * * The matcher maintains a stack of nodes representing the current path from root to * current tag. It only stores attribute values for the current (top) node to minimize * memory usage. Sibling tracking is used to auto-calculate position and counter. - * + * + * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to + * user callbacks — it always reflects current state with no Proxy overhead. + * * @example * const matcher = new Matcher(); * matcher.push("root", {}); * matcher.push("users", {}); * matcher.push("user", { id: "123", type: "admin" }); - * + * * const expr = new Expression("root.users.user"); * matcher.matches(expr); // true */ export default class Matcher { /** - * 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 = []; - // Each path node: { tag: string, values: object, position: number, counter: number } + // Each path node: { tag, values, position, counter, namespace? } // values only present for current (last) node // Each siblingStacks entry: Map tracking occurrences at each level + 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; + // Remove values from previous current node (now becoming ancestor) if (this.path.length > 0) { - const prev = this.path[this.path.length - 1]; - prev.values = undefined; + this.path[this.path.length - 1].values = undefined; } // Get or create sibling tracking for current level @@ -72,12 +230,10 @@ export default class Matcher { counter: counter }; - // Store namespace if provided if (namespace !== null && namespace !== undefined) { node.namespace = namespace; } - // Store values only for current node if (attrValues !== null && attrValues !== undefined) { node.values = attrValues; } @@ -86,19 +242,15 @@ export default class Matcher { } /** - * 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 undefined; - } + if (this.path.length === 0) return undefined; + this._pathStringCache = null; const node = this.path.pop(); - // Clean up sibling tracking for levels deeper than current - // After pop, path.length is the new depth - // We need to clean up siblingStacks[path.length + 1] and beyond if (this.siblingStacks.length > this.path.length + 1) { this.siblingStacks.length = this.path.length + 1; } @@ -107,9 +259,9 @@ export default class Matcher { } /** - * 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) { @@ -121,7 +273,7 @@ export default class Matcher { } /** - * Get current tag name + * Get current tag name. * @returns {string|undefined} */ getCurrentTag() { @@ -129,7 +281,7 @@ export default class Matcher { } /** - * Get current namespace + * Get current namespace. * @returns {string|undefined} */ getCurrentNamespace() { @@ -137,19 +289,18 @@ export default class Matcher { } /** - * 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 undefined; - 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) { @@ -159,7 +310,7 @@ export default class Matcher { } /** - * Get current node's sibling position (child index in parent) + * Get current node's sibling position (child index in parent). * @returns {number} */ getPosition() { @@ -168,7 +319,7 @@ export default class Matcher { } /** - * 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() { @@ -177,7 +328,7 @@ export default class Matcher { } /** - * 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 */ @@ -186,7 +337,7 @@ export default class Matcher { } /** - * Get current path depth + * Get current path depth. * @returns {number} */ getDepth() { @@ -194,23 +345,33 @@ export default class Matcher { } /** - * 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 sep = separator || this.separator; - return this.path.map(n => { - if (includeNamespace && n.namespace) { - return `${n.namespace}:${n.tag}`; + const isDefault = (sep === this.separator && includeNamespace === true); + + if (isDefault) { + if (this._pathStringCache !== null) { + return this._pathStringCache; } - return n.tag; - }).join(sep); + const result = this.path.map(n => + (n.namespace) ? `${n.namespace}:${n.tag}` : n.tag + ).join(sep); + this._pathStringCache = result; + return result; + } + + return this.path.map(n => + (includeNamespace && n.namespace) ? `${n.namespace}:${n.tag}` : n.tag + ).join(sep); } /** - * Get path as array of tag names + * Get path as array of tag names. * @returns {string[]} */ toArray() { @@ -218,17 +379,18 @@ export default class Matcher { } /** - * Reset the path to empty + * Reset the path to empty. */ reset() { + this._pathStringCache = null; this.path = []; 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; @@ -237,32 +399,23 @@ export default class Matcher { return false; } - // Handle deep wildcard patterns if (expression.hasDeepWildcard()) { return this._matchWithDeepWildcard(segments); } - // Simple path matching (no deep wildcards) return this._matchSimple(segments); } /** - * Match simple path (no deep wildcards) * @private */ _matchSimple(segments) { - // Path must be same length as segments if (this.path.length !== segments.length) { return false; } - // Match each segment bottom-to-top 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; } } @@ -271,32 +424,27 @@ export default class Matcher { } /** - * Match path with deep wildcards * @private */ _matchWithDeepWildcard(segments) { - let pathIdx = this.path.length - 1; // Start from current node (bottom) - let segIdx = segments.length - 1; // Start from last segment + let pathIdx = this.path.length - 1; + let segIdx = segments.length - 1; while (segIdx >= 0 && pathIdx >= 0) { const segment = segments[segIdx]; if (segment.type === 'deep-wildcard') { - // ".." matches zero or more levels segIdx--; if (segIdx < 0) { - // Pattern ends with "..", always matches return true; } - // Find where next segment matches in the path 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; @@ -308,9 +456,7 @@ export default class Matcher { return false; } } else { - // Regular segment - 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--; @@ -318,38 +464,25 @@ export default class Matcher { } } - // All segments must be consumed 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) { - // Match tag name (* is wildcard) if (segment.tag !== '*' && segment.tag !== node.tag) { return false; } - // Match namespace if specified in segment if (segment.namespace !== undefined) { - // Segment has namespace - node must match it if (segment.namespace !== '*' && segment.namespace !== node.namespace) { return false; } } - // If segment has no namespace, it matches nodes with or without namespace - // Match attribute name (check if node has this attribute) - // Can only check for current node since ancestors don't have values if (segment.attrName !== undefined) { if (!isCurrentNode) { - // Can't check attributes for ancestor nodes (values not stored) return false; } @@ -357,20 +490,15 @@ export default class Matcher { return false; } - // Match attribute value (only possible for current node) if (segment.attrValue !== undefined) { - const actualValue = node.values[segment.attrName]; - // Both should be strings - if (String(actualValue) !== String(segment.attrValue)) { + if (String(node.values[segment.attrName]) !== String(segment.attrValue)) { return false; } } } - // Match position (only for current node) if (segment.position !== undefined) { if (!isCurrentNode) { - // Can't check position for ancestor nodes return false; } @@ -382,10 +510,8 @@ export default class Matcher { 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; } } @@ -393,8 +519,17 @@ export default class Matcher { } /** - * 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 { @@ -404,11 +539,32 @@ export default class Matcher { } /** - * Restore state from snapshot - * @param {Object} snapshot - State snapshot + * Restore state from snapshot. + * @param {Object} snapshot */ restore(snapshot) { + this._pathStringCache = null; this.path = snapshot.path.map(node => ({ ...node })); this.siblingStacks = snapshot.siblingStacks.map(map => new Map(map)); } + + /** + * Return the read-only {@link MatcherView} for this matcher. + * + * 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 {MatcherView} + * + * @example + * 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() { + return this._view; + } } \ No newline at end of file diff --git a/node_modules/path-expression-matcher/src/index.d.ts b/node_modules/path-expression-matcher/src/index.d.ts index a30f056b..18cd2d02 100644 --- a/node_modules/path-expression-matcher/src/index.d.ts +++ b/node_modules/path-expression-matcher/src/index.d.ts @@ -189,22 +189,81 @@ export interface MatcherSnapshot { } /** - * Matcher - Tracks current path in XML/JSON tree and matches against Expressions - * + * MatcherView - A lightweight read-only view over a {@link Matcher} instance. + * + * Created once by {@link Matcher} and reused across all callbacks — no allocation + * on every invocation. Holds a direct reference to the parent Matcher's internal + * state so it always reflects the current parser position with zero copying or + * freezing overhead. + * + * Mutation methods (`push`, `pop`, `reset`, `updateCurrent`, `restore`) are simply + * absent from this class, so misuse is caught at compile time by TypeScript rather + * than at runtime. + * + * Obtain via {@link Matcher#readOnly} — the same instance is returned every time. + * + * @example + * ```typescript + * const matcher = new Matcher(); + * const view: MatcherView = matcher.readOnly(); + * + * matcher.push("root", {}); + * matcher.push("users", {}); + * matcher.push("user", { id: "123" }); + * + * view.matches(expr); // ✓ true + * view.getCurrentTag(); // ✓ "user" + * view.getDepth(); // ✓ 3 + * // view.push(...) // ✗ Property 'push' does not exist on type 'MatcherView' + * ``` + */ +export class MatcherView { + /** + * Default path separator (read-only, delegates to parent Matcher) + */ + readonly separator: string; + + getCurrentTag(): string | undefined; + getCurrentNamespace(): string | undefined; + getAttrValue(attrName: string): any; + hasAttr(attrName: string): boolean; + getPosition(): number; + getCounter(): number; + /** @deprecated Use getPosition() or getCounter() instead */ + getIndex(): number; + getDepth(): number; + toString(separator?: string, includeNamespace?: boolean): string; + toArray(): string[]; + matches(expression: Expression): boolean; + matchesAny(exprSet: ExpressionSet): boolean; +} + +/** + * @deprecated Use {@link MatcherView} instead. + * Alias kept for backward compatibility with code that references `ReadOnlyMatcher`. + */ +export type ReadOnlyMatcher = MatcherView; + +/** + * Matcher - Tracks current path in XML/JSON tree and matches against Expressions. + * * The matcher maintains a stack of nodes representing the current path from root to * current tag. It only stores attribute values for the current (top) node to minimize * memory usage. - * + * + * Use {@link Matcher#readOnly} to obtain a {@link MatcherView} safe to pass to + * user callbacks — the same instance is reused on every call with no allocation overhead. + * * @example * ```typescript * const matcher = new Matcher(); * matcher.push("root", {}); * matcher.push("users", {}); * matcher.push("user", { id: "123", type: "admin" }); - * + * * const expr = new Expression("root.users.user"); * matcher.matches(expr); // true - * + * * matcher.pop(); * matcher.matches(expr); // false * ``` @@ -215,11 +274,6 @@ export class Matcher { */ readonly separator: string; - /** - * Current path stack - */ - readonly path: PathNode[]; - /** * Create a new Matcher * @param options - Configuration options @@ -227,11 +281,11 @@ export class Matcher { constructor(options?: MatcherOptions); /** - * Push a new tag onto the path + * Push a new tag onto the path. * @param tagName - Name of the tag * @param attrValues - Attribute key-value pairs for current node (optional) * @param namespace - Namespace for the tag (optional) - * + * * @example * ```typescript * matcher.push("user", { id: "123", type: "admin" }); @@ -242,125 +296,228 @@ export class Matcher { push(tagName: string, attrValues?: Record | null, namespace?: string | null): void; /** - * Pop the last tag from the path + * Pop the last tag from the path. * @returns The popped node or undefined if path is empty */ pop(): PathNode | undefined; /** - * Update current node's attribute values - * Useful when attributes are parsed after push + * Update current node's attribute values. + * Useful when attributes are parsed after push. * @param attrValues - Attribute values */ updateCurrent(attrValues: Record): void; /** - * Get current tag name - * @returns Current tag name or undefined if path is empty + * Reset the path to empty. */ - getCurrentTag(): string | undefined; + reset(): void; /** - * Get current namespace - * @returns Current namespace or undefined if not present or path is empty + * Create a snapshot of current state. + * @returns State snapshot that can be restored later */ - getCurrentNamespace(): string | undefined; + snapshot(): MatcherSnapshot; /** - * Get current node's attribute value - * @param attrName - Attribute name - * @returns Attribute value or undefined + * Restore state from snapshot. + * @param snapshot - State snapshot from previous snapshot() call */ - getAttrValue(attrName: string): any; + restore(snapshot: MatcherSnapshot): void; - /** - * Check if current node has an attribute - * @param attrName - Attribute name - */ + getCurrentTag(): string | undefined; + getCurrentNamespace(): string | undefined; + getAttrValue(attrName: string): any; hasAttr(attrName: string): boolean; + getPosition(): number; + getCounter(): number; + /** @deprecated Use getPosition() or getCounter() instead */ + getIndex(): number; + getDepth(): number; + toString(separator?: string, includeNamespace?: boolean): string; + toArray(): string[]; + matches(expression: Expression): boolean; + matchesAny(exprSet: ExpressionSet): boolean; /** - * Get current node's sibling position (child index in parent) - * @returns Position index or -1 if path is empty + * Return the read-only {@link MatcherView} for this matcher. + * + * The same instance is returned on every call — no allocation occurs. + * Pass this to user callbacks; it always reflects current parser state. + * + * @example + * ```typescript + * const view = matcher.readOnly(); + * // same reference every time — safe to cache + * view === matcher.readOnly(); // true + * ``` */ - getPosition(): number; + readOnly(): MatcherView; +} +/** + * ExpressionSet - An indexed collection of Expressions for efficient bulk matching + * + * Pre-indexes expressions at insertion time by depth and terminal tag name so + * that `matchesAny()` performs an O(1) bucket lookup rather than a full O(E) + * linear scan on every tag. + * + * Three internal buckets are maintained automatically: + * - **exact** — expressions with a fixed depth and a concrete terminal tag + * - **depth-wildcard** — fixed depth but terminal tag is `*` + * - **deep-wildcard** — expressions containing `..` (cannot be depth-indexed) + * + * @example + * ```typescript + * import { Expression, ExpressionSet, Matcher } from 'fast-xml-tagger'; + * + * // Build once at config time + * const stopNodes = new ExpressionSet(); + * stopNodes + * .add(new Expression('root.users.user')) + * .add(new Expression('root.config.*')) + * .add(new Expression('..script')) + * .seal(); // prevent accidental mutation during parsing + * + * // Query on every tag — hot path + * if (stopNodes.matchesAny(matcher)) { + * // handle stop node + * } + * ``` + */ +export class ExpressionSet { /** - * Get current node's repeat counter (occurrence count of this tag name) - * @returns Counter value or -1 if path is empty + * Create an empty ExpressionSet. */ - getCounter(): number; + constructor(); /** - * Get current node's sibling index (alias for getPosition for backward compatibility) - * @returns Index or -1 if path is empty - * @deprecated Use getPosition() or getCounter() instead + * Number of expressions currently in the set. */ - getIndex(): number; + readonly size: number; /** - * Get current path depth - * @returns Number of nodes in the path + * Whether the set has been sealed against further modifications. */ - getDepth(): number; + readonly isSealed: boolean; /** - * Get path as string - * @param separator - Optional separator (uses default if not provided) - * @param includeNamespace - Whether to include namespace in output - * @returns Path string (e.g., "root.users.user" or "ns:root.ns:users.user") + * Add a single Expression to the set. + * + * Duplicate patterns (same `expression.pattern` string) are silently ignored. + * + * @param expression - A pre-constructed Expression instance + * @returns `this` — for chaining + * @throws {TypeError} if the set has been sealed + * + * @example + * ```typescript + * set.add(new Expression('root.users.user')); + * set.add(new Expression('..script')); + * ``` */ - toString(separator?: string, includeNamespace?: boolean): string; + add(expression: Expression): this; /** - * Get path as array of tag names - * @returns Array of tag names + * Add multiple expressions at once. + * + * @param expressions - Array of Expression instances + * @returns `this` — for chaining + * @throws {TypeError} if the set has been sealed + * + * @example + * ```typescript + * set.addAll([ + * new Expression('root.users.user'), + * new Expression('root.config.setting'), + * ]); + * ``` */ - toArray(): string[]; + addAll(expressions: Expression[]): this; /** - * Reset the path to empty + * Check whether an Expression with the same pattern is already present. + * + * @param expression - Expression to look up + * @returns `true` if the pattern was already added */ - reset(): void; + has(expression: Expression): boolean; /** - * Match current path against an Expression - * @param expression - The expression to match against - * @returns True if current path matches the expression - * + * Seal the set against further modifications. + * + * After calling `seal()`, any call to `add()` or `addAll()` will throw a + * `TypeError`. This is useful to prevent accidental mutation once the config + * has been fully built and parsing has started. + * + * @returns `this` — for chaining + * * @example * ```typescript - * const expr = new Expression("root.users.user[id]"); - * const matcher = new Matcher(); - * - * matcher.push("root"); - * matcher.push("users"); - * matcher.push("user", { id: "123" }); - * - * matcher.matches(expr); // true + * const stopNodes = new ExpressionSet(); + * stopNodes.addAll(patterns.map(p => new Expression(p))).seal(); + * + * // Later — safe: reads are still allowed + * stopNodes.matchesAny(matcher); + * + * // Later — throws TypeError: ExpressionSet is sealed + * stopNodes.add(new Expression('root.extra')); * ``` */ - matches(expression: Expression): boolean; + seal(): this; /** - * Create a snapshot of current state - * @returns State snapshot that can be restored later + * Test whether the matcher's current path matches **any** expression in the set. + * + * Uses the pre-built index to evaluate only the relevant bucket(s): + * 1. Exact depth + tag — O(1) lookup + * 2. Depth-matched wildcard tag — O(1) lookup + * 3. Deep-wildcard expressions — always scanned (typically a small list) + * + * @param matcher - A `Matcher` instance or a `ReadOnlyMatcher` view + * @returns `true` if at least one expression matches the current path + * + * @example + * ```typescript + * // Replaces: + * // for (const expr of stopNodeExpressions) { + * // if (matcher.matches(expr)) return true; + * // } + * + * if (stopNodes.matchesAny(matcher)) { + * // current tag is a stop node + * } + * ``` */ - snapshot(): MatcherSnapshot; + matchesAny(matcher: Matcher | MatcherView): boolean; /** - * Restore state from snapshot - * @param snapshot - State snapshot from previous snapshot() call + * Find the first expression in the set that matches the matcher's current path. + * + * Uses the pre-built index to evaluate only the relevant bucket(s): + * 1. Exact depth + tag — O(1) lookup + * 2. Depth-matched wildcard tag — O(1) lookup + * 3. Deep-wildcard expressions — always scanned (typically a small list) + * + * @param matcher - A `Matcher` instance or a `ReadOnlyMatcher` view + * @returns Expression if at least one expression matches the current path + * + * @example + * ```typescript + * const node = stopNodes.findMatch(matcher); + * ``` */ - restore(snapshot: MatcherSnapshot): void; + findMatch(matcher: Matcher | MatcherView): Expression; } /** - * Default export containing both Expression and Matcher + * Default export containing Expression, Matcher, and ExpressionSet */ declare const _default: { Expression: typeof Expression; Matcher: typeof Matcher; + MatcherView: typeof MatcherView; + ExpressionSet: typeof ExpressionSet; }; export default _default; \ No newline at end of file diff --git a/node_modules/path-expression-matcher/src/index.js b/node_modules/path-expression-matcher/src/index.js index 630262d3..acea0dc5 100644 --- a/node_modules/path-expression-matcher/src/index.js +++ b/node_modules/path-expression-matcher/src/index.js @@ -23,6 +23,7 @@ import Expression from './Expression.js'; import Matcher from './Matcher.js'; +import ExpressionSet from './ExpressionSet.js'; -export { Expression, Matcher }; -export default { Expression, Matcher }; +export { Expression, Matcher, ExpressionSet }; +export default { Expression, Matcher, ExpressionSet }; diff --git a/node_modules/strnum/.github/SECURITY.md b/node_modules/strnum/.github/SECURITY.md deleted file mode 100644 index 0db86ca5..00000000 --- a/node_modules/strnum/.github/SECURITY.md +++ /dev/null @@ -1,5 +0,0 @@ -If you believe you have found a security vulnerability in this repository which can be potentially harful for the users in anyway, please do not report security vulnerabilities through public GitHub issues. Instead, please report it to us as described below. - -## Security contact information - -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. diff --git a/node_modules/strnum/.vscode/launch.json b/node_modules/strnum/.vscode/launch.json deleted file mode 100644 index b87b3491..00000000 --- a/node_modules/strnum/.vscode/launch.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Jasmine Tests", - "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js", - "args": [ - "${workspaceFolder}/spec/attr_spec.js" - ], - "internalConsoleOptions": "openOnSessionStart" - },{ - "type": "node", - "request": "launch", - "name": "Jasmine Tests current test file", - "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js", - "args": [ - "${file}" - ], - "internalConsoleOptions": "openOnSessionStart" - } - ] - -} \ No newline at end of file diff --git a/node_modules/strnum/CHANGELOG.md b/node_modules/strnum/CHANGELOG.md index d7c7f2b5..97a8ee4e 100644 --- a/node_modules/strnum/CHANGELOG.md +++ b/node_modules/strnum/CHANGELOG.md @@ -1,4 +1,8 @@ +**2.2.2 / 2026-03-23** +- fix for space string + + **2.2.1 / 2026-03-19** - fix false positive for eNotation when no leading zeros diff --git a/node_modules/strnum/algo.stflow b/node_modules/strnum/algo.stflow deleted file mode 100644 index fd0e64e6..00000000 --- a/node_modules/strnum/algo.stflow +++ /dev/null @@ -1,84 +0,0 @@ - -FLOW: toNumber -input: x, options -IF not string - END x -ELSE_IF should skip - END x -ELSE_IF 0 - END 0 -ELSE_IF hex is supported AND x is hex - END int of x of base 16 -ELSE_IF possible e notation - FOLLOW: resolve enotation (x, trimmed x, options) -ELSE - IF match numeric pattern - separate sign, leading zeros, pure number - IF x doesn't starts with "[+-]0." - END number(x) - IF leading zeros are not allowed - IF leading zeros > 1 - #00.1 - END x - ELSE_IF leading zeros == 1 AND decimal is not adjacent to leading zeros - #06.5 - #but not 0.65, .65, 6.0 - END x - ELSE_IF str has only zeros - END 0 - ELSE - parse x to number - IF parsed x == 0 or -0 - END parsed x - ELSE_IF parsed x is eNotation - IF conversion to enotation is allowed - END parsed x - ELSE - END x - ELSE_IF floating number - IF parsed x is 0 - END parsed x - ELSE_IF parsed x == number without leading 0s - #0.456. 0.79000 - END parsed x - ELSE_IF parsed x is negative AND == parsed x == number without leading 0s - END parsed x - ELSE - END x - ELSE_IF leading 0s are present - IF parsed x == x without leading 0s - END parsed x - ELSE - END x - ELSE - IF parsed x == x (consider sign) - END parsed x - ELSE - END x - - ELSE - END x - - - -FLOW: resolve enotation -input: x, trimmed x, options -IF eNotation has not to be evaluated - END x -IF match eNotation pattern - extract sign, eChar, leading zeros - find if eChar adjacent to leading zeros - - IF leading zeros > 1 AND eChar adjacent to leading zeros - # 00e, -00e - END x - ELSE_IF exp is `0e`, `0.e`, `-0.e`, `-0e` - END number(x); - ELSE_IF leading zeros are allowed but eChar is not adjacent to leading zeros - # -003e2 - remove leading zeros - END number(x) - ELSE - END x -ELSE - END x \ No newline at end of file diff --git a/node_modules/strnum/package.json b/node_modules/strnum/package.json index 76577b82..37d0ce40 100644 --- a/node_modules/strnum/package.json +++ b/node_modules/strnum/package.json @@ -1,6 +1,6 @@ { "name": "strnum", - "version": "2.2.1", + "version": "2.2.3", "description": "Parse String to Number based on configuration", "type": "module", "main": "strnum.js", diff --git a/node_modules/strnum/strnum.js b/node_modules/strnum/strnum.js index 661c37c3..3099d60c 100644 --- a/node_modules/strnum/strnum.js +++ b/node_modules/strnum/strnum.js @@ -20,8 +20,9 @@ export default function toNumber(str, options = {}) { let trimmedStr = str.trim(); - if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str; - else if (str === "0") return 0; + if (trimmedStr.length === 0) return str; + else if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str; + else if (trimmedStr === "0") return 0; else if (options.hex && hexRegex.test(trimmedStr)) { return parse_int(trimmedStr, 16); // }else if (options.oct && octRegex.test(str)) { diff --git a/node_modules/strnum/tests/infinity_test.js b/node_modules/strnum/tests/infinity_test.js deleted file mode 100644 index cb62da9c..00000000 --- a/node_modules/strnum/tests/infinity_test.js +++ /dev/null @@ -1,18 +0,0 @@ -import toNumber from "../strnum.js"; - -describe("Should convert all the valid numeric strings to number", () => { - it("should return infinity as per user option", () => { - expect(toNumber("1e1000", { infinity: "original" })).toEqual("1e1000"); - expect(toNumber("1e1000", { infinity: "null" })).toEqual(null); - expect(toNumber("1e1000", { infinity: "infinity" })).toEqual(Infinity); - expect(toNumber("1e1000", { infinity: "string" })).toEqual("Infinity"); - expect(toNumber("-1e1000", { infinity: "original" })).toEqual("-1e1000"); - expect(toNumber("-1e1000", { infinity: "null" })).toEqual(null); - expect(toNumber("-1e1000", { infinity: "infinity" })).toEqual(-Infinity); - expect(toNumber("-1e1000", { infinity: "string" })).toEqual("-Infinity"); - - - expect(toNumber("1e309")).toEqual("1e309"); - - }); -}); \ No newline at end of file diff --git a/node_modules/strnum/tests/strnum_test.js b/node_modules/strnum/tests/strnum_test.js deleted file mode 100644 index c9171045..00000000 --- a/node_modules/strnum/tests/strnum_test.js +++ /dev/null @@ -1,174 +0,0 @@ -import toNumber from "../strnum.js"; - -describe("Should convert all the valid numeric strings to number", () => { - it("should return undefined, null, empty string, or non-numeric as it is", () => { - expect(toNumber(undefined)).not.toBeDefined(); - expect(toNumber(null)).toEqual(null); - expect(toNumber("")).toEqual(""); - expect(toNumber("string")).toEqual("string"); - expect(toNumber("e89794659669cb7bb967db73a7ea6889c3891727")).toEqual("e89794659669cb7bb967db73a7ea6889c3891727"); - }); - it("should not parse number with spaces or comma", () => { - expect(toNumber("12,12")).toEqual("12,12"); - expect(toNumber("12 12")).toEqual("12 12"); - expect(toNumber("12-12")).toEqual("12-12"); - expect(toNumber("12.12.12")).toEqual("12.12.12"); - }) - it("should consider + sign", () => { - expect(toNumber("+12")).toEqual(12); - expect(toNumber("+ 12")).toEqual("+ 12"); - expect(toNumber("12+12")).toEqual("12+12"); - expect(toNumber("1212+")).toEqual("1212+"); - }) - it("should parse hexadecimal values", () => { - expect(toNumber("0x2f")).toEqual(47); - expect(toNumber("-0x2f")).toEqual(-47); - expect(toNumber("0x2f", { hex: true })).toEqual(47); - expect(toNumber("-0x2f", { hex: true })).toEqual(-47); - expect(toNumber("0x2f", { hex: false })).toEqual("0x2f"); - expect(toNumber("-0x2f", { hex: false })).toEqual("-0x2f"); - }) - it("should not parse strings with 0x embedded", () => { - expect(toNumber("0xzz")).toEqual("0xzz"); - expect(toNumber("iweraf0x123qwerqwer")).toEqual("iweraf0x123qwerqwer"); - expect(toNumber("1230x55")).toEqual("1230x55"); - expect(toNumber("JVBERi0xLjMNCiXi48")).toEqual("JVBERi0xLjMNCiXi48"); - }) - it("leading zeros", () => { - expect(toNumber("0")).toEqual(0); - expect(toNumber("00")).toEqual(0); - expect(toNumber("00.0")).toEqual(0); - - expect(toNumber("0", { leadingZeros: false })).toEqual(0); - expect(toNumber("00", { leadingZeros: false })).toEqual("00"); - expect(toNumber("00.0", { leadingZeros: false })).toEqual("00.0"); - - expect(toNumber("06")).toEqual(6); - expect(toNumber("06", { leadingZeros: true })).toEqual(6); - expect(toNumber("06", { leadingZeros: false })).toEqual("06"); - - expect(toNumber("006")).toEqual(6); - expect(toNumber("006", { leadingZeros: true })).toEqual(6); - expect(toNumber("006", { leadingZeros: false })).toEqual("006"); - - expect(toNumber("000000000000000000000000017717", { leadingZeros: false })).toEqual("000000000000000000000000017717"); - expect(toNumber("000000000000000000000000017717", { leadingZeros: true })).toEqual(17717); - expect(toNumber("020211201030005811824")).toEqual("020211201030005811824"); - expect(toNumber("0420926189200190257681175017717")).toEqual(4.209261892001902e+29); - }) - it("invalid floating number", () => { - expect(toNumber("20.21.030")).toEqual("20.21.030"); - expect(toNumber("0.21.030")).toEqual("0.21.030"); - expect(toNumber("0.21.")).toEqual("0.21."); - }); - it("floating point and leading zeros", () => { - expect(toNumber("0.")).toEqual(0); - expect(toNumber("+0.")).toEqual(0); - expect(toNumber("-0.")).toEqual(-0); - expect(toNumber("1.")).toEqual(1); - expect(toNumber("00.00")).toEqual(0); - expect(toNumber("0.06")).toEqual(0.06); - expect(toNumber("00.6")).toEqual(0.6); - expect(toNumber(".006")).toEqual(0.006); - expect(toNumber("6.0")).toEqual(6); - expect(toNumber("06.0")).toEqual(6); - - expect(toNumber("0.0", { leadingZeros: false })).toEqual(0); - expect(toNumber("00.00", { leadingZeros: false })).toEqual("00.00"); - expect(toNumber("0.06", { leadingZeros: false })).toEqual(0.06); - expect(toNumber("00.6", { leadingZeros: false })).toEqual("00.6"); - expect(toNumber(".006", { leadingZeros: false })).toEqual(0.006); - expect(toNumber("6.0", { leadingZeros: false })).toEqual(6); - expect(toNumber("06.0", { leadingZeros: false })).toEqual("06.0"); - }) - it("negative number leading zeros", () => { - expect(toNumber("+06")).toEqual(6); - expect(toNumber("-06")).toEqual(-6); - expect(toNumber("-06", { leadingZeros: true })).toEqual(-6); - expect(toNumber("-06", { leadingZeros: false })).toEqual("-06"); - - expect(toNumber("-0.0")).toEqual(-0); - expect(toNumber("-00.00")).toEqual(-0); - expect(toNumber("-0.06")).toEqual(-0.06); - expect(toNumber("-00.6")).toEqual(-0.6); - expect(toNumber("-.006")).toEqual(-0.006); - expect(toNumber("-6.0")).toEqual(-6); - expect(toNumber("-06.0")).toEqual(-6); - expect(toNumber("+06.0")).toEqual(6); - - expect(toNumber("-0.0", { leadingZeros: false })).toEqual(-0); - expect(toNumber("-00.00", { leadingZeros: false })).toEqual("-00.00"); - expect(toNumber("-0.06", { leadingZeros: false })).toEqual(-0.06); - expect(toNumber("-00.6", { leadingZeros: false })).toEqual("-00.6"); - expect(toNumber("-.006", { leadingZeros: false })).toEqual(-0.006); - expect(toNumber("-6.0", { leadingZeros: false })).toEqual(-6); - expect(toNumber("-06.0", { leadingZeros: false })).toEqual("-06.0"); - }) - it("long number", () => { - expect(toNumber("020211201030005811824")).toEqual("020211201030005811824"); - expect(toNumber("20211201030005811824")).toEqual("20211201030005811824"); - expect(toNumber("20.211201030005811824")).toEqual("20.211201030005811824"); - expect(toNumber("0.211201030005811824")).toEqual("0.211201030005811824"); - }); - it("scientific notation", () => { - expect(toNumber("01.0e2", { leadingZeros: false })).toEqual("01.0e2"); - expect(toNumber("-01.0e2", { leadingZeros: false })).toEqual("-01.0e2"); - expect(toNumber("01.0e2")).toEqual(100); - expect(toNumber("-01.0e2")).toEqual(-100); - expect(toNumber("1.0e2")).toEqual(100); - - expect(toNumber("-1.0e2")).toEqual(-100); - expect(toNumber("1.0e-2")).toEqual(0.01); - - expect(toNumber("420926189200190257681175017717")).toEqual(4.209261892001902e+29); - expect(toNumber("420926189200190257681175017717", { eNotation: false })).toEqual("420926189200190257681175017717"); - - expect(toNumber("1e-2")).toEqual(0.01); - expect(toNumber("1e+2")).toEqual(100); - expect(toNumber("1.e+2")).toEqual(100); - - expect(toNumber("1.5e3", { leadingZeros: false })).toEqual(1500); - }); - - it("scientific notation with upper E", () => { - expect(toNumber("01.0E2", { leadingZeros: false })).toEqual("01.0E2"); - expect(toNumber("-01.0E2", { leadingZeros: false })).toEqual("-01.0E2"); - expect(toNumber("01.0E2")).toEqual(100); - expect(toNumber("-01.0E2")).toEqual(-100); - expect(toNumber("1.0E2")).toEqual(100); - - expect(toNumber("-1.0E2")).toEqual(-100); - expect(toNumber("1.0E-2")).toEqual(0.01); - - expect(toNumber("E-2")).toEqual("E-2"); - expect(toNumber("E2")).toEqual("E2"); - expect(toNumber("0E2")).toEqual(0); - expect(toNumber("-0E2")).toEqual(-0); - expect(toNumber("00E2")).toEqual("00E2"); - expect(toNumber("00E2", { leadingZeros: false })).toEqual("00E2"); - }); - - it("should skip matching pattern", () => { - expect(toNumber("0", { skipLike: /.*/ })).toEqual("0"); - expect(toNumber("+12", { skipLike: /\+[0-9]{10}/ })).toEqual(12); - expect(toNumber("12+12", { skipLike: /\+[0-9]{10}/ })).toEqual("12+12"); - expect(toNumber("12+1212121212", { skipLike: /\+[0-9]{10}/ })).toEqual("12+1212121212"); - expect(toNumber("+1212121212")).toEqual(1212121212); - expect(toNumber("+1212121212", { skipLike: /\+[0-9]{10}/ })).toEqual("+1212121212"); - }) - it("should not change string if not number", () => { - expect(toNumber("+12 12")).toEqual("+12 12"); - expect(toNumber(" +12 12 ")).toEqual(" +12 12 "); - }) - it("should ignore sorrounded spaces ", () => { - expect(toNumber(" +1212 ")).toEqual(1212); - }) - - it("negative numbers", () => { - expect(toNumber("+1212")).toEqual(1212); - expect(toNumber("+12.12")).toEqual(12.12); - expect(toNumber("-12.12")).toEqual(-12.12); - expect(toNumber("-012.12")).toEqual(-12.12); - expect(toNumber("-012.12")).toEqual(-12.12); - }) -}); diff --git a/node_modules/strnum/tests/temp.js b/node_modules/strnum/tests/temp.js deleted file mode 100644 index 13c2e019..00000000 --- a/node_modules/strnum/tests/temp.js +++ /dev/null @@ -1,8 +0,0 @@ -import toNumber from "../strnum.js"; - -console.log(toNumber("1.5e3", {leadingZeros: false})) -// describe("temp", () = { - -// it("scientific notation", () => { -// }); -// }) \ No newline at end of file