From 6234091037ae46b56c0460100aa6e24438460ef3 Mon Sep 17 00:00:00 2001 From: chrisftian Date: Mon, 12 Aug 2024 15:41:50 +0800 Subject: [PATCH] Dev/1.8.4 (#217) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 更换 xml 解析库 * feat: 增加重试请求头 --- demo/demo.js | 86 +- demo/index.html | 3 +- dist/cos-js-sdk-v5.js | 7406 ++++++++++--------------------------- dist/cos-js-sdk-v5.min.js | 2 +- lib/json2xml.js | 167 - lib/xml2json.js | 166 - package.json | 4 +- server/sts.js | 14 +- src/base.js | 15 +- src/util.js | 21 +- test/test.js | 201 +- 11 files changed, 2262 insertions(+), 5823 deletions(-) delete mode 100644 lib/json2xml.js delete mode 100644 lib/xml2json.js diff --git a/demo/demo.js b/demo/demo.js index 9cb8c8e..6c35074 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -1350,43 +1350,63 @@ function sliceUploadFile() { ); } +function upload(file) { + // stsUrl 是上方搭建的临时密钥服务 + const stsUrl = `http://127.0.0.1:3000/getKeyAndCredentials?filename=${file.name}`; + return new Promise((resolve, reject) => { + fetch(stsUrl) + .then((response) => response.json()) + .then((data) => { + // 服务端接口需要返回:上传的存储桶、地域、随机路径的对象键、临时密钥 + console.log('getKeyAndCredentials:', data); + // 在返回值里取临时密钥信息,上传的文件路径信息 + const { TmpSecretId, TmpSecretKey, SessionToken, StartTime, ExpiredTime, Bucket, Region, Key } = data; + // 创建 JS SDK 实例,传入临时密钥参数 + // 其他配置项可参考下方 初始化配置项 + const cos = new COS({ + SecretId: TmpSecretId, + SecretKey: TmpSecretKey, + SecurityToken: SessionToken, + StartTime: StartTime, + ExpiredTime: ExpiredTime, + }); + // 上传文件 + cos.uploadFile( + { + Bucket, + Region, + Key, + Body: file, // 要上传的文件对象。 + onProgress: function (progressData) { + console.log('上传进度:', progressData); + }, + }, + function (err, data) { + console.log('上传结束', err || data); + if (err) { + reject(err); + } else { + resolve(data); + } + } + ); + }) + .catch((error) => { + console.error('获取上传路径和临时密钥失败', error); + reject(error); + }); + }); +} + function selectFileToUpload() { // 选择本地文件上传 - util.selectLocalFile(function (files) { + util.selectLocalFile(async function (files) { var file = files && files[0]; if (!file) return; - if (file.size > 1024 * 1024 * 3) { - cos.sliceUploadFile( - { - Bucket: config.Bucket, // Bucket 格式:test-1250000000 - Region: config.Region, - Key: file.name, - Body: file, - // Callback: COS.util.encodeBase64(JSON.stringify(callback)), - // CallbackVar: COS.util.encodeBase64(JSON.stringify(callbackVar)), - // ReturnBody: COS.util.encodeBase64(JSON.stringify(returnBody)), - // PicOperations: '{"is_pic_info": 1, "rules": [{"fileid": "test.jpg", "rule": "imageMogr2/thumbnail/!50p"}]}', - }, - function (err, data) { - logger.log('selectFileToUpload:', err || data); - } - ); - } else { - cos.putObject( - { - Bucket: config.Bucket, // Bucket 格式:test-1250000000 - Region: config.Region, - Key: file.name, - Body: file, - // Callback: COS.util.encodeBase64(JSON.stringify(callback)), - // CallbackVar: COS.util.encodeBase64(JSON.stringify(callbackVar)), - // ReturnBody: COS.util.encodeBase64(JSON.stringify(returnBody)), - // PicOperations: '{"is_pic_info": 1, "rules": [{"fileid": "test.jpg", "rule": "imageMogr2/thumbnail/!50p"}]}', - }, - function (err, data) { - logger.log('selectFileToUpload:', err || data); - } - ); + try { + const res = await upload(file); + } catch (e) { + console.log(e); } }); } diff --git a/demo/index.html b/demo/index.html index 0abbe1e..b59a8c5 100644 --- a/demo/index.html +++ b/demo/index.html @@ -142,14 +142,13 @@

ciMain.className = 'main cos-main show'; }); - var getAuthorization = function (options, callback) { // 格式一、(推荐)后端通过获取临时密钥给到前端,前端计算签名 // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/ // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk var url = '/sts'; // 如果是 npm run sts.js 起的 nodejs server,使用这个 var xhr = new XMLHttpRequest(); - xhr.open('POST', url, true); + xhr.open('get', url, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function (e) { try { diff --git a/dist/cos-js-sdk-v5.js b/dist/cos-js-sdk-v5.js index 3ad26fe..6d84e4c 100644 --- a/dist/cos-js-sdk-v5.js +++ b/dist/cos-js-sdk-v5.js @@ -619,153 +619,6 @@ if (( false ? undefined : _typeof(module)) === 'object') { /***/ }), -/***/ "./lib/json2xml.js": -/*!*************************!*\ - !*** ./lib/json2xml.js ***! - \*************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -var _typeof = __webpack_require__(/*! @babel/runtime/helpers/typeof */ "./node_modules/@babel/runtime/helpers/typeof.js"); -//copyright Ryan Day 2010 , Joscha Feth 2013 [MIT Licensed] - -var element_start_char = "a-zA-Z_\xC0-\xD6\xD8-\xF6\xF8-\xFF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FFF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"; -var element_non_start_char = "-.0-9\xB7\u0300-\u036F\u203F\u2040"; -var element_replace = new RegExp("^([^" + element_start_char + "])|^((x|X)(m|M)(l|L))|([^" + element_start_char + element_non_start_char + "])", "g"); -var not_safe_in_xml = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm; -var objKeys = function objKeys(obj) { - var l = []; - if (obj instanceof Object) { - for (var k in obj) { - if (obj.hasOwnProperty(k)) { - l.push(k); - } - } - } - return l; -}; -var process_to_xml = function process_to_xml(node_data, options) { - var makeNode = function makeNode(name, content, attributes, level, hasSubNodes) { - var indent_value = options.indent !== undefined ? options.indent : "\t"; - var indent = options.prettyPrint ? '\n' + new Array(level).join(indent_value) : ''; - if (options.removeIllegalNameCharacters) { - name = name.replace(element_replace, '_'); - } - var node = [indent, '<', name, attributes || '']; - if (content && content.length > 0) { - node.push('>'); - node.push(content); - hasSubNodes && node.push(indent); - node.push(''); - } else { - node.push('/>'); - } - return node.join(''); - }; - return function fn(node_data, node_descriptor, level) { - var type = _typeof(node_data); - if (Array.isArray ? Array.isArray(node_data) : node_data instanceof Array) { - type = 'array'; - } else if (node_data instanceof Date) { - type = 'date'; - } - switch (type) { - //if value is an array create child nodes from values - case 'array': - var ret = []; - node_data.map(function (v) { - ret.push(fn(v, 1, level + 1)); - //entries that are values of an array are the only ones that can be special node descriptors - }); - options.prettyPrint && ret.push('\n'); - return ret.join(''); - break; - case 'date': - // cast dates to ISO 8601 date (soap likes it) - return node_data.toJSON ? node_data.toJSON() : node_data + ''; - break; - case 'object': - var nodes = []; - for (var name in node_data) { - if (node_data.hasOwnProperty(name)) { - if (node_data[name] instanceof Array) { - for (var j = 0; j < node_data[name].length; j++) { - if (node_data[name].hasOwnProperty(j)) { - nodes.push(makeNode(name, fn(node_data[name][j], 0, level + 1), null, level + 1, objKeys(node_data[name][j]).length)); - } - } - } else { - nodes.push(makeNode(name, fn(node_data[name], 0, level + 1), null, level + 1)); - } - } - } - options.prettyPrint && nodes.length > 0 && nodes.push('\n'); - return nodes.join(''); - break; - case 'function': - return node_data(); - break; - default: - return options.escape ? esc(node_data) : '' + node_data; - } - }(node_data, 0, 0); -}; -var xml_header = function xml_header(standalone) { - var ret = [''); - return ret.join(''); -}; -function esc(str) { - return ('' + str).replace(/&/g, '&').replace(//g, '>').replace(/'/g, ''').replace(/"/g, '"').replace(not_safe_in_xml, ''); -} -module.exports = function (obj, options) { - if (!options) { - options = { - xmlHeader: { - standalone: true - }, - prettyPrint: true, - indent: " ", - escape: true - }; - } - if (typeof obj == 'string') { - try { - obj = JSON.parse(obj.toString()); - } catch (e) { - return false; - } - } - var xmlheader = ''; - var docType = ''; - if (options) { - if (_typeof(options) == 'object') { - // our config is an object - - if (options.xmlHeader) { - // the user wants an xml header - xmlheader = xml_header(!!options.xmlHeader.standalone); - } - if (typeof options.docType != 'undefined') { - docType = ''; - } - } else { - // our config is a boolean value, so just add xml header - xmlheader = xml_header(); - } - } - options = options || {}; - var ret = [xmlheader, options.prettyPrint && docType ? '\n' : '', docType, process_to_xml(obj, options)]; - return ret.join('').replace(/\n{2,}/g, '\n').replace(/\s+$/g, ''); -}; - -/***/ }), - /***/ "./lib/md5.js": /*!********************!*\ !*** ./lib/md5.js ***! @@ -1508,161 +1361,6 @@ module.exports = request; /***/ }), -/***/ "./lib/xml2json.js": -/*!*************************!*\ - !*** ./lib/xml2json.js ***! - \*************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -/* Copyright 2015 William Summers, MetaTribal LLC - * adapted from https://developer.mozilla.org/en-US/docs/JXON - * - * Licensed under the MIT License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/MIT - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @author William Summers - * https://github.com/metatribal/xmlToJSON - */ -var DOMParser = __webpack_require__(/*! @xmldom/xmldom */ "./node_modules/@xmldom/xmldom/lib/index.js").DOMParser; -var xmlToJSON = function () { - this.version = "1.3.5"; - var options = { - // set up the default options - mergeCDATA: true, - // extract cdata and merge with text - normalize: true, - // collapse multiple spaces to single space - stripElemPrefix: true // for elements of same name in diff namespaces, you can enable namespaces and access the nskey property - }; - var prefixMatch = new RegExp(/(?!xmlns)^.*:/); - var trimMatch = new RegExp(/^\s+|\s+$/g); - this.grokType = function (sValue) { - if (/^\s*$/.test(sValue)) { - return null; - } - if (/^(?:true|false)$/i.test(sValue)) { - return sValue.toLowerCase() === "true"; - } - if (isFinite(sValue)) { - return parseFloat(sValue); - } - return sValue; - }; - this.parseString = function (xmlString, opt) { - if (xmlString) { - var xml = this.stringToXML(xmlString); - if (xml.getElementsByTagName('parsererror').length) { - return null; - } else { - return this.parseXML(xml, opt); - } - } else { - return null; - } - }; - this.parseXML = function (oXMLParent, opt) { - // initialize options - for (var key in opt) { - options[key] = opt[key]; - } - var vResult = {}, - nLength = 0, - sCollectedTxt = ""; - - // iterate over the children - var childNum = oXMLParent.childNodes.length; - if (childNum) { - for (var oNode, sProp, vContent, nItem = 0; nItem < oXMLParent.childNodes.length; nItem++) { - oNode = oXMLParent.childNodes.item(nItem); - if (oNode.nodeType === 4) { - if (options.mergeCDATA) { - sCollectedTxt += oNode.nodeValue; - } - } /* nodeType is "CDATASection" (4) */else if (oNode.nodeType === 3) { - sCollectedTxt += oNode.nodeValue; - } /* nodeType is "Text" (3) */else if (oNode.nodeType === 1) { - /* nodeType is "Element" (1) */ - - if (nLength === 0) { - vResult = {}; - } - - // using nodeName to support browser (IE) implementation with no 'localName' property - if (options.stripElemPrefix) { - sProp = oNode.nodeName.replace(prefixMatch, ''); - } else { - sProp = oNode.nodeName; - } - vContent = xmlToJSON.parseXML(oNode); - if (vResult.hasOwnProperty(sProp)) { - if (vResult[sProp].constructor !== Array) { - vResult[sProp] = [vResult[sProp]]; - } - vResult[sProp].push(vContent); - } else { - vResult[sProp] = vContent; - nLength++; - } - } - } - } - if (!Object.keys(vResult).length) { - // vResult = sCollectedTxt.replace(trimMatch, '') || ''; // by carsonxu 修复 getBucket返回的 Key 是 " /" 这种场景 - vResult = sCollectedTxt || ''; - } - return vResult; - }; - - // Convert xmlDocument to a string - // Returns null on failure - this.xmlToString = function (xmlDoc) { - try { - var xmlString = xmlDoc.xml ? xmlDoc.xml : new XMLSerializer().serializeToString(xmlDoc); - return xmlString; - } catch (err) { - return null; - } - }; - - // Convert a string to XML Node Structure - // Returns null on failure - this.stringToXML = function (xmlString) { - try { - var xmlDoc = null; - if (window.DOMParser) { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(xmlString, "text/xml"); - return xmlDoc; - } else { - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = false; - xmlDoc.loadXML(xmlString); - return xmlDoc; - } - } catch (e) { - return null; - } - }; - return this; -}.call({}); -var xml2json = function xml2json(xmlString) { - return xmlToJSON.parseString(xmlString); -}; -module.exports = xml2json; - -/***/ }), - /***/ "./node_modules/@babel/runtime/helpers/classCallCheck.js": /*!***************************************************************!*\ !*** ./node_modules/@babel/runtime/helpers/classCallCheck.js ***! @@ -1767,5268 +1465,2037 @@ module.exports = _typeof, module.exports.__esModule = true, module.exports["defa /***/ }), -/***/ "./node_modules/@xmldom/xmldom/lib/conventions.js": -/*!********************************************************!*\ - !*** ./node_modules/@xmldom/xmldom/lib/conventions.js ***! - \********************************************************/ +/***/ "./node_modules/fast-xml-parser/src/fxp.js": +/*!*************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/fxp.js ***! + \*************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/** - * Ponyfill for `Array.prototype.find` which is only available in ES6 runtimes. - * - * Works with anything that has a `length` property and index access properties, including NodeList. - * - * @template {unknown} T - * @param {Array | ({length:number, [number]: T})} list - * @param {function (item: T, index: number, list:Array | ({length:number, [number]: T})):boolean} predicate - * @param {Partial>?} ac `Array.prototype` by default, - * allows injecting a custom implementation in tests - * @returns {T | undefined} - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find - * @see https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.find - */ -function find(list, predicate, ac) { - if (ac === undefined) { - ac = Array.prototype; - } - if (list && typeof ac.find === 'function') { - return ac.find.call(list, predicate); - } - for (var i = 0; i < list.length; i++) { - if (Object.prototype.hasOwnProperty.call(list, i)) { - var item = list[i]; - if (predicate.call(undefined, item, i, list)) { - return item; - } - } - } -} - -/** - * "Shallow freezes" an object to render it immutable. - * Uses `Object.freeze` if available, - * otherwise the immutability is only in the type. - * - * Is used to create "enum like" objects. - * - * @template T - * @param {T} object the object to freeze - * @param {Pick = Object} oc `Object` by default, - * allows to inject custom object constructor for tests - * @returns {Readonly} - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze - */ -function freeze(object, oc) { - if (oc === undefined) { - oc = Object - } - return oc && typeof oc.freeze === 'function' ? oc.freeze(object) : object -} +const validator = __webpack_require__(/*! ./validator */ "./node_modules/fast-xml-parser/src/validator.js"); +const XMLParser = __webpack_require__(/*! ./xmlparser/XMLParser */ "./node_modules/fast-xml-parser/src/xmlparser/XMLParser.js"); +const XMLBuilder = __webpack_require__(/*! ./xmlbuilder/json2xml */ "./node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js"); -/** - * Since we can not rely on `Object.assign` we provide a simplified version - * that is sufficient for our needs. - * - * @param {Object} target - * @param {Object | null | undefined} source - * - * @returns {Object} target - * @throws TypeError if target is not an object - * - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - * @see https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-object.assign - */ -function assign(target, source) { - if (target === null || typeof target !== 'object') { - throw new TypeError('target is not an object') - } - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - return target +module.exports = { + XMLParser: XMLParser, + XMLValidator: validator, + XMLBuilder: XMLBuilder } -/** - * All mime types that are allowed as input to `DOMParser.parseFromString` - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02 MDN - * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparsersupportedtype WHATWG HTML Spec - * @see DOMParser.prototype.parseFromString - */ -var MIME_TYPE = freeze({ - /** - * `text/html`, the only mime type that triggers treating an XML document as HTML. - * - * @see DOMParser.SupportedType.isHTML - * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration - * @see https://en.wikipedia.org/wiki/HTML Wikipedia - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN - * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring WHATWG HTML Spec - */ - HTML: 'text/html', - - /** - * Helper method to check a mime type if it indicates an HTML document - * - * @param {string} [value] - * @returns {boolean} - * - * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration - * @see https://en.wikipedia.org/wiki/HTML Wikipedia - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN - * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring */ - isHTML: function (value) { - return value === MIME_TYPE.HTML - }, - - /** - * `application/xml`, the standard mime type for XML documents. - * - * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType registration - * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303 - * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia - */ - XML_APPLICATION: 'application/xml', - - /** - * `text/html`, an alias for `application/xml`. - * - * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303 - * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration - * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia - */ - XML_TEXT: 'text/xml', - - /** - * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace, - * but is parsed as an XML document. - * - * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType registration - * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec - * @see https://en.wikipedia.org/wiki/XHTML Wikipedia - */ - XML_XHTML_APPLICATION: 'application/xhtml+xml', - - /** - * `image/svg+xml`, - * - * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration - * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1 - * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia - */ - XML_SVG_IMAGE: 'image/svg+xml', -}) - -/** - * Namespaces that are used in this code base. - * - * @see http://www.w3.org/TR/REC-xml-names - */ -var NAMESPACE = freeze({ - /** - * The XHTML namespace. - * - * @see http://www.w3.org/1999/xhtml - */ - HTML: 'http://www.w3.org/1999/xhtml', - - /** - * Checks if `uri` equals `NAMESPACE.HTML`. - * - * @param {string} [uri] - * - * @see NAMESPACE.HTML - */ - isHTML: function (uri) { - return uri === NAMESPACE.HTML - }, - - /** - * The SVG namespace. - * - * @see http://www.w3.org/2000/svg - */ - SVG: 'http://www.w3.org/2000/svg', - - /** - * The `xml:` namespace. - * - * @see http://www.w3.org/XML/1998/namespace - */ - XML: 'http://www.w3.org/XML/1998/namespace', - - /** - * The `xmlns:` namespace - * - * @see https://www.w3.org/2000/xmlns/ - */ - XMLNS: 'http://www.w3.org/2000/xmlns/', -}) - -exports.assign = assign; -exports.find = find; -exports.freeze = freeze; -exports.MIME_TYPE = MIME_TYPE; -exports.NAMESPACE = NAMESPACE; - - /***/ }), -/***/ "./node_modules/@xmldom/xmldom/lib/dom-parser.js": -/*!*******************************************************!*\ - !*** ./node_modules/@xmldom/xmldom/lib/dom-parser.js ***! - \*******************************************************/ +/***/ "./node_modules/fast-xml-parser/src/util.js": +/*!**************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/util.js ***! + \**************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -var conventions = __webpack_require__(/*! ./conventions */ "./node_modules/@xmldom/xmldom/lib/conventions.js"); -var dom = __webpack_require__(/*! ./dom */ "./node_modules/@xmldom/xmldom/lib/dom.js") -var entities = __webpack_require__(/*! ./entities */ "./node_modules/@xmldom/xmldom/lib/entities.js"); -var sax = __webpack_require__(/*! ./sax */ "./node_modules/@xmldom/xmldom/lib/sax.js"); +"use strict"; -var DOMImplementation = dom.DOMImplementation; -var NAMESPACE = conventions.NAMESPACE; +const 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'; +const nameChar = nameStartChar + '\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040'; +const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*' +const regexName = new RegExp('^' + nameRegexp + '$'); -var ParseError = sax.ParseError; -var XMLReader = sax.XMLReader; +const getAllMatches = function(string, regex) { + const matches = []; + let match = regex.exec(string); + while (match) { + const allmatches = []; + allmatches.startIndex = regex.lastIndex - match[0].length; + const len = match.length; + for (let index = 0; index < len; index++) { + allmatches.push(match[index]); + } + matches.push(allmatches); + match = regex.exec(string); + } + return matches; +}; -/** - * Normalizes line ending according to https://www.w3.org/TR/xml11/#sec-line-ends: - * - * > XML parsed entities are often stored in computer files which, - * > for editing convenience, are organized into lines. - * > These lines are typically separated by some combination - * > of the characters CARRIAGE RETURN (#xD) and LINE FEED (#xA). - * > - * > To simplify the tasks of applications, the XML processor must behave - * > as if it normalized all line breaks in external parsed entities (including the document entity) - * > on input, before parsing, by translating all of the following to a single #xA character: - * > - * > 1. the two-character sequence #xD #xA - * > 2. the two-character sequence #xD #x85 - * > 3. the single character #x85 - * > 4. the single character #x2028 - * > 5. any #xD character that is not immediately followed by #xA or #x85. - * - * @param {string} input - * @returns {string} - */ -function normalizeLineEndings(input) { - return input - .replace(/\r[\n\u0085]/g, '\n') - .replace(/[\r\u0085\u2028]/g, '\n') -} +const isName = function(string) { + const match = regexName.exec(string); + return !(match === null || typeof match === 'undefined'); +}; -/** - * @typedef Locator - * @property {number} [columnNumber] - * @property {number} [lineNumber] - */ +exports.isExist = function(v) { + return typeof v !== 'undefined'; +}; -/** - * @typedef DOMParserOptions - * @property {DOMHandler} [domBuilder] - * @property {Function} [errorHandler] - * @property {(string) => string} [normalizeLineEndings] used to replace line endings before parsing - * defaults to `normalizeLineEndings` - * @property {Locator} [locator] - * @property {Record} [xmlns] - * - * @see normalizeLineEndings - */ +exports.isEmptyObject = function(obj) { + return Object.keys(obj).length === 0; +}; /** - * The DOMParser interface provides the ability to parse XML or HTML source code - * from a string into a DOM `Document`. - * - * _xmldom is different from the spec in that it allows an `options` parameter, - * to override the default behavior._ - * - * @param {DOMParserOptions} [options] - * @constructor - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser - * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-parsing-and-serialization + * Copy all the properties of a into b. + * @param {*} target + * @param {*} a */ -function DOMParser(options){ - this.options = options ||{locator:{}}; -} - -DOMParser.prototype.parseFromString = function(source,mimeType){ - var options = this.options; - var sax = new XMLReader(); - var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler - var errorHandler = options.errorHandler; - var locator = options.locator; - var defaultNSMap = options.xmlns||{}; - var isHTML = /\/x?html?$/.test(mimeType);//mimeType.toLowerCase().indexOf('html') > -1; - var entityMap = isHTML ? entities.HTML_ENTITIES : entities.XML_ENTITIES; - if(locator){ - domBuilder.setDocumentLocator(locator) - } - - sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator); - sax.domBuilder = options.domBuilder || domBuilder; - if(isHTML){ - defaultNSMap[''] = NAMESPACE.HTML; - } - defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML; - var normalize = options.normalizeLineEndings || normalizeLineEndings; - if (source && typeof source === 'string') { - sax.parse( - normalize(source), - defaultNSMap, - entityMap - ) - } else { - sax.errorHandler.error('invalid doc source') - } - return domBuilder.doc; -} -function buildErrorHandler(errorImpl,domBuilder,locator){ - if(!errorImpl){ - if(domBuilder instanceof DOMHandler){ - return domBuilder; - } - errorImpl = domBuilder ; - } - var errorHandler = {} - var isCallback = errorImpl instanceof Function; - locator = locator||{} - function build(key){ - var fn = errorImpl[key]; - if(!fn && isCallback){ - fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl; - } - errorHandler[key] = fn && function(msg){ - fn('[xmldom '+key+']\t'+msg+_locator(locator)); - }||function(){}; - } - build('warning'); - build('error'); - build('fatalError'); - return errorHandler; -} +exports.merge = function(target, a, arrayMode) { + if (a) { + const keys = Object.keys(a); // will return an array of own properties + const len = keys.length; //don't make it inline + for (let i = 0; i < len; i++) { + if (arrayMode === 'strict') { + target[keys[i]] = [ a[keys[i]] ]; + } else { + target[keys[i]] = a[keys[i]]; + } + } + } +}; +/* exports.merge =function (b,a){ + return Object.assign(b,a); +} */ -//console.log('#\n\n\n\n\n\n\n####') -/** - * +ContentHandler+ErrorHandler - * +LexicalHandler+EntityResolver2 - * -DeclHandler-DTDHandler - * - * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler - * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2 - * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html - */ -function DOMHandler() { - this.cdata = false; -} -function position(locator,node){ - node.lineNumber = locator.lineNumber; - node.columnNumber = locator.columnNumber; -} -/** - * @see org.xml.sax.ContentHandler#startDocument - * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html - */ -DOMHandler.prototype = { - startDocument : function() { - this.doc = new DOMImplementation().createDocument(null, null, null); - if (this.locator) { - this.doc.documentURI = this.locator.systemId; - } - }, - startElement:function(namespaceURI, localName, qName, attrs) { - var doc = this.doc; - var el = doc.createElementNS(namespaceURI, qName||localName); - var len = attrs.length; - appendElement(this, el); - this.currentElement = el; - - this.locator && position(this.locator,el) - for (var i = 0 ; i < len; i++) { - var namespaceURI = attrs.getURI(i); - var value = attrs.getValue(i); - var qName = attrs.getQName(i); - var attr = doc.createAttributeNS(namespaceURI, qName); - this.locator &&position(attrs.getLocator(i),attr); - attr.value = attr.nodeValue = value; - el.setAttributeNode(attr) - } - }, - endElement:function(namespaceURI, localName, qName) { - var current = this.currentElement - var tagName = current.tagName; - this.currentElement = current.parentNode; - }, - startPrefixMapping:function(prefix, uri) { - }, - endPrefixMapping:function(prefix) { - }, - processingInstruction:function(target, data) { - var ins = this.doc.createProcessingInstruction(target, data); - this.locator && position(this.locator,ins) - appendElement(this, ins); - }, - ignorableWhitespace:function(ch, start, length) { - }, - characters:function(chars, start, length) { - chars = _toString.apply(this,arguments) - //console.log(chars) - if(chars){ - if (this.cdata) { - var charNode = this.doc.createCDATASection(chars); - } else { - var charNode = this.doc.createTextNode(chars); - } - if(this.currentElement){ - this.currentElement.appendChild(charNode); - }else if(/^\s*$/.test(chars)){ - this.doc.appendChild(charNode); - //process xml - } - this.locator && position(this.locator,charNode) - } - }, - skippedEntity:function(name) { - }, - endDocument:function() { - this.doc.normalize(); - }, - setDocumentLocator:function (locator) { - if(this.locator = locator){// && !('lineNumber' in locator)){ - locator.lineNumber = 0; - } - }, - //LexicalHandler - comment:function(chars, start, length) { - chars = _toString.apply(this,arguments) - var comm = this.doc.createComment(chars); - this.locator && position(this.locator,comm) - appendElement(this, comm); - }, - - startCDATA:function() { - //used in characters() methods - this.cdata = true; - }, - endCDATA:function() { - this.cdata = false; - }, - - startDTD:function(name, publicId, systemId) { - var impl = this.doc.implementation; - if (impl && impl.createDocumentType) { - var dt = impl.createDocumentType(name, publicId, systemId); - this.locator && position(this.locator,dt) - appendElement(this, dt); - this.doc.doctype = dt; - } - }, - /** - * @see org.xml.sax.ErrorHandler - * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html - */ - warning:function(error) { - console.warn('[xmldom warning]\t'+error,_locator(this.locator)); - }, - error:function(error) { - console.error('[xmldom error]\t'+error,_locator(this.locator)); - }, - fatalError:function(error) { - throw new ParseError(error, this.locator); - } -} -function _locator(l){ - if(l){ - return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']' - } -} -function _toString(chars,start,length){ - if(typeof chars == 'string'){ - return chars.substr(start,length) - }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)") - if(chars.length >= start+length || start){ - return new java.lang.String(chars,start,length)+''; - } - return chars; - } -} +exports.getValue = function(v) { + if (exports.isExist(v)) { + return v; + } else { + return ''; + } +}; -/* - * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html - * used method of org.xml.sax.ext.LexicalHandler: - * #comment(chars, start, length) - * #startCDATA() - * #endCDATA() - * #startDTD(name, publicId, systemId) - * - * - * IGNORED method of org.xml.sax.ext.LexicalHandler: - * #endDTD() - * #startEntity(name) - * #endEntity(name) - * - * - * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html - * IGNORED method of org.xml.sax.ext.DeclHandler - * #attributeDecl(eName, aName, type, mode, value) - * #elementDecl(name, model) - * #externalEntityDecl(name, publicId, systemId) - * #internalEntityDecl(name, value) - * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html - * IGNORED method of org.xml.sax.EntityResolver2 - * #resolveEntity(String name,String publicId,String baseURI,String systemId) - * #resolveEntity(publicId, systemId) - * #getExternalSubset(name, baseURI) - * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html - * IGNORED method of org.xml.sax.DTDHandler - * #notationDecl(name, publicId, systemId) {}; - * #unparsedEntityDecl(name, publicId, systemId, notationName) {}; - */ -"endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){ - DOMHandler.prototype[key] = function(){return null} -}) - -/* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */ -function appendElement (hander,node) { - if (!hander.currentElement) { - hander.doc.appendChild(node); - } else { - hander.currentElement.appendChild(node); - } -}//appendChild and setAttributeNS are preformance key +// const fakeCall = function(a) {return a;}; +// const fakeCallNoReturn = function() {}; -exports.__DOMHandler = DOMHandler; -exports.normalizeLineEndings = normalizeLineEndings; -exports.DOMParser = DOMParser; +exports.isName = isName; +exports.getAllMatches = getAllMatches; +exports.nameRegexp = nameRegexp; /***/ }), -/***/ "./node_modules/@xmldom/xmldom/lib/dom.js": -/*!************************************************!*\ - !*** ./node_modules/@xmldom/xmldom/lib/dom.js ***! - \************************************************/ +/***/ "./node_modules/fast-xml-parser/src/validator.js": +/*!*******************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/validator.js ***! + \*******************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -var conventions = __webpack_require__(/*! ./conventions */ "./node_modules/@xmldom/xmldom/lib/conventions.js"); +"use strict"; -var find = conventions.find; -var NAMESPACE = conventions.NAMESPACE; -/** - * A prerequisite for `[].filter`, to drop elements that are empty - * @param {string} input - * @returns {boolean} - */ -function notEmptyString (input) { - return input !== '' -} -/** - * @see https://infra.spec.whatwg.org/#split-on-ascii-whitespace - * @see https://infra.spec.whatwg.org/#ascii-whitespace - * - * @param {string} input - * @returns {string[]} (can be empty) - */ -function splitOnASCIIWhitespace(input) { - // U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, U+0020 SPACE - return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [] -} +const util = __webpack_require__(/*! ./util */ "./node_modules/fast-xml-parser/src/util.js"); -/** - * Adds element as a key to current if it is not already present. - * - * @param {Record} current - * @param {string} element - * @returns {Record} - */ -function orderedSetReducer (current, element) { - if (!current.hasOwnProperty(element)) { - current[element] = true; - } - return current; -} +const defaultOptions = { + allowBooleanAttributes: false, //A tag can have attributes without any value + unpairedTags: [] +}; -/** - * @see https://infra.spec.whatwg.org/#ordered-set - * @param {string} input - * @returns {string[]} - */ -function toOrderedSet(input) { - if (!input) return []; - var list = splitOnASCIIWhitespace(input); - return Object.keys(list.reduce(orderedSetReducer, {})) -} +//const tagsPattern = new RegExp("<\\/?([\\w:\\-_\.]+)\\s*\/?>","g"); +exports.validate = function (xmlData, options) { + options = Object.assign({}, defaultOptions, options); -/** - * Uses `list.indexOf` to implement something like `Array.prototype.includes`, - * which we can not rely on being available. - * - * @param {any[]} list - * @returns {function(any): boolean} - */ -function arrayIncludes (list) { - return function(element) { - return list && list.indexOf(element) !== -1; - } -} + //xmlData = xmlData.replace(/(\r\n|\n|\r)/gm,"");//make it single line + //xmlData = xmlData.replace(/(^\s*<\?xml.*?\?>)/g,"");//Remove XML starting tag + //xmlData = xmlData.replace(/()/g,"");//Remove DOCTYPE + const tags = []; + let tagFound = false; -function copy(src,dest){ - for(var p in src){ - if (Object.prototype.hasOwnProperty.call(src, p)) { - dest[p] = src[p]; - } - } -} + //indicates that the root tag has been closed (aka. depth 0 has been reached) + let reachedRoot = false; -/** -^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));? -^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));? - */ -function _extends(Class,Super){ - var pt = Class.prototype; - if(!(pt instanceof Super)){ - function t(){}; - t.prototype = Super.prototype; - t = new t(); - copy(pt,t); - Class.prototype = pt = t; - } - if(pt.constructor != Class){ - if(typeof Class != 'function'){ - console.error("unknown Class:"+Class) - } - pt.constructor = Class - } -} + if (xmlData[0] === '\ufeff') { + // check for byte order mark (BOM) + xmlData = xmlData.substr(1); + } + + for (let i = 0; i < xmlData.length; i++) { + + if (xmlData[i] === '<' && xmlData[i+1] === '?') { + i+=2; + i = readPI(xmlData,i); + if (i.err) return i; + }else if (xmlData[i] === '<') { + //starting of tag + //read until you reach to '>' avoiding any '>' in attribute value + let tagStartPos = i; + i++; + + if (xmlData[i] === '!') { + i = readCommentAndCDATA(xmlData, i); + continue; + } else { + let closingTag = false; + if (xmlData[i] === '/') { + //closing tag + closingTag = true; + i++; + } + //read tagname + let tagName = ''; + for (; i < xmlData.length && + xmlData[i] !== '>' && + xmlData[i] !== ' ' && + xmlData[i] !== '\t' && + xmlData[i] !== '\n' && + xmlData[i] !== '\r'; i++ + ) { + tagName += xmlData[i]; + } + tagName = tagName.trim(); + //console.log(tagName); + + if (tagName[tagName.length - 1] === '/') { + //self closing tag without attributes + tagName = tagName.substring(0, tagName.length - 1); + //continue; + i--; + } + if (!validateTagName(tagName)) { + let msg; + if (tagName.trim().length === 0) { + msg = "Invalid space after '<'."; + } else { + msg = "Tag '"+tagName+"' is an invalid name."; + } + return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i)); + } -// Node Types -var NodeType = {} -var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1; -var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2; -var TEXT_NODE = NodeType.TEXT_NODE = 3; -var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4; -var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5; -var ENTITY_NODE = NodeType.ENTITY_NODE = 6; -var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7; -var COMMENT_NODE = NodeType.COMMENT_NODE = 8; -var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9; -var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10; -var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11; -var NOTATION_NODE = NodeType.NOTATION_NODE = 12; - -// ExceptionCode -var ExceptionCode = {} -var ExceptionMessage = {}; -var INDEX_SIZE_ERR = ExceptionCode.INDEX_SIZE_ERR = ((ExceptionMessage[1]="Index size error"),1); -var DOMSTRING_SIZE_ERR = ExceptionCode.DOMSTRING_SIZE_ERR = ((ExceptionMessage[2]="DOMString size error"),2); -var HIERARCHY_REQUEST_ERR = ExceptionCode.HIERARCHY_REQUEST_ERR = ((ExceptionMessage[3]="Hierarchy request error"),3); -var WRONG_DOCUMENT_ERR = ExceptionCode.WRONG_DOCUMENT_ERR = ((ExceptionMessage[4]="Wrong document"),4); -var INVALID_CHARACTER_ERR = ExceptionCode.INVALID_CHARACTER_ERR = ((ExceptionMessage[5]="Invalid character"),5); -var NO_DATA_ALLOWED_ERR = ExceptionCode.NO_DATA_ALLOWED_ERR = ((ExceptionMessage[6]="No data allowed"),6); -var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = ((ExceptionMessage[7]="No modification allowed"),7); -var NOT_FOUND_ERR = ExceptionCode.NOT_FOUND_ERR = ((ExceptionMessage[8]="Not found"),8); -var NOT_SUPPORTED_ERR = ExceptionCode.NOT_SUPPORTED_ERR = ((ExceptionMessage[9]="Not supported"),9); -var INUSE_ATTRIBUTE_ERR = ExceptionCode.INUSE_ATTRIBUTE_ERR = ((ExceptionMessage[10]="Attribute in use"),10); -//level2 -var INVALID_STATE_ERR = ExceptionCode.INVALID_STATE_ERR = ((ExceptionMessage[11]="Invalid state"),11); -var SYNTAX_ERR = ExceptionCode.SYNTAX_ERR = ((ExceptionMessage[12]="Syntax error"),12); -var INVALID_MODIFICATION_ERR = ExceptionCode.INVALID_MODIFICATION_ERR = ((ExceptionMessage[13]="Invalid modification"),13); -var NAMESPACE_ERR = ExceptionCode.NAMESPACE_ERR = ((ExceptionMessage[14]="Invalid namespace"),14); -var INVALID_ACCESS_ERR = ExceptionCode.INVALID_ACCESS_ERR = ((ExceptionMessage[15]="Invalid access"),15); + const result = readAttributeStr(xmlData, i); + if (result === false) { + return getErrorObject('InvalidAttr', "Attributes for '"+tagName+"' have open quote.", getLineNumberForPosition(xmlData, i)); + } + let attrStr = result.value; + i = result.index; + + if (attrStr[attrStr.length - 1] === '/') { + //self closing tag + const attrStrStart = i - attrStr.length; + attrStr = attrStr.substring(0, attrStr.length - 1); + const isValid = validateAttributeString(attrStr, options); + if (isValid === true) { + tagFound = true; + //continue; //text may presents after self closing tag + } else { + //the result from the nested function returns the position of the error within the attribute + //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 + //this gives us the absolute index in the entire xml, which we can use to find the line at last + return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line)); + } + } else if (closingTag) { + if (!result.tagClosed) { + return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' doesn't have proper closing.", getLineNumberForPosition(xmlData, i)); + } else if (attrStr.trim().length > 0) { + return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' can't have attributes or invalid starting.", getLineNumberForPosition(xmlData, tagStartPos)); + } else if (tags.length === 0) { + return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' has not been opened.", getLineNumberForPosition(xmlData, tagStartPos)); + } else { + const otg = tags.pop(); + if (tagName !== otg.tagName) { + let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos); + return getErrorObject('InvalidTag', + "Expected closing tag '"+otg.tagName+"' (opened in line "+openPos.line+", col "+openPos.col+") instead of closing tag '"+tagName+"'.", + getLineNumberForPosition(xmlData, tagStartPos)); + } -/** - * DOM Level 2 - * Object DOMException - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html - * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html - */ -function DOMException(code, message) { - if(message instanceof Error){ - var error = message; - }else{ - error = this; - Error.call(this, ExceptionMessage[code]); - this.message = ExceptionMessage[code]; - if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException); - } - error.code = code; - if(message) this.message = this.message + ": " + message; - return error; -}; -DOMException.prototype = Error.prototype; -copy(ExceptionCode,DOMException) + //when there are no more tags, we reached the root level. + if (tags.length == 0) { + reachedRoot = true; + } + } + } else { + const isValid = validateAttributeString(attrStr, options); + if (isValid !== true) { + //the result from the nested function returns the position of the error within the attribute + //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 + //this gives us the absolute index in the entire xml, which we can use to find the line at last + return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line)); + } -/** - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177 - * The NodeList interface provides the abstraction of an ordered collection of nodes, without defining or constraining how this collection is implemented. NodeList objects in the DOM are live. - * The items in the NodeList are accessible via an integral index, starting from 0. - */ -function NodeList() { -}; -NodeList.prototype = { - /** - * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive. - * @standard level1 - */ - length:0, - /** - * Returns the indexth item in the collection. If index is greater than or equal to the number of nodes in the list, this returns null. - * @standard level1 - * @param index unsigned long - * Index into the collection. - * @return Node - * The node at the indexth position in the NodeList, or null if that is not a valid index. - */ - item: function(index) { - return index >= 0 && index < this.length ? this[index] : null; - }, - toString:function(isHTML,nodeFilter){ - for(var buf = [], i = 0;i 0) { + return getErrorObject('InvalidXml', "Invalid '"+ + JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\r?\n/g, '')+ + "' found.", {line: 1, col: 1}); + } -/** - * Objects implementing the NamedNodeMap interface are used - * to represent collections of nodes that can be accessed by name. - * Note that NamedNodeMap does not inherit from NodeList; - * NamedNodeMaps are not maintained in any particular order. - * Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, - * but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, - * and does not imply that the DOM specifies an order to these Nodes. - * NamedNodeMap objects in the DOM are live. - * used for attributes or DocumentType entities - */ -function NamedNodeMap() { + return true; }; -function _findNodeIndex(list,node){ - var i = list.length; - while(i--){ - if(list[i] === node){return i} - } +function isWhiteSpace(char){ + return char === ' ' || char === '\t' || char === '\n' || char === '\r'; } - -function _addNamedNode(el,list,newAttr,oldAttr){ - if(oldAttr){ - list[_findNodeIndex(list,oldAttr)] = newAttr; - }else{ - list[list.length++] = newAttr; - } - if(el){ - newAttr.ownerElement = el; - var doc = el.ownerDocument; - if(doc){ - oldAttr && _onRemoveAttribute(doc,el,oldAttr); - _onAddAttribute(doc,el,newAttr); - } - } +/** + * Read Processing insstructions and skip + * @param {*} xmlData + * @param {*} i + */ +function readPI(xmlData, i) { + const start = i; + for (; i < xmlData.length; i++) { + if (xmlData[i] == '?' || xmlData[i] == ' ') { + //tagname + const tagname = xmlData.substr(start, i - start); + if (i > 5 && tagname === 'xml') { + return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i)); + } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') { + //check if valid attribut string + i++; + break; + } else { + continue; + } + } + } + return i; } -function _removeNamedNode(el,list,attr){ - //console.log('remove attr:'+attr) - var i = _findNodeIndex(list,attr); - if(i>=0){ - var lastIndex = list.length-1 - while(i i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') { + //comment + for (i += 3; i < xmlData.length; i++) { + if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') { + i += 2; + break; + } + } + } else if ( + xmlData.length > i + 8 && + xmlData[i + 1] === 'D' && + xmlData[i + 2] === 'O' && + xmlData[i + 3] === 'C' && + xmlData[i + 4] === 'T' && + xmlData[i + 5] === 'Y' && + xmlData[i + 6] === 'P' && + xmlData[i + 7] === 'E' + ) { + let angleBracketsCount = 1; + for (i += 8; i < xmlData.length; i++) { + if (xmlData[i] === '<') { + angleBracketsCount++; + } else if (xmlData[i] === '>') { + angleBracketsCount--; + if (angleBracketsCount === 0) { + break; + } + } + } + } else if ( + xmlData.length > i + 9 && + xmlData[i + 1] === '[' && + xmlData[i + 2] === 'C' && + xmlData[i + 3] === 'D' && + xmlData[i + 4] === 'A' && + xmlData[i + 5] === 'T' && + xmlData[i + 6] === 'A' && + xmlData[i + 7] === '[' + ) { + for (i += 8; i < xmlData.length; i++) { + if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') { + i += 2; + break; + } + } + } + + return i; } -NamedNodeMap.prototype = { - length:0, - item:NodeList.prototype.item, - getNamedItem: function(key) { -// if(key.indexOf(':')>0 || key == 'xmlns'){ -// return null; -// } - //console.log() - var i = this.length; - while(i--){ - var attr = this[i]; - //console.log(attr.nodeName,key) - if(attr.nodeName == key){ - return attr; - } - } - }, - setNamedItem: function(attr) { - var el = attr.ownerElement; - if(el && el!=this._ownerElement){ - throw new DOMException(INUSE_ATTRIBUTE_ERR); - } - var oldAttr = this.getNamedItem(attr.nodeName); - _addNamedNode(this._ownerElement,this,attr,oldAttr); - return oldAttr; - }, - /* returns Node */ - setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR - var el = attr.ownerElement, oldAttr; - if(el && el!=this._ownerElement){ - throw new DOMException(INUSE_ATTRIBUTE_ERR); - } - oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName); - _addNamedNode(this._ownerElement,this,attr,oldAttr); - return oldAttr; - }, - - /* returns Node */ - removeNamedItem: function(key) { - var attr = this.getNamedItem(key); - _removeNamedNode(this._ownerElement,this,attr); - return attr; - - - },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR - - //for level2 - removeNamedItemNS:function(namespaceURI,localName){ - var attr = this.getNamedItemNS(namespaceURI,localName); - _removeNamedNode(this._ownerElement,this,attr); - return attr; - }, - getNamedItemNS: function(namespaceURI, localName) { - var i = this.length; - while(i--){ - var node = this[i]; - if(node.localName == localName && node.namespaceURI == namespaceURI){ - return node; - } - } - return null; - } -}; + +const doubleQuote = '"'; +const singleQuote = "'"; /** - * The DOMImplementation interface represents an object providing methods - * which are not dependent on any particular document. - * Such an object is returned by the `Document.implementation` property. - * - * __The individual methods describe the differences compared to the specs.__ - * - * @constructor - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation MDN - * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490 DOM Level 1 Core (Initial) - * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490 DOM Level 2 Core - * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490 DOM Level 3 Core - * @see https://dom.spec.whatwg.org/#domimplementation DOM Living Standard + * Keep reading xmlData until '<' is found outside the attribute value. + * @param {string} xmlData + * @param {number} i */ -function DOMImplementation() { -} - -DOMImplementation.prototype = { - /** - * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given feature is supported. - * The different implementations fairly diverged in what kind of features were reported. - * The latest version of the spec settled to force this method to always return true, where the functionality was accurate and in use. - * - * @deprecated It is deprecated and modern browsers return true in all cases. - * - * @param {string} feature - * @param {string} [version] - * @returns {boolean} always true - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN - * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core - * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard - */ - hasFeature: function(feature, version) { - return true; - }, - /** - * Creates an XML Document object of the specified type with its document element. - * - * __It behaves slightly different from the description in the living standard__: - * - There is no interface/class `XMLDocument`, it returns a `Document` instance. - * - `contentType`, `encoding`, `mode`, `origin`, `url` fields are currently not declared. - * - this implementation is not validating names or qualified names - * (when parsing XML strings, the SAX parser takes care of that) - * - * @param {string|null} namespaceURI - * @param {string} qualifiedName - * @param {DocumentType=null} doctype - * @returns {Document} - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN - * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM Level 2 Core (initial) - * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Level 2 Core - * - * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract - * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names - * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names - */ - createDocument: function(namespaceURI, qualifiedName, doctype){ - var doc = new Document(); - doc.implementation = this; - doc.childNodes = new NodeList(); - doc.doctype = doctype || null; - if (doctype){ - doc.appendChild(doctype); - } - if (qualifiedName){ - var root = doc.createElementNS(namespaceURI, qualifiedName); - doc.appendChild(root); - } - return doc; - }, - /** - * Returns a doctype, with the given `qualifiedName`, `publicId`, and `systemId`. - * - * __This behavior is slightly different from the in the specs__: - * - this implementation is not validating names or qualified names - * (when parsing XML strings, the SAX parser takes care of that) - * - * @param {string} qualifiedName - * @param {string} [publicId] - * @param {string} [systemId] - * @returns {DocumentType} which can either be used with `DOMImplementation.createDocument` upon document creation - * or can be put into the document via methods like `Node.insertBefore()` or `Node.replaceChild()` - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType MDN - * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM Level 2 Core - * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living Standard - * - * @see https://dom.spec.whatwg.org/#validate-and-extract DOM: Validate and extract - * @see https://www.w3.org/TR/xml/#NT-NameStartChar XML Spec: Names - * @see https://www.w3.org/TR/xml-names/#ns-qualnames XML Namespaces: Qualified names - */ - createDocumentType: function(qualifiedName, publicId, systemId){ - var node = new DocumentType(); - node.name = qualifiedName; - node.nodeName = qualifiedName; - node.publicId = publicId || ''; - node.systemId = systemId || ''; - - return node; - } -}; +function readAttributeStr(xmlData, i) { + let attrStr = ''; + let startChar = ''; + let tagClosed = false; + for (; i < xmlData.length; i++) { + if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) { + if (startChar === '') { + startChar = xmlData[i]; + } else if (startChar !== xmlData[i]) { + //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa + } else { + startChar = ''; + } + } else if (xmlData[i] === '>') { + if (startChar === '') { + tagClosed = true; + break; + } + } + attrStr += xmlData[i]; + } + if (startChar !== '') { + return false; + } + return { + value: attrStr, + index: i, + tagClosed: tagClosed + }; +} /** - * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247 + * Select all the attributes whether valid or invalid. */ +const validAttrStrRegxp = new RegExp('(\\s*)([^\\s=]+)(\\s*=)?(\\s*([\'"])(([\\s\\S])*?)\\5)?', 'g'); + +//attr, ="sd", a="amit's", a="sd"b="saf", ab cd="" + +function validateAttributeString(attrStr, options) { + //console.log("start:"+attrStr+":end"); + + //if(attrStr.trim().length === 0) return true; //empty string + + const matches = util.getAllMatches(attrStr, validAttrStrRegxp); + const attrNames = {}; + + for (let i = 0; i < matches.length; i++) { + if (matches[i][1].length === 0) { + //nospace before attribute name: a="sd"b="saf" + return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' has no space in starting.", getPositionFromMatch(matches[i])) + } else if (matches[i][3] !== undefined && matches[i][4] === undefined) { + return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' is without value.", getPositionFromMatch(matches[i])); + } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) { + //independent attribute: ab + return getErrorObject('InvalidAttr', "boolean attribute '"+matches[i][2]+"' is not allowed.", getPositionFromMatch(matches[i])); + } + /* else if(matches[i][6] === undefined){//attribute without value: ab= + return { err: { code:"InvalidAttr",msg:"attribute " + matches[i][2] + " has no value assigned."}}; + } */ + const attrName = matches[i][2]; + if (!validateAttrName(attrName)) { + return getErrorObject('InvalidAttr', "Attribute '"+attrName+"' is an invalid name.", getPositionFromMatch(matches[i])); + } + if (!attrNames.hasOwnProperty(attrName)) { + //check for duplicate attribute. + attrNames[attrName] = 1; + } else { + return getErrorObject('InvalidAttr', "Attribute '"+attrName+"' is repeated.", getPositionFromMatch(matches[i])); + } + } -function Node() { -}; + return true; +} -Node.prototype = { - firstChild : null, - lastChild : null, - previousSibling : null, - nextSibling : null, - attributes : null, - parentNode : null, - childNodes : null, - ownerDocument : null, - nodeValue : null, - namespaceURI : null, - prefix : null, - localName : null, - // Modified in DOM Level 2: - insertBefore:function(newChild, refChild){//raises - return _insertBefore(this,newChild,refChild); - }, - replaceChild:function(newChild, oldChild){//raises - _insertBefore(this, newChild,oldChild, assertPreReplacementValidityInDocument); - if(oldChild){ - this.removeChild(oldChild); - } - }, - removeChild:function(oldChild){ - return _removeChild(this,oldChild); - }, - appendChild:function(newChild){ - return this.insertBefore(newChild,null); - }, - hasChildNodes:function(){ - return this.firstChild != null; - }, - cloneNode:function(deep){ - return cloneNode(this.ownerDocument||this,this,deep); - }, - // Modified in DOM Level 2: - normalize:function(){ - var child = this.firstChild; - while(child){ - var next = child.nextSibling; - if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){ - this.removeChild(next); - child.appendData(next.data); - }else{ - child.normalize(); - child = next; - } - } - }, - // Introduced in DOM Level 2: - isSupported:function(feature, version){ - return this.ownerDocument.implementation.hasFeature(feature,version); - }, - // Introduced in DOM Level 2: - hasAttributes:function(){ - return this.attributes.length>0; - }, - /** - * Look up the prefix associated to the given namespace URI, starting from this node. - * **The default namespace declarations are ignored by this method.** - * See Namespace Prefix Lookup for details on the algorithm used by this method. - * - * _Note: The implementation seems to be incomplete when compared to the algorithm described in the specs._ - * - * @param {string | null} namespaceURI - * @returns {string | null} - * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix - * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo - * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix - * @see https://github.com/xmldom/xmldom/issues/322 - */ - lookupPrefix:function(namespaceURI){ - var el = this; - while(el){ - var map = el._nsMap; - //console.dir(map) - if(map){ - for(var n in map){ - if (Object.prototype.hasOwnProperty.call(map, n) && map[n] === namespaceURI) { - return n; - } - } - } - el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode; - } - return null; - }, - // Introduced in DOM Level 3: - lookupNamespaceURI:function(prefix){ - var el = this; - while(el){ - var map = el._nsMap; - //console.dir(map) - if(map){ - if(Object.prototype.hasOwnProperty.call(map, prefix)){ - return map[prefix] ; - } - } - el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode; - } - return null; +function validateNumberAmpersand(xmlData, i) { + let re = /\d/; + if (xmlData[i] === 'x') { + i++; + re = /[\da-fA-F]/; + } + for (; i < xmlData.length; i++) { + if (xmlData[i] === ';') + return i; + if (!xmlData[i].match(re)) + break; + } + return -1; +} + +function validateAmpersand(xmlData, i) { + // https://www.w3.org/TR/xml/#dt-charref + i++; + if (xmlData[i] === ';') + return -1; + if (xmlData[i] === '#') { + i++; + return validateNumberAmpersand(xmlData, i); + } + let count = 0; + for (; i < xmlData.length; i++, count++) { + if (xmlData[i].match(/\w/) && count < 20) + continue; + if (xmlData[i] === ';') + break; + return -1; + } + return i; +} + +function getErrorObject(code, message, lineNumber) { + return { + err: { + code: code, + msg: message, + line: lineNumber.line || lineNumber, + col: lineNumber.col, }, - // Introduced in DOM Level 3: - isDefaultNamespace:function(namespaceURI){ - var prefix = this.lookupPrefix(namespaceURI); - return prefix == null; - } -}; + }; +} + +function validateAttrName(attrName) { + return util.isName(attrName); +} +// const startsWithXML = /^xml/i; -function _xmlEncoder(c){ - return c == '<' && '<' || - c == '>' && '>' || - c == '&' && '&' || - c == '"' && '"' || - '&#'+c.charCodeAt()+';' +function validateTagName(tagname) { + return util.isName(tagname) /* && !tagname.match(startsWithXML) */; } +//this function returns the line number for the character at the given index +function getLineNumberForPosition(xmlData, index) { + const lines = xmlData.substring(0, index).split(/\r?\n/); + return { + line: lines.length, -copy(NodeType,Node); -copy(NodeType,Node.prototype); + // column number is last line's length + 1, because column numbering starts at 1: + col: lines[lines.length - 1].length + 1 + }; +} -/** - * @param callback return true for continue,false for break - * @return boolean true: break visit; - */ -function _visitNode(node,callback){ - if(callback(node)){ - return true; - } - if(node = node.firstChild){ - do{ - if(_visitNode(node,callback)){return true} - }while(node=node.nextSibling) - } +//this function returns the position of the first character of match within attrStr +function getPositionFromMatch(match) { + return match.startIndex + match[1].length; } +/***/ }), + +/***/ "./node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js": +/*!*****************************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js ***! + \*****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +//parse Empty Node as self closing node +const buildFromOrderedJs = __webpack_require__(/*! ./orderedJs2Xml */ "./node_modules/fast-xml-parser/src/xmlbuilder/orderedJs2Xml.js"); + +const defaultOptions = { + attributeNamePrefix: '@_', + attributesGroupName: false, + textNodeName: '#text', + ignoreAttributes: true, + cdataPropName: false, + format: false, + indentBy: ' ', + suppressEmptyNode: false, + suppressUnpairedNode: true, + suppressBooleanAttributes: true, + tagValueProcessor: function(key, a) { + return a; + }, + attributeValueProcessor: function(attrName, a) { + return a; + }, + preserveOrder: false, + commentPropName: false, + unpairedTags: [], + entities: [ + { regex: new RegExp("&", "g"), val: "&" },//it must be on top + { regex: new RegExp(">", "g"), val: ">" }, + { regex: new RegExp("<", "g"), val: "<" }, + { regex: new RegExp("\'", "g"), val: "'" }, + { regex: new RegExp("\"", "g"), val: """ } + ], + processEntities: true, + stopNodes: [], + // transformTagName: false, + // transformAttributeName: false, + oneListGroup: false +}; + +function Builder(options) { + this.options = Object.assign({}, defaultOptions, options); + if (this.options.ignoreAttributes || this.options.attributesGroupName) { + this.isAttribute = function(/*a*/) { + return false; + }; + } else { + this.attrPrefixLen = this.options.attributeNamePrefix.length; + this.isAttribute = isAttribute; + } + + this.processTextOrObjNode = processTextOrObjNode -function Document(){ - this.ownerDocument = this; + if (this.options.format) { + this.indentate = indentate; + this.tagEndChar = '>\n'; + this.newLine = '\n'; + } else { + this.indentate = function() { + return ''; + }; + this.tagEndChar = '>'; + this.newLine = ''; + } } -function _onAddAttribute(doc,el,newAttr){ - doc && doc._inc++; - var ns = newAttr.namespaceURI ; - if(ns === NAMESPACE.XMLNS){ - //update namespace - el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value - } +Builder.prototype.build = function(jObj) { + if(this.options.preserveOrder){ + return buildFromOrderedJs(jObj, this.options); + }else { + if(Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1){ + jObj = { + [this.options.arrayNodeName] : jObj + } + } + return this.j2x(jObj, 0).val; + } +}; + +Builder.prototype.j2x = function(jObj, level) { + let attrStr = ''; + let val = ''; + for (let key in jObj) { + if(!Object.prototype.hasOwnProperty.call(jObj, key)) continue; + if (typeof jObj[key] === 'undefined') { + // supress undefined node only if it is not an attribute + if (this.isAttribute(key)) { + val += ''; + } + } else if (jObj[key] === null) { + // null attribute should be ignored by the attribute list, but should not cause the tag closing + if (this.isAttribute(key)) { + val += ''; + } else if (key[0] === '?') { + val += this.indentate(level) + '<' + key + '?' + this.tagEndChar; + } else { + val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + } + // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + } else if (jObj[key] instanceof Date) { + val += this.buildTextValNode(jObj[key], key, '', level); + } else if (typeof jObj[key] !== 'object') { + //premitive type + const attr = this.isAttribute(key); + if (attr) { + attrStr += this.buildAttrPairStr(attr, '' + jObj[key]); + }else { + //tag value + if (key === this.options.textNodeName) { + let newval = this.options.tagValueProcessor(key, '' + jObj[key]); + val += this.replaceEntitiesValue(newval); + } else { + val += this.buildTextValNode(jObj[key], key, '', level); + } + } + } else if (Array.isArray(jObj[key])) { + //repeated nodes + const arrLen = jObj[key].length; + let listTagVal = ""; + for (let j = 0; j < arrLen; j++) { + const item = jObj[key][j]; + if (typeof item === 'undefined') { + // supress undefined node + } else if (item === null) { + if(key[0] === "?") val += this.indentate(level) + '<' + key + '?' + this.tagEndChar; + else val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + } else if (typeof item === 'object') { + if(this.options.oneListGroup ){ + listTagVal += this.j2x(item, level + 1).val; + }else{ + listTagVal += this.processTextOrObjNode(item, key, level) + } + } else { + listTagVal += this.buildTextValNode(item, key, '', level); + } + } + if(this.options.oneListGroup){ + listTagVal = this.buildObjectNode(listTagVal, key, '', level); + } + val += listTagVal; + } else { + //nested node + if (this.options.attributesGroupName && key === this.options.attributesGroupName) { + const Ks = Object.keys(jObj[key]); + const L = Ks.length; + for (let j = 0; j < L; j++) { + attrStr += this.buildAttrPairStr(Ks[j], '' + jObj[key][Ks[j]]); + } + } else { + val += this.processTextOrObjNode(jObj[key], key, level) + } + } + } + return {attrStr: attrStr, val: val}; +}; + +Builder.prototype.buildAttrPairStr = function(attrName, val){ + val = this.options.attributeValueProcessor(attrName, '' + val); + val = this.replaceEntitiesValue(val); + if (this.options.suppressBooleanAttributes && val === "true") { + return ' ' + attrName; + } else return ' ' + attrName + '="' + val + '"'; } -function _onRemoveAttribute(doc,el,newAttr,remove){ - doc && doc._inc++; - var ns = newAttr.namespaceURI ; - if(ns === NAMESPACE.XMLNS){ - //update namespace - delete el._nsMap[newAttr.prefix?newAttr.localName:''] - } +function processTextOrObjNode (object, key, level) { + const result = this.j2x(object, level + 1); + if (object[this.options.textNodeName] !== undefined && Object.keys(object).length === 1) { + return this.buildTextValNode(object[this.options.textNodeName], key, result.attrStr, level); + } else { + return this.buildObjectNode(result.val, key, result.attrStr, level); + } } -/** - * Updates `el.childNodes`, updating the indexed items and it's `length`. - * Passing `newChild` means it will be appended. - * Otherwise it's assumed that an item has been removed, - * and `el.firstNode` and it's `.nextSibling` are used - * to walk the current list of child nodes. - * - * @param {Document} doc - * @param {Node} el - * @param {Node} [newChild] - * @private - */ -function _onUpdateChild (doc, el, newChild) { - if(doc && doc._inc){ - doc._inc++; - //update childNodes - var cs = el.childNodes; - if (newChild) { - cs[cs.length++] = newChild; - } else { - var child = el.firstChild; - var i = 0; - while (child) { - cs[i++] = child; - child = child.nextSibling; - } - cs.length = i; - delete cs[cs.length]; - } - } +Builder.prototype.buildObjectNode = function(val, key, attrStr, level) { + if(val === ""){ + if(key[0] === "?") return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar; + else { + return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar; + } + }else{ + + let tagEndExp = '' + val + tagEndExp ); + } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) { + return this.indentate(level) + `` + this.newLine; + }else { + return ( + this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar + + val + + this.indentate(level) + tagEndExp ); + } + } } -/** - * Removes the connections between `parentNode` and `child` - * and any existing `child.previousSibling` or `child.nextSibling`. - * - * @see https://github.com/xmldom/xmldom/issues/135 - * @see https://github.com/xmldom/xmldom/issues/145 - * - * @param {Node} parentNode - * @param {Node} child - * @returns {Node} the child that was removed. - * @private - */ -function _removeChild (parentNode, child) { - var previous = child.previousSibling; - var next = child.nextSibling; - if (previous) { - previous.nextSibling = next; - } else { - parentNode.firstChild = next; - } - if (next) { - next.previousSibling = previous; - } else { - parentNode.lastChild = previous; - } - child.parentNode = null; - child.previousSibling = null; - child.nextSibling = null; - _onUpdateChild(parentNode.ownerDocument, parentNode); - return child; +Builder.prototype.closeTag = function(key){ + let closeTag = ""; + if(this.options.unpairedTags.indexOf(key) !== -1){ //unpaired + if(!this.options.suppressUnpairedNode) closeTag = "/" + }else if(this.options.suppressEmptyNode){ //empty + closeTag = "/"; + }else{ + closeTag = `>` + this.newLine; + }else if (this.options.commentPropName !== false && key === this.options.commentPropName) { + return this.indentate(level) + `` + this.newLine; + }else if(key[0] === "?") {//PI tag + return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar; + }else{ + let textValue = this.options.tagValueProcessor(key, val); + textValue = this.replaceEntitiesValue(textValue); + + if( textValue === ''){ + return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar; + }else{ + return this.indentate(level) + '<' + key + attrStr + '>' + + textValue + + ' 0 && this.options.processEntities){ + for (let i=0; i parentChildNodes.indexOf(child)); +function toXml(jArray, options) { + let indentation = ""; + if (options.format && options.indentBy.length > 0) { + indentation = EOL; + } + return arrToStr(jArray, options, "", indentation); } -/** - * Check if en element node can be inserted before `child`, or at the end if child is falsy, - * according to the presence and position of a doctype node on the same level. - * - * @param {Node} doc The document node - * @param {Node} child the node that would become the nextSibling if the element would be inserted - * @returns {boolean} `true` if an element can be inserted before child - * @private - * https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - */ -function isElementReplacementPossible(doc, child) { - var parentChildNodes = doc.childNodes || []; +function arrToStr(arr, options, jPath, indentation) { + let xmlStr = ""; + let isPreviousElementTag = false; - function hasElementChildThatIsNotChild(node) { - return isElementNode(node) && node !== child; - } + for (let i = 0; i < arr.length; i++) { + const tagObj = arr[i]; + const tagName = propName(tagObj); + if(tagName === undefined) continue; - if (find(parentChildNodes, hasElementChildThatIsNotChild)) { - return false; - } - var docTypeNode = find(parentChildNodes, isDocTypeNode); - return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child)); + let newJPath = ""; + if (jPath.length === 0) newJPath = tagName + else newJPath = `${jPath}.${tagName}`; + + if (tagName === options.textNodeName) { + let tagText = tagObj[tagName]; + if (!isStopNode(newJPath, options)) { + tagText = options.tagValueProcessor(tagName, tagText); + tagText = replaceEntitiesValue(tagText, options); + } + if (isPreviousElementTag) { + xmlStr += indentation; + } + xmlStr += tagText; + isPreviousElementTag = false; + continue; + } else if (tagName === options.cdataPropName) { + if (isPreviousElementTag) { + xmlStr += indentation; + } + xmlStr += ``; + isPreviousElementTag = false; + continue; + } else if (tagName === options.commentPropName) { + xmlStr += indentation + ``; + isPreviousElementTag = true; + continue; + } else if (tagName[0] === "?") { + const attStr = attr_to_str(tagObj[":@"], options); + const tempInd = tagName === "?xml" ? "" : indentation; + let piTextNodeName = tagObj[tagName][0][options.textNodeName]; + piTextNodeName = piTextNodeName.length !== 0 ? " " + piTextNodeName : ""; //remove extra spacing + xmlStr += tempInd + `<${tagName}${piTextNodeName}${attStr}?>`; + isPreviousElementTag = true; + continue; + } + let newIdentation = indentation; + if (newIdentation !== "") { + newIdentation += options.indentBy; + } + const attStr = attr_to_str(tagObj[":@"], options); + const tagStart = indentation + `<${tagName}${attStr}`; + const tagValue = arrToStr(tagObj[tagName], options, newJPath, newIdentation); + if (options.unpairedTags.indexOf(tagName) !== -1) { + if (options.suppressUnpairedNode) xmlStr += tagStart + ">"; + else xmlStr += tagStart + "/>"; + } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) { + xmlStr += tagStart + "/>"; + } else if (tagValue && tagValue.endsWith(">")) { + xmlStr += tagStart + `>${tagValue}${indentation}`; + } else { + xmlStr += tagStart + ">"; + if (tagValue && indentation !== "" && (tagValue.includes("/>") || tagValue.includes("`; + } + isPreviousElementTag = true; + } + + return xmlStr; } -/** - * @private - * Steps 1-5 of the checks before inserting and before replacing a child are the same. - * - * @param {Node} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node=} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - * @see https://dom.spec.whatwg.org/#concept-node-replace - */ -function assertPreInsertionValidity1to5(parent, node, child) { - // 1. If `parent` is not a Document, DocumentFragment, or Element node, then throw a "HierarchyRequestError" DOMException. - if (!hasValidParentNodeType(parent)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Unexpected parent node type ' + parent.nodeType); - } - // 2. If `node` is a host-including inclusive ancestor of `parent`, then throw a "HierarchyRequestError" DOMException. - // not implemented! - // 3. If `child` is non-null and its parent is not `parent`, then throw a "NotFoundError" DOMException. - if (child && child.parentNode !== parent) { - throw new DOMException(NOT_FOUND_ERR, 'child not in parent'); - } - if ( - // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException. - !hasInsertableNodeType(node) || - // 5. If either `node` is a Text node and `parent` is a document, - // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0 - // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE) - // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException. - (isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE) - ) { - throw new DOMException( - HIERARCHY_REQUEST_ERR, - 'Unexpected node type ' + node.nodeType + ' for parent node type ' + parent.nodeType - ); - } +function propName(obj) { + const keys = Object.keys(obj); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if(!obj.hasOwnProperty(key)) continue; + if (key !== ":@") return key; + } } -/** - * @private - * Step 6 of the checks before inserting and before replacing a child are different. - * - * @param {Document} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node | undefined} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - * @see https://dom.spec.whatwg.org/#concept-node-replace - */ -function assertPreInsertionValidityInDocument(parent, node, child) { - var parentChildNodes = parent.childNodes || []; - var nodeChildNodes = node.childNodes || []; - - // DocumentFragment - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - var nodeChildElements = nodeChildNodes.filter(isElementNode); - // If node has more than one element child or has a Text node child. - if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); - } - // Otherwise, if `node` has one element child and either `parent` has an element child, - // `child` is a doctype, or `child` is non-null and a doctype is following `child`. - if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); - } - } - // Element - if (isElementNode(node)) { - // `parent` has an element child, `child` is a doctype, - // or `child` is non-null and a doctype is following `child`. - if (!isElementInsertionPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); - } - } - // DocumentType - if (isDocTypeNode(node)) { - // `parent` has a doctype child, - if (find(parentChildNodes, isDocTypeNode)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); - } - var parentElementChild = find(parentChildNodes, isElementNode); - // `child` is non-null and an element is preceding `child`, - if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); - } - // or `child` is null and `parent` has an element child. - if (!child && parentElementChild) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can not be appended since element is present'); - } - } +function attr_to_str(attrMap, options) { + let attrStr = ""; + if (attrMap && !options.ignoreAttributes) { + for (let attr in attrMap) { + if(!attrMap.hasOwnProperty(attr)) continue; + let attrVal = options.attributeValueProcessor(attr, attrMap[attr]); + attrVal = replaceEntitiesValue(attrVal, options); + if (attrVal === true && options.suppressBooleanAttributes) { + attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`; + } else { + attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}="${attrVal}"`; + } + } + } + return attrStr; } -/** - * @private - * Step 6 of the checks before inserting and before replacing a child are different. - * - * @param {Document} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node | undefined} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - * @see https://dom.spec.whatwg.org/#concept-node-replace - */ -function assertPreReplacementValidityInDocument(parent, node, child) { - var parentChildNodes = parent.childNodes || []; - var nodeChildNodes = node.childNodes || []; - - // DocumentFragment - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - var nodeChildElements = nodeChildNodes.filter(isElementNode); - // If `node` has more than one element child or has a Text node child. - if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'More than one element or text in fragment'); - } - // Otherwise, if `node` has one element child and either `parent` has an element child that is not `child` or a doctype is following `child`. - if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Element in fragment can not be inserted before doctype'); - } - } - // Element - if (isElementNode(node)) { - // `parent` has an element child that is not `child` or a doctype is following `child`. - if (!isElementReplacementPossible(parent, child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one element can be added and only after doctype'); - } - } - // DocumentType - if (isDocTypeNode(node)) { - function hasDoctypeChildThatIsNotChild(node) { - return isDocTypeNode(node) && node !== child; - } - - // `parent` has a doctype child that is not `child`, - if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Only one doctype is allowed'); - } - var parentElementChild = find(parentChildNodes, isElementNode); - // or an element is preceding `child`. - if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) { - throw new DOMException(HIERARCHY_REQUEST_ERR, 'Doctype can only be inserted before an element'); - } - } +function isStopNode(jPath, options) { + jPath = jPath.substr(0, jPath.length - options.textNodeName.length - 1); + let tagName = jPath.substr(jPath.lastIndexOf(".") + 1); + for (let index in options.stopNodes) { + if (options.stopNodes[index] === jPath || options.stopNodes[index] === "*." + tagName) return true; + } + return false; } -/** - * @private - * @param {Node} parent the parent node to insert `node` into - * @param {Node} node the node to insert - * @param {Node=} child the node that should become the `nextSibling` of `node` - * @returns {Node} - * @throws DOMException for several node combinations that would create a DOM that is not well-formed. - * @throws DOMException if `child` is provided but is not a child of `parent`. - * @see https://dom.spec.whatwg.org/#concept-node-ensure-pre-insertion-validity - */ -function _insertBefore(parent, node, child, _inDocumentAssertion) { - // To ensure pre-insertion validity of a node into a parent before a child, run these steps: - assertPreInsertionValidity1to5(parent, node, child); - - // If parent is a document, and any of the statements below, switched on the interface node implements, - // are true, then throw a "HierarchyRequestError" DOMException. - if (parent.nodeType === Node.DOCUMENT_NODE) { - (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child); - } +function replaceEntitiesValue(textValue, options) { + if (textValue && textValue.length > 0 && options.processEntities) { + for (let i = 0; i < options.entities.length; i++) { + const entity = options.entities[i]; + textValue = textValue.replace(entity.regex, entity.val); + } + } + return textValue; +} +module.exports = toXml; - var cp = node.parentNode; - if(cp){ - cp.removeChild(node);//remove and update - } - if(node.nodeType === DOCUMENT_FRAGMENT_NODE){ - var newFirst = node.firstChild; - if (newFirst == null) { - return node; - } - var newLast = node.lastChild; - }else{ - newFirst = newLast = node; - } - var pre = child ? child.previousSibling : parent.lastChild; - newFirst.previousSibling = pre; - newLast.nextSibling = child; +/***/ }), + +/***/ "./node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js": +/*!*********************************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js ***! + \*********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { +const util = __webpack_require__(/*! ../util */ "./node_modules/fast-xml-parser/src/util.js"); + +//TODO: handle comments +function readDocType(xmlData, i){ + + const entities = {}; + if( xmlData[i + 3] === 'O' && + xmlData[i + 4] === 'C' && + xmlData[i + 5] === 'T' && + xmlData[i + 6] === 'Y' && + xmlData[i + 7] === 'P' && + xmlData[i + 8] === 'E') + { + i = i+9; + let angleBracketsCount = 1; + let hasBody = false, comment = false; + let exp = ""; + for(;i') { //Read tag content + if(comment){ + if( xmlData[i - 1] === "-" && xmlData[i - 2] === "-"){ + comment = false; + angleBracketsCount--; + } + }else{ + angleBracketsCount--; + } + if (angleBracketsCount === 0) { + break; + } + }else if( xmlData[i] === '['){ + hasBody = true; + }else{ + exp += xmlData[i]; + } + } + if(angleBracketsCount !== 0){ + throw new Error(`Unclosed DOCTYPE`); + } + }else{ + throw new Error(`Invalid Tag instead of DOCTYPE`); + } + return {entities, i}; +} + +function readEntityExp(xmlData,i){ + //External entities are not supported + // + + //Parameter entities are not supported + // + + //Internal entities are supported + // + + //read EntityName + let entityName = ""; + for (; i < xmlData.length && (xmlData[i] !== "'" && xmlData[i] !== '"' ); i++) { + // if(xmlData[i] === " ") continue; + // else + entityName += xmlData[i]; + } + entityName = entityName.trim(); + if(entityName.indexOf(" ") !== -1) throw new Error("External entites are not supported"); + + //read Entity Value + const startChar = xmlData[i++]; + let val = "" + for (; i < xmlData.length && xmlData[i] !== startChar ; i++) { + val += xmlData[i]; + } + return [entityName, val, i]; +} + +function isComment(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === '-' && + xmlData[i+3] === '-') return true + return false +} +function isEntity(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'E' && + xmlData[i+3] === 'N' && + xmlData[i+4] === 'T' && + xmlData[i+5] === 'I' && + xmlData[i+6] === 'T' && + xmlData[i+7] === 'Y') return true + return false +} +function isElement(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'E' && + xmlData[i+3] === 'L' && + xmlData[i+4] === 'E' && + xmlData[i+5] === 'M' && + xmlData[i+6] === 'E' && + xmlData[i+7] === 'N' && + xmlData[i+8] === 'T') return true + return false +} + +function isAttlist(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'A' && + xmlData[i+3] === 'T' && + xmlData[i+4] === 'T' && + xmlData[i+5] === 'L' && + xmlData[i+6] === 'I' && + xmlData[i+7] === 'S' && + xmlData[i+8] === 'T') return true + return false +} +function isNotation(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'N' && + xmlData[i+3] === 'O' && + xmlData[i+4] === 'T' && + xmlData[i+5] === 'A' && + xmlData[i+6] === 'T' && + xmlData[i+7] === 'I' && + xmlData[i+8] === 'O' && + xmlData[i+9] === 'N') return true + return false +} + +function validateEntityName(name){ + if (util.isName(name)) + return name; + else + throw new Error(`Invalid entity name ${name}`); +} + +module.exports = readDocType; - if(pre){ - pre.nextSibling = newFirst; - }else{ - parent.firstChild = newFirst; - } - if(child == null){ - parent.lastChild = newLast; - }else{ - child.previousSibling = newLast; - } - do{ - newFirst.parentNode = parent; - }while(newFirst !== newLast && (newFirst= newFirst.nextSibling)) - _onUpdateChild(parent.ownerDocument||parent, parent); - //console.log(parent.lastChild.nextSibling == null) - if (node.nodeType == DOCUMENT_FRAGMENT_NODE) { - node.firstChild = node.lastChild = null; - } - return node; -} -/** - * Appends `newChild` to `parentNode`. - * If `newChild` is already connected to a `parentNode` it is first removed from it. - * - * @see https://github.com/xmldom/xmldom/issues/135 - * @see https://github.com/xmldom/xmldom/issues/145 - * @param {Node} parentNode - * @param {Node} newChild - * @returns {Node} - * @private - */ -function _appendSingleChild (parentNode, newChild) { - if (newChild.parentNode) { - newChild.parentNode.removeChild(newChild); - } - newChild.parentNode = parentNode; - newChild.previousSibling = parentNode.lastChild; - newChild.nextSibling = null; - if (newChild.previousSibling) { - newChild.previousSibling.nextSibling = newChild; - } else { - parentNode.firstChild = newChild; - } - parentNode.lastChild = newChild; - _onUpdateChild(parentNode.ownerDocument, parentNode, newChild); - return newChild; -} - -Document.prototype = { - //implementation : null, - nodeName : '#document', - nodeType : DOCUMENT_NODE, - /** - * The DocumentType node of the document. - * - * @readonly - * @type DocumentType - */ - doctype : null, - documentElement : null, - _inc : 1, - - insertBefore : function(newChild, refChild){//raises - if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){ - var child = newChild.firstChild; - while(child){ - var next = child.nextSibling; - this.insertBefore(child,refChild); - child = next; - } - return newChild; - } - _insertBefore(this, newChild, refChild); - newChild.ownerDocument = this; - if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) { - this.documentElement = newChild; - } - - return newChild; - }, - removeChild : function(oldChild){ - if(this.documentElement == oldChild){ - this.documentElement = null; - } - return _removeChild(this,oldChild); - }, - replaceChild: function (newChild, oldChild) { - //raises - _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument); - newChild.ownerDocument = this; - if (oldChild) { - this.removeChild(oldChild); - } - if (isElementNode(newChild)) { - this.documentElement = newChild; - } - }, - // Introduced in DOM Level 2: - importNode : function(importedNode,deep){ - return importNode(this,importedNode,deep); - }, - // Introduced in DOM Level 2: - getElementById : function(id){ - var rtv = null; - _visitNode(this.documentElement,function(node){ - if(node.nodeType == ELEMENT_NODE){ - if(node.getAttribute('id') == id){ - rtv = node; - return true; - } - } - }) - return rtv; - }, - - /** - * The `getElementsByClassName` method of `Document` interface returns an array-like object - * of all child elements which have **all** of the given class name(s). - * - * Returns an empty list if `classeNames` is an empty string or only contains HTML white space characters. - * - * - * Warning: This is a live LiveNodeList. - * Changes in the DOM will reflect in the array as the changes occur. - * If an element selected by this array no longer qualifies for the selector, - * it will automatically be removed. Be aware of this for iteration purposes. - * - * @param {string} classNames is a string representing the class name(s) to match; multiple class names are separated by (ASCII-)whitespace - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName - * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname - */ - getElementsByClassName: function(classNames) { - var classNamesSet = toOrderedSet(classNames) - return new LiveNodeList(this, function(base) { - var ls = []; - if (classNamesSet.length > 0) { - _visitNode(base.documentElement, function(node) { - if(node !== base && node.nodeType === ELEMENT_NODE) { - var nodeClassNames = node.getAttribute('class') - // can be null if the attribute does not exist - if (nodeClassNames) { - // before splitting and iterating just compare them for the most common case - var matches = classNames === nodeClassNames; - if (!matches) { - var nodeClassNamesSet = toOrderedSet(nodeClassNames) - matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet)) - } - if(matches) { - ls.push(node); - } - } - } - }); - } - return ls; - }); - }, - - //document factory method: - createElement : function(tagName){ - var node = new Element(); - node.ownerDocument = this; - node.nodeName = tagName; - node.tagName = tagName; - node.localName = tagName; - node.childNodes = new NodeList(); - var attrs = node.attributes = new NamedNodeMap(); - attrs._ownerElement = node; - return node; - }, - createDocumentFragment : function(){ - var node = new DocumentFragment(); - node.ownerDocument = this; - node.childNodes = new NodeList(); - return node; - }, - createTextNode : function(data){ - var node = new Text(); - node.ownerDocument = this; - node.appendData(data) - return node; - }, - createComment : function(data){ - var node = new Comment(); - node.ownerDocument = this; - node.appendData(data) - return node; - }, - createCDATASection : function(data){ - var node = new CDATASection(); - node.ownerDocument = this; - node.appendData(data) - return node; - }, - createProcessingInstruction : function(target,data){ - var node = new ProcessingInstruction(); - node.ownerDocument = this; - node.tagName = node.nodeName = node.target = target; - node.nodeValue = node.data = data; - return node; - }, - createAttribute : function(name){ - var node = new Attr(); - node.ownerDocument = this; - node.name = name; - node.nodeName = name; - node.localName = name; - node.specified = true; - return node; - }, - createEntityReference : function(name){ - var node = new EntityReference(); - node.ownerDocument = this; - node.nodeName = name; - return node; - }, - // Introduced in DOM Level 2: - createElementNS : function(namespaceURI,qualifiedName){ - var node = new Element(); - var pl = qualifiedName.split(':'); - var attrs = node.attributes = new NamedNodeMap(); - node.childNodes = new NodeList(); - node.ownerDocument = this; - node.nodeName = qualifiedName; - node.tagName = qualifiedName; - node.namespaceURI = namespaceURI; - if(pl.length == 2){ - node.prefix = pl[0]; - node.localName = pl[1]; - }else{ - //el.prefix = null; - node.localName = qualifiedName; - } - attrs._ownerElement = node; - return node; - }, - // Introduced in DOM Level 2: - createAttributeNS : function(namespaceURI,qualifiedName){ - var node = new Attr(); - var pl = qualifiedName.split(':'); - node.ownerDocument = this; - node.nodeName = qualifiedName; - node.name = qualifiedName; - node.namespaceURI = namespaceURI; - node.specified = true; - if(pl.length == 2){ - node.prefix = pl[0]; - node.localName = pl[1]; - }else{ - //el.prefix = null; - node.localName = qualifiedName; - } - return node; - } -}; -_extends(Document,Node); +/***/ }), +/***/ "./node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js": +/*!**********************************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js ***! + \**********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { -function Element() { - this._nsMap = {}; -}; -Element.prototype = { - nodeType : ELEMENT_NODE, - hasAttribute : function(name){ - return this.getAttributeNode(name)!=null; - }, - getAttribute : function(name){ - var attr = this.getAttributeNode(name); - return attr && attr.value || ''; - }, - getAttributeNode : function(name){ - return this.attributes.getNamedItem(name); - }, - setAttribute : function(name, value){ - var attr = this.ownerDocument.createAttribute(name); - attr.value = attr.nodeValue = "" + value; - this.setAttributeNode(attr) - }, - removeAttribute : function(name){ - var attr = this.getAttributeNode(name) - attr && this.removeAttributeNode(attr); - }, - - //four real opeartion method - appendChild:function(newChild){ - if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){ - return this.insertBefore(newChild,null); - }else{ - return _appendSingleChild(this,newChild); - } - }, - setAttributeNode : function(newAttr){ - return this.attributes.setNamedItem(newAttr); - }, - setAttributeNodeNS : function(newAttr){ - return this.attributes.setNamedItemNS(newAttr); - }, - removeAttributeNode : function(oldAttr){ - //console.log(this == oldAttr.ownerElement) - return this.attributes.removeNamedItem(oldAttr.nodeName); - }, - //get real attribute name,and remove it by removeAttributeNode - removeAttributeNS : function(namespaceURI, localName){ - var old = this.getAttributeNodeNS(namespaceURI, localName); - old && this.removeAttributeNode(old); - }, - - hasAttributeNS : function(namespaceURI, localName){ - return this.getAttributeNodeNS(namespaceURI, localName)!=null; - }, - getAttributeNS : function(namespaceURI, localName){ - var attr = this.getAttributeNodeNS(namespaceURI, localName); - return attr && attr.value || ''; - }, - setAttributeNS : function(namespaceURI, qualifiedName, value){ - var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName); - attr.value = attr.nodeValue = "" + value; - this.setAttributeNode(attr) - }, - getAttributeNodeNS : function(namespaceURI, localName){ - return this.attributes.getNamedItemNS(namespaceURI, localName); - }, - - getElementsByTagName : function(tagName){ - return new LiveNodeList(this,function(base){ - var ls = []; - _visitNode(base,function(node){ - if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){ - ls.push(node); - } - }); - return ls; - }); - }, - getElementsByTagNameNS : function(namespaceURI, localName){ - return new LiveNodeList(this,function(base){ - var ls = []; - _visitNode(base,function(node){ - if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){ - ls.push(node); - } - }); - return ls; - }); - } +const defaultOptions = { + preserveOrder: false, + attributeNamePrefix: '@_', + attributesGroupName: false, + textNodeName: '#text', + ignoreAttributes: true, + removeNSPrefix: false, // remove NS from tag name or attribute name if true + allowBooleanAttributes: false, //a tag can have attributes without any value + //ignoreRootElement : false, + parseTagValue: true, + parseAttributeValue: false, + trimValues: true, //Trim string values of tag and attributes + cdataPropName: false, + numberParseOptions: { + hex: true, + leadingZeros: true, + eNotation: true + }, + tagValueProcessor: function(tagName, val) { + return val; + }, + attributeValueProcessor: function(attrName, val) { + return val; + }, + stopNodes: [], //nested tags will not be parsed even for errors + alwaysCreateTextNode: false, + isArray: () => false, + commentPropName: false, + unpairedTags: [], + processEntities: true, + htmlEntities: false, + ignoreDeclaration: false, + ignorePiTags: false, + transformTagName: false, + transformAttributeName: false, + updateTag: function(tagName, jPath, attrs){ + return tagName + }, + // skipEmptyListItem: false +}; + +const buildOptions = function(options) { + return Object.assign({}, defaultOptions, options); }; -Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName; -Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS; +exports.buildOptions = buildOptions; +exports.defaultOptions = defaultOptions; -_extends(Element,Node); -function Attr() { -}; -Attr.prototype.nodeType = ATTRIBUTE_NODE; -_extends(Attr,Node); +/***/ }), + +/***/ "./node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js": +/*!************************************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js ***! + \************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { +"use strict"; + +///@ts-check + +const util = __webpack_require__(/*! ../util */ "./node_modules/fast-xml-parser/src/util.js"); +const xmlNode = __webpack_require__(/*! ./xmlNode */ "./node_modules/fast-xml-parser/src/xmlparser/xmlNode.js"); +const readDocType = __webpack_require__(/*! ./DocTypeReader */ "./node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js"); +const toNumber = __webpack_require__(/*! strnum */ "./node_modules/strnum/strnum.js"); + +// const regx = +// '<((!\\[CDATA\\[([\\s\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\/)(NAME)\\s*>))([^<]*)' +// .replace(/NAME/g, util.nameRegexp); + +//const tagsRegx = new RegExp("<(\\/?[\\w:\\-\._]+)([^>]*)>(\\s*"+cdataRegx+")*([^<]+)?","g"); +//const tagsRegx = new RegExp("<(\\/?)((\\w*:)?([\\w:\\-\._]+))([^>]*)>([^<]*)("+cdataRegx+"([^<]*))*([^<]+)?","g"); + +class OrderedObjParser{ + constructor(options){ + 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) => String.fromCharCode(Number.parseInt(str, 10)) }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) }, + }; + this.addExternalEntities = addExternalEntities; + this.parseXml = parseXml; + this.parseTextData = parseTextData; + this.resolveNameSpace = resolveNameSpace; + this.buildAttributesMap = buildAttributesMap; + this.isItStopNode = isItStopNode; + this.replaceEntitiesValue = replaceEntitiesValue; + this.readStopNodeData = readStopNodeData; + this.saveTextToParentTag = saveTextToParentTag; + this.addChild = addChild; + } -function CharacterData() { -}; -CharacterData.prototype = { - data : '', - substringData : function(offset, count) { - return this.data.substring(offset, offset+count); - }, - appendData: function(text) { - text = this.data+text; - this.nodeValue = this.data = text; - this.length = text.length; - }, - insertData: function(offset,text) { - this.replaceData(offset,0,text); - - }, - appendChild:function(newChild){ - throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR]) - }, - deleteData: function(offset, count) { - this.replaceData(offset,count,""); - }, - replaceData: function(offset, count, text) { - var start = this.data.substring(0,offset); - var end = this.data.substring(offset+count); - text = start + text + end; - this.nodeValue = this.data = text; - this.length = text.length; - } } -_extends(CharacterData,Node); -function Text() { -}; -Text.prototype = { - nodeName : "#text", - nodeType : TEXT_NODE, - splitText : function(offset) { - var text = this.data; - var newText = text.substring(offset); - text = text.substring(0, offset); - this.data = this.nodeValue = text; - this.length = text.length; - var newNode = this.ownerDocument.createTextNode(newText); - if(this.parentNode){ - this.parentNode.insertBefore(newNode, this.nextSibling); - } - return newNode; - } + +function addExternalEntities(externalEntities){ + const entKeys = Object.keys(externalEntities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.lastEntities[ent] = { + regex: new RegExp("&"+ent+";","g"), + val : externalEntities[ent] + } + } } -_extends(Text,CharacterData); -function Comment() { -}; -Comment.prototype = { - nodeName : "#comment", - nodeType : COMMENT_NODE + +/** + * @param {string} val + * @param {string} tagName + * @param {string} jPath + * @param {boolean} dontTrim + * @param {boolean} hasAttributes + * @param {boolean} isLeafNode + * @param {boolean} escapeEntities + */ +function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) { + if (val !== undefined) { + if (this.options.trimValues && !dontTrim) { + val = val.trim(); + } + if(val.length > 0){ + if(!escapeEntities) val = this.replaceEntitiesValue(val); + + const newval = this.options.tagValueProcessor(tagName, val, jPath, 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{ + const trimmedVal = val.trim(); + if(trimmedVal === val){ + return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions); + }else{ + return val; + } + } + } + } } -_extends(Comment,CharacterData); -function CDATASection() { -}; -CDATASection.prototype = { - nodeName : "#cdata-section", - nodeType : CDATA_SECTION_NODE +function resolveNameSpace(tagname) { + if (this.options.removeNSPrefix) { + const tags = tagname.split(':'); + const prefix = tagname.charAt(0) === '/' ? '/' : ''; + if (tags[0] === 'xmlns') { + return ''; + } + if (tags.length === 2) { + tagname = prefix + tags[1]; + } + } + return tagname; +} + +//TODO: change regex to capture NS +//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 && typeof attrStr === 'string') { + // attrStr = attrStr.replace(/\r?\n/g, ' '); + //attrStr = attrStr || attrStr.trim(); + + const matches = util.getAllMatches(attrStr, attrsRegx); + const len = matches.length; //don't make it inline + const attrs = {}; + for (let i = 0; i < len; i++) { + const attrName = this.resolveNameSpace(matches[i][1]); + let oldVal = matches[i][4]; + let aName = this.options.attributeNamePrefix + attrName; + if (attrName.length) { + if (this.options.transformAttributeName) { + aName = this.options.transformAttributeName(aName); + } + if(aName === "__proto__") aName = "#__proto__"; + if (oldVal !== undefined) { + if (this.options.trimValues) { + oldVal = oldVal.trim(); + } + oldVal = this.replaceEntitiesValue(oldVal); + const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPath); + 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 + ); + } + } else if (this.options.allowBooleanAttributes) { + attrs[aName] = true; + } + } + } + if (!Object.keys(attrs).length) { + return; + } + if (this.options.attributesGroupName) { + const attrCollection = {}; + attrCollection[this.options.attributesGroupName] = attrs; + return attrCollection; + } + return attrs + } } -_extends(CDATASection,CharacterData); +const parseXml = function(xmlData) { + xmlData = xmlData.replace(/\r\n?/g, "\n"); //TODO: remove this line + const xmlObj = new xmlNode('!xml'); + let currentNode = xmlObj; + let textData = ""; + let jPath = ""; + for(let i=0; i< xmlData.length; 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 closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.") + let tagName = xmlData.substring(i+2,closeIndex).trim(); + + if(this.options.removeNSPrefix){ + const colonIndex = tagName.indexOf(":"); + if(colonIndex !== -1){ + tagName = tagName.substr(colonIndex+1); + } + } -function DocumentType() { -}; -DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE; -_extends(DocumentType,Node); + if(this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } -function Notation() { -}; -Notation.prototype.nodeType = NOTATION_NODE; -_extends(Notation,Node); + if(currentNode){ + textData = this.saveTextToParentTag(textData, currentNode, jPath); + } -function Entity() { -}; -Entity.prototype.nodeType = ENTITY_NODE; -_extends(Entity,Node); + //check if last tag of nested tag was unpaired tag + const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1); + if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){ + throw new Error(`Unpaired tag can not be used as closing tag: `); + } + let propIndex = 0 + if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){ + propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1) + this.tagsNodeStack.pop(); + }else{ + propIndex = jPath.lastIndexOf("."); + } + jPath = jPath.substring(0, propIndex); + + currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope + textData = ""; + i = closeIndex; + } else if( xmlData[i+1] === '?') { + + let tagData = readTagExp(xmlData,i, false, "?>"); + if(!tagData) throw new Error("Pi Tag is not closed."); + + textData = this.saveTextToParentTag(textData, currentNode, jPath); + if( (this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags){ + + }else{ + + const childNode = new xmlNode(tagData.tagName); + childNode.add(this.options.textNodeName, ""); + + if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){ + childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName); + } + this.addChild(currentNode, childNode, jPath) -function EntityReference() { -}; -EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE; -_extends(EntityReference,Node); + } -function DocumentFragment() { -}; -DocumentFragment.prototype.nodeName = "#document-fragment"; -DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE; -_extends(DocumentFragment,Node); - - -function ProcessingInstruction() { -} -ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE; -_extends(ProcessingInstruction,Node); -function XMLSerializer(){} -XMLSerializer.prototype.serializeToString = function(node,isHtml,nodeFilter){ - return nodeSerializeToString.call(node,isHtml,nodeFilter); -} -Node.prototype.toString = nodeSerializeToString; -function nodeSerializeToString(isHtml,nodeFilter){ - var buf = []; - var refNode = this.nodeType == 9 && this.documentElement || this; - var prefix = refNode.prefix; - var uri = refNode.namespaceURI; - - if(uri && prefix == null){ - //console.log(prefix) - var prefix = refNode.lookupPrefix(uri); - if(prefix == null){ - //isHTML = true; - var visibleNamespaces=[ - {namespace:uri,prefix:null} - //{namespace:uri,prefix:''} - ] - } - } - serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces); - //console.log('###',this.nodeType,uri,prefix,buf.join('')) - return buf.join(''); -} - -function needNamespaceDefine(node, isHTML, visibleNamespaces) { - var prefix = node.prefix || ''; - var uri = node.namespaceURI; - // According to [Namespaces in XML 1.0](https://www.w3.org/TR/REC-xml-names/#ns-using) , - // and more specifically https://www.w3.org/TR/REC-xml-names/#nsc-NoPrefixUndecl : - // > In a namespace declaration for a prefix [...], the attribute value MUST NOT be empty. - // in a similar manner [Namespaces in XML 1.1](https://www.w3.org/TR/xml-names11/#ns-using) - // and more specifically https://www.w3.org/TR/xml-names11/#nsc-NSDeclared : - // > [...] Furthermore, the attribute value [...] must not be an empty string. - // so serializing empty namespace value like xmlns:ds="" would produce an invalid XML document. - if (!uri) { - return false; - } - if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) { - return false; - } - var i = visibleNamespaces.length - while (i--) { - var ns = visibleNamespaces[i]; - // get namespace prefix - if (ns.prefix === prefix) { - return ns.namespace !== uri; - } - } - return true; -} -/** - * Well-formed constraint: No < in Attribute Values - * > The replacement text of any entity referred to directly or indirectly - * > in an attribute value must not contain a <. - * @see https://www.w3.org/TR/xml11/#CleanAttrVals - * @see https://www.w3.org/TR/xml11/#NT-AttValue - * - * Literal whitespace other than space that appear in attribute values - * are serialized as their entity references, so they will be preserved. - * (In contrast to whitespace literals in the input which are normalized to spaces) - * @see https://www.w3.org/TR/xml11/#AVNormalize - * @see https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes - */ -function addSerializedAttribute(buf, qualifiedName, value) { - buf.push(' ', qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"') -} + i = tagData.closeIndex + 1; + } else if(xmlData.substr(i + 1, 3) === '!--') { + const endIndex = findClosingIndex(xmlData, "-->", i+4, "Comment is not closed.") + if(this.options.commentPropName){ + const comment = xmlData.substring(i + 4, endIndex - 2); -function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){ - if (!visibleNamespaces) { - visibleNamespaces = []; - } + textData = this.saveTextToParentTag(textData, currentNode, jPath); - if(nodeFilter){ - node = nodeFilter(node); - if(node){ - if(typeof node == 'string'){ - buf.push(node); - return; - } - }else{ - return; - } - //buf.sort.apply(attrs, attributeSorter); - } + currentNode.add(this.options.commentPropName, [ { [this.options.textNodeName] : comment } ]); + } + i = endIndex; + } else if( xmlData.substr(i + 1, 2) === '!D') { + const result = readDocType(xmlData, i); + this.docTypeEntities = result.entities; + i = result.i; + }else if(xmlData.substr(i + 1, 2) === '![') { + const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2; + const tagExp = xmlData.substring(i + 9,closeIndex); + + textData = this.saveTextToParentTag(textData, currentNode, jPath); + + let val = this.parseTextData(tagExp, currentNode.tagname, jPath, 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 } ]); + }else{ + currentNode.add(this.options.textNodeName, val); + } + + i = closeIndex + 2; + }else {//Opening tag + let result = readTagExp(xmlData,i, this.options.removeNSPrefix); + let tagName= result.tagName; + const rawTagName = result.rawTagName; + let tagExp = result.tagExp; + let attrExpPresent = result.attrExpPresent; + let closeIndex = result.closeIndex; + + if (this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } + + //save text as child node + if (currentNode && textData) { + if(currentNode.tagname !== '!xml'){ + //when nested tag is found + textData = this.saveTextToParentTag(textData, currentNode, jPath, false); + } + } - switch(node.nodeType){ - case ELEMENT_NODE: - var attrs = node.attributes; - var len = attrs.length; - var child = node.firstChild; - var nodeName = node.tagName; - - isHTML = NAMESPACE.isHTML(node.namespaceURI) || isHTML - - var prefixedNodeName = nodeName - if (!isHTML && !node.prefix && node.namespaceURI) { - var defaultNS - // lookup current default ns from `xmlns` attribute - for (var ai = 0; ai < attrs.length; ai++) { - if (attrs.item(ai).name === 'xmlns') { - defaultNS = attrs.item(ai).value - break - } - } - if (!defaultNS) { - // lookup current default ns in visibleNamespaces - for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { - var namespace = visibleNamespaces[nsi] - if (namespace.prefix === '' && namespace.namespace === node.namespaceURI) { - defaultNS = namespace.namespace - break - } - } - } - if (defaultNS !== node.namespaceURI) { - for (var nsi = visibleNamespaces.length - 1; nsi >= 0; nsi--) { - var namespace = visibleNamespaces[nsi] - if (namespace.namespace === node.namespaceURI) { - if (namespace.prefix) { - prefixedNodeName = namespace.prefix + ':' + nodeName - } - break - } - } - } - } + //check if last tag was unpaired tag + const lastTag = currentNode; + if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){ + currentNode = this.tagsNodeStack.pop(); + jPath = jPath.substring(0, jPath.lastIndexOf(".")); + } + if(tagName !== xmlObj.tagname){ + jPath += jPath ? "." + tagName : tagName; + } + if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) { + let tagContent = ""; + //self-closing tag + if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){ + if(tagName[tagName.length - 1] === "/"){ //remove trailing '/' + tagName = tagName.substr(0, tagName.length - 1); + jPath = jPath.substr(0, jPath.length - 1); + tagExp = tagName; + }else{ + tagExp = tagExp.substr(0, tagExp.length - 1); + } + i = result.closeIndex; + } + //unpaired tag + else if(this.options.unpairedTags.indexOf(tagName) !== -1){ + + i = result.closeIndex; + } + //normal tag + else{ + //read until closing tag is found + const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1); + if(!result) throw new Error(`Unexpected end of ${rawTagName}`); + i = result.i; + tagContent = result.tagContent; + } - buf.push('<', prefixedNodeName); + const childNode = new xmlNode(tagName); + if(tagName !== tagExp && attrExpPresent){ + childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName); + } + if(tagContent) { + tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true); + } + + jPath = jPath.substr(0, jPath.lastIndexOf(".")); + childNode.add(this.options.textNodeName, tagContent); + + this.addChild(currentNode, childNode, jPath) + }else{ + //selfClosing tag + if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){ + if(tagName[tagName.length - 1] === "/"){ //remove trailing '/' + tagName = tagName.substr(0, tagName.length - 1); + jPath = jPath.substr(0, jPath.length - 1); + tagExp = tagName; + }else{ + tagExp = tagExp.substr(0, tagExp.length - 1); + } + + if(this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } - for(var i=0;i'); - //if is cdata child node - if(isHTML && /^script$/i.test(nodeName)){ - while(child){ - if(child.data){ - buf.push(child.data); - }else{ - serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - } - child = child.nextSibling; - } - }else - { - while(child){ - serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - child = child.nextSibling; - } - } - buf.push(''); - }else{ - buf.push('/>'); - } - // remove added visible namespaces - //visibleNamespaces.length = startVisibleNamespaces; - return; - case DOCUMENT_NODE: - case DOCUMENT_FRAGMENT_NODE: - var child = node.firstChild; - while(child){ - serializeToString(child, buf, isHTML, nodeFilter, visibleNamespaces.slice()); - child = child.nextSibling; - } - return; - case ATTRIBUTE_NODE: - return addSerializedAttribute(buf, node.name, node.value); - case TEXT_NODE: - /** - * The ampersand character (&) and the left angle bracket (<) must not appear in their literal form, - * except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section. - * If they are needed elsewhere, they must be escaped using either numeric character references or the strings - * `&` and `<` respectively. - * The right angle bracket (>) may be represented using the string " > ", and must, for compatibility, - * be escaped using either `>` or a character reference when it appears in the string `]]>` in content, - * when that string is not marking the end of a CDATA section. - * - * In the content of elements, character data is any string of characters - * which does not contain the start-delimiter of any markup - * and does not include the CDATA-section-close delimiter, `]]>`. - * - * @see https://www.w3.org/TR/xml/#NT-CharData - * @see https://w3c.github.io/DOM-Parsing/#xml-serializing-a-text-node - */ - return buf.push(node.data - .replace(/[<&>]/g,_xmlEncoder) - ); - case CDATA_SECTION_NODE: - return buf.push( ''); - case COMMENT_NODE: - return buf.push( ""); - case DOCUMENT_TYPE_NODE: - var pubid = node.publicId; - var sysid = node.systemId; - buf.push(''); - }else if(sysid && sysid!='.'){ - buf.push(' SYSTEM ', sysid, '>'); - }else{ - var sub = node.internalSubset; - if(sub){ - buf.push(" [",sub,"]"); - } - buf.push(">"); - } - return; - case PROCESSING_INSTRUCTION_NODE: - return buf.push( ""); - case ENTITY_REFERENCE_NODE: - return buf.push( '&',node.nodeName,';'); - //case ENTITY_NODE: - //case NOTATION_NODE: - default: - buf.push('??',node.nodeName); - } -} -function importNode(doc,node,deep){ - var node2; - switch (node.nodeType) { - case ELEMENT_NODE: - node2 = node.cloneNode(false); - node2.ownerDocument = doc; - //var attrs = node2.attributes; - //var len = attrs.length; - //for(var i=0;i', - lt: '<', - quot: '"', -}); +function readStopNodeData(xmlData, tagName, i){ + const startIndex = i; + // Starting at 1 since we already have an open tag + let openTagCount = 1; + + for (; i < xmlData.length; i++) { + if( xmlData[i] === "<"){ + if (xmlData[i+1] === "/") {//close tag + const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`); + let closeTagName = xmlData.substring(i+2,closeIndex).trim(); + if(closeTagName === tagName){ + openTagCount--; + if (openTagCount === 0) { + return { + tagContent: xmlData.substring(startIndex, i), + i : closeIndex + } + } + } + i=closeIndex; + } else if(xmlData[i+1] === '?') { + const closeIndex = findClosingIndex(xmlData, "?>", i+1, "StopNode is not closed.") + i=closeIndex; + } else if(xmlData.substr(i + 1, 3) === '!--') { + const closeIndex = findClosingIndex(xmlData, "-->", i+3, "StopNode is not closed.") + i=closeIndex; + } else if(xmlData.substr(i + 1, 2) === '![') { + const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2; + i=closeIndex; + } else { + const tagData = readTagExp(xmlData, i, '>') -/** - * A map of all entities that are detected in an HTML document. - * They contain all entries from `XML_ENTITIES`. - * - * @see XML_ENTITIES - * @see DOMParser.parseFromString - * @see DOMImplementation.prototype.createHTMLDocument - * @see https://html.spec.whatwg.org/#named-character-references WHATWG HTML(5) Spec - * @see https://html.spec.whatwg.org/entities.json JSON - * @see https://www.w3.org/TR/xml-entity-names/ W3C XML Entity Names - * @see https://www.w3.org/TR/html4/sgml/entities.html W3C HTML4/SGML - * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML Wikipedia (HTML) - * @see https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Entities_representing_special_characters_in_XHTML Wikpedia (XHTML) - */ -exports.HTML_ENTITIES = freeze({ - Aacute: '\u00C1', - aacute: '\u00E1', - Abreve: '\u0102', - abreve: '\u0103', - ac: '\u223E', - acd: '\u223F', - acE: '\u223E\u0333', - Acirc: '\u00C2', - acirc: '\u00E2', - acute: '\u00B4', - Acy: '\u0410', - acy: '\u0430', - AElig: '\u00C6', - aelig: '\u00E6', - af: '\u2061', - Afr: '\uD835\uDD04', - afr: '\uD835\uDD1E', - Agrave: '\u00C0', - agrave: '\u00E0', - alefsym: '\u2135', - aleph: '\u2135', - Alpha: '\u0391', - alpha: '\u03B1', - Amacr: '\u0100', - amacr: '\u0101', - amalg: '\u2A3F', - AMP: '\u0026', - amp: '\u0026', - And: '\u2A53', - and: '\u2227', - andand: '\u2A55', - andd: '\u2A5C', - andslope: '\u2A58', - andv: '\u2A5A', - ang: '\u2220', - ange: '\u29A4', - angle: '\u2220', - angmsd: '\u2221', - angmsdaa: '\u29A8', - angmsdab: '\u29A9', - angmsdac: '\u29AA', - angmsdad: '\u29AB', - angmsdae: '\u29AC', - angmsdaf: '\u29AD', - angmsdag: '\u29AE', - angmsdah: '\u29AF', - angrt: '\u221F', - angrtvb: '\u22BE', - angrtvbd: '\u299D', - angsph: '\u2222', - angst: '\u00C5', - angzarr: '\u237C', - Aogon: '\u0104', - aogon: '\u0105', - Aopf: '\uD835\uDD38', - aopf: '\uD835\uDD52', - ap: '\u2248', - apacir: '\u2A6F', - apE: '\u2A70', - ape: '\u224A', - apid: '\u224B', - apos: '\u0027', - ApplyFunction: '\u2061', - approx: '\u2248', - approxeq: '\u224A', - Aring: '\u00C5', - aring: '\u00E5', - Ascr: '\uD835\uDC9C', - ascr: '\uD835\uDCB6', - Assign: '\u2254', - ast: '\u002A', - asymp: '\u2248', - asympeq: '\u224D', - Atilde: '\u00C3', - atilde: '\u00E3', - Auml: '\u00C4', - auml: '\u00E4', - awconint: '\u2233', - awint: '\u2A11', - backcong: '\u224C', - backepsilon: '\u03F6', - backprime: '\u2035', - backsim: '\u223D', - backsimeq: '\u22CD', - Backslash: '\u2216', - Barv: '\u2AE7', - barvee: '\u22BD', - Barwed: '\u2306', - barwed: '\u2305', - barwedge: '\u2305', - bbrk: '\u23B5', - bbrktbrk: '\u23B6', - bcong: '\u224C', - Bcy: '\u0411', - bcy: '\u0431', - bdquo: '\u201E', - becaus: '\u2235', - Because: '\u2235', - because: '\u2235', - bemptyv: '\u29B0', - bepsi: '\u03F6', - bernou: '\u212C', - Bernoullis: '\u212C', - Beta: '\u0392', - beta: '\u03B2', - beth: '\u2136', - between: '\u226C', - Bfr: '\uD835\uDD05', - bfr: '\uD835\uDD1F', - bigcap: '\u22C2', - bigcirc: '\u25EF', - bigcup: '\u22C3', - bigodot: '\u2A00', - bigoplus: '\u2A01', - bigotimes: '\u2A02', - bigsqcup: '\u2A06', - bigstar: '\u2605', - bigtriangledown: '\u25BD', - bigtriangleup: '\u25B3', - biguplus: '\u2A04', - bigvee: '\u22C1', - bigwedge: '\u22C0', - bkarow: '\u290D', - blacklozenge: '\u29EB', - blacksquare: '\u25AA', - blacktriangle: '\u25B4', - blacktriangledown: '\u25BE', - blacktriangleleft: '\u25C2', - blacktriangleright: '\u25B8', - blank: '\u2423', - blk12: '\u2592', - blk14: '\u2591', - blk34: '\u2593', - block: '\u2588', - bne: '\u003D\u20E5', - bnequiv: '\u2261\u20E5', - bNot: '\u2AED', - bnot: '\u2310', - Bopf: '\uD835\uDD39', - bopf: '\uD835\uDD53', - bot: '\u22A5', - bottom: '\u22A5', - bowtie: '\u22C8', - boxbox: '\u29C9', - boxDL: '\u2557', - boxDl: '\u2556', - boxdL: '\u2555', - boxdl: '\u2510', - boxDR: '\u2554', - boxDr: '\u2553', - boxdR: '\u2552', - boxdr: '\u250C', - boxH: '\u2550', - boxh: '\u2500', - boxHD: '\u2566', - boxHd: '\u2564', - boxhD: '\u2565', - boxhd: '\u252C', - boxHU: '\u2569', - boxHu: '\u2567', - boxhU: '\u2568', - boxhu: '\u2534', - boxminus: '\u229F', - boxplus: '\u229E', - boxtimes: '\u22A0', - boxUL: '\u255D', - boxUl: '\u255C', - boxuL: '\u255B', - boxul: '\u2518', - boxUR: '\u255A', - boxUr: '\u2559', - boxuR: '\u2558', - boxur: '\u2514', - boxV: '\u2551', - boxv: '\u2502', - boxVH: '\u256C', - boxVh: '\u256B', - boxvH: '\u256A', - boxvh: '\u253C', - boxVL: '\u2563', - boxVl: '\u2562', - boxvL: '\u2561', - boxvl: '\u2524', - boxVR: '\u2560', - boxVr: '\u255F', - boxvR: '\u255E', - boxvr: '\u251C', - bprime: '\u2035', - Breve: '\u02D8', - breve: '\u02D8', - brvbar: '\u00A6', - Bscr: '\u212C', - bscr: '\uD835\uDCB7', - bsemi: '\u204F', - bsim: '\u223D', - bsime: '\u22CD', - bsol: '\u005C', - bsolb: '\u29C5', - bsolhsub: '\u27C8', - bull: '\u2022', - bullet: '\u2022', - bump: '\u224E', - bumpE: '\u2AAE', - bumpe: '\u224F', - Bumpeq: '\u224E', - bumpeq: '\u224F', - Cacute: '\u0106', - cacute: '\u0107', - Cap: '\u22D2', - cap: '\u2229', - capand: '\u2A44', - capbrcup: '\u2A49', - capcap: '\u2A4B', - capcup: '\u2A47', - capdot: '\u2A40', - CapitalDifferentialD: '\u2145', - caps: '\u2229\uFE00', - caret: '\u2041', - caron: '\u02C7', - Cayleys: '\u212D', - ccaps: '\u2A4D', - Ccaron: '\u010C', - ccaron: '\u010D', - Ccedil: '\u00C7', - ccedil: '\u00E7', - Ccirc: '\u0108', - ccirc: '\u0109', - Cconint: '\u2230', - ccups: '\u2A4C', - ccupssm: '\u2A50', - Cdot: '\u010A', - cdot: '\u010B', - cedil: '\u00B8', - Cedilla: '\u00B8', - cemptyv: '\u29B2', - cent: '\u00A2', - CenterDot: '\u00B7', - centerdot: '\u00B7', - Cfr: '\u212D', - cfr: '\uD835\uDD20', - CHcy: '\u0427', - chcy: '\u0447', - check: '\u2713', - checkmark: '\u2713', - Chi: '\u03A7', - chi: '\u03C7', - cir: '\u25CB', - circ: '\u02C6', - circeq: '\u2257', - circlearrowleft: '\u21BA', - circlearrowright: '\u21BB', - circledast: '\u229B', - circledcirc: '\u229A', - circleddash: '\u229D', - CircleDot: '\u2299', - circledR: '\u00AE', - circledS: '\u24C8', - CircleMinus: '\u2296', - CirclePlus: '\u2295', - CircleTimes: '\u2297', - cirE: '\u29C3', - cire: '\u2257', - cirfnint: '\u2A10', - cirmid: '\u2AEF', - cirscir: '\u29C2', - ClockwiseContourIntegral: '\u2232', - CloseCurlyDoubleQuote: '\u201D', - CloseCurlyQuote: '\u2019', - clubs: '\u2663', - clubsuit: '\u2663', - Colon: '\u2237', - colon: '\u003A', - Colone: '\u2A74', - colone: '\u2254', - coloneq: '\u2254', - comma: '\u002C', - commat: '\u0040', - comp: '\u2201', - compfn: '\u2218', - complement: '\u2201', - complexes: '\u2102', - cong: '\u2245', - congdot: '\u2A6D', - Congruent: '\u2261', - Conint: '\u222F', - conint: '\u222E', - ContourIntegral: '\u222E', - Copf: '\u2102', - copf: '\uD835\uDD54', - coprod: '\u2210', - Coproduct: '\u2210', - COPY: '\u00A9', - copy: '\u00A9', - copysr: '\u2117', - CounterClockwiseContourIntegral: '\u2233', - crarr: '\u21B5', - Cross: '\u2A2F', - cross: '\u2717', - Cscr: '\uD835\uDC9E', - cscr: '\uD835\uDCB8', - csub: '\u2ACF', - csube: '\u2AD1', - csup: '\u2AD0', - csupe: '\u2AD2', - ctdot: '\u22EF', - cudarrl: '\u2938', - cudarrr: '\u2935', - cuepr: '\u22DE', - cuesc: '\u22DF', - cularr: '\u21B6', - cularrp: '\u293D', - Cup: '\u22D3', - cup: '\u222A', - cupbrcap: '\u2A48', - CupCap: '\u224D', - cupcap: '\u2A46', - cupcup: '\u2A4A', - cupdot: '\u228D', - cupor: '\u2A45', - cups: '\u222A\uFE00', - curarr: '\u21B7', - curarrm: '\u293C', - curlyeqprec: '\u22DE', - curlyeqsucc: '\u22DF', - curlyvee: '\u22CE', - curlywedge: '\u22CF', - curren: '\u00A4', - curvearrowleft: '\u21B6', - curvearrowright: '\u21B7', - cuvee: '\u22CE', - cuwed: '\u22CF', - cwconint: '\u2232', - cwint: '\u2231', - cylcty: '\u232D', - Dagger: '\u2021', - dagger: '\u2020', - daleth: '\u2138', - Darr: '\u21A1', - dArr: '\u21D3', - darr: '\u2193', - dash: '\u2010', - Dashv: '\u2AE4', - dashv: '\u22A3', - dbkarow: '\u290F', - dblac: '\u02DD', - Dcaron: '\u010E', - dcaron: '\u010F', - Dcy: '\u0414', - dcy: '\u0434', - DD: '\u2145', - dd: '\u2146', - ddagger: '\u2021', - ddarr: '\u21CA', - DDotrahd: '\u2911', - ddotseq: '\u2A77', - deg: '\u00B0', - Del: '\u2207', - Delta: '\u0394', - delta: '\u03B4', - demptyv: '\u29B1', - dfisht: '\u297F', - Dfr: '\uD835\uDD07', - dfr: '\uD835\uDD21', - dHar: '\u2965', - dharl: '\u21C3', - dharr: '\u21C2', - DiacriticalAcute: '\u00B4', - DiacriticalDot: '\u02D9', - DiacriticalDoubleAcute: '\u02DD', - DiacriticalGrave: '\u0060', - DiacriticalTilde: '\u02DC', - diam: '\u22C4', - Diamond: '\u22C4', - diamond: '\u22C4', - diamondsuit: '\u2666', - diams: '\u2666', - die: '\u00A8', - DifferentialD: '\u2146', - digamma: '\u03DD', - disin: '\u22F2', - div: '\u00F7', - divide: '\u00F7', - divideontimes: '\u22C7', - divonx: '\u22C7', - DJcy: '\u0402', - djcy: '\u0452', - dlcorn: '\u231E', - dlcrop: '\u230D', - dollar: '\u0024', - Dopf: '\uD835\uDD3B', - dopf: '\uD835\uDD55', - Dot: '\u00A8', - dot: '\u02D9', - DotDot: '\u20DC', - doteq: '\u2250', - doteqdot: '\u2251', - DotEqual: '\u2250', - dotminus: '\u2238', - dotplus: '\u2214', - dotsquare: '\u22A1', - doublebarwedge: '\u2306', - DoubleContourIntegral: '\u222F', - DoubleDot: '\u00A8', - DoubleDownArrow: '\u21D3', - DoubleLeftArrow: '\u21D0', - DoubleLeftRightArrow: '\u21D4', - DoubleLeftTee: '\u2AE4', - DoubleLongLeftArrow: '\u27F8', - DoubleLongLeftRightArrow: '\u27FA', - DoubleLongRightArrow: '\u27F9', - DoubleRightArrow: '\u21D2', - DoubleRightTee: '\u22A8', - DoubleUpArrow: '\u21D1', - DoubleUpDownArrow: '\u21D5', - DoubleVerticalBar: '\u2225', - DownArrow: '\u2193', - Downarrow: '\u21D3', - downarrow: '\u2193', - DownArrowBar: '\u2913', - DownArrowUpArrow: '\u21F5', - DownBreve: '\u0311', - downdownarrows: '\u21CA', - downharpoonleft: '\u21C3', - downharpoonright: '\u21C2', - DownLeftRightVector: '\u2950', - DownLeftTeeVector: '\u295E', - DownLeftVector: '\u21BD', - DownLeftVectorBar: '\u2956', - DownRightTeeVector: '\u295F', - DownRightVector: '\u21C1', - DownRightVectorBar: '\u2957', - DownTee: '\u22A4', - DownTeeArrow: '\u21A7', - drbkarow: '\u2910', - drcorn: '\u231F', - drcrop: '\u230C', - Dscr: '\uD835\uDC9F', - dscr: '\uD835\uDCB9', - DScy: '\u0405', - dscy: '\u0455', - dsol: '\u29F6', - Dstrok: '\u0110', - dstrok: '\u0111', - dtdot: '\u22F1', - dtri: '\u25BF', - dtrif: '\u25BE', - duarr: '\u21F5', - duhar: '\u296F', - dwangle: '\u29A6', - DZcy: '\u040F', - dzcy: '\u045F', - dzigrarr: '\u27FF', - Eacute: '\u00C9', - eacute: '\u00E9', - easter: '\u2A6E', - Ecaron: '\u011A', - ecaron: '\u011B', - ecir: '\u2256', - Ecirc: '\u00CA', - ecirc: '\u00EA', - ecolon: '\u2255', - Ecy: '\u042D', - ecy: '\u044D', - eDDot: '\u2A77', - Edot: '\u0116', - eDot: '\u2251', - edot: '\u0117', - ee: '\u2147', - efDot: '\u2252', - Efr: '\uD835\uDD08', - efr: '\uD835\uDD22', - eg: '\u2A9A', - Egrave: '\u00C8', - egrave: '\u00E8', - egs: '\u2A96', - egsdot: '\u2A98', - el: '\u2A99', - Element: '\u2208', - elinters: '\u23E7', - ell: '\u2113', - els: '\u2A95', - elsdot: '\u2A97', - Emacr: '\u0112', - emacr: '\u0113', - empty: '\u2205', - emptyset: '\u2205', - EmptySmallSquare: '\u25FB', - emptyv: '\u2205', - EmptyVerySmallSquare: '\u25AB', - emsp: '\u2003', - emsp13: '\u2004', - emsp14: '\u2005', - ENG: '\u014A', - eng: '\u014B', - ensp: '\u2002', - Eogon: '\u0118', - eogon: '\u0119', - Eopf: '\uD835\uDD3C', - eopf: '\uD835\uDD56', - epar: '\u22D5', - eparsl: '\u29E3', - eplus: '\u2A71', - epsi: '\u03B5', - Epsilon: '\u0395', - epsilon: '\u03B5', - epsiv: '\u03F5', - eqcirc: '\u2256', - eqcolon: '\u2255', - eqsim: '\u2242', - eqslantgtr: '\u2A96', - eqslantless: '\u2A95', - Equal: '\u2A75', - equals: '\u003D', - EqualTilde: '\u2242', - equest: '\u225F', - Equilibrium: '\u21CC', - equiv: '\u2261', - equivDD: '\u2A78', - eqvparsl: '\u29E5', - erarr: '\u2971', - erDot: '\u2253', - Escr: '\u2130', - escr: '\u212F', - esdot: '\u2250', - Esim: '\u2A73', - esim: '\u2242', - Eta: '\u0397', - eta: '\u03B7', - ETH: '\u00D0', - eth: '\u00F0', - Euml: '\u00CB', - euml: '\u00EB', - euro: '\u20AC', - excl: '\u0021', - exist: '\u2203', - Exists: '\u2203', - expectation: '\u2130', - ExponentialE: '\u2147', - exponentiale: '\u2147', - fallingdotseq: '\u2252', - Fcy: '\u0424', - fcy: '\u0444', - female: '\u2640', - ffilig: '\uFB03', - fflig: '\uFB00', - ffllig: '\uFB04', - Ffr: '\uD835\uDD09', - ffr: '\uD835\uDD23', - filig: '\uFB01', - FilledSmallSquare: '\u25FC', - FilledVerySmallSquare: '\u25AA', - fjlig: '\u0066\u006A', - flat: '\u266D', - fllig: '\uFB02', - fltns: '\u25B1', - fnof: '\u0192', - Fopf: '\uD835\uDD3D', - fopf: '\uD835\uDD57', - ForAll: '\u2200', - forall: '\u2200', - fork: '\u22D4', - forkv: '\u2AD9', - Fouriertrf: '\u2131', - fpartint: '\u2A0D', - frac12: '\u00BD', - frac13: '\u2153', - frac14: '\u00BC', - frac15: '\u2155', - frac16: '\u2159', - frac18: '\u215B', - frac23: '\u2154', - frac25: '\u2156', - frac34: '\u00BE', - frac35: '\u2157', - frac38: '\u215C', - frac45: '\u2158', - frac56: '\u215A', - frac58: '\u215D', - frac78: '\u215E', - frasl: '\u2044', - frown: '\u2322', - Fscr: '\u2131', - fscr: '\uD835\uDCBB', - gacute: '\u01F5', - Gamma: '\u0393', - gamma: '\u03B3', - Gammad: '\u03DC', - gammad: '\u03DD', - gap: '\u2A86', - Gbreve: '\u011E', - gbreve: '\u011F', - Gcedil: '\u0122', - Gcirc: '\u011C', - gcirc: '\u011D', - Gcy: '\u0413', - gcy: '\u0433', - Gdot: '\u0120', - gdot: '\u0121', - gE: '\u2267', - ge: '\u2265', - gEl: '\u2A8C', - gel: '\u22DB', - geq: '\u2265', - geqq: '\u2267', - geqslant: '\u2A7E', - ges: '\u2A7E', - gescc: '\u2AA9', - gesdot: '\u2A80', - gesdoto: '\u2A82', - gesdotol: '\u2A84', - gesl: '\u22DB\uFE00', - gesles: '\u2A94', - Gfr: '\uD835\uDD0A', - gfr: '\uD835\uDD24', - Gg: '\u22D9', - gg: '\u226B', - ggg: '\u22D9', - gimel: '\u2137', - GJcy: '\u0403', - gjcy: '\u0453', - gl: '\u2277', - gla: '\u2AA5', - glE: '\u2A92', - glj: '\u2AA4', - gnap: '\u2A8A', - gnapprox: '\u2A8A', - gnE: '\u2269', - gne: '\u2A88', - gneq: '\u2A88', - gneqq: '\u2269', - gnsim: '\u22E7', - Gopf: '\uD835\uDD3E', - gopf: '\uD835\uDD58', - grave: '\u0060', - GreaterEqual: '\u2265', - GreaterEqualLess: '\u22DB', - GreaterFullEqual: '\u2267', - GreaterGreater: '\u2AA2', - GreaterLess: '\u2277', - GreaterSlantEqual: '\u2A7E', - GreaterTilde: '\u2273', - Gscr: '\uD835\uDCA2', - gscr: '\u210A', - gsim: '\u2273', - gsime: '\u2A8E', - gsiml: '\u2A90', - Gt: '\u226B', - GT: '\u003E', - gt: '\u003E', - gtcc: '\u2AA7', - gtcir: '\u2A7A', - gtdot: '\u22D7', - gtlPar: '\u2995', - gtquest: '\u2A7C', - gtrapprox: '\u2A86', - gtrarr: '\u2978', - gtrdot: '\u22D7', - gtreqless: '\u22DB', - gtreqqless: '\u2A8C', - gtrless: '\u2277', - gtrsim: '\u2273', - gvertneqq: '\u2269\uFE00', - gvnE: '\u2269\uFE00', - Hacek: '\u02C7', - hairsp: '\u200A', - half: '\u00BD', - hamilt: '\u210B', - HARDcy: '\u042A', - hardcy: '\u044A', - hArr: '\u21D4', - harr: '\u2194', - harrcir: '\u2948', - harrw: '\u21AD', - Hat: '\u005E', - hbar: '\u210F', - Hcirc: '\u0124', - hcirc: '\u0125', - hearts: '\u2665', - heartsuit: '\u2665', - hellip: '\u2026', - hercon: '\u22B9', - Hfr: '\u210C', - hfr: '\uD835\uDD25', - HilbertSpace: '\u210B', - hksearow: '\u2925', - hkswarow: '\u2926', - hoarr: '\u21FF', - homtht: '\u223B', - hookleftarrow: '\u21A9', - hookrightarrow: '\u21AA', - Hopf: '\u210D', - hopf: '\uD835\uDD59', - horbar: '\u2015', - HorizontalLine: '\u2500', - Hscr: '\u210B', - hscr: '\uD835\uDCBD', - hslash: '\u210F', - Hstrok: '\u0126', - hstrok: '\u0127', - HumpDownHump: '\u224E', - HumpEqual: '\u224F', - hybull: '\u2043', - hyphen: '\u2010', - Iacute: '\u00CD', - iacute: '\u00ED', - ic: '\u2063', - Icirc: '\u00CE', - icirc: '\u00EE', - Icy: '\u0418', - icy: '\u0438', - Idot: '\u0130', - IEcy: '\u0415', - iecy: '\u0435', - iexcl: '\u00A1', - iff: '\u21D4', - Ifr: '\u2111', - ifr: '\uD835\uDD26', - Igrave: '\u00CC', - igrave: '\u00EC', - ii: '\u2148', - iiiint: '\u2A0C', - iiint: '\u222D', - iinfin: '\u29DC', - iiota: '\u2129', - IJlig: '\u0132', - ijlig: '\u0133', - Im: '\u2111', - Imacr: '\u012A', - imacr: '\u012B', - image: '\u2111', - ImaginaryI: '\u2148', - imagline: '\u2110', - imagpart: '\u2111', - imath: '\u0131', - imof: '\u22B7', - imped: '\u01B5', - Implies: '\u21D2', - in: '\u2208', - incare: '\u2105', - infin: '\u221E', - infintie: '\u29DD', - inodot: '\u0131', - Int: '\u222C', - int: '\u222B', - intcal: '\u22BA', - integers: '\u2124', - Integral: '\u222B', - intercal: '\u22BA', - Intersection: '\u22C2', - intlarhk: '\u2A17', - intprod: '\u2A3C', - InvisibleComma: '\u2063', - InvisibleTimes: '\u2062', - IOcy: '\u0401', - iocy: '\u0451', - Iogon: '\u012E', - iogon: '\u012F', - Iopf: '\uD835\uDD40', - iopf: '\uD835\uDD5A', - Iota: '\u0399', - iota: '\u03B9', - iprod: '\u2A3C', - iquest: '\u00BF', - Iscr: '\u2110', - iscr: '\uD835\uDCBE', - isin: '\u2208', - isindot: '\u22F5', - isinE: '\u22F9', - isins: '\u22F4', - isinsv: '\u22F3', - isinv: '\u2208', - it: '\u2062', - Itilde: '\u0128', - itilde: '\u0129', - Iukcy: '\u0406', - iukcy: '\u0456', - Iuml: '\u00CF', - iuml: '\u00EF', - Jcirc: '\u0134', - jcirc: '\u0135', - Jcy: '\u0419', - jcy: '\u0439', - Jfr: '\uD835\uDD0D', - jfr: '\uD835\uDD27', - jmath: '\u0237', - Jopf: '\uD835\uDD41', - jopf: '\uD835\uDD5B', - Jscr: '\uD835\uDCA5', - jscr: '\uD835\uDCBF', - Jsercy: '\u0408', - jsercy: '\u0458', - Jukcy: '\u0404', - jukcy: '\u0454', - Kappa: '\u039A', - kappa: '\u03BA', - kappav: '\u03F0', - Kcedil: '\u0136', - kcedil: '\u0137', - Kcy: '\u041A', - kcy: '\u043A', - Kfr: '\uD835\uDD0E', - kfr: '\uD835\uDD28', - kgreen: '\u0138', - KHcy: '\u0425', - khcy: '\u0445', - KJcy: '\u040C', - kjcy: '\u045C', - Kopf: '\uD835\uDD42', - kopf: '\uD835\uDD5C', - Kscr: '\uD835\uDCA6', - kscr: '\uD835\uDCC0', - lAarr: '\u21DA', - Lacute: '\u0139', - lacute: '\u013A', - laemptyv: '\u29B4', - lagran: '\u2112', - Lambda: '\u039B', - lambda: '\u03BB', - Lang: '\u27EA', - lang: '\u27E8', - langd: '\u2991', - langle: '\u27E8', - lap: '\u2A85', - Laplacetrf: '\u2112', - laquo: '\u00AB', - Larr: '\u219E', - lArr: '\u21D0', - larr: '\u2190', - larrb: '\u21E4', - larrbfs: '\u291F', - larrfs: '\u291D', - larrhk: '\u21A9', - larrlp: '\u21AB', - larrpl: '\u2939', - larrsim: '\u2973', - larrtl: '\u21A2', - lat: '\u2AAB', - lAtail: '\u291B', - latail: '\u2919', - late: '\u2AAD', - lates: '\u2AAD\uFE00', - lBarr: '\u290E', - lbarr: '\u290C', - lbbrk: '\u2772', - lbrace: '\u007B', - lbrack: '\u005B', - lbrke: '\u298B', - lbrksld: '\u298F', - lbrkslu: '\u298D', - Lcaron: '\u013D', - lcaron: '\u013E', - Lcedil: '\u013B', - lcedil: '\u013C', - lceil: '\u2308', - lcub: '\u007B', - Lcy: '\u041B', - lcy: '\u043B', - ldca: '\u2936', - ldquo: '\u201C', - ldquor: '\u201E', - ldrdhar: '\u2967', - ldrushar: '\u294B', - ldsh: '\u21B2', - lE: '\u2266', - le: '\u2264', - LeftAngleBracket: '\u27E8', - LeftArrow: '\u2190', - Leftarrow: '\u21D0', - leftarrow: '\u2190', - LeftArrowBar: '\u21E4', - LeftArrowRightArrow: '\u21C6', - leftarrowtail: '\u21A2', - LeftCeiling: '\u2308', - LeftDoubleBracket: '\u27E6', - LeftDownTeeVector: '\u2961', - LeftDownVector: '\u21C3', - LeftDownVectorBar: '\u2959', - LeftFloor: '\u230A', - leftharpoondown: '\u21BD', - leftharpoonup: '\u21BC', - leftleftarrows: '\u21C7', - LeftRightArrow: '\u2194', - Leftrightarrow: '\u21D4', - leftrightarrow: '\u2194', - leftrightarrows: '\u21C6', - leftrightharpoons: '\u21CB', - leftrightsquigarrow: '\u21AD', - LeftRightVector: '\u294E', - LeftTee: '\u22A3', - LeftTeeArrow: '\u21A4', - LeftTeeVector: '\u295A', - leftthreetimes: '\u22CB', - LeftTriangle: '\u22B2', - LeftTriangleBar: '\u29CF', - LeftTriangleEqual: '\u22B4', - LeftUpDownVector: '\u2951', - LeftUpTeeVector: '\u2960', - LeftUpVector: '\u21BF', - LeftUpVectorBar: '\u2958', - LeftVector: '\u21BC', - LeftVectorBar: '\u2952', - lEg: '\u2A8B', - leg: '\u22DA', - leq: '\u2264', - leqq: '\u2266', - leqslant: '\u2A7D', - les: '\u2A7D', - lescc: '\u2AA8', - lesdot: '\u2A7F', - lesdoto: '\u2A81', - lesdotor: '\u2A83', - lesg: '\u22DA\uFE00', - lesges: '\u2A93', - lessapprox: '\u2A85', - lessdot: '\u22D6', - lesseqgtr: '\u22DA', - lesseqqgtr: '\u2A8B', - LessEqualGreater: '\u22DA', - LessFullEqual: '\u2266', - LessGreater: '\u2276', - lessgtr: '\u2276', - LessLess: '\u2AA1', - lesssim: '\u2272', - LessSlantEqual: '\u2A7D', - LessTilde: '\u2272', - lfisht: '\u297C', - lfloor: '\u230A', - Lfr: '\uD835\uDD0F', - lfr: '\uD835\uDD29', - lg: '\u2276', - lgE: '\u2A91', - lHar: '\u2962', - lhard: '\u21BD', - lharu: '\u21BC', - lharul: '\u296A', - lhblk: '\u2584', - LJcy: '\u0409', - ljcy: '\u0459', - Ll: '\u22D8', - ll: '\u226A', - llarr: '\u21C7', - llcorner: '\u231E', - Lleftarrow: '\u21DA', - llhard: '\u296B', - lltri: '\u25FA', - Lmidot: '\u013F', - lmidot: '\u0140', - lmoust: '\u23B0', - lmoustache: '\u23B0', - lnap: '\u2A89', - lnapprox: '\u2A89', - lnE: '\u2268', - lne: '\u2A87', - lneq: '\u2A87', - lneqq: '\u2268', - lnsim: '\u22E6', - loang: '\u27EC', - loarr: '\u21FD', - lobrk: '\u27E6', - LongLeftArrow: '\u27F5', - Longleftarrow: '\u27F8', - longleftarrow: '\u27F5', - LongLeftRightArrow: '\u27F7', - Longleftrightarrow: '\u27FA', - longleftrightarrow: '\u27F7', - longmapsto: '\u27FC', - LongRightArrow: '\u27F6', - Longrightarrow: '\u27F9', - longrightarrow: '\u27F6', - looparrowleft: '\u21AB', - looparrowright: '\u21AC', - lopar: '\u2985', - Lopf: '\uD835\uDD43', - lopf: '\uD835\uDD5D', - loplus: '\u2A2D', - lotimes: '\u2A34', - lowast: '\u2217', - lowbar: '\u005F', - LowerLeftArrow: '\u2199', - LowerRightArrow: '\u2198', - loz: '\u25CA', - lozenge: '\u25CA', - lozf: '\u29EB', - lpar: '\u0028', - lparlt: '\u2993', - lrarr: '\u21C6', - lrcorner: '\u231F', - lrhar: '\u21CB', - lrhard: '\u296D', - lrm: '\u200E', - lrtri: '\u22BF', - lsaquo: '\u2039', - Lscr: '\u2112', - lscr: '\uD835\uDCC1', - Lsh: '\u21B0', - lsh: '\u21B0', - lsim: '\u2272', - lsime: '\u2A8D', - lsimg: '\u2A8F', - lsqb: '\u005B', - lsquo: '\u2018', - lsquor: '\u201A', - Lstrok: '\u0141', - lstrok: '\u0142', - Lt: '\u226A', - LT: '\u003C', - lt: '\u003C', - ltcc: '\u2AA6', - ltcir: '\u2A79', - ltdot: '\u22D6', - lthree: '\u22CB', - ltimes: '\u22C9', - ltlarr: '\u2976', - ltquest: '\u2A7B', - ltri: '\u25C3', - ltrie: '\u22B4', - ltrif: '\u25C2', - ltrPar: '\u2996', - lurdshar: '\u294A', - luruhar: '\u2966', - lvertneqq: '\u2268\uFE00', - lvnE: '\u2268\uFE00', - macr: '\u00AF', - male: '\u2642', - malt: '\u2720', - maltese: '\u2720', - Map: '\u2905', - map: '\u21A6', - mapsto: '\u21A6', - mapstodown: '\u21A7', - mapstoleft: '\u21A4', - mapstoup: '\u21A5', - marker: '\u25AE', - mcomma: '\u2A29', - Mcy: '\u041C', - mcy: '\u043C', - mdash: '\u2014', - mDDot: '\u223A', - measuredangle: '\u2221', - MediumSpace: '\u205F', - Mellintrf: '\u2133', - Mfr: '\uD835\uDD10', - mfr: '\uD835\uDD2A', - mho: '\u2127', - micro: '\u00B5', - mid: '\u2223', - midast: '\u002A', - midcir: '\u2AF0', - middot: '\u00B7', - minus: '\u2212', - minusb: '\u229F', - minusd: '\u2238', - minusdu: '\u2A2A', - MinusPlus: '\u2213', - mlcp: '\u2ADB', - mldr: '\u2026', - mnplus: '\u2213', - models: '\u22A7', - Mopf: '\uD835\uDD44', - mopf: '\uD835\uDD5E', - mp: '\u2213', - Mscr: '\u2133', - mscr: '\uD835\uDCC2', - mstpos: '\u223E', - Mu: '\u039C', - mu: '\u03BC', - multimap: '\u22B8', - mumap: '\u22B8', - nabla: '\u2207', - Nacute: '\u0143', - nacute: '\u0144', - nang: '\u2220\u20D2', - nap: '\u2249', - napE: '\u2A70\u0338', - napid: '\u224B\u0338', - napos: '\u0149', - napprox: '\u2249', - natur: '\u266E', - natural: '\u266E', - naturals: '\u2115', - nbsp: '\u00A0', - nbump: '\u224E\u0338', - nbumpe: '\u224F\u0338', - ncap: '\u2A43', - Ncaron: '\u0147', - ncaron: '\u0148', - Ncedil: '\u0145', - ncedil: '\u0146', - ncong: '\u2247', - ncongdot: '\u2A6D\u0338', - ncup: '\u2A42', - Ncy: '\u041D', - ncy: '\u043D', - ndash: '\u2013', - ne: '\u2260', - nearhk: '\u2924', - neArr: '\u21D7', - nearr: '\u2197', - nearrow: '\u2197', - nedot: '\u2250\u0338', - NegativeMediumSpace: '\u200B', - NegativeThickSpace: '\u200B', - NegativeThinSpace: '\u200B', - NegativeVeryThinSpace: '\u200B', - nequiv: '\u2262', - nesear: '\u2928', - nesim: '\u2242\u0338', - NestedGreaterGreater: '\u226B', - NestedLessLess: '\u226A', - NewLine: '\u000A', - nexist: '\u2204', - nexists: '\u2204', - Nfr: '\uD835\uDD11', - nfr: '\uD835\uDD2B', - ngE: '\u2267\u0338', - nge: '\u2271', - ngeq: '\u2271', - ngeqq: '\u2267\u0338', - ngeqslant: '\u2A7E\u0338', - nges: '\u2A7E\u0338', - nGg: '\u22D9\u0338', - ngsim: '\u2275', - nGt: '\u226B\u20D2', - ngt: '\u226F', - ngtr: '\u226F', - nGtv: '\u226B\u0338', - nhArr: '\u21CE', - nharr: '\u21AE', - nhpar: '\u2AF2', - ni: '\u220B', - nis: '\u22FC', - nisd: '\u22FA', - niv: '\u220B', - NJcy: '\u040A', - njcy: '\u045A', - nlArr: '\u21CD', - nlarr: '\u219A', - nldr: '\u2025', - nlE: '\u2266\u0338', - nle: '\u2270', - nLeftarrow: '\u21CD', - nleftarrow: '\u219A', - nLeftrightarrow: '\u21CE', - nleftrightarrow: '\u21AE', - nleq: '\u2270', - nleqq: '\u2266\u0338', - nleqslant: '\u2A7D\u0338', - nles: '\u2A7D\u0338', - nless: '\u226E', - nLl: '\u22D8\u0338', - nlsim: '\u2274', - nLt: '\u226A\u20D2', - nlt: '\u226E', - nltri: '\u22EA', - nltrie: '\u22EC', - nLtv: '\u226A\u0338', - nmid: '\u2224', - NoBreak: '\u2060', - NonBreakingSpace: '\u00A0', - Nopf: '\u2115', - nopf: '\uD835\uDD5F', - Not: '\u2AEC', - not: '\u00AC', - NotCongruent: '\u2262', - NotCupCap: '\u226D', - NotDoubleVerticalBar: '\u2226', - NotElement: '\u2209', - NotEqual: '\u2260', - NotEqualTilde: '\u2242\u0338', - NotExists: '\u2204', - NotGreater: '\u226F', - NotGreaterEqual: '\u2271', - NotGreaterFullEqual: '\u2267\u0338', - NotGreaterGreater: '\u226B\u0338', - NotGreaterLess: '\u2279', - NotGreaterSlantEqual: '\u2A7E\u0338', - NotGreaterTilde: '\u2275', - NotHumpDownHump: '\u224E\u0338', - NotHumpEqual: '\u224F\u0338', - notin: '\u2209', - notindot: '\u22F5\u0338', - notinE: '\u22F9\u0338', - notinva: '\u2209', - notinvb: '\u22F7', - notinvc: '\u22F6', - NotLeftTriangle: '\u22EA', - NotLeftTriangleBar: '\u29CF\u0338', - NotLeftTriangleEqual: '\u22EC', - NotLess: '\u226E', - NotLessEqual: '\u2270', - NotLessGreater: '\u2278', - NotLessLess: '\u226A\u0338', - NotLessSlantEqual: '\u2A7D\u0338', - NotLessTilde: '\u2274', - NotNestedGreaterGreater: '\u2AA2\u0338', - NotNestedLessLess: '\u2AA1\u0338', - notni: '\u220C', - notniva: '\u220C', - notnivb: '\u22FE', - notnivc: '\u22FD', - NotPrecedes: '\u2280', - NotPrecedesEqual: '\u2AAF\u0338', - NotPrecedesSlantEqual: '\u22E0', - NotReverseElement: '\u220C', - NotRightTriangle: '\u22EB', - NotRightTriangleBar: '\u29D0\u0338', - NotRightTriangleEqual: '\u22ED', - NotSquareSubset: '\u228F\u0338', - NotSquareSubsetEqual: '\u22E2', - NotSquareSuperset: '\u2290\u0338', - NotSquareSupersetEqual: '\u22E3', - NotSubset: '\u2282\u20D2', - NotSubsetEqual: '\u2288', - NotSucceeds: '\u2281', - NotSucceedsEqual: '\u2AB0\u0338', - NotSucceedsSlantEqual: '\u22E1', - NotSucceedsTilde: '\u227F\u0338', - NotSuperset: '\u2283\u20D2', - NotSupersetEqual: '\u2289', - NotTilde: '\u2241', - NotTildeEqual: '\u2244', - NotTildeFullEqual: '\u2247', - NotTildeTilde: '\u2249', - NotVerticalBar: '\u2224', - npar: '\u2226', - nparallel: '\u2226', - nparsl: '\u2AFD\u20E5', - npart: '\u2202\u0338', - npolint: '\u2A14', - npr: '\u2280', - nprcue: '\u22E0', - npre: '\u2AAF\u0338', - nprec: '\u2280', - npreceq: '\u2AAF\u0338', - nrArr: '\u21CF', - nrarr: '\u219B', - nrarrc: '\u2933\u0338', - nrarrw: '\u219D\u0338', - nRightarrow: '\u21CF', - nrightarrow: '\u219B', - nrtri: '\u22EB', - nrtrie: '\u22ED', - nsc: '\u2281', - nsccue: '\u22E1', - nsce: '\u2AB0\u0338', - Nscr: '\uD835\uDCA9', - nscr: '\uD835\uDCC3', - nshortmid: '\u2224', - nshortparallel: '\u2226', - nsim: '\u2241', - nsime: '\u2244', - nsimeq: '\u2244', - nsmid: '\u2224', - nspar: '\u2226', - nsqsube: '\u22E2', - nsqsupe: '\u22E3', - nsub: '\u2284', - nsubE: '\u2AC5\u0338', - nsube: '\u2288', - nsubset: '\u2282\u20D2', - nsubseteq: '\u2288', - nsubseteqq: '\u2AC5\u0338', - nsucc: '\u2281', - nsucceq: '\u2AB0\u0338', - nsup: '\u2285', - nsupE: '\u2AC6\u0338', - nsupe: '\u2289', - nsupset: '\u2283\u20D2', - nsupseteq: '\u2289', - nsupseteqq: '\u2AC6\u0338', - ntgl: '\u2279', - Ntilde: '\u00D1', - ntilde: '\u00F1', - ntlg: '\u2278', - ntriangleleft: '\u22EA', - ntrianglelefteq: '\u22EC', - ntriangleright: '\u22EB', - ntrianglerighteq: '\u22ED', - Nu: '\u039D', - nu: '\u03BD', - num: '\u0023', - numero: '\u2116', - numsp: '\u2007', - nvap: '\u224D\u20D2', - nVDash: '\u22AF', - nVdash: '\u22AE', - nvDash: '\u22AD', - nvdash: '\u22AC', - nvge: '\u2265\u20D2', - nvgt: '\u003E\u20D2', - nvHarr: '\u2904', - nvinfin: '\u29DE', - nvlArr: '\u2902', - nvle: '\u2264\u20D2', - nvlt: '\u003C\u20D2', - nvltrie: '\u22B4\u20D2', - nvrArr: '\u2903', - nvrtrie: '\u22B5\u20D2', - nvsim: '\u223C\u20D2', - nwarhk: '\u2923', - nwArr: '\u21D6', - nwarr: '\u2196', - nwarrow: '\u2196', - nwnear: '\u2927', - Oacute: '\u00D3', - oacute: '\u00F3', - oast: '\u229B', - ocir: '\u229A', - Ocirc: '\u00D4', - ocirc: '\u00F4', - Ocy: '\u041E', - ocy: '\u043E', - odash: '\u229D', - Odblac: '\u0150', - odblac: '\u0151', - odiv: '\u2A38', - odot: '\u2299', - odsold: '\u29BC', - OElig: '\u0152', - oelig: '\u0153', - ofcir: '\u29BF', - Ofr: '\uD835\uDD12', - ofr: '\uD835\uDD2C', - ogon: '\u02DB', - Ograve: '\u00D2', - ograve: '\u00F2', - ogt: '\u29C1', - ohbar: '\u29B5', - ohm: '\u03A9', - oint: '\u222E', - olarr: '\u21BA', - olcir: '\u29BE', - olcross: '\u29BB', - oline: '\u203E', - olt: '\u29C0', - Omacr: '\u014C', - omacr: '\u014D', - Omega: '\u03A9', - omega: '\u03C9', - Omicron: '\u039F', - omicron: '\u03BF', - omid: '\u29B6', - ominus: '\u2296', - Oopf: '\uD835\uDD46', - oopf: '\uD835\uDD60', - opar: '\u29B7', - OpenCurlyDoubleQuote: '\u201C', - OpenCurlyQuote: '\u2018', - operp: '\u29B9', - oplus: '\u2295', - Or: '\u2A54', - or: '\u2228', - orarr: '\u21BB', - ord: '\u2A5D', - order: '\u2134', - orderof: '\u2134', - ordf: '\u00AA', - ordm: '\u00BA', - origof: '\u22B6', - oror: '\u2A56', - orslope: '\u2A57', - orv: '\u2A5B', - oS: '\u24C8', - Oscr: '\uD835\uDCAA', - oscr: '\u2134', - Oslash: '\u00D8', - oslash: '\u00F8', - osol: '\u2298', - Otilde: '\u00D5', - otilde: '\u00F5', - Otimes: '\u2A37', - otimes: '\u2297', - otimesas: '\u2A36', - Ouml: '\u00D6', - ouml: '\u00F6', - ovbar: '\u233D', - OverBar: '\u203E', - OverBrace: '\u23DE', - OverBracket: '\u23B4', - OverParenthesis: '\u23DC', - par: '\u2225', - para: '\u00B6', - parallel: '\u2225', - parsim: '\u2AF3', - parsl: '\u2AFD', - part: '\u2202', - PartialD: '\u2202', - Pcy: '\u041F', - pcy: '\u043F', - percnt: '\u0025', - period: '\u002E', - permil: '\u2030', - perp: '\u22A5', - pertenk: '\u2031', - Pfr: '\uD835\uDD13', - pfr: '\uD835\uDD2D', - Phi: '\u03A6', - phi: '\u03C6', - phiv: '\u03D5', - phmmat: '\u2133', - phone: '\u260E', - Pi: '\u03A0', - pi: '\u03C0', - pitchfork: '\u22D4', - piv: '\u03D6', - planck: '\u210F', - planckh: '\u210E', - plankv: '\u210F', - plus: '\u002B', - plusacir: '\u2A23', - plusb: '\u229E', - pluscir: '\u2A22', - plusdo: '\u2214', - plusdu: '\u2A25', - pluse: '\u2A72', - PlusMinus: '\u00B1', - plusmn: '\u00B1', - plussim: '\u2A26', - plustwo: '\u2A27', - pm: '\u00B1', - Poincareplane: '\u210C', - pointint: '\u2A15', - Popf: '\u2119', - popf: '\uD835\uDD61', - pound: '\u00A3', - Pr: '\u2ABB', - pr: '\u227A', - prap: '\u2AB7', - prcue: '\u227C', - prE: '\u2AB3', - pre: '\u2AAF', - prec: '\u227A', - precapprox: '\u2AB7', - preccurlyeq: '\u227C', - Precedes: '\u227A', - PrecedesEqual: '\u2AAF', - PrecedesSlantEqual: '\u227C', - PrecedesTilde: '\u227E', - preceq: '\u2AAF', - precnapprox: '\u2AB9', - precneqq: '\u2AB5', - precnsim: '\u22E8', - precsim: '\u227E', - Prime: '\u2033', - prime: '\u2032', - primes: '\u2119', - prnap: '\u2AB9', - prnE: '\u2AB5', - prnsim: '\u22E8', - prod: '\u220F', - Product: '\u220F', - profalar: '\u232E', - profline: '\u2312', - profsurf: '\u2313', - prop: '\u221D', - Proportion: '\u2237', - Proportional: '\u221D', - propto: '\u221D', - prsim: '\u227E', - prurel: '\u22B0', - Pscr: '\uD835\uDCAB', - pscr: '\uD835\uDCC5', - Psi: '\u03A8', - psi: '\u03C8', - puncsp: '\u2008', - Qfr: '\uD835\uDD14', - qfr: '\uD835\uDD2E', - qint: '\u2A0C', - Qopf: '\u211A', - qopf: '\uD835\uDD62', - qprime: '\u2057', - Qscr: '\uD835\uDCAC', - qscr: '\uD835\uDCC6', - quaternions: '\u210D', - quatint: '\u2A16', - quest: '\u003F', - questeq: '\u225F', - QUOT: '\u0022', - quot: '\u0022', - rAarr: '\u21DB', - race: '\u223D\u0331', - Racute: '\u0154', - racute: '\u0155', - radic: '\u221A', - raemptyv: '\u29B3', - Rang: '\u27EB', - rang: '\u27E9', - rangd: '\u2992', - range: '\u29A5', - rangle: '\u27E9', - raquo: '\u00BB', - Rarr: '\u21A0', - rArr: '\u21D2', - rarr: '\u2192', - rarrap: '\u2975', - rarrb: '\u21E5', - rarrbfs: '\u2920', - rarrc: '\u2933', - rarrfs: '\u291E', - rarrhk: '\u21AA', - rarrlp: '\u21AC', - rarrpl: '\u2945', - rarrsim: '\u2974', - Rarrtl: '\u2916', - rarrtl: '\u21A3', - rarrw: '\u219D', - rAtail: '\u291C', - ratail: '\u291A', - ratio: '\u2236', - rationals: '\u211A', - RBarr: '\u2910', - rBarr: '\u290F', - rbarr: '\u290D', - rbbrk: '\u2773', - rbrace: '\u007D', - rbrack: '\u005D', - rbrke: '\u298C', - rbrksld: '\u298E', - rbrkslu: '\u2990', - Rcaron: '\u0158', - rcaron: '\u0159', - Rcedil: '\u0156', - rcedil: '\u0157', - rceil: '\u2309', - rcub: '\u007D', - Rcy: '\u0420', - rcy: '\u0440', - rdca: '\u2937', - rdldhar: '\u2969', - rdquo: '\u201D', - rdquor: '\u201D', - rdsh: '\u21B3', - Re: '\u211C', - real: '\u211C', - realine: '\u211B', - realpart: '\u211C', - reals: '\u211D', - rect: '\u25AD', - REG: '\u00AE', - reg: '\u00AE', - ReverseElement: '\u220B', - ReverseEquilibrium: '\u21CB', - ReverseUpEquilibrium: '\u296F', - rfisht: '\u297D', - rfloor: '\u230B', - Rfr: '\u211C', - rfr: '\uD835\uDD2F', - rHar: '\u2964', - rhard: '\u21C1', - rharu: '\u21C0', - rharul: '\u296C', - Rho: '\u03A1', - rho: '\u03C1', - rhov: '\u03F1', - RightAngleBracket: '\u27E9', - RightArrow: '\u2192', - Rightarrow: '\u21D2', - rightarrow: '\u2192', - RightArrowBar: '\u21E5', - RightArrowLeftArrow: '\u21C4', - rightarrowtail: '\u21A3', - RightCeiling: '\u2309', - RightDoubleBracket: '\u27E7', - RightDownTeeVector: '\u295D', - RightDownVector: '\u21C2', - RightDownVectorBar: '\u2955', - RightFloor: '\u230B', - rightharpoondown: '\u21C1', - rightharpoonup: '\u21C0', - rightleftarrows: '\u21C4', - rightleftharpoons: '\u21CC', - rightrightarrows: '\u21C9', - rightsquigarrow: '\u219D', - RightTee: '\u22A2', - RightTeeArrow: '\u21A6', - RightTeeVector: '\u295B', - rightthreetimes: '\u22CC', - RightTriangle: '\u22B3', - RightTriangleBar: '\u29D0', - RightTriangleEqual: '\u22B5', - RightUpDownVector: '\u294F', - RightUpTeeVector: '\u295C', - RightUpVector: '\u21BE', - RightUpVectorBar: '\u2954', - RightVector: '\u21C0', - RightVectorBar: '\u2953', - ring: '\u02DA', - risingdotseq: '\u2253', - rlarr: '\u21C4', - rlhar: '\u21CC', - rlm: '\u200F', - rmoust: '\u23B1', - rmoustache: '\u23B1', - rnmid: '\u2AEE', - roang: '\u27ED', - roarr: '\u21FE', - robrk: '\u27E7', - ropar: '\u2986', - Ropf: '\u211D', - ropf: '\uD835\uDD63', - roplus: '\u2A2E', - rotimes: '\u2A35', - RoundImplies: '\u2970', - rpar: '\u0029', - rpargt: '\u2994', - rppolint: '\u2A12', - rrarr: '\u21C9', - Rrightarrow: '\u21DB', - rsaquo: '\u203A', - Rscr: '\u211B', - rscr: '\uD835\uDCC7', - Rsh: '\u21B1', - rsh: '\u21B1', - rsqb: '\u005D', - rsquo: '\u2019', - rsquor: '\u2019', - rthree: '\u22CC', - rtimes: '\u22CA', - rtri: '\u25B9', - rtrie: '\u22B5', - rtrif: '\u25B8', - rtriltri: '\u29CE', - RuleDelayed: '\u29F4', - ruluhar: '\u2968', - rx: '\u211E', - Sacute: '\u015A', - sacute: '\u015B', - sbquo: '\u201A', - Sc: '\u2ABC', - sc: '\u227B', - scap: '\u2AB8', - Scaron: '\u0160', - scaron: '\u0161', - sccue: '\u227D', - scE: '\u2AB4', - sce: '\u2AB0', - Scedil: '\u015E', - scedil: '\u015F', - Scirc: '\u015C', - scirc: '\u015D', - scnap: '\u2ABA', - scnE: '\u2AB6', - scnsim: '\u22E9', - scpolint: '\u2A13', - scsim: '\u227F', - Scy: '\u0421', - scy: '\u0441', - sdot: '\u22C5', - sdotb: '\u22A1', - sdote: '\u2A66', - searhk: '\u2925', - seArr: '\u21D8', - searr: '\u2198', - searrow: '\u2198', - sect: '\u00A7', - semi: '\u003B', - seswar: '\u2929', - setminus: '\u2216', - setmn: '\u2216', - sext: '\u2736', - Sfr: '\uD835\uDD16', - sfr: '\uD835\uDD30', - sfrown: '\u2322', - sharp: '\u266F', - SHCHcy: '\u0429', - shchcy: '\u0449', - SHcy: '\u0428', - shcy: '\u0448', - ShortDownArrow: '\u2193', - ShortLeftArrow: '\u2190', - shortmid: '\u2223', - shortparallel: '\u2225', - ShortRightArrow: '\u2192', - ShortUpArrow: '\u2191', - shy: '\u00AD', - Sigma: '\u03A3', - sigma: '\u03C3', - sigmaf: '\u03C2', - sigmav: '\u03C2', - sim: '\u223C', - simdot: '\u2A6A', - sime: '\u2243', - simeq: '\u2243', - simg: '\u2A9E', - simgE: '\u2AA0', - siml: '\u2A9D', - simlE: '\u2A9F', - simne: '\u2246', - simplus: '\u2A24', - simrarr: '\u2972', - slarr: '\u2190', - SmallCircle: '\u2218', - smallsetminus: '\u2216', - smashp: '\u2A33', - smeparsl: '\u29E4', - smid: '\u2223', - smile: '\u2323', - smt: '\u2AAA', - smte: '\u2AAC', - smtes: '\u2AAC\uFE00', - SOFTcy: '\u042C', - softcy: '\u044C', - sol: '\u002F', - solb: '\u29C4', - solbar: '\u233F', - Sopf: '\uD835\uDD4A', - sopf: '\uD835\uDD64', - spades: '\u2660', - spadesuit: '\u2660', - spar: '\u2225', - sqcap: '\u2293', - sqcaps: '\u2293\uFE00', - sqcup: '\u2294', - sqcups: '\u2294\uFE00', - Sqrt: '\u221A', - sqsub: '\u228F', - sqsube: '\u2291', - sqsubset: '\u228F', - sqsubseteq: '\u2291', - sqsup: '\u2290', - sqsupe: '\u2292', - sqsupset: '\u2290', - sqsupseteq: '\u2292', - squ: '\u25A1', - Square: '\u25A1', - square: '\u25A1', - SquareIntersection: '\u2293', - SquareSubset: '\u228F', - SquareSubsetEqual: '\u2291', - SquareSuperset: '\u2290', - SquareSupersetEqual: '\u2292', - SquareUnion: '\u2294', - squarf: '\u25AA', - squf: '\u25AA', - srarr: '\u2192', - Sscr: '\uD835\uDCAE', - sscr: '\uD835\uDCC8', - ssetmn: '\u2216', - ssmile: '\u2323', - sstarf: '\u22C6', - Star: '\u22C6', - star: '\u2606', - starf: '\u2605', - straightepsilon: '\u03F5', - straightphi: '\u03D5', - strns: '\u00AF', - Sub: '\u22D0', - sub: '\u2282', - subdot: '\u2ABD', - subE: '\u2AC5', - sube: '\u2286', - subedot: '\u2AC3', - submult: '\u2AC1', - subnE: '\u2ACB', - subne: '\u228A', - subplus: '\u2ABF', - subrarr: '\u2979', - Subset: '\u22D0', - subset: '\u2282', - subseteq: '\u2286', - subseteqq: '\u2AC5', - SubsetEqual: '\u2286', - subsetneq: '\u228A', - subsetneqq: '\u2ACB', - subsim: '\u2AC7', - subsub: '\u2AD5', - subsup: '\u2AD3', - succ: '\u227B', - succapprox: '\u2AB8', - succcurlyeq: '\u227D', - Succeeds: '\u227B', - SucceedsEqual: '\u2AB0', - SucceedsSlantEqual: '\u227D', - SucceedsTilde: '\u227F', - succeq: '\u2AB0', - succnapprox: '\u2ABA', - succneqq: '\u2AB6', - succnsim: '\u22E9', - succsim: '\u227F', - SuchThat: '\u220B', - Sum: '\u2211', - sum: '\u2211', - sung: '\u266A', - Sup: '\u22D1', - sup: '\u2283', - sup1: '\u00B9', - sup2: '\u00B2', - sup3: '\u00B3', - supdot: '\u2ABE', - supdsub: '\u2AD8', - supE: '\u2AC6', - supe: '\u2287', - supedot: '\u2AC4', - Superset: '\u2283', - SupersetEqual: '\u2287', - suphsol: '\u27C9', - suphsub: '\u2AD7', - suplarr: '\u297B', - supmult: '\u2AC2', - supnE: '\u2ACC', - supne: '\u228B', - supplus: '\u2AC0', - Supset: '\u22D1', - supset: '\u2283', - supseteq: '\u2287', - supseteqq: '\u2AC6', - supsetneq: '\u228B', - supsetneqq: '\u2ACC', - supsim: '\u2AC8', - supsub: '\u2AD4', - supsup: '\u2AD6', - swarhk: '\u2926', - swArr: '\u21D9', - swarr: '\u2199', - swarrow: '\u2199', - swnwar: '\u292A', - szlig: '\u00DF', - Tab: '\u0009', - target: '\u2316', - Tau: '\u03A4', - tau: '\u03C4', - tbrk: '\u23B4', - Tcaron: '\u0164', - tcaron: '\u0165', - Tcedil: '\u0162', - tcedil: '\u0163', - Tcy: '\u0422', - tcy: '\u0442', - tdot: '\u20DB', - telrec: '\u2315', - Tfr: '\uD835\uDD17', - tfr: '\uD835\uDD31', - there4: '\u2234', - Therefore: '\u2234', - therefore: '\u2234', - Theta: '\u0398', - theta: '\u03B8', - thetasym: '\u03D1', - thetav: '\u03D1', - thickapprox: '\u2248', - thicksim: '\u223C', - ThickSpace: '\u205F\u200A', - thinsp: '\u2009', - ThinSpace: '\u2009', - thkap: '\u2248', - thksim: '\u223C', - THORN: '\u00DE', - thorn: '\u00FE', - Tilde: '\u223C', - tilde: '\u02DC', - TildeEqual: '\u2243', - TildeFullEqual: '\u2245', - TildeTilde: '\u2248', - times: '\u00D7', - timesb: '\u22A0', - timesbar: '\u2A31', - timesd: '\u2A30', - tint: '\u222D', - toea: '\u2928', - top: '\u22A4', - topbot: '\u2336', - topcir: '\u2AF1', - Topf: '\uD835\uDD4B', - topf: '\uD835\uDD65', - topfork: '\u2ADA', - tosa: '\u2929', - tprime: '\u2034', - TRADE: '\u2122', - trade: '\u2122', - triangle: '\u25B5', - triangledown: '\u25BF', - triangleleft: '\u25C3', - trianglelefteq: '\u22B4', - triangleq: '\u225C', - triangleright: '\u25B9', - trianglerighteq: '\u22B5', - tridot: '\u25EC', - trie: '\u225C', - triminus: '\u2A3A', - TripleDot: '\u20DB', - triplus: '\u2A39', - trisb: '\u29CD', - tritime: '\u2A3B', - trpezium: '\u23E2', - Tscr: '\uD835\uDCAF', - tscr: '\uD835\uDCC9', - TScy: '\u0426', - tscy: '\u0446', - TSHcy: '\u040B', - tshcy: '\u045B', - Tstrok: '\u0166', - tstrok: '\u0167', - twixt: '\u226C', - twoheadleftarrow: '\u219E', - twoheadrightarrow: '\u21A0', - Uacute: '\u00DA', - uacute: '\u00FA', - Uarr: '\u219F', - uArr: '\u21D1', - uarr: '\u2191', - Uarrocir: '\u2949', - Ubrcy: '\u040E', - ubrcy: '\u045E', - Ubreve: '\u016C', - ubreve: '\u016D', - Ucirc: '\u00DB', - ucirc: '\u00FB', - Ucy: '\u0423', - ucy: '\u0443', - udarr: '\u21C5', - Udblac: '\u0170', - udblac: '\u0171', - udhar: '\u296E', - ufisht: '\u297E', - Ufr: '\uD835\uDD18', - ufr: '\uD835\uDD32', - Ugrave: '\u00D9', - ugrave: '\u00F9', - uHar: '\u2963', - uharl: '\u21BF', - uharr: '\u21BE', - uhblk: '\u2580', - ulcorn: '\u231C', - ulcorner: '\u231C', - ulcrop: '\u230F', - ultri: '\u25F8', - Umacr: '\u016A', - umacr: '\u016B', - uml: '\u00A8', - UnderBar: '\u005F', - UnderBrace: '\u23DF', - UnderBracket: '\u23B5', - UnderParenthesis: '\u23DD', - Union: '\u22C3', - UnionPlus: '\u228E', - Uogon: '\u0172', - uogon: '\u0173', - Uopf: '\uD835\uDD4C', - uopf: '\uD835\uDD66', - UpArrow: '\u2191', - Uparrow: '\u21D1', - uparrow: '\u2191', - UpArrowBar: '\u2912', - UpArrowDownArrow: '\u21C5', - UpDownArrow: '\u2195', - Updownarrow: '\u21D5', - updownarrow: '\u2195', - UpEquilibrium: '\u296E', - upharpoonleft: '\u21BF', - upharpoonright: '\u21BE', - uplus: '\u228E', - UpperLeftArrow: '\u2196', - UpperRightArrow: '\u2197', - Upsi: '\u03D2', - upsi: '\u03C5', - upsih: '\u03D2', - Upsilon: '\u03A5', - upsilon: '\u03C5', - UpTee: '\u22A5', - UpTeeArrow: '\u21A5', - upuparrows: '\u21C8', - urcorn: '\u231D', - urcorner: '\u231D', - urcrop: '\u230E', - Uring: '\u016E', - uring: '\u016F', - urtri: '\u25F9', - Uscr: '\uD835\uDCB0', - uscr: '\uD835\uDCCA', - utdot: '\u22F0', - Utilde: '\u0168', - utilde: '\u0169', - utri: '\u25B5', - utrif: '\u25B4', - uuarr: '\u21C8', - Uuml: '\u00DC', - uuml: '\u00FC', - uwangle: '\u29A7', - vangrt: '\u299C', - varepsilon: '\u03F5', - varkappa: '\u03F0', - varnothing: '\u2205', - varphi: '\u03D5', - varpi: '\u03D6', - varpropto: '\u221D', - vArr: '\u21D5', - varr: '\u2195', - varrho: '\u03F1', - varsigma: '\u03C2', - varsubsetneq: '\u228A\uFE00', - varsubsetneqq: '\u2ACB\uFE00', - varsupsetneq: '\u228B\uFE00', - varsupsetneqq: '\u2ACC\uFE00', - vartheta: '\u03D1', - vartriangleleft: '\u22B2', - vartriangleright: '\u22B3', - Vbar: '\u2AEB', - vBar: '\u2AE8', - vBarv: '\u2AE9', - Vcy: '\u0412', - vcy: '\u0432', - VDash: '\u22AB', - Vdash: '\u22A9', - vDash: '\u22A8', - vdash: '\u22A2', - Vdashl: '\u2AE6', - Vee: '\u22C1', - vee: '\u2228', - veebar: '\u22BB', - veeeq: '\u225A', - vellip: '\u22EE', - Verbar: '\u2016', - verbar: '\u007C', - Vert: '\u2016', - vert: '\u007C', - VerticalBar: '\u2223', - VerticalLine: '\u007C', - VerticalSeparator: '\u2758', - VerticalTilde: '\u2240', - VeryThinSpace: '\u200A', - Vfr: '\uD835\uDD19', - vfr: '\uD835\uDD33', - vltri: '\u22B2', - vnsub: '\u2282\u20D2', - vnsup: '\u2283\u20D2', - Vopf: '\uD835\uDD4D', - vopf: '\uD835\uDD67', - vprop: '\u221D', - vrtri: '\u22B3', - Vscr: '\uD835\uDCB1', - vscr: '\uD835\uDCCB', - vsubnE: '\u2ACB\uFE00', - vsubne: '\u228A\uFE00', - vsupnE: '\u2ACC\uFE00', - vsupne: '\u228B\uFE00', - Vvdash: '\u22AA', - vzigzag: '\u299A', - Wcirc: '\u0174', - wcirc: '\u0175', - wedbar: '\u2A5F', - Wedge: '\u22C0', - wedge: '\u2227', - wedgeq: '\u2259', - weierp: '\u2118', - Wfr: '\uD835\uDD1A', - wfr: '\uD835\uDD34', - Wopf: '\uD835\uDD4E', - wopf: '\uD835\uDD68', - wp: '\u2118', - wr: '\u2240', - wreath: '\u2240', - Wscr: '\uD835\uDCB2', - wscr: '\uD835\uDCCC', - xcap: '\u22C2', - xcirc: '\u25EF', - xcup: '\u22C3', - xdtri: '\u25BD', - Xfr: '\uD835\uDD1B', - xfr: '\uD835\uDD35', - xhArr: '\u27FA', - xharr: '\u27F7', - Xi: '\u039E', - xi: '\u03BE', - xlArr: '\u27F8', - xlarr: '\u27F5', - xmap: '\u27FC', - xnis: '\u22FB', - xodot: '\u2A00', - Xopf: '\uD835\uDD4F', - xopf: '\uD835\uDD69', - xoplus: '\u2A01', - xotime: '\u2A02', - xrArr: '\u27F9', - xrarr: '\u27F6', - Xscr: '\uD835\uDCB3', - xscr: '\uD835\uDCCD', - xsqcup: '\u2A06', - xuplus: '\u2A04', - xutri: '\u25B3', - xvee: '\u22C1', - xwedge: '\u22C0', - Yacute: '\u00DD', - yacute: '\u00FD', - YAcy: '\u042F', - yacy: '\u044F', - Ycirc: '\u0176', - ycirc: '\u0177', - Ycy: '\u042B', - ycy: '\u044B', - yen: '\u00A5', - Yfr: '\uD835\uDD1C', - yfr: '\uD835\uDD36', - YIcy: '\u0407', - yicy: '\u0457', - Yopf: '\uD835\uDD50', - yopf: '\uD835\uDD6A', - Yscr: '\uD835\uDCB4', - yscr: '\uD835\uDCCE', - YUcy: '\u042E', - yucy: '\u044E', - Yuml: '\u0178', - yuml: '\u00FF', - Zacute: '\u0179', - zacute: '\u017A', - Zcaron: '\u017D', - zcaron: '\u017E', - Zcy: '\u0417', - zcy: '\u0437', - Zdot: '\u017B', - zdot: '\u017C', - zeetrf: '\u2128', - ZeroWidthSpace: '\u200B', - Zeta: '\u0396', - zeta: '\u03B6', - Zfr: '\u2128', - zfr: '\uD835\uDD37', - ZHcy: '\u0416', - zhcy: '\u0436', - zigrarr: '\u21DD', - Zopf: '\u2124', - zopf: '\uD835\uDD6B', - Zscr: '\uD835\uDCB5', - zscr: '\uD835\uDCCF', - zwj: '\u200D', - zwnj: '\u200C', -}); + if (tagData) { + const openTagName = tagData && tagData.tagName; + if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") { + openTagCount++; + } + i=tagData.closeIndex; + } + } + } + }//end for loop +} + +function parseValue(val, shouldParse, options) { + if (shouldParse && typeof val === 'string') { + //console.log(options) + const newval = val.trim(); + if(newval === 'true' ) return true; + else if(newval === 'false' ) return false; + else return toNumber(val, options); + } else { + if (util.isExist(val)) { + return val; + } else { + return ''; + } + } +} -/** - * @deprecated use `HTML_ENTITIES` instead - * @see HTML_ENTITIES - */ -exports.entityMap = exports.HTML_ENTITIES; + +module.exports = OrderedObjParser; /***/ }), -/***/ "./node_modules/@xmldom/xmldom/lib/index.js": -/*!**************************************************!*\ - !*** ./node_modules/@xmldom/xmldom/lib/index.js ***! - \**************************************************/ +/***/ "./node_modules/fast-xml-parser/src/xmlparser/XMLParser.js": +/*!*****************************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/xmlparser/XMLParser.js ***! + \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -var dom = __webpack_require__(/*! ./dom */ "./node_modules/@xmldom/xmldom/lib/dom.js") -exports.DOMImplementation = dom.DOMImplementation -exports.XMLSerializer = dom.XMLSerializer -exports.DOMParser = __webpack_require__(/*! ./dom-parser */ "./node_modules/@xmldom/xmldom/lib/dom-parser.js").DOMParser +const { buildOptions} = __webpack_require__(/*! ./OptionsBuilder */ "./node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js"); +const OrderedObjParser = __webpack_require__(/*! ./OrderedObjParser */ "./node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js"); +const { prettify} = __webpack_require__(/*! ./node2json */ "./node_modules/fast-xml-parser/src/xmlparser/node2json.js"); +const validator = __webpack_require__(/*! ../validator */ "./node_modules/fast-xml-parser/src/validator.js"); + +class XMLParser{ + + constructor(options){ + this.externalEntities = {}; + this.options = buildOptions(options); + + } + /** + * Parse XML dats to JS object + * @param {string|Buffer} xmlData + * @param {boolean|Object} validationOption + */ + parse(xmlData,validationOption){ + if(typeof xmlData === "string"){ + }else if( xmlData.toString){ + xmlData = xmlData.toString(); + }else{ + throw new Error("XML data is accepted in String or Bytes[] form.") + } + if( validationOption){ + if(validationOption === true) validationOption = {}; //validate with default options + + const result = validator.validate(xmlData, validationOption); + if (result !== true) { + throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` ) + } + } + const orderedObjParser = new OrderedObjParser(this.options); + orderedObjParser.addExternalEntities(this.externalEntities); + const orderedResult = orderedObjParser.parseXml(xmlData); + if(this.options.preserveOrder || orderedResult === undefined) return orderedResult; + else return prettify(orderedResult, this.options); + } + + /** + * Add Entity which is not by default supported by this library + * @param {string} key + * @param {string} value + */ + addEntity(key, value){ + if(value.indexOf("&") !== -1){ + throw new Error("Entity value can't have '&'") + }else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){ + throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for ' '") + }else if(value === "&"){ + throw new Error("An entity with value '&' is not permitted"); + }else{ + this.externalEntities[key] = value; + } + } +} +module.exports = XMLParser; /***/ }), -/***/ "./node_modules/@xmldom/xmldom/lib/sax.js": -/*!************************************************!*\ - !*** ./node_modules/@xmldom/xmldom/lib/sax.js ***! - \************************************************/ +/***/ "./node_modules/fast-xml-parser/src/xmlparser/node2json.js": +/*!*****************************************************************!*\ + !*** ./node_modules/fast-xml-parser/src/xmlparser/node2json.js ***! + \*****************************************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -var NAMESPACE = __webpack_require__(/*! ./conventions */ "./node_modules/@xmldom/xmldom/lib/conventions.js").NAMESPACE; - -//[4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] -//[4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] -//[5] Name ::= NameStartChar (NameChar)* -var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]///\u10000-\uEFFFF -var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]"); -var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$'); -//var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/ -//var handlers = 'resolveEntity,getExternalSubset,characters,endDocument,endElement,endPrefixMapping,ignorableWhitespace,processingInstruction,setDocumentLocator,skippedEntity,startDocument,startElement,startPrefixMapping,notationDecl,unparsedEntityDecl,error,fatalError,warning,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,comment,endCDATA,endDTD,endEntity,startCDATA,startDTD,startEntity'.split(',') - -//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE -//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE -var S_TAG = 0;//tag name offerring -var S_ATTR = 1;//attr name offerring -var S_ATTR_SPACE=2;//attr name end and space offer -var S_EQ = 3;//=space? -var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only) -var S_ATTR_END = 5;//attr value end and no space(quot end) -var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer) -var S_TAG_CLOSE = 7;//closed el +"use strict"; + /** - * Creates an error that will not be caught by XMLReader aka the SAX parser. - * - * @param {string} message - * @param {any?} locator Optional, can provide details about the location in the source - * @constructor + * + * @param {array} node + * @param {any} options + * @returns */ -function ParseError(message, locator) { - this.message = message - this.locator = locator - if(Error.captureStackTrace) Error.captureStackTrace(this, ParseError); +function prettify(node, options){ + return compress( node, options); } -ParseError.prototype = new Error(); -ParseError.prototype.name = ParseError.name -function XMLReader(){ +/** + * + * @param {array} arr + * @param {object} options + * @param {string} jPath + * @returns object + */ +function compress(arr, options, jPath){ + let text; + const compressedObj = {}; + for (let i = 0; i < arr.length; i++) { + const tagObj = arr[i]; + const property = propName(tagObj); + let newJpath = ""; + if(jPath === undefined) newJpath = property; + else newJpath = jPath + "." + property; + + if(property === options.textNodeName){ + if(text === undefined) text = tagObj[property]; + else text += "" + tagObj[property]; + }else if(property === undefined){ + continue; + }else if(tagObj[property]){ + + let val = compress(tagObj[property], options, newJpath); + const isLeaf = isLeafTag(val, options); + + if(tagObj[":@"]){ + assignAttributes( val, tagObj[":@"], newJpath, 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){ + if(options.alwaysCreateTextNode) val[options.textNodeName] = ""; + else val = ""; + } + if(compressedObj[property] !== undefined && compressedObj.hasOwnProperty(property)) { + if(!Array.isArray(compressedObj[property])) { + compressedObj[property] = [ compressedObj[property] ]; + } + compressedObj[property].push(val); + }else{ + //TODO: if a node is not an array, then check if it should be an array + //also determine if it is a leaf node + if (options.isArray(property, newJpath, isLeaf )) { + compressedObj[property] = [val]; + }else{ + compressedObj[property] = val; + } + } + } + + } + // if(text && text.length > 0) compressedObj[options.textNodeName] = text; + if(typeof text === "string"){ + if(text.length > 0) compressedObj[options.textNodeName] = text; + }else if(text !== undefined) compressedObj[options.textNodeName] = text; + return compressedObj; +} + +function propName(obj){ + const keys = Object.keys(obj); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if(key !== ":@") return key; + } } -XMLReader.prototype = { - parse:function(source,defaultNSMap,entityMap){ - var domBuilder = this.domBuilder; - domBuilder.startDocument(); - _copy(defaultNSMap ,defaultNSMap = {}) - parse(source,defaultNSMap,entityMap, - domBuilder,this.errorHandler); - domBuilder.endDocument(); - } -} -function parse(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){ - function fixedFromCharCode(code) { - // String.prototype.fromCharCode does not supports - // > 2 bytes unicode chars directly - if (code > 0xffff) { - code -= 0x10000; - var surrogate1 = 0xd800 + (code >> 10) - , surrogate2 = 0xdc00 + (code & 0x3ff); - - return String.fromCharCode(surrogate1, surrogate2); - } else { - return String.fromCharCode(code); - } - } - function entityReplacer(a){ - var k = a.slice(1,-1); - if (Object.hasOwnProperty.call(entityMap, k)) { - return entityMap[k]; - }else if(k.charAt(0) === '#'){ - return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x'))) - }else{ - errorHandler.error('entity not found:'+a); - return a; - } - } - function appendText(end){//has some bugs - if(end>start){ - var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer); - locator&&position(start); - domBuilder.characters(xt,0,end-start); - start = end - } - } - function position(p,m){ - while(p>=lineEnd && (m = linePattern.exec(source))){ - lineStart = m.index; - lineEnd = lineStart + m[0].length; - locator.lineNumber++; - //console.log('line++:',locator,startPos,endPos) - } - locator.columnNumber = p-lineStart+1; - } - var lineStart = 0; - var lineEnd = 0; - var linePattern = /.*(?:\r\n?|\n)|.*$/g - var locator = domBuilder.locator; - - var parseStack = [{currentNSMap:defaultNSMapCopy}] - var closeMap = {}; - var start = 0; - while(true){ - try{ - var tagStart = source.indexOf('<',start); - if(tagStart<0){ - if(!source.substr(start).match(/^\s*$/)){ - var doc = domBuilder.doc; - var text = doc.createTextNode(source.substr(start)); - doc.appendChild(text); - domBuilder.currentElement = text; - } - return; - } - if(tagStart>start){ - appendText(tagStart); - } - switch(source.charAt(tagStart+1)){ - case '/': - var end = source.indexOf('>',tagStart+3); - var tagName = source.substring(tagStart + 2, end).replace(/[ \t\n\r]+$/g, ''); - var config = parseStack.pop(); - if(end<0){ - - tagName = source.substring(tagStart+2).replace(/[\s<].*/,''); - errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName); - end = tagStart+1+tagName.length; - }else if(tagName.match(/\s - locator&&position(tagStart); - end = parseInstruction(source,tagStart,domBuilder); - break; - case '!':// start){ - start = end; - }else{ - //TODO: 这里有可能sax回退,有位置错误风险 - appendText(Math.max(tagStart,start)+1); - } - } -} -function copyLocator(f,t){ - t.lineNumber = f.lineNumber; - t.columnNumber = f.columnNumber; - return t; +function assignAttributes(obj, attrMap, jpath, options){ + if (attrMap) { + const keys = Object.keys(attrMap); + const len = keys.length; //don't make it inline + for (let i = 0; i < len; i++) { + const atrrName = keys[i]; + if (options.isArray(atrrName, jpath + "." + atrrName, true, true)) { + obj[atrrName] = [ attrMap[atrrName] ]; + } else { + obj[atrrName] = attrMap[atrrName]; + } + } + } } -/** - * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack); - * @return end of the elementStartPart(end of elementEndPart for selfClosed el) - */ -function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){ - - /** - * @param {string} qname - * @param {string} value - * @param {number} startIndex - */ - function addAttribute(qname, value, startIndex) { - if (el.attributeNames.hasOwnProperty(qname)) { - errorHandler.fatalError('Attribute ' + qname + ' redefined') - } - el.addValue( - qname, - // @see https://www.w3.org/TR/xml/#AVNormalize - // since the xmldom sax parser does not "interpret" DTD the following is not implemented: - // - recursive replacement of (DTD) entity references - // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA - value.replace(/[\t\n\r]/g, ' ').replace(/&#?\w+;/g, entityReplacer), - startIndex - ) - } - var attrName; - var value; - var p = ++start; - var s = S_TAG;//status - while(true){ - var c = source.charAt(p); - switch(c){ - case '=': - if(s === S_ATTR){//attrName - attrName = source.slice(start,p); - s = S_EQ; - }else if(s === S_ATTR_SPACE){ - s = S_EQ; - }else{ - //fatalError: equal must after attrName or space after attrName - throw new Error('attribute equal must after attrName'); // No known test case - } - break; - case '\'': - case '"': - if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE - ){//equal - if(s === S_ATTR){ - errorHandler.warning('attribute value must after "="') - attrName = source.slice(start,p) - } - start = p+1; - p = source.indexOf(c,start) - if(p>0){ - value = source.slice(start, p); - addAttribute(attrName, value, start-1); - s = S_ATTR_END; - }else{ - //fatalError: no end quot match - throw new Error('attribute value no end \''+c+'\' match'); - } - }else if(s == S_ATTR_NOQUOT_VALUE){ - value = source.slice(start, p); - addAttribute(attrName, value, start); - errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!'); - start = p+1; - s = S_ATTR_END - }else{ - //fatalError: no equal before - throw new Error('attribute value must after "="'); // No known test case - } - break; - case '/': - switch(s){ - case S_TAG: - el.setTagName(source.slice(start,p)); - case S_ATTR_END: - case S_TAG_SPACE: - case S_TAG_CLOSE: - s =S_TAG_CLOSE; - el.closed = true; - case S_ATTR_NOQUOT_VALUE: - case S_ATTR: - break; - case S_ATTR_SPACE: - el.closed = true; - break; - //case S_EQ: - default: - throw new Error("attribute invalid close char('/')") // No known test case - } - break; - case ''://end document - errorHandler.error('unexpected end of input'); - if(s == S_TAG){ - el.setTagName(source.slice(start,p)); - } - return p; - case '>': - switch(s){ - case S_TAG: - el.setTagName(source.slice(start,p)); - case S_ATTR_END: - case S_TAG_SPACE: - case S_TAG_CLOSE: - break;//normal - case S_ATTR_NOQUOT_VALUE://Compatible state - case S_ATTR: - value = source.slice(start,p); - if(value.slice(-1) === '/'){ - el.closed = true; - value = value.slice(0,-1) - } - case S_ATTR_SPACE: - if(s === S_ATTR_SPACE){ - value = attrName; - } - if(s == S_ATTR_NOQUOT_VALUE){ - errorHandler.warning('attribute "'+value+'" missed quot(")!'); - addAttribute(attrName, value, start) - }else{ - if(!NAMESPACE.isHTML(currentNSMap['']) || !value.match(/^(?:disabled|checked|selected)$/i)){ - errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!') - } - addAttribute(value, value, start) - } - break; - case S_EQ: - throw new Error('attribute value missed!!'); - } -// console.log(tagName,tagNamePattern,tagNamePattern.test(tagName)) - return p; - /*xml space '\x20' | #x9 | #xD | #xA; */ - case '\u0080': - c = ' '; - default: - if(c<= ' '){//space - switch(s){ - case S_TAG: - el.setTagName(source.slice(start,p));//tagName - s = S_TAG_SPACE; - break; - case S_ATTR: - attrName = source.slice(start,p) - s = S_ATTR_SPACE; - break; - case S_ATTR_NOQUOT_VALUE: - var value = source.slice(start, p); - errorHandler.warning('attribute "'+value+'" missed quot(")!!'); - addAttribute(attrName, value, start) - case S_ATTR_END: - s = S_TAG_SPACE; - break; - //case S_TAG_SPACE: - //case S_EQ: - //case S_ATTR_SPACE: - // void();break; - //case S_TAG_CLOSE: - //ignore warning - } - }else{//not space -//S_TAG, S_ATTR, S_EQ, S_ATTR_NOQUOT_VALUE -//S_ATTR_SPACE, S_ATTR_END, S_TAG_SPACE, S_TAG_CLOSE - switch(s){ - //case S_TAG:void();break; - //case S_ATTR:void();break; - //case S_ATTR_NOQUOT_VALUE:void();break; - case S_ATTR_SPACE: - var tagName = el.tagName; - if (!NAMESPACE.isHTML(currentNSMap['']) || !attrName.match(/^(?:disabled|checked|selected)$/i)) { - errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!') - } - addAttribute(attrName, attrName, start); - start = p; - s = S_ATTR; - break; - case S_ATTR_END: - errorHandler.warning('attribute space is required"'+attrName+'"!!') - case S_TAG_SPACE: - s = S_ATTR; - start = p; - break; - case S_EQ: - s = S_ATTR_NOQUOT_VALUE; - start = p; - break; - case S_TAG_CLOSE: - throw new Error("elements closed character '/' and '>' must be connected to"); - } - } - }//end outer switch - //console.log('p++',p) - p++; - } -} -/** - * @return true if has new namespace define - */ -function appendElement(el,domBuilder,currentNSMap){ - var tagName = el.tagName; - var localNSMap = null; - //var currentNSMap = parseStack[parseStack.length-1].currentNSMap; - var i = el.length; - while(i--){ - var a = el[i]; - var qName = a.qName; - var value = a.value; - var nsp = qName.indexOf(':'); - if(nsp>0){ - var prefix = a.prefix = qName.slice(0,nsp); - var localName = qName.slice(nsp+1); - var nsPrefix = prefix === 'xmlns' && localName - }else{ - localName = qName; - prefix = null - nsPrefix = qName === 'xmlns' && '' - } - //can not set prefix,because prefix !== '' - a.localName = localName ; - //prefix == null for no ns prefix attribute - if(nsPrefix !== false){//hack!! - if(localNSMap == null){ - localNSMap = {} - //console.log(currentNSMap,0) - _copy(currentNSMap,currentNSMap={}) - //console.log(currentNSMap,1) - } - currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value; - a.uri = NAMESPACE.XMLNS - domBuilder.startPrefixMapping(nsPrefix, value) - } - } - var i = el.length; - while(i--){ - a = el[i]; - var prefix = a.prefix; - if(prefix){//no prefix attribute has no namespace - if(prefix === 'xml'){ - a.uri = NAMESPACE.XML; - }if(prefix !== 'xmlns'){ - a.uri = currentNSMap[prefix || ''] - - //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)} - } - } - } - var nsp = tagName.indexOf(':'); - if(nsp>0){ - prefix = el.prefix = tagName.slice(0,nsp); - localName = el.localName = tagName.slice(nsp+1); - }else{ - prefix = null;//important!! - localName = el.localName = tagName; - } - //no prefix element has default namespace - var ns = el.uri = currentNSMap[prefix || '']; - domBuilder.startElement(ns,localName,tagName,el); - //endPrefixMapping and startPrefixMapping have not any help for dom builder - //localNSMap = null - if(el.closed){ - domBuilder.endElement(ns,localName,tagName); - if(localNSMap){ - for (prefix in localNSMap) { - if (Object.prototype.hasOwnProperty.call(localNSMap, prefix)) { - domBuilder.endPrefixMapping(prefix); - } - } - } - }else{ - el.currentNSMap = currentNSMap; - el.localNSMap = localNSMap; - //parseStack.push(el); - return true; - } -} -function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){ - if(/^(?:script|textarea)$/i.test(tagName)){ - var elEndStart = source.indexOf('',elStartEnd); - var text = source.substring(elStartEnd+1,elEndStart); - if(/[&<]/.test(text)){ - if(/^script$/i.test(tagName)){ - //if(!/\]\]>/.test(text)){ - //lexHandler.startCDATA(); - domBuilder.characters(text,0,text.length); - //lexHandler.endCDATA(); - return elEndStart; - //} - }//}else{//text area - text = text.replace(/&#?\w+;/g,entityReplacer); - domBuilder.characters(text,0,text.length); - return elEndStart; - //} - - } - } - return elStartEnd+1; -} -function fixSelfClosed(source,elStartEnd,tagName,closeMap){ - //if(tagName in closeMap){ - var pos = closeMap[tagName]; - if(pos == null){ - //console.log(tagName) - pos = source.lastIndexOf('') - if(pos',start+4); - //append comment source.substring(4,end)//