diff --git a/.eslintrc.json b/.eslintrc.json index cfe1e0b3..3d95f13f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,7 @@ { "env": { "browser": true, + "node": true, "es2021": true }, "extends": "eslint:recommended", @@ -9,5 +10,6 @@ "sourceType": "module" }, "rules": { - } + }, + "ignorePatterns": ["worker.js"] } diff --git a/README.md b/README.md index e1b3eac7..0cec7f88 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ **Social Media Photo by [JJ Ying](https://unsplash.com/@jjying) on [Unsplash](https://unsplash.com/)** -### This is not a crawler! - LinkeDOM is a [triple-linked list](#data-structure) based DOM-like namespace, for DOM-less environments, with the following goals: * **avoid** maximum callstack/recursion or **crashes**, even under heaviest conditions. diff --git a/cjs/dom/parser.js b/cjs/dom/parser.js index ecb31781..c5a02a24 100644 --- a/cjs/dom/parser.js +++ b/cjs/dom/parser.js @@ -13,10 +13,11 @@ class DOMParser { /** @typedef {{ "text/html": HTMLDocument, "image/svg+xml": SVGDocument, "text/xml": XMLDocument }} MimeToDoc */ /** + * @template {string|NodeJS.ReadableStream} INPUT * @template {keyof MimeToDoc} MIME - * @param {string} markupLanguage + * @param {INPUT} markupLanguage * @param {MIME} mimeType - * @returns {MimeToDoc[MIME]} + * @returns {INPUT extends string ? MimeToDoc[MIME] : Promise} */ parseFromString(markupLanguage, mimeType, globals = null) { let isHTML = false, document; diff --git a/cjs/dom/stream.js b/cjs/dom/stream.js new file mode 100644 index 00000000..2d0b64d5 --- /dev/null +++ b/cjs/dom/stream.js @@ -0,0 +1,135 @@ +'use strict'; +const {Writable} = require('stream'); +const {WritableStream} = require('htmlparser2/lib/WritableStream'); + +const { + onprocessinginstruction, onopentag, oncomment, ontext, onclosetag +} = require('../shared/parser-handlers') + +const {HTMLDocument} = require('../html/document.js'); +const {SVGDocument} = require('../svg/document.js'); +const {XMLDocument} = require('../xml/document.js'); + + +/** + * @typedef {import('../interface/node').Node} Node + * @typedef {import('../svg/element').SVGElement} SVGElement + * @typedef {{ "text/html": HTMLDocument, "image/svg+xml": SVGDocument, "text/xml": XMLDocument }} MimeToDoc + */ + +/** + * @template {keyof MimeToDoc} MIME + * @extends {Writable} + */ +class DOMStream extends Writable { + /** + * @param {MIME} mimeType + * @param {(name: string, attributes: Record) => boolean} filter + */ + constructor (mimeType, filter) { + super(); + this.mimeType = mimeType; + if (mimeType === 'text/html') this.isHTML = true; + this.filter = filter; + /** + * @type {{ + * document: MimeToDoc[MIME] + * node: MimeToDoc[MIME]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }[]} + */ + this.stack = []; // LIFO + this.init(); + } + + newDocument () { + let document; + if (this.mimeType === 'text/html') { + document = new HTMLDocument(); + } else if (this.mimeType === 'image/svg+xml') { + document = new SVGDocument(); + } else { + document = new XMLDocument(); + } + if (this.doctype) document.doctype = this.doctype; + this.stack.push({ document, node: document }); + } + + init () { + this.parserStream = new WritableStream({ + // + onprocessinginstruction: (name, data) => { + this.doctype = onprocessinginstruction(name, data); + }, + // + onopentag: (name, attributes) => { + if (this.filter(name, attributes)) this.newDocument(); + for (const item of this.stack) { + onopentag(name, attributes, item, this.isHTML); + } + }, + // #text, #comment + oncomment: (data) => { + for (const item of this.stack) { + oncomment(data, item); + } + }, + ontext: (text) => { + for (const item of this.stack) { + ontext(text, item); + } + }, + // + onclosetag: () => { + for (const item of this.stack) { + onclosetag(item, this.isHTML, document => { + this.emit('document', document); + this.stack.length -= 1; + }) + } + } + }, { + lowerCaseAttributeNames: false, + decodeEntities: true, + xmlMode: !this.isHTML + }) + this.parserStream.on('error', err => this.emit('error', err)) + } + + /** + * @param {string|Buffer} chunk + * @param {string} encoding + * @param {() => void} callback + */ + _write(chunk, encoding, callback) { + this.parserStream._write(chunk, encoding, callback); + } + + /** + * @param {() => void} callback + */ + _final(callback) { + this.parserStream._final(callback); + } + + /** + * An alias for `docStream.on('document', doc => {...})` + * @param {(doc: MimeToDoc[MIME]) => void} listener + */ + ondocument (listener) { + this.on('document', listener) + return this + } + + /** + * An alias for `docStream.on('error', err => {...})` + * or `docStream.parserStream.on('error', err => {...})` + * @param {(err: Error) => void} listener + */ + onerror (listener) { + this.on('error', listener) + return this + } +} +exports.DOMStream = DOMStream diff --git a/cjs/index.js b/cjs/index.js index 3960b91a..37e6e31a 100644 --- a/cjs/index.js +++ b/cjs/index.js @@ -1,5 +1,6 @@ 'use strict'; const {DOMParser} = require('./dom/parser.js'); +const {DOMStream} = require('./dom/stream.js'); const {Document: _Document} = require('./interface/document.js'); const {illegalConstructor} = require('./shared/facades.js'); @@ -15,6 +16,7 @@ const {setPrototypeOf} = require('./shared/object.js'); (require('./shared/html-classes.js')); exports.DOMParser = DOMParser; +exports.DOMStream = DOMStream; (m => { exports.CustomEvent = m.CustomEvent; diff --git a/cjs/shared/parse-from-string.js b/cjs/shared/parse-from-string.js index 04eb852c..be24cd57 100644 --- a/cjs/shared/parse-from-string.js +++ b/cjs/shared/parse-from-string.js @@ -1,14 +1,10 @@ 'use strict'; -const HTMLParser2 = require('htmlparser2'); +const {WritableStream} = require('htmlparser2/lib/WritableStream'); -const {ELEMENT_NODE, SVG_NAMESPACE} = require('./constants.js'); -const {CUSTOM_ELEMENTS, PREV, END, VALUE} = require('./symbols.js'); -const {keys} = require('./object.js'); +const { + onprocessinginstruction, onopentag, oncomment, ontext, onclosetag +} = require('../shared/parser-handlers') -const {knownBoundaries, knownSiblings} = require('./utils.js'); -const {attributeChangedCallback, connectedCallback} = require('../interface/custom-element-registry.js'); - -const {Parser} = HTMLParser2; // import {Mime} from './mime.js'; // const VOID_SOURCE = Mime['text/html'].voidElements.source.slice(4, -2); @@ -16,87 +12,55 @@ const {Parser} = HTMLParser2; // const VOID_SANITIZER = (_, $1, $2) => `<${$1}${$2}${/\/$/.test($2) ? '' : ' /'}>`; // const voidSanitizer = html => html.replace(VOID_ELEMENTS, VOID_SANITIZER); -let notParsing = true; - -const append = (self, node, active) => { - const end = self[END]; - node.parentNode = self; - knownBoundaries(end[PREV], node, end); - if (active && node.nodeType === ELEMENT_NODE) - connectedCallback(node); - return node; -}; - -const attribute = (element, end, attribute, value, active) => { - attribute[VALUE] = value; - attribute.ownerElement = element; - knownSiblings(end[PREV], attribute, end); - if (attribute.name === 'class') - element.className = value; - if (active) - attributeChangedCallback(element, attribute.name, null, value); -}; +/** + * @typedef {import('../html/document.js').HTMLDocument} HTMLDocument + * @typedef {import('../svg/document.js').SVGDocument} SVGDocument + * @typedef {import('../xml/document.js').XMLDocument} XMLDocument + */ +let notParsing = true; const isNotParsing = () => notParsing; exports.isNotParsing = isNotParsing; +/** + * @template {HTMLDocument|SVGDocument|XMLDocument} DOC + * @template {string|NodeJS.ReadableStream} INPUT + * @param {DOC} document + * @param {Boolean} isHTML + * @param {INPUT} markupLanguage + * @returns {INPUT extends string ? DOC : Promise} + */ const parseFromString = (document, isHTML, markupLanguage) => { - const {active, registry} = document[CUSTOM_ELEMENTS]; - - let node = document; - let ownerSVGElement = null; - + /** + * @type {{ + * document: DOC + * node: DOC|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} + */ + const item = { document, node: document } notParsing = false; - const content = new Parser({ + const content = new WritableStream({ // onprocessinginstruction(name, data) { - if (name.toLowerCase() === '!doctype') - document.doctype = data.slice(name.length).trim(); + document.doctype = onprocessinginstruction(name, data); }, - // onopentag(name, attributes) { - let create = true; - if (isHTML) { - if (ownerSVGElement) { - node = append(node, document.createElementNS(SVG_NAMESPACE, name), active); - node.ownerSVGElement = ownerSVGElement; - create = false; - } - else if (name === 'svg' || name === 'SVG') { - ownerSVGElement = document.createElementNS(SVG_NAMESPACE, name); - node = append(node, ownerSVGElement, active); - create = false; - } - else if (active) { - const ce = name.includes('-') ? name : (attributes.is || ''); - if (ce && registry.has(ce)) { - const {Class} = registry.get(ce); - node = append(node, new Class, active); - delete attributes.is; - create = false; - } - } - } - - if (create) - node = append(node, document.createElement(name), false); - - let end = node[END]; - for (const name of keys(attributes)) - attribute(node, end, document.createAttribute(name), attributes[name], active); + onopentag(name, attributes, item, isHTML); }, - // #text, #comment - oncomment(data) { append(node, document.createComment(data), active); }, - ontext(text) { append(node, document.createTextNode(text), active); }, - + oncomment(data) { + oncomment(data, item); + }, + ontext(text) { + ontext(text, item); + }, // onclosetag() { - if (isHTML && node === ownerSVGElement) - ownerSVGElement = null; - node = node.parentNode; + onclosetag(item, isHTML) } }, { lowerCaseAttributeNames: false, @@ -104,11 +68,26 @@ const parseFromString = (document, isHTML, markupLanguage) => { xmlMode: !isHTML }); - content.write(markupLanguage); - content.end(); - - notParsing = true; - - return document; + if (typeof markupLanguage === 'string') { + content.write(markupLanguage); + content.end(); + notParsing = true; + return item.document; + } else { + return new Promise((resolve, reject) => { + markupLanguage.pipe(content); + markupLanguage.once('end', () => { + notParsing = true; + resolve(item.document); + }); + const errorCb = err => { + content.end(); + notParsing = true; + reject(err); + } + markupLanguage.once('error', errorCb); + content.once('error', errorCb); + }); + } }; exports.parseFromString = parseFromString; diff --git a/cjs/shared/parser-handlers.js b/cjs/shared/parser-handlers.js new file mode 100644 index 00000000..d067fdd4 --- /dev/null +++ b/cjs/shared/parser-handlers.js @@ -0,0 +1,149 @@ +'use strict'; +const {ELEMENT_NODE, SVG_NAMESPACE} = require('./constants.js'); +const {CUSTOM_ELEMENTS, PREV, END, VALUE} = require('./symbols.js'); +const {keys} = require('./object.js'); + +const {knownBoundaries, knownSiblings} = require('./utils.js'); +const {attributeChangedCallback, connectedCallback} = require('../interface/custom-element-registry.js'); + + +/** + * @typedef {import('../interface/node').Node} Node + * @typedef {import('../svg/element').SVGElement} SVGElement + * @typedef {import('../html/document.js').HTMLDocument} HTMLDocument + * @typedef {import('../svg/document').SVGDocument} SVGDocument + * @typedef {import('../xml/document').XMLDocument} XMLDocument + * @typedef {{ "text/html": HTMLDocument, "image/svg+xml": SVGDocument, "text/xml": XMLDocument }} MimeToDoc + */ + +const append = (self, node, active) => { + const end = self[END]; + node.parentNode = self; + knownBoundaries(end[PREV], node, end); + if (active && node.nodeType === ELEMENT_NODE) + connectedCallback(node); + return node; +}; +exports.append = append; + +const attribute = (element, end, attribute, value, active) => { + attribute[VALUE] = value; + attribute.ownerElement = element; + knownSiblings(end[PREV], attribute, end); + if (attribute.name === 'class') + element.className = value; + if (active) + attributeChangedCallback(element, attribute.name, null, value); +}; +exports.attribute = attribute; + +/** + * @param {string} name + * @param {string} data + */ +const onprocessinginstruction = (name, data) => { + if (name.toLowerCase() === '!doctype') + return data.slice(name.length).trim(); +} +exports.onprocessinginstruction = onprocessinginstruction + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {string} name + * @param {Record} attributes + * @param {StackItem} item + * @param {boolean} isHTML + */ +const onopentag = (name, attributes, item, isHTML) => { + const { document } = item; + const { active, registry } = document[CUSTOM_ELEMENTS]; + let create = true; + if (isHTML) { + if (item.ownerSVGElement) { + item.node = append(item.node, document.createElementNS(SVG_NAMESPACE, name), active); + item.node.ownerSVGElement = item.ownerSVGElement; + create = false; + } else if (name === 'svg' || name === 'SVG') { + item.ownerSVGElement = document.createElementNS(SVG_NAMESPACE, name); + item.node = append(item.node, item.ownerSVGElement, active); + create = false; + } else if (active) { + const ce = name.includes('-') ? name : (attributes.is || ''); + if (ce && registry.has(ce)) { + const {Class} = registry.get(ce); + item.node = append(item.node, new Class, active); + delete attributes.is; + create = false; + } + } + } + if (create) item.node = append(item.node, document.createElement(name), false); + let end = item.node[END]; + for (const name of keys(attributes)) { + attribute(item.node, end, document.createAttribute(name), attributes[name], active); + } + if (!item.rootNode) item.rootNode = item.node; +} +exports.onopentag = onopentag + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {string} data + * @param {StackItem} item + */ +const oncomment = (data, item) => { + const { document, node } = item; + const { active } = document[CUSTOM_ELEMENTS]; + append(node, document.createComment(data), active); +} +exports.oncomment = oncomment + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {string} data + * @param {StackItem} item + */ +const ontext = (text, item) => { + const { document, node } = item; + const { active } = document[CUSTOM_ELEMENTS]; + append(node, document.createTextNode(text), active); +} +exports.ontext = ontext + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {StackItem} item + * @param {boolean} isHTML + * @param {((document: MimeToDoc[keyof MimeToDoc]) => void)|undefined} cb + */ +const onclosetag = (item, isHTML, cb) => { + const { document } = item + if (isHTML && item.node === item.ownerSVGElement) { + item.ownerSVGElement = undefined; + } + if (item.node === item.rootNode) { + cb && cb(document); + } + item.node = item.node.parentNode; +} +exports.onclosetag = onclosetag diff --git a/esm/dom/parser.js b/esm/dom/parser.js index 1ca423d0..5d060639 100644 --- a/esm/dom/parser.js +++ b/esm/dom/parser.js @@ -12,10 +12,11 @@ export class DOMParser { /** @typedef {{ "text/html": HTMLDocument, "image/svg+xml": SVGDocument, "text/xml": XMLDocument }} MimeToDoc */ /** + * @template {string|NodeJS.ReadableStream} INPUT * @template {keyof MimeToDoc} MIME - * @param {string} markupLanguage + * @param {INPUT} markupLanguage * @param {MIME} mimeType - * @returns {MimeToDoc[MIME]} + * @returns {INPUT extends string ? MimeToDoc[MIME] : Promise} */ parseFromString(markupLanguage, mimeType, globals = null) { let isHTML = false, document; diff --git a/esm/dom/stream.js b/esm/dom/stream.js new file mode 100644 index 00000000..5e30a7e3 --- /dev/null +++ b/esm/dom/stream.js @@ -0,0 +1,133 @@ +import {Writable} from 'stream'; +import {WritableStream} from 'htmlparser2/lib/WritableStream'; + +import { + onprocessinginstruction, onopentag, oncomment, ontext, onclosetag +} from '../shared/parser-handlers' + +import {HTMLDocument} from '../html/document.js'; +import {SVGDocument} from '../svg/document.js'; +import {XMLDocument} from '../xml/document.js'; + + +/** + * @typedef {import('../interface/node').Node} Node + * @typedef {import('../svg/element').SVGElement} SVGElement + * @typedef {{ "text/html": HTMLDocument, "image/svg+xml": SVGDocument, "text/xml": XMLDocument }} MimeToDoc + */ + +/** + * @template {keyof MimeToDoc} MIME + * @extends {Writable} + */ +export class DOMStream extends Writable { + /** + * @param {MIME} mimeType + * @param {(name: string, attributes: Record) => boolean} filter + */ + constructor (mimeType, filter) { + super(); + this.mimeType = mimeType; + if (mimeType === 'text/html') this.isHTML = true; + this.filter = filter; + /** + * @type {{ + * document: MimeToDoc[MIME] + * node: MimeToDoc[MIME]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }[]} + */ + this.stack = []; // LIFO + this.init(); + } + + newDocument () { + let document; + if (this.mimeType === 'text/html') { + document = new HTMLDocument(); + } else if (this.mimeType === 'image/svg+xml') { + document = new SVGDocument(); + } else { + document = new XMLDocument(); + } + if (this.doctype) document.doctype = this.doctype; + this.stack.push({ document, node: document }); + } + + init () { + this.parserStream = new WritableStream({ + // + onprocessinginstruction: (name, data) => { + this.doctype = onprocessinginstruction(name, data); + }, + // + onopentag: (name, attributes) => { + if (this.filter(name, attributes)) this.newDocument(); + for (const item of this.stack) { + onopentag(name, attributes, item, this.isHTML); + } + }, + // #text, #comment + oncomment: (data) => { + for (const item of this.stack) { + oncomment(data, item); + } + }, + ontext: (text) => { + for (const item of this.stack) { + ontext(text, item); + } + }, + // + onclosetag: () => { + for (const item of this.stack) { + onclosetag(item, this.isHTML, document => { + this.emit('document', document); + this.stack.length -= 1; + }) + } + } + }, { + lowerCaseAttributeNames: false, + decodeEntities: true, + xmlMode: !this.isHTML + }) + this.parserStream.on('error', err => this.emit('error', err)) + } + + /** + * @param {string|Buffer} chunk + * @param {string} encoding + * @param {() => void} callback + */ + _write(chunk, encoding, callback) { + this.parserStream._write(chunk, encoding, callback); + } + + /** + * @param {() => void} callback + */ + _final(callback) { + this.parserStream._final(callback); + } + + /** + * An alias for `docStream.on('document', doc => {...})` + * @param {(doc: MimeToDoc[MIME]) => void} listener + */ + ondocument (listener) { + this.on('document', listener) + return this + } + + /** + * An alias for `docStream.on('error', err => {...})` + * or `docStream.parserStream.on('error', err => {...})` + * @param {(err: Error) => void} listener + */ + onerror (listener) { + this.on('error', listener) + return this + } +} diff --git a/esm/index.js b/esm/index.js index 9a34dc75..d420b45d 100644 --- a/esm/index.js +++ b/esm/index.js @@ -1,4 +1,5 @@ import {DOMParser} from './dom/parser.js'; +import {DOMStream} from './dom/stream.js'; import {Document as _Document} from './interface/document.js'; import {illegalConstructor} from './shared/facades.js'; @@ -9,6 +10,7 @@ export * from './shared/facades.js'; export * from './shared/html-classes.js'; export {DOMParser}; +export {DOMStream}; export {CustomEvent} from './interface/custom-event.js'; export {Event} from './interface/event.js'; diff --git a/esm/shared/parse-from-string.js b/esm/shared/parse-from-string.js index edc901d4..b5d51cc1 100644 --- a/esm/shared/parse-from-string.js +++ b/esm/shared/parse-from-string.js @@ -1,13 +1,9 @@ -import * as HTMLParser2 from 'htmlparser2'; +import {WritableStream} from 'htmlparser2/lib/WritableStream'; -import {ELEMENT_NODE, SVG_NAMESPACE} from './constants.js'; -import {CUSTOM_ELEMENTS, PREV, END, VALUE} from './symbols.js'; -import {keys} from './object.js'; +import { + onprocessinginstruction, onopentag, oncomment, ontext, onclosetag +} from '../shared/parser-handlers' -import {knownBoundaries, knownSiblings} from './utils.js'; -import {attributeChangedCallback, connectedCallback} from '../interface/custom-element-registry.js'; - -const {Parser} = HTMLParser2; // import {Mime} from './mime.js'; // const VOID_SOURCE = Mime['text/html'].voidElements.source.slice(4, -2); @@ -15,86 +11,54 @@ const {Parser} = HTMLParser2; // const VOID_SANITIZER = (_, $1, $2) => `<${$1}${$2}${/\/$/.test($2) ? '' : ' /'}>`; // const voidSanitizer = html => html.replace(VOID_ELEMENTS, VOID_SANITIZER); -let notParsing = true; - -const append = (self, node, active) => { - const end = self[END]; - node.parentNode = self; - knownBoundaries(end[PREV], node, end); - if (active && node.nodeType === ELEMENT_NODE) - connectedCallback(node); - return node; -}; - -const attribute = (element, end, attribute, value, active) => { - attribute[VALUE] = value; - attribute.ownerElement = element; - knownSiblings(end[PREV], attribute, end); - if (attribute.name === 'class') - element.className = value; - if (active) - attributeChangedCallback(element, attribute.name, null, value); -}; +/** + * @typedef {import('../html/document.js').HTMLDocument} HTMLDocument + * @typedef {import('../svg/document.js').SVGDocument} SVGDocument + * @typedef {import('../xml/document.js').XMLDocument} XMLDocument + */ +let notParsing = true; export const isNotParsing = () => notParsing; +/** + * @template {HTMLDocument|SVGDocument|XMLDocument} DOC + * @template {string|NodeJS.ReadableStream} INPUT + * @param {DOC} document + * @param {Boolean} isHTML + * @param {INPUT} markupLanguage + * @returns {INPUT extends string ? DOC : Promise} + */ export const parseFromString = (document, isHTML, markupLanguage) => { - const {active, registry} = document[CUSTOM_ELEMENTS]; - - let node = document; - let ownerSVGElement = null; - + /** + * @type {{ + * document: DOC + * node: DOC|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} + */ + const item = { document, node: document } notParsing = false; - const content = new Parser({ + const content = new WritableStream({ // onprocessinginstruction(name, data) { - if (name.toLowerCase() === '!doctype') - document.doctype = data.slice(name.length).trim(); + document.doctype = onprocessinginstruction(name, data); }, - // onopentag(name, attributes) { - let create = true; - if (isHTML) { - if (ownerSVGElement) { - node = append(node, document.createElementNS(SVG_NAMESPACE, name), active); - node.ownerSVGElement = ownerSVGElement; - create = false; - } - else if (name === 'svg' || name === 'SVG') { - ownerSVGElement = document.createElementNS(SVG_NAMESPACE, name); - node = append(node, ownerSVGElement, active); - create = false; - } - else if (active) { - const ce = name.includes('-') ? name : (attributes.is || ''); - if (ce && registry.has(ce)) { - const {Class} = registry.get(ce); - node = append(node, new Class, active); - delete attributes.is; - create = false; - } - } - } - - if (create) - node = append(node, document.createElement(name), false); - - let end = node[END]; - for (const name of keys(attributes)) - attribute(node, end, document.createAttribute(name), attributes[name], active); + onopentag(name, attributes, item, isHTML); }, - // #text, #comment - oncomment(data) { append(node, document.createComment(data), active); }, - ontext(text) { append(node, document.createTextNode(text), active); }, - + oncomment(data) { + oncomment(data, item); + }, + ontext(text) { + ontext(text, item); + }, // onclosetag() { - if (isHTML && node === ownerSVGElement) - ownerSVGElement = null; - node = node.parentNode; + onclosetag(item, isHTML) } }, { lowerCaseAttributeNames: false, @@ -102,10 +66,25 @@ export const parseFromString = (document, isHTML, markupLanguage) => { xmlMode: !isHTML }); - content.write(markupLanguage); - content.end(); - - notParsing = true; - - return document; + if (typeof markupLanguage === 'string') { + content.write(markupLanguage); + content.end(); + notParsing = true; + return item.document; + } else { + return new Promise((resolve, reject) => { + markupLanguage.pipe(content); + markupLanguage.once('end', () => { + notParsing = true; + resolve(item.document); + }); + const errorCb = err => { + content.end(); + notParsing = true; + reject(err); + } + markupLanguage.once('error', errorCb); + content.once('error', errorCb); + }); + } }; diff --git a/esm/shared/parser-handlers.js b/esm/shared/parser-handlers.js new file mode 100644 index 00000000..462239c3 --- /dev/null +++ b/esm/shared/parser-handlers.js @@ -0,0 +1,141 @@ +import {ELEMENT_NODE, SVG_NAMESPACE} from './constants.js'; +import {CUSTOM_ELEMENTS, PREV, END, VALUE} from './symbols.js'; +import {keys} from './object.js'; + +import {knownBoundaries, knownSiblings} from './utils.js'; +import {attributeChangedCallback, connectedCallback} from '../interface/custom-element-registry.js'; + + +/** + * @typedef {import('../interface/node').Node} Node + * @typedef {import('../svg/element').SVGElement} SVGElement + * @typedef {import('../html/document.js').HTMLDocument} HTMLDocument + * @typedef {import('../svg/document').SVGDocument} SVGDocument + * @typedef {import('../xml/document').XMLDocument} XMLDocument + * @typedef {{ "text/html": HTMLDocument, "image/svg+xml": SVGDocument, "text/xml": XMLDocument }} MimeToDoc + */ + +export const append = (self, node, active) => { + const end = self[END]; + node.parentNode = self; + knownBoundaries(end[PREV], node, end); + if (active && node.nodeType === ELEMENT_NODE) + connectedCallback(node); + return node; +}; + +export const attribute = (element, end, attribute, value, active) => { + attribute[VALUE] = value; + attribute.ownerElement = element; + knownSiblings(end[PREV], attribute, end); + if (attribute.name === 'class') + element.className = value; + if (active) + attributeChangedCallback(element, attribute.name, null, value); +}; + +/** + * @param {string} name + * @param {string} data + */ +export const onprocessinginstruction = (name, data) => { + if (name.toLowerCase() === '!doctype') + return data.slice(name.length).trim(); +} + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {string} name + * @param {Record} attributes + * @param {StackItem} item + * @param {boolean} isHTML + */ +export const onopentag = (name, attributes, item, isHTML) => { + const { document } = item; + const { active, registry } = document[CUSTOM_ELEMENTS]; + let create = true; + if (isHTML) { + if (item.ownerSVGElement) { + item.node = append(item.node, document.createElementNS(SVG_NAMESPACE, name), active); + item.node.ownerSVGElement = item.ownerSVGElement; + create = false; + } else if (name === 'svg' || name === 'SVG') { + item.ownerSVGElement = document.createElementNS(SVG_NAMESPACE, name); + item.node = append(item.node, item.ownerSVGElement, active); + create = false; + } else if (active) { + const ce = name.includes('-') ? name : (attributes.is || ''); + if (ce && registry.has(ce)) { + const {Class} = registry.get(ce); + item.node = append(item.node, new Class, active); + delete attributes.is; + create = false; + } + } + } + if (create) item.node = append(item.node, document.createElement(name), false); + let end = item.node[END]; + for (const name of keys(attributes)) { + attribute(item.node, end, document.createAttribute(name), attributes[name], active); + } + if (!item.rootNode) item.rootNode = item.node; +} + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {string} data + * @param {StackItem} item + */ +export const oncomment = (data, item) => { + const { document, node } = item; + const { active } = document[CUSTOM_ELEMENTS]; + append(node, document.createComment(data), active); +} + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {string} data + * @param {StackItem} item + */ +export const ontext = (text, item) => { + const { document, node } = item; + const { active } = document[CUSTOM_ELEMENTS]; + append(node, document.createTextNode(text), active); +} + +/** + * @template {{ + * document: MimeToDoc[keyof MimeToDoc] + * node: MimeToDoc[keyof MimeToDoc]|Node + * ownerSVGElement: SVGElement|undefined + * rootNode: Node|undefined + * }} StackItem + * @param {StackItem} item + * @param {boolean} isHTML + * @param {((document: MimeToDoc[keyof MimeToDoc]) => void)|undefined} cb + */ +export const onclosetag = (item, isHTML, cb) => { + const { document } = item + if (isHTML && item.node === item.ownerSVGElement) { + item.ownerSVGElement = undefined; + } + if (item.node === item.rootNode) { + cb && cb(document); + } + item.node = item.node.parentNode; +} diff --git a/package-lock.json b/package-lock.json index 8e5a182c..a49db696 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,11 +19,20 @@ "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.3.0", + "@types/node": "^18.11.0", "ascjs": "^5.0.1", + "basichtml": "^2.4.9", "c8": "^7.11.2", "eslint": "^8.15.0", + "jsdom": "^20.0.1", + "jsdon": "^0.1.15", "rollup": "^2.72.0", + "rollup-plugin-polyfill-node": "^0.11.0", "typescript": "4.5" + }, + "optionalDependencies": { + "basichtml": "^2.4.9", + "jsdon": "^0.1.15" } }, "node_modules/@babel/parser": { @@ -139,6 +148,68 @@ "rollup": "^2.68.0" } }, + "node_modules/@rollup/plugin-inject": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.2.tgz", + "integrity": "sha512-zRthPC/sZ2OaQwPh2LvFn0A+3SyMAZR1Vqsp89mWkIuGXKswT8ty1JWj1pf7xdZvft4gHZaCuhdopuiCwjclWg==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.26.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-inject/node_modules/@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-inject/node_modules/@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, + "node_modules/@rollup/plugin-inject/node_modules/magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@rollup/plugin-json": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", @@ -194,6 +265,15 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -207,9 +287,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "17.0.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.31.tgz", - "integrity": "sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q==", + "version": "18.11.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz", + "integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==", "dev": true }, "node_modules/@types/resolve": { @@ -221,10 +301,22 @@ "@types/node": "*" } }, + "node_modules/@webreflection/interface": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@webreflection/interface/-/interface-0.1.1.tgz", + "integrity": "sha512-n5t7JLDaLzAPqCWIqC2i+i0RXoxUjXvcpYmTYQ6cR2XyyCL5jTqDh6th21FuZzfi5j+PFvpeYxFPv5b4/vnJzA==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -233,6 +325,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -242,6 +344,27 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -300,12 +423,125 @@ "ascjs": "bin.js" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/basichtml": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/basichtml/-/basichtml-2.4.9.tgz", + "integrity": "sha512-/vz9qpgCBp7sCjlsxisCaMX6KPzy1ncEzyAQjofWiOY9U0y9VXH+EV2iYjaOmIYXXSAcZaugdYKBml2dmkW0vQ==", + "deprecated": "The effort has moved into LinkeDOM module: https://www.npmjs.com/package/linkedom", + "dev": true, + "dependencies": { + "@webreflection/interface": "^0.1.1", + "broadcast": "^3.0.0", + "html-escaper": "^3.0.0", + "htmlparser2": "^4.1.0" + } + }, + "node_modules/basichtml/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/basichtml/node_modules/dom-serializer/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/basichtml/node_modules/domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/basichtml/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/basichtml/node_modules/domutils/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/basichtml/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/basichtml/node_modules/htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -321,6 +557,12 @@ "concat-map": "0.0.1" } }, + "node_modules/broadcast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/broadcast/-/broadcast-3.0.0.tgz", + "integrity": "sha512-q//26zihgUvAtvSBRD1xtk/9KBVNfiUrS8Phz8dN95Y5mqINO/gFT6181b4Yvhoeal3Aa9+rsFnKzA6a6UTHfg==", + "dev": true + }, "node_modules/builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -413,6 +655,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -479,6 +733,38 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -496,6 +782,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==", + "dev": true + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -511,6 +803,15 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -547,6 +848,18 @@ } ] }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", @@ -581,9 +894,9 @@ "dev": true }, "node_modules/entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz", - "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", "engines": { "node": ">=0.12" }, @@ -612,6 +925,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/eslint": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", @@ -727,6 +1113,19 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -853,6 +1252,20 @@ "node": ">=8.0.0" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -962,6 +1375,18 @@ "node": ">=8" } }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/html-escaper": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", @@ -985,6 +1410,45 @@ "entities": "^4.3.0" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -1095,6 +1559,12 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -1164,6 +1634,57 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.0", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.9.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdon": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/jsdon/-/jsdon-0.1.15.tgz", + "integrity": "sha512-3ZrE0EfFIJVgCggM3H81xN7KN8BLWmiYiSSErMKo5w6xJUi0JkdbOQs3lQ8cPBcF01JAIIve7JqXfJHLFbifPg==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1234,6 +1755,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1269,6 +1811,12 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", + "dev": true + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1337,6 +1885,18 @@ "node": ">=6" } }, + "node_modules/parse5": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", + "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1391,6 +1951,12 @@ "node": ">= 0.8.0" } }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -1400,6 +1966,12 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -1421,6 +1993,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -1477,12 +2055,42 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup-plugin-polyfill-node": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.11.0.tgz", + "integrity": "sha512-5t+qhq4LAQKQBgbPOQJEoxxGzU5b+zLfvzpUAGy9u0MCMs8y+mrjUAv8+xrkWdxnwXQwJtjmCMnA9lCflsMzNw==", + "dev": true, + "dependencies": { + "@rollup/plugin-inject": "^5.0.1" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -1519,6 +2127,16 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -1587,6 +2205,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -1607,6 +2231,33 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/tough-cookie": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1649,6 +2300,15 @@ "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.1.0.tgz", "integrity": "sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw==" }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1658,6 +2318,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -1678,6 +2348,61 @@ "node": ">=10.12.0" } }, + "node_modules/w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1725,6 +2450,42 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "node_modules/ws": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -1864,6 +2625,45 @@ "resolve": "^1.17.0" } }, + "@rollup/plugin-inject": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.0.2.tgz", + "integrity": "sha512-zRthPC/sZ2OaQwPh2LvFn0A+3SyMAZR1Vqsp89mWkIuGXKswT8ty1JWj1pf7xdZvft4gHZaCuhdopuiCwjclWg==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^5.0.1", + "estree-walker": "^2.0.2", + "magic-string": "^0.26.4" + }, + "dependencies": { + "@rollup/pluginutils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", + "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", + "dev": true, + "requires": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==", + "dev": true + }, + "magic-string": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz", + "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + } + } + }, "@rollup/plugin-json": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", @@ -1906,6 +2706,12 @@ } } }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -1919,9 +2725,9 @@ "dev": true }, "@types/node": { - "version": "17.0.31", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.31.tgz", - "integrity": "sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q==", + "version": "18.11.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.3.tgz", + "integrity": "sha512-fNjDQzzOsZeKZu5NATgXUPsaFaTxeRgFXoosrHivTl8RGeV733OLawXsGfEk9a8/tySyZUyiZ6E8LcjPFZ2y1A==", "dev": true }, "@types/resolve": { @@ -1933,12 +2739,34 @@ "@types/node": "*" } }, + "@webreflection/interface": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@webreflection/interface/-/interface-0.1.1.tgz", + "integrity": "sha512-n5t7JLDaLzAPqCWIqC2i+i0RXoxUjXvcpYmTYQ6cR2XyyCL5jTqDh6th21FuZzfi5j+PFvpeYxFPv5b4/vnJzA==", + "dev": true + }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true }, + "acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "requires": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -1946,6 +2774,21 @@ "dev": true, "requires": {} }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1988,12 +2831,103 @@ "@babel/parser": "^7.12.5" } }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "basichtml": { + "version": "2.4.9", + "resolved": "https://registry.npmjs.org/basichtml/-/basichtml-2.4.9.tgz", + "integrity": "sha512-/vz9qpgCBp7sCjlsxisCaMX6KPzy1ncEzyAQjofWiOY9U0y9VXH+EV2iYjaOmIYXXSAcZaugdYKBml2dmkW0vQ==", + "dev": true, + "requires": { + "@webreflection/interface": "^0.1.1", + "broadcast": "^3.0.0", + "html-escaper": "^3.0.0", + "htmlparser2": "^4.1.0" + }, + "dependencies": { + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "dependencies": { + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + } + } + }, + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "dependencies": { + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + } + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + } + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -2009,6 +2943,12 @@ "concat-map": "0.0.1" } }, + "broadcast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/broadcast/-/broadcast-3.0.0.tgz", + "integrity": "sha512-q//26zihgUvAtvSBRD1xtk/9KBVNfiUrS8Phz8dN95Y5mqINO/gFT6181b4Yvhoeal3Aa9+rsFnKzA6a6UTHfg==", + "dev": true + }, "builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -2077,6 +3017,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2131,6 +3080,34 @@ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==" }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2140,6 +3117,12 @@ "ms": "2.1.2" } }, + "decimal.js": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", + "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==", + "dev": true + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2152,6 +3135,12 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2176,6 +3165,15 @@ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, "domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", @@ -2201,9 +3199,9 @@ "dev": true }, "entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz", - "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" }, "escalade": { "version": "3.1.1", @@ -2217,6 +3215,60 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, "eslint": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", @@ -2304,6 +3356,12 @@ "eslint-visitor-keys": "^3.3.0" } }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", @@ -2403,6 +3461,17 @@ "signal-exit": "^3.0.2" } }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2481,6 +3550,15 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, "html-escaper": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", @@ -2497,6 +3575,36 @@ "entities": "^4.3.0" } }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -2580,6 +3688,12 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -2639,6 +3753,46 @@ "argparse": "^2.0.1" } }, + "jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.0", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.1", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^3.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.9.0", + "xml-name-validator": "^4.0.0" + } + }, + "jsdon": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/jsdon/-/jsdon-0.1.15.tgz", + "integrity": "sha512-3ZrE0EfFIJVgCggM3H81xN7KN8BLWmiYiSSErMKo5w6xJUi0JkdbOQs3lQ8cPBcF01JAIIve7JqXfJHLFbifPg==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2694,6 +3848,21 @@ "semver": "^6.0.0" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2723,6 +3892,12 @@ "boolbase": "^1.0.0" } }, + "nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2773,6 +3948,15 @@ "callsites": "^3.0.0" } }, + "parse5": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", + "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", + "dev": true, + "requires": { + "entities": "^4.4.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2809,12 +3993,24 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -2827,6 +4023,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "resolve": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", @@ -2862,12 +4064,36 @@ "fsevents": "~2.3.2" } }, + "rollup-plugin-polyfill-node": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.11.0.tgz", + "integrity": "sha512-5t+qhq4LAQKQBgbPOQJEoxxGzU5b+zLfvzpUAGy9u0MCMs8y+mrjUAv8+xrkWdxnwXQwJtjmCMnA9lCflsMzNw==", + "dev": true, + "requires": { + "@rollup/plugin-inject": "^5.0.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2895,6 +4121,13 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, "sourcemap-codec": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", @@ -2942,6 +4175,12 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -2959,6 +4198,27 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "tough-cookie": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2985,6 +4245,12 @@ "resolved": "https://registry.npmjs.org/uhyphen/-/uhyphen-0.1.0.tgz", "integrity": "sha512-o0QVGuFg24FK765Qdd5kk0zU/U4dEsCtN/GSiwNI9i8xsSVtjIAOdTaVhLwZ1nrbWxFVMxNDDl+9fednsOMsBw==" }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2994,6 +4260,16 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -3011,6 +4287,46 @@ "convert-source-map": "^1.6.0" } }, + "w3c-xmlserializer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", + "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dev": true, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3043,6 +4359,25 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "ws": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==", + "dev": true, + "requires": {} + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index e94722e4..c2f2016a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.14.19", "description": "A triple-linked lists based DOM implementation", "main": "./cjs/index.js", - "types": "./types/index.d.ts", + "types": "./types/esm/index.d.ts", "scripts": { "benchmark": "node test/benchmark/linkedom.js", "benchmark:w3c": "node test/benchmark/linkedom.js --w3c; node test/benchmark/linkedom-cached.js --w3c; node test/benchmark/jsdom.js --w3c; node test/benchmark/basichtml.js --w3c", @@ -11,14 +11,17 @@ "benchmark:dom": "node test/benchmark/linkedom.js --dom; node test/benchmark/linkedom-cached.js --dom; node test/benchmark/jsdom.js --dom; node test/benchmark/basichtml.js --dom", "benchmark:dom:ce": "node test/benchmark/linkedom.js --dom --custom-elements; node test/benchmark/linkedom-cached.js --dom --custom-elements; node test/benchmark/jsdom.js --dom --custom-elements; node test/benchmark/basichtml.js --dom --custom-elements", "benchmark:html": "node test/benchmark/jsdon.js --html; node test/benchmark/linkedom.js --html; node test/benchmark/linkedom-cached.js --html; #node test/benchmark/jsdom.js --html", + "benchmark:html:st": "node test/benchmark/linkedom.js --html; node test/benchmark/linkedom.js --html --html-as-stream", "benchmark:html:ce": "node test/benchmark/linkedom.js --html --custom-elements; node test/benchmark/linkedom-cached.js --html --custom-elements; #node test/benchmark/jsdom.js --html --custom-elements", "benchmark:html:mo": "node test/benchmark/linkedom.js --html --mutation-observer --custom-elements; node test/benchmark/linkedom-cached.js --html --mutation-observer --custom-elements", "benchmark:html:nc": "node test/benchmark/linkedom.js --html --no-clone; node test/benchmark/linkedom-cached.js --html --no-clone; #node test/benchmark/jsdom.js --html --no-clone", + "domstream": "node test/benchmark/domstream.js", "build": "npm run tsc && npm run cjs && rollup -c rollup/es.config.js && npm run test", "cjs": "ascjs --no-default esm cjs", "tsc": "tsc -p .", "hello": "if [[ \"$(node --version)\" =~ ^v1[^2] ]]; then node --input-type=module -e \"import {DOMParser} from './esm/index.js';console.log('\\x1b[7m\\x1b[1m',(new DOMParser).parseFromString('LinkeDOM','text/html').querySelectorAll('html')[0].firstChild.toString(),'\\x1b[0m')\"; fi", - "test": "eslint esm/ && npm run hello && node test/benchmark/linkedom.js --w3c --mutation-observer --custom-elements && c8 node test/index.js && c8 report -r html", + "test": "eslint esm/ && npm run hello && node test/benchmark/linkedom.js --w3c --mutation-observer --custom-elements && node test/benchmark/linkedom.js --w3c --mutation-observer --custom-elements --html-as-stream && node test/benchmark/domstream.js --silent && npm run c8", + "c8": "c8 node test/index.js && c8 report -r html", "coverage": "mkdir -p ./coverage; c8 report --reporter=text-lcov > ./coverage/lcov.info" }, "keywords": [ @@ -34,10 +37,15 @@ "@rollup/plugin-commonjs": "^22.0.0", "@rollup/plugin-json": "^4.1.0", "@rollup/plugin-node-resolve": "^13.3.0", + "@types/node": "^18.11.0", "ascjs": "^5.0.1", + "basichtml": "^2.4.9", "c8": "^7.11.2", "eslint": "^8.15.0", + "jsdom": "^20.0.1", + "jsdon": "^0.1.15", "rollup": "^2.72.0", + "rollup-plugin-polyfill-node": "^0.11.0", "typescript": "4.5" }, "module": "./esm/index.js", @@ -69,5 +77,9 @@ "bugs": { "url": "https://github.com/WebReflection/linkedom/issues" }, - "homepage": "https://github.com/WebReflection/linkedom#readme" + "homepage": "https://github.com/WebReflection/linkedom#readme", + "optionalDependencies": { + "basichtml": "^2.4.9", + "jsdon": "^0.1.15" + } } diff --git a/rollup/es.config.js b/rollup/es.config.js index a8fa09b3..7d6e7a92 100644 --- a/rollup/es.config.js +++ b/rollup/es.config.js @@ -1,4 +1,5 @@ import {nodeResolve} from '@rollup/plugin-node-resolve'; +import nodePolyfills from 'rollup-plugin-polyfill-node'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; @@ -6,6 +7,7 @@ export default { input: './esm/index.js', plugins: [ shims(), + nodePolyfills(), nodeResolve(), commonjs(), json() diff --git a/test/benchmark/content.js b/test/benchmark/content.js index ba482205..ea65acf4 100644 --- a/test/benchmark/content.js +++ b/test/benchmark/content.js @@ -15,6 +15,7 @@ const bench = (name, count, times) => { return total; }; +// eslint-disable-next-line no-control-regex const clean = str => browser ? str.replace(/\x1b\[\dm/g, '') : str; const crawl = (element, kind) => { @@ -28,7 +29,15 @@ const crawl = (element, kind) => { const sleep = ms => new Promise($ => setTimeout($, ms)); -const onContent = async (createDocument, html, times, logHeap = () => {}, cloneBench = true, customElements = false, mutationObserver = false) => { +const onContent = async ({ + createDocument, + html, + times, + logHeap = () => {}, + cloneBench = true, + customElements = false, + mutationObserver = false +}) => { console.time(clean('\x1b[1mtotal benchmark time\x1b[0m')); @@ -38,7 +47,7 @@ const onContent = async (createDocument, html, times, logHeap = () => {}, cloneB let document; try { console.time(clean(' parsing \x1b[2mcold\x1b[0m')); - document = createDocument(html.toString()); + document = await createDocument(html); console.timeEnd(clean(' parsing \x1b[2mcold\x1b[0m')); console.log(); logHeap('document heap'); @@ -221,6 +230,7 @@ const onContent = async (createDocument, html, times, logHeap = () => {}, cloneB if (cloneBench) { await sleep(100); console.time(' html.innerHTML'); + // eslint-disable-next-line no-self-assign document.documentElement.innerHTML = document.documentElement.innerHTML; console.timeEnd(' html.innerHTML'); } diff --git a/test/benchmark/domstream.js b/test/benchmark/domstream.js new file mode 100644 index 00000000..3ee0efcc --- /dev/null +++ b/test/benchmark/domstream.js @@ -0,0 +1,46 @@ +const fs = require('fs'); +const {join} = require('path'); +const {memoryUsage} = require('process'); +const {DOMStream} = require('../../cjs/index.js'); + +let silent = process.argv.some(arg => arg === '--silent'); + +let length = 0; + +const logStatus = (message = 'total heap memory') => { + const used = memoryUsage().heapUsed / 1024 / 1024; + const processed = length / 1024 / 1024; + console.log( + `\x1b[1m${message}:\x1b[0m ${Math.round(used * 100) / 100} MB`, + `\x1b[1mtotal processed:\x1b[0m ${Math.round(processed * 100) / 100} MB` + ); +} + +console.log(''); +console.log(`\x1b[7m\x1b[1m DOMStream \x1b[0m\x1b[7m\x1b[2m benchmark for \x1b[0m\x1b[7m ./html/html\x1b[0m`); +console.log(''); + +logStatus('initial heap'); + +const domStream = new DOMStream('text/html', (name) => { + return name === 'span'; +}); + +const src = fs.createReadStream(join(__dirname, './html.html')); +src.on('data', chunk => { + length += chunk.length; + logStatus(); +}); + +console.time(' parsing \x1b[2mcold\x1b[0m'); +src.on('end', () => { + console.timeEnd(' parsing \x1b[2mcold\x1b[0m'); + console.log(); + logStatus('end heap'); +}) + +src.pipe(domStream).ondocument(doc => { + const html = doc.documentElement.outerHTML + if (!silent) console.log(html); + if (!silent) logStatus('doc heap'); +}); diff --git a/test/benchmark/html.html b/test/benchmark/html.html index a89f67d3..2c6b4099 100644 --- a/test/benchmark/html.html +++ b/test/benchmark/html.html @@ -17,7 +17,7 @@