6001 lines
210 KiB
JavaScript
6001 lines
210 KiB
JavaScript
import { walkTree } from "markmap-common";
|
||
const defaultOpts$1 = {
|
||
_useHtmlParser2: false
|
||
};
|
||
function flattenOptions(options, baseOptions) {
|
||
if (!options) {
|
||
return baseOptions !== null && baseOptions !== void 0 ? baseOptions : defaultOpts$1;
|
||
}
|
||
const opts = {
|
||
_useHtmlParser2: !!options.xmlMode,
|
||
...baseOptions,
|
||
...options
|
||
};
|
||
if (options.xml) {
|
||
opts._useHtmlParser2 = true;
|
||
opts.xmlMode = true;
|
||
if (options.xml !== true) {
|
||
Object.assign(opts, options.xml);
|
||
}
|
||
} else if (options.xmlMode) {
|
||
opts._useHtmlParser2 = true;
|
||
}
|
||
return opts;
|
||
}
|
||
var ElementType;
|
||
(function(ElementType2) {
|
||
ElementType2["Root"] = "root";
|
||
ElementType2["Text"] = "text";
|
||
ElementType2["Directive"] = "directive";
|
||
ElementType2["Comment"] = "comment";
|
||
ElementType2["Script"] = "script";
|
||
ElementType2["Style"] = "style";
|
||
ElementType2["Tag"] = "tag";
|
||
ElementType2["CDATA"] = "cdata";
|
||
ElementType2["Doctype"] = "doctype";
|
||
})(ElementType || (ElementType = {}));
|
||
function isTag$1(elem) {
|
||
return elem.type === ElementType.Tag || elem.type === ElementType.Script || elem.type === ElementType.Style;
|
||
}
|
||
const Root = ElementType.Root;
|
||
const Text$1 = ElementType.Text;
|
||
const Directive = ElementType.Directive;
|
||
const Comment$1 = ElementType.Comment;
|
||
const Script = ElementType.Script;
|
||
const Style = ElementType.Style;
|
||
const Tag = ElementType.Tag;
|
||
const CDATA$1 = ElementType.CDATA;
|
||
const Doctype = ElementType.Doctype;
|
||
class Node {
|
||
constructor() {
|
||
this.parent = null;
|
||
this.prev = null;
|
||
this.next = null;
|
||
this.startIndex = null;
|
||
this.endIndex = null;
|
||
}
|
||
// Read-write aliases for properties
|
||
/**
|
||
* Same as {@link parent}.
|
||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||
*/
|
||
get parentNode() {
|
||
return this.parent;
|
||
}
|
||
set parentNode(parent2) {
|
||
this.parent = parent2;
|
||
}
|
||
/**
|
||
* Same as {@link prev}.
|
||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||
*/
|
||
get previousSibling() {
|
||
return this.prev;
|
||
}
|
||
set previousSibling(prev2) {
|
||
this.prev = prev2;
|
||
}
|
||
/**
|
||
* Same as {@link next}.
|
||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||
*/
|
||
get nextSibling() {
|
||
return this.next;
|
||
}
|
||
set nextSibling(next2) {
|
||
this.next = next2;
|
||
}
|
||
/**
|
||
* Clone this node, and optionally its children.
|
||
*
|
||
* @param recursive Clone child nodes as well.
|
||
* @returns A clone of the node.
|
||
*/
|
||
cloneNode(recursive = false) {
|
||
return cloneNode(this, recursive);
|
||
}
|
||
}
|
||
class DataNode extends Node {
|
||
/**
|
||
* @param data The content of the data node
|
||
*/
|
||
constructor(data2) {
|
||
super();
|
||
this.data = data2;
|
||
}
|
||
/**
|
||
* Same as {@link data}.
|
||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||
*/
|
||
get nodeValue() {
|
||
return this.data;
|
||
}
|
||
set nodeValue(data2) {
|
||
this.data = data2;
|
||
}
|
||
}
|
||
class Text extends DataNode {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.type = ElementType.Text;
|
||
}
|
||
get nodeType() {
|
||
return 3;
|
||
}
|
||
}
|
||
class Comment extends DataNode {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.type = ElementType.Comment;
|
||
}
|
||
get nodeType() {
|
||
return 8;
|
||
}
|
||
}
|
||
class ProcessingInstruction extends DataNode {
|
||
constructor(name, data2) {
|
||
super(data2);
|
||
this.name = name;
|
||
this.type = ElementType.Directive;
|
||
}
|
||
get nodeType() {
|
||
return 1;
|
||
}
|
||
}
|
||
class NodeWithChildren extends Node {
|
||
/**
|
||
* @param children Children of the node. Only certain node types can have children.
|
||
*/
|
||
constructor(children2) {
|
||
super();
|
||
this.children = children2;
|
||
}
|
||
// Aliases
|
||
/** First child of the node. */
|
||
get firstChild() {
|
||
var _a2;
|
||
return (_a2 = this.children[0]) !== null && _a2 !== void 0 ? _a2 : null;
|
||
}
|
||
/** Last child of the node. */
|
||
get lastChild() {
|
||
return this.children.length > 0 ? this.children[this.children.length - 1] : null;
|
||
}
|
||
/**
|
||
* Same as {@link children}.
|
||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||
*/
|
||
get childNodes() {
|
||
return this.children;
|
||
}
|
||
set childNodes(children2) {
|
||
this.children = children2;
|
||
}
|
||
}
|
||
class CDATA extends NodeWithChildren {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.type = ElementType.CDATA;
|
||
}
|
||
get nodeType() {
|
||
return 4;
|
||
}
|
||
}
|
||
class Document extends NodeWithChildren {
|
||
constructor() {
|
||
super(...arguments);
|
||
this.type = ElementType.Root;
|
||
}
|
||
get nodeType() {
|
||
return 9;
|
||
}
|
||
}
|
||
class Element extends NodeWithChildren {
|
||
/**
|
||
* @param name Name of the tag, eg. `div`, `span`.
|
||
* @param attribs Object mapping attribute names to attribute values.
|
||
* @param children Children of the node.
|
||
*/
|
||
constructor(name, attribs, children2 = [], type = name === "script" ? ElementType.Script : name === "style" ? ElementType.Style : ElementType.Tag) {
|
||
super(children2);
|
||
this.name = name;
|
||
this.attribs = attribs;
|
||
this.type = type;
|
||
}
|
||
get nodeType() {
|
||
return 1;
|
||
}
|
||
// DOM Level 1 aliases
|
||
/**
|
||
* Same as {@link name}.
|
||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||
*/
|
||
get tagName() {
|
||
return this.name;
|
||
}
|
||
set tagName(name) {
|
||
this.name = name;
|
||
}
|
||
get attributes() {
|
||
return Object.keys(this.attribs).map((name) => {
|
||
var _a2, _b;
|
||
return {
|
||
name,
|
||
value: this.attribs[name],
|
||
namespace: (_a2 = this["x-attribsNamespace"]) === null || _a2 === void 0 ? void 0 : _a2[name],
|
||
prefix: (_b = this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name]
|
||
};
|
||
});
|
||
}
|
||
}
|
||
function isTag(node) {
|
||
return isTag$1(node);
|
||
}
|
||
function isCDATA(node) {
|
||
return node.type === ElementType.CDATA;
|
||
}
|
||
function isText(node) {
|
||
return node.type === ElementType.Text;
|
||
}
|
||
function isComment(node) {
|
||
return node.type === ElementType.Comment;
|
||
}
|
||
function isDirective(node) {
|
||
return node.type === ElementType.Directive;
|
||
}
|
||
function isDocument(node) {
|
||
return node.type === ElementType.Root;
|
||
}
|
||
function hasChildren(node) {
|
||
return Object.prototype.hasOwnProperty.call(node, "children");
|
||
}
|
||
function cloneNode(node, recursive = false) {
|
||
let result;
|
||
if (isText(node)) {
|
||
result = new Text(node.data);
|
||
} else if (isComment(node)) {
|
||
result = new Comment(node.data);
|
||
} else if (isTag(node)) {
|
||
const children2 = recursive ? cloneChildren(node.children) : [];
|
||
const clone2 = new Element(node.name, { ...node.attribs }, children2);
|
||
children2.forEach((child) => child.parent = clone2);
|
||
if (node.namespace != null) {
|
||
clone2.namespace = node.namespace;
|
||
}
|
||
if (node["x-attribsNamespace"]) {
|
||
clone2["x-attribsNamespace"] = { ...node["x-attribsNamespace"] };
|
||
}
|
||
if (node["x-attribsPrefix"]) {
|
||
clone2["x-attribsPrefix"] = { ...node["x-attribsPrefix"] };
|
||
}
|
||
result = clone2;
|
||
} else if (isCDATA(node)) {
|
||
const children2 = recursive ? cloneChildren(node.children) : [];
|
||
const clone2 = new CDATA(children2);
|
||
children2.forEach((child) => child.parent = clone2);
|
||
result = clone2;
|
||
} else if (isDocument(node)) {
|
||
const children2 = recursive ? cloneChildren(node.children) : [];
|
||
const clone2 = new Document(children2);
|
||
children2.forEach((child) => child.parent = clone2);
|
||
if (node["x-mode"]) {
|
||
clone2["x-mode"] = node["x-mode"];
|
||
}
|
||
result = clone2;
|
||
} else if (isDirective(node)) {
|
||
const instruction = new ProcessingInstruction(node.name, node.data);
|
||
if (node["x-name"] != null) {
|
||
instruction["x-name"] = node["x-name"];
|
||
instruction["x-publicId"] = node["x-publicId"];
|
||
instruction["x-systemId"] = node["x-systemId"];
|
||
}
|
||
result = instruction;
|
||
} else {
|
||
throw new Error(`Not implemented yet: ${node.type}`);
|
||
}
|
||
result.startIndex = node.startIndex;
|
||
result.endIndex = node.endIndex;
|
||
if (node.sourceCodeLocation != null) {
|
||
result.sourceCodeLocation = node.sourceCodeLocation;
|
||
}
|
||
return result;
|
||
}
|
||
function cloneChildren(childs) {
|
||
const children2 = childs.map((child) => cloneNode(child, true));
|
||
for (let i = 1; i < children2.length; i++) {
|
||
children2[i].prev = children2[i - 1];
|
||
children2[i - 1].next = children2[i];
|
||
}
|
||
return children2;
|
||
}
|
||
const defaultOpts = {
|
||
withStartIndices: false,
|
||
withEndIndices: false,
|
||
xmlMode: false
|
||
};
|
||
class DomHandler {
|
||
/**
|
||
* @param callback Called once parsing has completed.
|
||
* @param options Settings for the handler.
|
||
* @param elementCB Callback whenever a tag is closed.
|
||
*/
|
||
constructor(callback, options, elementCB) {
|
||
this.dom = [];
|
||
this.root = new Document(this.dom);
|
||
this.done = false;
|
||
this.tagStack = [this.root];
|
||
this.lastNode = null;
|
||
this.parser = null;
|
||
if (typeof options === "function") {
|
||
elementCB = options;
|
||
options = defaultOpts;
|
||
}
|
||
if (typeof callback === "object") {
|
||
options = callback;
|
||
callback = void 0;
|
||
}
|
||
this.callback = callback !== null && callback !== void 0 ? callback : null;
|
||
this.options = options !== null && options !== void 0 ? options : defaultOpts;
|
||
this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;
|
||
}
|
||
onparserinit(parser) {
|
||
this.parser = parser;
|
||
}
|
||
// Resets the handler back to starting state
|
||
onreset() {
|
||
this.dom = [];
|
||
this.root = new Document(this.dom);
|
||
this.done = false;
|
||
this.tagStack = [this.root];
|
||
this.lastNode = null;
|
||
this.parser = null;
|
||
}
|
||
// Signals the handler that parsing is done
|
||
onend() {
|
||
if (this.done)
|
||
return;
|
||
this.done = true;
|
||
this.parser = null;
|
||
this.handleCallback(null);
|
||
}
|
||
onerror(error) {
|
||
this.handleCallback(error);
|
||
}
|
||
onclosetag() {
|
||
this.lastNode = null;
|
||
const elem = this.tagStack.pop();
|
||
if (this.options.withEndIndices) {
|
||
elem.endIndex = this.parser.endIndex;
|
||
}
|
||
if (this.elementCB)
|
||
this.elementCB(elem);
|
||
}
|
||
onopentag(name, attribs) {
|
||
const type = this.options.xmlMode ? ElementType.Tag : void 0;
|
||
const element = new Element(name, attribs, void 0, type);
|
||
this.addNode(element);
|
||
this.tagStack.push(element);
|
||
}
|
||
ontext(data2) {
|
||
const { lastNode } = this;
|
||
if (lastNode && lastNode.type === ElementType.Text) {
|
||
lastNode.data += data2;
|
||
if (this.options.withEndIndices) {
|
||
lastNode.endIndex = this.parser.endIndex;
|
||
}
|
||
} else {
|
||
const node = new Text(data2);
|
||
this.addNode(node);
|
||
this.lastNode = node;
|
||
}
|
||
}
|
||
oncomment(data2) {
|
||
if (this.lastNode && this.lastNode.type === ElementType.Comment) {
|
||
this.lastNode.data += data2;
|
||
return;
|
||
}
|
||
const node = new Comment(data2);
|
||
this.addNode(node);
|
||
this.lastNode = node;
|
||
}
|
||
oncommentend() {
|
||
this.lastNode = null;
|
||
}
|
||
oncdatastart() {
|
||
const text2 = new Text("");
|
||
const node = new CDATA([text2]);
|
||
this.addNode(node);
|
||
text2.parent = node;
|
||
this.lastNode = text2;
|
||
}
|
||
oncdataend() {
|
||
this.lastNode = null;
|
||
}
|
||
onprocessinginstruction(name, data2) {
|
||
const node = new ProcessingInstruction(name, data2);
|
||
this.addNode(node);
|
||
}
|
||
handleCallback(error) {
|
||
if (typeof this.callback === "function") {
|
||
this.callback(error, this.dom);
|
||
} else if (error) {
|
||
throw error;
|
||
}
|
||
}
|
||
addNode(node) {
|
||
const parent2 = this.tagStack[this.tagStack.length - 1];
|
||
const previousSibling = parent2.children[parent2.children.length - 1];
|
||
if (this.options.withStartIndices) {
|
||
node.startIndex = this.parser.startIndex;
|
||
}
|
||
if (this.options.withEndIndices) {
|
||
node.endIndex = this.parser.endIndex;
|
||
}
|
||
parent2.children.push(node);
|
||
if (previousSibling) {
|
||
node.prev = previousSibling;
|
||
previousSibling.next = node;
|
||
}
|
||
node.parent = parent2;
|
||
this.lastNode = null;
|
||
}
|
||
}
|
||
const htmlDecodeTree = new Uint16Array(
|
||
// prettier-ignore
|
||
'ᵁ<Õıʊҝջאٵ۞ޢߖࠏઑඡ༉༦ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲϏϢϸontourIntegraìȹoɴ\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲy;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱còJTabcdfgorstרׯؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ߂ߐĀiyޱrc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣসে্ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४ĀnrࢃgleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpwਖਛgȀLRlr৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼અઋp;椅y;䐜Ādl੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑඞcy;䐊cute;䅃ƀaeyહાron;䅇dil;䅅;䐝ƀgswે૰ativeƀMTV૨ediumSpace;怋hiĀcn૦ëeryThiîtedĀGLଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷreak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪௫ఄ಄ದൡඅ櫬Āoungruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater;EFGLSTஶஷ扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹverseElement;戌ghtTriangleƀ;BEೋೌ拫ar;쀀⧐̸qual;拭ĀquೝഌuareSuĀbp೨setĀ;Eೳ쀀⊏̸qual;拢ersetĀ;Eഃആ쀀⊐̸qual;拣ƀbcpഓതൎsetĀ;Eഛഞ쀀⊂⃒qual;抈ceedsȀ;ESTലള഻െ抁qual;쀀⪰̸lantEqual;拡ilde;쀀≿̸ersetĀ;E൘൛쀀⊃⃒qual;抉ildeȀ;EFT൮൯൵ൿ扁qual;扄ullEqual;扇ilde;扉erticalBar;戤cr;쀀𝒩ilde耻Ñ䃑;䎝܀Eacdfgmoprstuvලෂෛ෧ขภยา฿ไlig;䅒cute耻Ó䃓Āiyීrc耻Ô䃔;䐞blac;䅐r;쀀𝔒rave耻Ò䃒ƀaei෮ෲcr;䅌ga;䎩cron;䎟pf;쀀𝕆enCurlyĀDQฎบoubleQuote;怜uote;怘;橔Āclวฬr;쀀𝒪ash耻Ø䃘iŬืde耻Õ䃕es;樷ml耻Ö䃖erĀBP๋Āar๐๓r;怾acĀek๚;揞et;掴arenthesis;揜ҀacfhilorsງຊຏຒດຝະrtialD;戂y;䐟r;쀀𝔓i;䎦;䎠usMinus;䂱Āipຢອncareplanåڝf;愙Ȁ;eio຺ູ檻cedesȀ;EST່້扺qual;檯lantEqual;扼ilde;找me;怳Ādpuct;戏ortionĀ;aȥl;戝Āci༁༆r;쀀𝒫;䎨ȀUfos༑༖༛༟OT耻"䀢r;쀀𝔔pf;愚cr;쀀𝒬BEacefhiorsu༾གྷཇའཱིྦྷྪྭ႖ႩႴႾarr;椐G耻®䂮ƀcnrཎནབute;䅔g;柫rĀ;tཛྷཝ憠l;椖ƀaeyཧཬཱron;䅘dil;䅖;䐠Ā;vླྀཹ愜erseĀEUྂྙĀlq྇ྎement;戋uilibrium;懋pEquilibrium;楯r»ཹo;䎡ghtЀACDFTUVa࿁ဢဨၛႇϘĀnr࿆࿒gleBracket;柩rowƀ;BL憒ar;懥eftArrow;懄eiling;按oǵ\0စbleBracket;柧nǔည\0နeeVector;楝ectorĀ;Bဝသ懂ar;楕loor;挋Āerိ၃eƀ;AVဵံြ抢rrow;憦ector;楛iangleƀ;BEၐၑၕ抳ar;槐qual;抵pƀDTVၣၮၸownVector;楏eeVector;楜ectorĀ;Bႂႃ憾ar;楔ectorĀ;B႑႒懀ar;楓Āpuႛ႞f;愝ndImplies;楰ightarrow;懛ĀchႹႼr;愛;憱leDelayed;槴ڀHOacfhimoqstuფჱჷჽᄙᄞᅑᅖᅡᅧᆵᆻᆿĀCcჩხHcy;䐩y;䐨FTcy;䐬cute;䅚ʀ;aeiyᄈᄉᄎᄓᄗ檼ron;䅠dil;䅞rc;䅜;䐡r;쀀𝔖ortȀDLRUᄪᄴᄾᅉownArrow»ОeftArrow»࢚ightArrow»pArrow;憑gma;䎣allCircle;战pf;쀀𝕊ɲᅭ\0\0ᅰt;戚areȀ;ISUᅻᅼᆉᆯ斡ntersection;抓uĀbpᆏᆞsetĀ;Eᆗᆘ抏qual;抑ersetĀ;Eᆨᆩ抐qual;抒nion;抔cr;쀀𝒮ar;拆ȀbcmpᇈᇛሉላĀ;sᇍᇎ拐etĀ;Eᇍᇕqual;抆ĀchᇠህeedsȀ;ESTᇭᇮᇴᇿ扻qual;檰lantEqual;扽ilde;承Tháྌ;我ƀ;esሒሓሣ拑rsetĀ;Eሜም抃qual;抇et»ሓրHRSacfhiorsሾቄቕቱቶኟዂወዑORN耻Þ䃞ADE;愢ĀHcቒcy;䐋y;䐦Ābuቚቜ;䀉;䎤ƀaeyብቪቯron;䅤dil;䅢;䐢r;쀀𝔗ĀeiቻDzኀ\0ኇefore;戴a;䎘ĀcnኘkSpace;쀀 Space;怉ldeȀ;EFTካኬኲኼ戼qual;扃ullEqual;扅ilde;扈pf;쀀𝕋ipleDot;惛Āctዖዛr;쀀𝒯rok;䅦ૡዷጎጚጦ\0ጬጱ\0\0\0\0\0ጸጽ፷ᎅ\0ᐄᐊᐐĀcrዻጁute耻Ú䃚rĀ;oጇገ憟cir;楉rǣጓ\0y;䐎ve;䅬Āiyጞጣrc耻Û䃛;䐣blac;䅰r;쀀𝔘rave耻Ù䃙acr;䅪Ādiፁ፩erĀBPፈ፝Āarፍፐr;䁟acĀekፗፙ;揟et;掵arenthesis;揝onĀ;P፰፱拃lus;抎Āgp፻on;䅲f;쀀𝕌ЀADETadps᎕ᎮᎸᏄϨᏒᏗᏳrrowƀ;BDᅐᎠᎤar;椒ownArrow;懅ownArrow;憕quilibrium;楮eeĀ;AᏋᏌ报rrow;憥ownáϳerĀLRᏞᏨeftArrow;憖ightArrow;憗iĀ;lᏹᏺ䏒on;䎥ing;䅮cr;쀀𝒰ilde;䅨ml耻Ü䃜ҀDbcdefosvᐧᐬᐰᐳᐾᒅᒊᒐᒖash;披ar;櫫y;䐒ashĀ;lᐻᐼ抩;櫦Āerᑃᑅ;拁ƀbtyᑌᑐᑺar;怖Ā;iᑏᑕcalȀBLSTᑡᑥᑪᑴar;戣ine;䁼eparator;杘ilde;所ThinSpace;怊r;쀀𝔙pf;쀀𝕍cr;쀀𝒱dash;抪ʀcefosᒧᒬᒱᒶᒼirc;䅴dge;拀r;쀀𝔚pf;쀀𝕎cr;쀀𝒲Ȁfiosᓋᓐᓒᓘr;쀀𝔛;䎞pf;쀀𝕏cr;쀀𝒳ҀAIUacfosuᓱᓵᓹᓽᔄᔏᔔᔚᔠcy;䐯cy;䐇cy;䐮cute耻Ý䃝Āiyᔉᔍrc;䅶;䐫r;쀀𝔜pf;쀀𝕐cr;쀀𝒴ml;䅸ЀHacdefosᔵᔹᔿᕋᕏᕝᕠᕤcy;䐖cute;䅹Āayᕄᕉron;䅽;䐗ot;䅻Dzᕔ\0ᕛoWidtèa;䎖r;愨pf;愤cr;쀀𝒵ᖃᖊᖐ\0ᖰᖶᖿ\0\0\0\0ᗆᗛᗫᙟ᙭\0ᚕ᚛ᚲᚹ\0ᚾcute耻á䃡reve;䄃̀;Ediuyᖜᖝᖡᖣᖨᖭ戾;쀀∾̳;房rc耻â䃢te肻´̆;䐰lig耻æ䃦Ā;r²ᖺ;쀀𝔞rave耻à䃠ĀepᗊᗖĀfpᗏᗔsym;愵èᗓha;䎱ĀapᗟcĀclᗤᗧr;䄁g;樿ɤᗰ\0\0ᘊʀ;adsvᗺᗻᗿᘁᘇ戧nd;橕;橜lope;橘;橚;elmrszᘘᘙᘛᘞᘿᙏᙙ戠;榤e»ᘙsdĀ;aᘥᘦ戡ѡᘰᘲᘴᘶᘸᘺᘼᘾ;榨;榩;榪;榫;榬;榭;榮;榯tĀ;vᙅᙆ戟bĀ;dᙌᙍ抾;榝Āptᙔᙗh;戢»¹arr;捼Āgpᙣᙧon;䄅f;쀀𝕒;Eaeiopᙻᙽᚂᚄᚇᚊ;橰cir;橯;扊d;手s;䀧roxĀ;eᚒñᚃing耻å䃥ƀctyᚡᚦᚨr;쀀𝒶;䀪mpĀ;eᚯñʈilde耻ã䃣ml耻ä䃤Āciᛂᛈoninôɲnt;樑ࠀNabcdefiklnoprsu᛭ᛱᜰᝃᝈ០៦ᠹᡐᜍ᥈ᥰot;櫭ĀcrᛶkȀcepsᜀᜅᜍᜓong;扌psilon;䏶rime;怵imĀ;e戽q;拍Ŷᜢᜦee;抽edĀ;gᜬᜭ挅e»ᜭrkĀ;tbrk;掶Āoyᜁᝁ;䐱quo;怞ʀcmprtᝓᝡᝤᝨausĀ;eĊĉptyv;榰séᜌnoõēƀahwᝯᝳ;䎲;愶een;扬r;쀀𝔟gcostuvwឍឝឳេ៕៛ƀaiuបពរðݠrc;旯p»፱ƀdptឤឨឭot;樀lus;樁imes;樂ɱឹ\0\0ើcup;樆ar;昅riangleĀdu៍្own;施p;斳plus;樄eåᑄåᒭarow;植ƀakoᠦᠵĀcn៲ᠣkƀlst֫᠂ozenge;槫riangleȀ;dlr᠒᠓᠘斴own;斾eft;旂ight;斸k;搣Ʊᠫ\0ᠳƲᠯ\0ᠱ;斒;斑4;斓ck;斈ĀeoᠾᡍĀ;qᡃᡆ쀀=⃥uiv;쀀≡⃥t;挐Ȁptwxᡙᡞᡧᡬf;쀀𝕓Ā;tᏋᡣom»Ꮜtie;拈DHUVbdhmptuvᢅᢖᢪᢻᣗᣛᣬᤅᤊᤐᤡȀLRlrᢎᢐᢒᢔ;敗;敔;敖;敓ʀ;DUduᢡᢢᢤᢦᢨ敐;敦;敩;敤;敧ȀLRlrᢳᢵᢷᢹ;敝;敚;敜;教;HLRhlrᣊᣋᣍᣏᣑᣓᣕ救;敬;散;敠;敫;敢;敟ox;槉ȀLRlrᣤᣦᣨᣪ;敕;敒;攐;攌ʀ;DUduڽ;敥;敨;攬;攴inus;抟lus;択imes;抠ȀLRlrᤙᤛᤝ;敛;敘;攘;攔;HLRhlrᤰᤱᤳᤵᤷ᤻᤹攂;敪;敡;敞;攼;攤;攜Āevģbar耻¦䂦Ȁceioᥑᥖᥚᥠr;쀀𝒷mi;恏mĀ;elƀ;bhᥨᥩᥫ䁜;槅sub;柈ŬᥴlĀ;e怢t»pƀ;Eeįᦅᦇ;檮Ā;qۜۛೡᦧ\0᧨ᨑᨕᨲ\0ᨷᩐ\0\0᪴\0\0᫁\0\0ᬡᬮ᭒\0᯽\0ᰌƀcprᦲute;䄇̀;abcdsᦿᧀᧄ᧕᧙戩nd;橄rcup;橉Āau᧒p;橋p;橇ot;橀;쀀∩︀Āeo᧢᧥t;恁îړȀaeiu᧰᧻ᨁᨅǰ᧵\0᧸s;橍on;䄍dil耻ç䃧rc;䄉psĀ;sᨌᨍ橌m;橐ot;䄋ƀdmnᨛᨠᨦil肻¸ƭptyv;榲t脀¢;eᨭᨮ䂢räƲr;쀀𝔠ƀceiᨽᩀᩍy;䑇ckĀ;mᩇᩈ朓ark»ᩈ;䏇r;Ecefms᩠ᩢᩫ᪤᪪旋;槃ƀ;elᩩᩪᩭ䋆q;扗eɡᩴ\0\0᪈rrowĀlr᩼᪁eft;憺ight;憻ʀRSacd᪒᪔᪖»ཇ;擈st;抛irc;抚ash;抝nint;樐id;櫯cir;槂ubsĀ;u᪻᪼晣it»᪼ˬ᫇\0ᬊonĀ;eᫍᫎ䀺Ā;qÇÆɭ\0\0aĀ;t䀬;䁀ƀ;fl戁îᅠeĀmxent»eóɍǧ\0ᬇĀ;dኻᬂot;橭nôɆƀfryᬐᬔᬗ;쀀𝕔oäɔ脀©;sŕᬝr;愗Āaoᬥᬩrr;憵ss;朗Ācuᬲᬷr;쀀𝒸Ābpᬼ᭄Ā;eᭁᭂ櫏;櫑Ā;eᭉᭊ櫐;櫒dot;拯delprvw᭠᭬᭷ᮂᮬᯔarrĀlr᭨᭪;椸;椵ɰ᭲\0\0᭵r;拞c;拟arrĀ;pᮀ憶;椽̀;bcdosᮏᮐᮖᮡᮥᮨ截rcap;橈Āauᮛᮞp;橆p;橊ot;抍r;橅;쀀∪︀Ȁalrv᮵ᮿᯞᯣrrĀ;mᮼᮽ憷;椼yƀevwᯇᯔᯘqɰᯎ\0\0ᯒreã᭳uã᭵ee;拎edge;拏en耻¤䂤earrowĀlrᯮ᯳eft»ᮀight»ᮽeäᯝĀciᰁᰇoninôǷnt;戱lcty;挭ঀAHabcdefhijlorstuwz᰻᰿ᱝᱩᱵᲞᲬᲷᴍᵻᶑᶫᶻ᷆᷍ròar;楥Ȁglrs᱈ᱍ᱒᱔ger;怠eth;愸òᄳhĀ;vᱚᱛ怐»ऊūᱡᱧarow;椏aã̕Āayᱮᱳron;䄏;䐴ƀ;ao̲ᱼᲄĀgrʿᲁr;懊tseq;橷ƀglmᲑᲔᲘ耻°䂰ta;䎴ptyv;榱ĀirᲣᲨsht;楿;쀀𝔡arĀlrᲳᲵ»ࣜ»သʀaegsv᳂᳖᳜᳠mƀ;oș᳔ndĀ;ș᳑uit;晦amma;䏝in;拲ƀ;io᳧᳨᳸䃷de脀÷;o᳧ᳰntimes;拇nø᳷cy;䑒cɯᴆ\0\0ᴊrn;挞op;挍ʀlptuwᴘᴝᴢᵉᵕlar;䀤f;쀀𝕕ʀ;emps̋ᴭᴷᴽᵂqĀ;d͒ᴳot;扑inus;戸lus;戔quare;抡blebarwedgåúnƀadhᄮᵝᵧownarrowóᲃarpoonĀlrᵲᵶefôᲴighôᲶŢᵿᶅkaro÷གɯᶊ\0\0ᶎrn;挟op;挌ƀcotᶘᶣᶦĀryᶝᶡ;쀀𝒹;䑕l;槶rok;䄑Ādrᶰᶴot;拱iĀ;fᶺ᠖斿Āah᷀᷃ròЩaòྦangle;榦Āci᷒ᷕy;䑟grarr;柿ऀDacdefglmnopqrstuxḁḉḙḸոḼṉṡṾấắẽỡἪἷὄĀDoḆᴴoôĀcsḎḔute耻é䃩ter;橮ȀaioyḢḧḱḶron;䄛rĀ;cḭḮ扖耻ê䃪lon;払;䑍ot;䄗ĀDrṁṅot;扒;쀀𝔢ƀ;rsṐṑṗ檚ave耻è䃨Ā;dṜṝ檖ot;檘Ȁ;ilsṪṫṲṴ檙nters;揧;愓Ā;dṹṺ檕ot;檗ƀapsẅẉẗcr;䄓tyƀ;svẒẓẕ戅et»ẓpĀ1;ẝẤijạả;怄;怅怃ĀgsẪẬ;䅋p;怂ĀgpẴẸon;䄙f;쀀𝕖ƀalsỄỎỒrĀ;sỊị拕l;槣us;橱iƀ;lvỚớở䎵on»ớ;䏵ȀcsuvỪỳἋἣĀioữḱrc»Ḯɩỹ\0\0ỻíՈantĀglἂἆtr»ṝess»ṺƀaeiἒἚls;䀽st;扟vĀ;DȵἠD;橸parsl;槥ĀDaἯἳot;打rr;楱ƀcdiἾὁỸr;愯oô͒ĀahὉὋ;䎷耻ð䃰Āmrὓὗl耻ë䃫o;悬ƀcipὡὤὧl;䀡sôծĀeoὬὴctatioîՙnentialåչৡᾒ\0ᾞ\0ᾡᾧ\0\0ῆῌ\0ΐ\0ῦῪ \0 ⁚llingdotseñṄy;䑄male;晀ƀilrᾭᾳ῁lig;耀ffiɩᾹ\0\0᾽g;耀ffig;耀ffl;쀀𝔣lig;耀filig;쀀fjƀaltῙῡt;晭ig;耀flns;斱of;䆒ǰ΅\0ῳf;쀀𝕗ĀakֿῷĀ;vῼ´拔;櫙artint;樍Āao⁕Ācs‑⁒ႉ‸⁅⁈\0⁐β•‥‧\0耻½䂽;慓耻¼䂼;慕;慙;慛Ƴ‴\0‶;慔;慖ʴ‾⁁\0\0⁃耻¾䂾;慗;慜5;慘ƶ⁌\0⁎;慚;慝8;慞l;恄wn;挢cr;쀀𝒻ࢀEabcdefgijlnorstv₂₉₥₰₴⃰℃ℒℸ̗ℾ⅒↞Ā;lٍ₇;檌ƀcmpₐₕute;䇵maĀ;dₜ᳚䎳;檆reve;䄟Āiy₪₮rc;䄝;䐳ot;䄡Ȁ;lqsؾق₽ƀ;qsؾٌlanô٥Ȁ;cdl٥⃒⃥⃕c;檩otĀ;o⃜⃝檀Ā;l⃢⃣檂;檄Ā;e⃪⃭쀀⋛︀s;檔r;쀀𝔤Ā;gٳ؛mel;愷cy;䑓Ȁ;Eajٚℌℎℐ;檒;檥;檤ȀEaesℛℝ℩ℴ;扩pĀ;p℣ℤ檊rox»ℤĀ;q℮ℯ檈Ā;q℮ℛim;拧pf;쀀𝕘Āci⅃ⅆr;愊mƀ;el٫ⅎ⅐;檎;檐茀>;cdlqrⅠⅪⅮⅳⅹĀciⅥⅧ;檧r;橺ot;拗Par;榕uest;橼ʀadelsↄⅪ←ٖ↛ǰ↉\0proør;楸qĀlqؿ↖lesó₈ií٫Āen↣↭rtneqq;쀀≩︀Å↪ԀAabcefkosy⇄⇇⇱⇵⇺∘∝∯≨≽ròΠȀilmr⇐⇔⇗⇛rsðᒄf»․ilôکĀdr⇠⇤cy;䑊ƀ;cwࣴ⇫⇯ir;楈;憭ar;意irc;䄥ƀalr∁∎∓rtsĀ;u∉∊晥it»∊lip;怦con;抹r;쀀𝔥sĀew∣∩arow;椥arow;椦ʀamopr∺∾≃≞≣rr;懿tht;戻kĀlr≉≓eftarrow;憩ightarrow;憪f;쀀𝕙bar;怕ƀclt≯≴≸r;쀀𝒽asè⇴rok;䄧Ābp⊂⊇ull;恃hen»ᱛૡ⊣\0⊪\0⊸⋅⋎\0⋕⋳\0\0⋸⌢⍧⍢⍿\0⎆⎪⎴cute耻í䃭ƀ;iyݱ⊰⊵rc耻î䃮;䐸Ācx⊼⊿y;䐵cl耻¡䂡ĀfrΟ⋉;쀀𝔦rave耻ì䃬Ȁ;inoܾ⋝⋩⋮Āin⋢⋦nt;樌t;戭fin;槜ta;愩lig;䄳ƀaop⋾⌚⌝ƀcgt⌅⌈⌗r;䄫ƀelpܟ⌏⌓inåގarôܠh;䄱f;抷ed;䆵ʀ;cfotӴ⌬⌱⌽⍁are;愅inĀ;t⌸⌹戞ie;槝doô⌙ʀ;celpݗ⍌⍐⍛⍡al;抺Āgr⍕⍙eróᕣã⍍arhk;樗rod;樼Ȁcgpt⍯⍲⍶⍻y;䑑on;䄯f;쀀𝕚a;䎹uest耻¿䂿Āci⎊⎏r;쀀𝒾nʀ;EdsvӴ⎛⎝⎡ӳ;拹ot;拵Ā;v⎦⎧拴;拳Ā;iݷ⎮lde;䄩ǫ⎸\0⎼cy;䑖l耻ï䃯̀cfmosu⏌⏗⏜⏡⏧⏵Āiy⏑⏕rc;䄵;䐹r;쀀𝔧ath;䈷pf;쀀𝕛ǣ⏬\0⏱r;쀀𝒿rcy;䑘kcy;䑔Ѐacfghjos␋␖␢ppaĀ;v␓␔䎺;䏰Āey␛␠dil;䄷;䐺r;쀀𝔨reen;䄸cy;䑅cy;䑜pf;쀀𝕜cr;쀀𝓀ABEHabcdefghjlmnoprstuv⑰⒁⒆⒍⒑┎┽╚▀♎♞♥♹♽⚚⚲⛘❝❨➋⟀⠁⠒ƀart⑷⑺⑼ròòΕail;椛arr;椎Ā;gঔ⒋;檋ar;楢ॣ⒥\0⒪\0⒱\0\0\0\0\0⒵Ⓔ\0ⓆⓈⓍ\0⓹ute;䄺mptyv;榴raîࡌbda;䎻gƀ;dlࢎⓁⓃ;榑åࢎ;檅uo耻«䂫rЀ;bfhlpst࢙ⓞⓦⓩ⓫⓮⓱⓵Ā;f࢝ⓣs;椟s;椝ë≒p;憫l;椹im;楳l;憢ƀ;ae⓿─┄檫il;椙Ā;s┉┊檭;쀀⪭︀ƀabr┕┙┝rr;椌rk;杲Āak┢┬cĀek┨┪;䁻;䁛Āes┱┳;榋lĀdu┹┻;榏;榍Ȁaeuy╆╋╖╘ron;䄾Ādi═╔il;䄼ìࢰâ┩;䐻Ȁcqrs╣╦╭╽a;椶uoĀ;rนᝆĀdu╲╷har;楧shar;楋h;憲ʀ;fgqs▋▌উ◳◿扤tʀahlrt▘▤▷◂◨rrowĀ;t࢙□aé⓶arpoonĀdu▯▴own»њp»०eftarrows;懇ightƀahs◍◖◞rrowĀ;sࣴࢧarpoonóquigarro÷⇰hreetimes;拋ƀ;qs▋ও◺lanôবʀ;cdgsব☊☍☝☨c;檨otĀ;o☔☕橿Ā;r☚☛檁;檃Ā;e☢☥쀀⋚︀s;檓ʀadegs☳☹☽♉♋pproøⓆot;拖qĀgq♃♅ôউgtò⒌ôছiíলƀilr♕࣡♚sht;楼;쀀𝔩Ā;Eজ♣;檑š♩♶rĀdu▲♮Ā;l॥♳;楪lk;斄cy;䑙ʀ;achtੈ⚈⚋⚑⚖rò◁orneòᴈard;楫ri;旺Āio⚟⚤dot;䅀ustĀ;a⚬⚭掰che»⚭ȀEaes⚻⚽⛉⛔;扨pĀ;p⛃⛄檉rox»⛄Ā;q⛎⛏檇Ā;q⛎⚻im;拦Ѐabnoptwz⛩⛴⛷✚✯❁❇❐Ānr⛮⛱g;柬r;懽rëࣁgƀlmr⛿✍✔eftĀar০✇ightá৲apsto;柼ightá৽parrowĀlr✥✩efô⓭ight;憬ƀafl✶✹✽r;榅;쀀𝕝us;樭imes;樴š❋❏st;戗áፎƀ;ef❗❘᠀旊nge»❘arĀ;l❤❥䀨t;榓ʀachmt❳❶❼➅➇ròࢨorneòᶌarĀ;d➃;業;怎ri;抿̀achiqt➘➝ੀ➢➮➻quo;怹r;쀀𝓁mƀ;egল➪➬;檍;檏Ābu┪➳oĀ;rฟ➹;怚rok;䅂萀<;cdhilqrࠫ⟒☹⟜⟠⟥⟪⟰Āci⟗⟙;檦r;橹reå◲mes;拉arr;楶uest;橻ĀPi⟵⟹ar;榖ƀ;ef⠀भ旃rĀdu⠇⠍shar;楊har;楦Āen⠗⠡rtneqq;쀀≨︀Å⠞܀Dacdefhilnopsu⡀⡅⢂⢎⢓⢠⢥⢨⣚⣢⣤ઃ⣳⤂Dot;戺Ȁclpr⡎⡒⡣⡽r耻¯䂯Āet⡗⡙;時Ā;e⡞⡟朠se»⡟Ā;sျ⡨toȀ;dluျ⡳⡷⡻owîҌefôएðᏑker;斮Āoy⢇⢌mma;権;䐼ash;怔asuredangle»ᘦr;쀀𝔪o;愧ƀcdn⢯⢴⣉ro耻µ䂵Ȁ;acdᑤ⢽⣀⣄sôᚧir;櫰ot肻·Ƶusƀ;bd⣒ᤃ⣓戒Ā;uᴼ⣘;横ţ⣞⣡p;櫛ò−ðઁĀdp⣩⣮els;抧f;쀀𝕞Āct⣸⣽r;쀀𝓂pos»ᖝƀ;lm⤉⤊⤍䎼timap;抸ఀGLRVabcdefghijlmoprstuvw⥂⥓⥾⦉⦘⧚⧩⨕⨚⩘⩝⪃⪕⪤⪨⬄⬇⭄⭿⮮ⰴⱧⱼ⳩Āgt⥇⥋;쀀⋙̸Ā;v⥐쀀≫⃒ƀelt⥚⥲⥶ftĀar⥡⥧rrow;懍ightarrow;懎;쀀⋘̸Ā;v⥻ే쀀≪⃒ightarrow;懏ĀDd⦎⦓ash;抯ash;抮ʀbcnpt⦣⦧⦬⦱⧌la»˞ute;䅄g;쀀∠⃒ʀ;Eiop⦼⧀⧅⧈;쀀⩰̸d;쀀≋̸s;䅉roøurĀ;a⧓⧔普lĀ;s⧓ସdz⧟\0⧣p肻 ଷmpĀ;e௹ఀʀaeouy⧴⧾⨃⨐⨓ǰ⧹\0⧻;橃on;䅈dil;䅆ngĀ;dൾ⨊ot;쀀⩭̸p;橂;䐽ash;怓;Aadqsxஒ⨩⨭⨻⩁⩅⩐rr;懗rĀhr⨳⨶k;椤Ā;oᏲᏰot;쀀≐̸uiöୣĀei⩊⩎ar;椨íistĀ;sடr;쀀𝔫ȀEest⩦⩹⩼ƀ;qs⩭ƀ;qs⩴lanôií௪Ā;rஶ⪁»ஷƀAap⪊⪍⪑rò⥱rr;憮ar;櫲ƀ;svྍ⪜ྌĀ;d⪡⪢拼;拺cy;䑚AEadest⪷⪺⪾⫂⫅⫶⫹rò⥦;쀀≦̸rr;憚r;急Ȁ;fqs⫎⫣⫯tĀar⫔⫙rro÷⫁ightarro÷⪐ƀ;qs⪺⫪lanôౕĀ;sౕ⫴»శiíౝĀ;rవ⫾iĀ;eచథiäඐĀpt⬌⬑f;쀀𝕟膀¬;in⬙⬚⬶䂬nȀ;Edvஉ⬤⬨⬮;쀀⋹̸ot;쀀⋵̸ǡஉ⬳⬵;拷;拶iĀ;vಸ⬼ǡಸ⭁⭃;拾;拽ƀaor⭋⭣⭩rȀ;ast⭕⭚⭟lleìl;쀀⫽⃥;쀀∂̸lint;樔ƀ;ceಒ⭰⭳uåಥĀ;cಘ⭸Ā;eಒ⭽ñಘȀAait⮈⮋⮝⮧rò⦈rrƀ;cw⮔⮕⮙憛;쀀⤳̸;쀀↝̸ghtarrow»⮕riĀ;eೋೖchimpqu⮽⯍⯙⬄⯤⯯Ȁ;cerല⯆ഷ⯉uå;쀀𝓃ortɭ⬅\0\0⯖ará⭖mĀ;e൮⯟Ā;q൴൳suĀbp⯫⯭ååഋƀbcp⯶ⰑⰙȀ;Ees⯿ⰀഢⰄ抄;쀀⫅̸etĀ;eഛⰋqĀ;qണⰀcĀ;eലⰗñസȀ;EesⰢⰣൟⰧ抅;쀀⫆̸etĀ;e൘ⰮqĀ;qൠⰣȀgilrⰽⰿⱅⱇìௗlde耻ñ䃱çృiangleĀlrⱒⱜeftĀ;eచⱚñదightĀ;eೋⱥñĀ;mⱬⱭ䎽ƀ;esⱴⱵⱹ䀣ro;愖p;怇ҀDHadgilrsⲏⲔⲙⲞⲣⲰⲶⳓⳣash;抭arr;椄p;쀀≍⃒ash;抬ĀetⲨⲬ;쀀≥⃒;쀀>⃒nfin;槞ƀAetⲽⳁⳅrr;椂;쀀≤⃒Ā;rⳊⳍ쀀<⃒ie;쀀⊴⃒ĀAtⳘⳜrr;椃rie;쀀⊵⃒im;쀀∼⃒ƀAan⳰ⴂrr;懖rĀhr⳺⳽k;椣Ā;oᏧᏥear;椧ቓ᪕\0\0\0\0\0\0\0\0\0\0\0\0\0ⴭ\0ⴸⵈⵠⵥⶄᬇ\0\0ⶍⶫ\0ⷈⷎ\0ⷜ⸙⸫⸾⹃Ācsⴱ᪗ute耻ó䃳ĀiyⴼⵅrĀ;cⵂ耻ô䃴;䐾ʀabios᪠ⵒⵗLjⵚlac;䅑v;樸old;榼lig;䅓Ācrir;榿;쀀𝔬ͯ\0\0\0ⶂn;䋛ave耻ò䃲;槁Ābmⶈ෴ar;榵Ȁacitⶕⶥⶨrò᪀Āirⶠr;榾oss;榻nå๒;槀ƀaeiⶱⶵⶹcr;䅍ga;䏉ƀcdnⷀⷅǍron;䎿;榶pf;쀀𝕠ƀaelⷔǒr;榷rp;榹;adiosvⷪⷫⷮ⸈⸍⸐⸖戨rò᪆Ȁ;efmⷷⷸ⸂⸅橝rĀ;oⷾⷿ愴f»ⷿ耻ª䂪耻º䂺gof;抶r;橖lope;橗;橛ƀclo⸟⸡⸧ò⸁ash耻ø䃸l;折iŬⸯ⸴de耻õ䃵esĀ;aǛ⸺s;樶ml耻ö䃶bar;挽ૡ\0\0⺀⺝\0⺢⺹\0\0⻋ຜ\0⼓\0\0⼫⾼\0⿈rȀ;astЃ脀¶;l䂶leìЃɩ\0\0m;櫳;櫽y;䐿rʀcimpt⺋⺏⺓ᡥ⺗nt;䀥od;䀮il;怰enk;怱r;쀀𝔭ƀimo⺨⺰⺴Ā;v⺭⺮䏆;䏕maô੶ne;明ƀ;tv⺿⻀⻈䏀chfork»´;䏖Āau⻏⻟nĀck⻕⻝kĀ;h⇴⻛;愎ö⇴sҀ;abcdemst⻳ᤈ⼄⼆⼊⼎䀫cir;樣ir;樢Āouᵀ⼂;樥;橲n肻±ຝim;樦wo;樧ƀipu⼙⼠⼥ntint;樕f;쀀𝕡nd耻£䂣Ԁ;Eaceinosu່⼿⽁⽄⽇⾁⾉⾒⽾⾶;檳p;檷uå໙Ā;c໎⽌̀;acens່⽙⽟⽦⽨⽾pproø⽃urlyeñ໙ñ໎ƀaes⽯⽶⽺pprox;檹qq;檵im;拨iíໟmeĀ;s⾈ຮ怲ƀEas⽸⾐⽺ð⽵ƀdfp⾙⾯ƀals⾠⾥⾪lar;挮ine;挒urf;挓Ā;t⾴ïrel;抰Āci⿀⿅r;쀀𝓅;䏈ncsp;怈̀fiopsu⋢⿱r;쀀𝔮pf;쀀𝕢rime;恗cr;쀀𝓆ƀaeo⿸〉〓tĀei々rnionóڰnt;樖stĀ;e【】䀿ñἙô༔ABHabcdefhilmnoprstuxけさすムㄎㄫㅇㅢㅲㆎ㈆㈕㈤㈩㉘㉮㉲㊐㊰㊷ƀartぇおがròႳòϝail;検aròᱥar;楤cdenqrtとふへみわゔヌĀeuねぱ;쀀∽̱te;䅕iãᅮmptyv;榳gȀ;del࿑らるろ;榒;榥å࿑uo耻»䂻rր;abcfhlpstwガクシスゼゾダッデナp;極Ā;fゴs;椠;椳s;椞ë≝ð✮l;楅im;楴l;憣;憝Āaiパフil;椚oĀ;nホボ戶aló༞ƀabrョリヮrò៥rk;杳ĀakンヽcĀekヹ・;䁽;䁝Āes;榌lĀduㄊㄌ;榎;榐Ȁaeuyㄗㄜㄧㄩron;䅙Ādiㄡㄥil;䅗ìâヺ;䑀Ȁclqsㄴㄷㄽㅄa;椷dhar;楩uoĀ;rȎȍh;憳ƀacgㅎㅟངlȀ;ipsླྀㅘㅛႜnåႻarôྩt;断ƀilrㅩဣㅮsht;楽;쀀𝔯ĀaoㅷㆆrĀduㅽㅿ»ѻĀ;l႑ㆄ;楬Ā;vㆋㆌ䏁;䏱ƀgns㆕ㇹㇼht̀ahlrstㆤㆰ㇂㇘rrowĀ;tㆭaéトarpoonĀduㆻㆿowîㅾp»႒eftĀah㇊㇐rrowóarpoonóՑightarrows;應quigarro÷ニhreetimes;拌g;䋚ingdotseñἲƀahm㈍㈐㈓ròaòՑ;怏oustĀ;a㈞掱che»mid;櫮Ȁabpt㈲㈽㉀㉒Ānr㈷㈺g;柭r;懾rëဃƀafl㉇㉊㉎r;榆;쀀𝕣us;樮imes;樵Āap㉝㉧rĀ;g㉣㉤䀩t;榔olint;樒arò㇣Ȁachq㉻㊀Ⴜ㊅quo;怺r;쀀𝓇Ābu・㊊oĀ;rȔȓƀhir㊗㊛㊠reåㇸmes;拊iȀ;efl㊪ၙᠡ㊫方tri;槎luhar;楨;愞ൡ㋕㋛㋟㌬㌸㍱\0㍺㎤\0\0㏬㏰\0㐨㑈㑚㒭㒱㓊㓱\0㘖\0\0㘳cute;䅛quï➺Ԁ;Eaceinpsyᇭ㋳㋵㋿㌂㌋㌏㌟㌦㌩;檴ǰ㋺\0㋼;檸on;䅡uåᇾĀ;dᇳ㌇il;䅟rc;䅝ƀEas㌖㌘㌛;檶p;檺im;择olint;樓iíሄ;䑁otƀ;be㌴ᵇ㌵担;橦Aacmstx㍆㍊㍗㍛㍞㍣㍭rr;懘rĀhr㍐㍒ë∨Ā;oਸ਼t耻§䂧i;䀻war;椩mĀin㍩ðnuóñt;朶rĀ;o㍶⁕쀀𝔰Ȁacoy㎂㎆㎑㎠rp;景Āhy㎋㎏cy;䑉;䑈rtɭ㎙\0\0㎜iäᑤaraì耻䂭Āgm㎨㎴maƀ;fv㎱㎲㎲䏃;䏂Ѐ;deglnprካ㏅㏉㏎㏖㏞㏡㏦ot;橪Ā;qኰĀ;E㏓㏔檞;檠Ā;E㏛㏜檝;檟e;扆lus;樤arr;楲aròᄽȀaeit㏸㐈㐏㐗Āls㏽㐄lsetmé㍪hp;樳parsl;槤Ādlᑣ㐔e;挣Ā;e㐜㐝檪Ā;s㐢㐣檬;쀀⪬︀ƀflp㐮㐳㑂tcy;䑌Ā;b㐸㐹䀯Ā;a㐾㐿槄r;挿f;쀀𝕤aĀdr㑍ЂesĀ;u㑔㑕晠it»㑕ƀcsu㑠㑹㒟Āau㑥㑯pĀ;sᆈ㑫;쀀⊓︀pĀ;sᆴ㑵;쀀⊔︀uĀbp㑿㒏ƀ;esᆗᆜ㒆etĀ;eᆗ㒍ñᆝƀ;esᆨᆭ㒖etĀ;eᆨ㒝ñᆮƀ;afᅻ㒦ְrť㒫ֱ»ᅼaròᅈȀcemt㒹㒾㓂㓅r;쀀𝓈tmîñiì㐕aræᆾĀar㓎㓕rĀ;f㓔ឿ昆Āan㓚㓭ightĀep㓣㓪psiloîỠhé⺯s»⡒ʀbcmnp㓻㕞ሉ㖋㖎Ҁ;Edemnprs㔎㔏㔑㔕㔞㔣㔬㔱㔶抂;櫅ot;檽Ā;dᇚ㔚ot;櫃ult;櫁ĀEe㔨㔪;櫋;把lus;檿arr;楹ƀeiu㔽㕒㕕tƀ;en㔎㕅㕋qĀ;qᇚ㔏eqĀ;q㔫㔨m;櫇Ābp㕚㕜;櫕;櫓c̀;acensᇭ㕬㕲㕹㕻㌦pproø㋺urlyeñᇾñᇳƀaes㖂㖈㌛pproø㌚qñ㌗g;晪ڀ123;Edehlmnps㖩㖬㖯ሜ㖲㖴㗀㗉㗕㗚㗟㗨㗭耻¹䂹耻²䂲耻³䂳;櫆Āos㖹㖼t;檾ub;櫘Ā;dሢ㗅ot;櫄sĀou㗏㗒l;柉b;櫗arr;楻ult;櫂ĀEe㗤㗦;櫌;抋lus;櫀ƀeiu㗴㘉㘌tƀ;enሜ㗼㘂qĀ;qሢ㖲eqĀ;q㗧㗤m;櫈Ābp㘑㘓;櫔;櫖ƀAan㘜㘠㘭rr;懙rĀhr㘦㘨ë∮Ā;oਫwar;椪lig耻ß䃟㙑㙝㙠ዎ㙳㙹\0㙾㛂\0\0\0\0\0㛛㜃\0㜉㝬\0\0\0㞇ɲ㙖\0\0㙛get;挖;䏄rëƀaey㙦㙫㙰ron;䅥dil;䅣;䑂lrec;挕r;쀀𝔱Ȁeiko㚆㚝㚵㚼Dz㚋\0㚑eĀ4fኄኁaƀ;sv㚘㚙㚛䎸ym;䏑Ācn㚢㚲kĀas㚨㚮pproøim»ኬsðኞĀas㚺㚮ðrn耻þ䃾Ǭ̟㛆⋧es膀×;bd㛏㛐㛘䃗Ā;aᤏ㛕r;樱;樰ƀeps㛡㛣㜀á⩍Ȁ;bcf҆㛬㛰㛴ot;挶ir;櫱Ā;o㛹㛼쀀𝕥rk;櫚á㍢rime;怴ƀaip㜏㜒㝤dåቈadempst㜡㝍㝀㝑㝗㝜㝟ngleʀ;dlqr㜰㜱㜶㝀㝂斵own»ᶻeftĀ;e⠀㜾ñम;扜ightĀ;e㊪㝋ñၚot;旬inus;樺lus;樹b;槍ime;樻ezium;揢ƀcht㝲㝽㞁Āry㝷㝻;쀀𝓉;䑆cy;䑛rok;䅧Āio㞋㞎xôheadĀlr㞗㞠eftarro÷ࡏightarrow»ཝऀAHabcdfghlmoprstuw㟐㟓㟗㟤㟰㟼㠎㠜㠣㠴㡑㡝㡫㢩㣌㣒㣪㣶ròϭar;楣Ācr㟜㟢ute耻ú䃺òᅐrǣ㟪\0㟭y;䑞ve;䅭Āiy㟵㟺rc耻û䃻;䑃ƀabh㠃㠆㠋ròᎭlac;䅱aòᏃĀir㠓㠘sht;楾;쀀𝔲rave耻ù䃹š㠧㠱rĀlr㠬㠮»ॗ»ႃlk;斀Āct㠹㡍ɯ㠿\0\0㡊rnĀ;e㡅㡆挜r»㡆op;挏ri;旸Āal㡖㡚cr;䅫肻¨͉Āgp㡢㡦on;䅳f;쀀𝕦̀adhlsuᅋ㡸㡽፲㢑㢠ownáᎳarpoonĀlr㢈㢌efô㠭ighô㠯iƀ;hl㢙㢚㢜䏅»ᏺon»㢚parrows;懈ƀcit㢰㣄㣈ɯ㢶\0\0㣁rnĀ;e㢼㢽挝r»㢽op;挎ng;䅯ri;旹cr;쀀𝓊ƀdir㣙㣝㣢ot;拰lde;䅩iĀ;f㜰㣨»᠓Āam㣯㣲rò㢨l耻ü䃼angle;榧ހABDacdeflnoprsz㤜㤟㤩㤭㦵㦸㦽㧟㧤㧨㧳㧹㧽㨁㨠ròϷarĀ;v㤦㤧櫨;櫩asèϡĀnr㤲㤷grt;榜eknprst㓣㥆㥋㥒㥝㥤㦖appá␕othinçẖƀhir㓫⻈㥙opô⾵Ā;hᎷ㥢ïㆍĀiu㥩㥭gmá㎳Ābp㥲㦄setneqĀ;q㥽㦀쀀⊊︀;쀀⫋︀setneqĀ;q㦏㦒쀀⊋︀;쀀⫌︀Āhr㦛㦟etá㚜iangleĀlr㦪㦯eft»थight»ၑy;䐲ash»ံƀelr㧄㧒㧗ƀ;beⷪ㧋㧏ar;抻q;扚lip;拮Ābt㧜ᑨaòᑩr;쀀𝔳tré㦮suĀbp㧯㧱»ജ»൙pf;쀀𝕧roðtré㦴Ācu㨆㨋r;쀀𝓋Ābp㨐㨘nĀEe㦀㨖»㥾nĀEe㦒㨞»㦐igzag;榚cefoprs㨶㨻㩖㩛㩔㩡㩪irc;䅵Ādi㩀㩑Ābg㩅㩉ar;機eĀ;qᗺ㩏;扙erp;愘r;쀀𝔴pf;쀀𝕨Ā;eᑹ㩦atèᑹcr;쀀𝓌ૣណ㪇\0㪋\0㪐㪛\0\0㪝㪨㪫㪯\0\0㫃㫎\0㫘ៜtré៑r;쀀𝔵ĀAa㪔㪗ròσrò৶;䎾ĀAa㪡㪤ròθrò৫að✓is;拻ƀdptឤ㪵㪾Āfl㪺ឩ;쀀𝕩imåឲĀAa㫇㫊ròώròਁĀcq㫒ីr;쀀𝓍Āpt៖㫜ré។Ѐacefiosu㫰㫽㬈㬌㬑㬕㬛㬡cĀuy㫶㫻te耻ý䃽;䑏Āiy㬂㬆rc;䅷;䑋n耻¥䂥r;쀀𝔶cy;䑗pf;쀀𝕪cr;쀀𝓎Ācm㬦㬩y;䑎l耻ÿ䃿Ԁacdefhiosw㭂㭈㭔㭘㭤㭩㭭㭴㭺㮀cute;䅺Āay㭍㭒ron;䅾;䐷ot;䅼Āet㭝㭡træᕟa;䎶r;쀀𝔷cy;䐶grarr;懝pf;쀀𝕫cr;쀀𝓏Ājn㮅㮇;怍j;怌'.split("").map((c) => c.charCodeAt(0))
|
||
);
|
||
const xmlDecodeTree = new Uint16Array(
|
||
// prettier-ignore
|
||
"Ȁaglq \x1Bɭ\0\0p;䀦os;䀧t;䀾t;䀼uot;䀢".split("").map((c) => c.charCodeAt(0))
|
||
);
|
||
var _a;
|
||
const decodeMap = /* @__PURE__ */ new Map([
|
||
[0, 65533],
|
||
// C1 Unicode control character reference replacements
|
||
[128, 8364],
|
||
[130, 8218],
|
||
[131, 402],
|
||
[132, 8222],
|
||
[133, 8230],
|
||
[134, 8224],
|
||
[135, 8225],
|
||
[136, 710],
|
||
[137, 8240],
|
||
[138, 352],
|
||
[139, 8249],
|
||
[140, 338],
|
||
[142, 381],
|
||
[145, 8216],
|
||
[146, 8217],
|
||
[147, 8220],
|
||
[148, 8221],
|
||
[149, 8226],
|
||
[150, 8211],
|
||
[151, 8212],
|
||
[152, 732],
|
||
[153, 8482],
|
||
[154, 353],
|
||
[155, 8250],
|
||
[156, 339],
|
||
[158, 382],
|
||
[159, 376]
|
||
]);
|
||
const fromCodePoint = (
|
||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins
|
||
(_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function(codePoint) {
|
||
let output = "";
|
||
if (codePoint > 65535) {
|
||
codePoint -= 65536;
|
||
output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296);
|
||
codePoint = 56320 | codePoint & 1023;
|
||
}
|
||
output += String.fromCharCode(codePoint);
|
||
return output;
|
||
}
|
||
);
|
||
function replaceCodePoint(codePoint) {
|
||
var _a2;
|
||
if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) {
|
||
return 65533;
|
||
}
|
||
return (_a2 = decodeMap.get(codePoint)) !== null && _a2 !== void 0 ? _a2 : codePoint;
|
||
}
|
||
var CharCodes$1;
|
||
(function(CharCodes2) {
|
||
CharCodes2[CharCodes2["NUM"] = 35] = "NUM";
|
||
CharCodes2[CharCodes2["SEMI"] = 59] = "SEMI";
|
||
CharCodes2[CharCodes2["EQUALS"] = 61] = "EQUALS";
|
||
CharCodes2[CharCodes2["ZERO"] = 48] = "ZERO";
|
||
CharCodes2[CharCodes2["NINE"] = 57] = "NINE";
|
||
CharCodes2[CharCodes2["LOWER_A"] = 97] = "LOWER_A";
|
||
CharCodes2[CharCodes2["LOWER_F"] = 102] = "LOWER_F";
|
||
CharCodes2[CharCodes2["LOWER_X"] = 120] = "LOWER_X";
|
||
CharCodes2[CharCodes2["LOWER_Z"] = 122] = "LOWER_Z";
|
||
CharCodes2[CharCodes2["UPPER_A"] = 65] = "UPPER_A";
|
||
CharCodes2[CharCodes2["UPPER_F"] = 70] = "UPPER_F";
|
||
CharCodes2[CharCodes2["UPPER_Z"] = 90] = "UPPER_Z";
|
||
})(CharCodes$1 || (CharCodes$1 = {}));
|
||
const TO_LOWER_BIT = 32;
|
||
var BinTrieFlags;
|
||
(function(BinTrieFlags2) {
|
||
BinTrieFlags2[BinTrieFlags2["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
|
||
BinTrieFlags2[BinTrieFlags2["BRANCH_LENGTH"] = 16256] = "BRANCH_LENGTH";
|
||
BinTrieFlags2[BinTrieFlags2["JUMP_TABLE"] = 127] = "JUMP_TABLE";
|
||
})(BinTrieFlags || (BinTrieFlags = {}));
|
||
function isNumber(code) {
|
||
return code >= CharCodes$1.ZERO && code <= CharCodes$1.NINE;
|
||
}
|
||
function isHexadecimalCharacter(code) {
|
||
return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_F || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_F;
|
||
}
|
||
function isAsciiAlphaNumeric(code) {
|
||
return code >= CharCodes$1.UPPER_A && code <= CharCodes$1.UPPER_Z || code >= CharCodes$1.LOWER_A && code <= CharCodes$1.LOWER_Z || isNumber(code);
|
||
}
|
||
function isEntityInAttributeInvalidEnd(code) {
|
||
return code === CharCodes$1.EQUALS || isAsciiAlphaNumeric(code);
|
||
}
|
||
var EntityDecoderState;
|
||
(function(EntityDecoderState2) {
|
||
EntityDecoderState2[EntityDecoderState2["EntityStart"] = 0] = "EntityStart";
|
||
EntityDecoderState2[EntityDecoderState2["NumericStart"] = 1] = "NumericStart";
|
||
EntityDecoderState2[EntityDecoderState2["NumericDecimal"] = 2] = "NumericDecimal";
|
||
EntityDecoderState2[EntityDecoderState2["NumericHex"] = 3] = "NumericHex";
|
||
EntityDecoderState2[EntityDecoderState2["NamedEntity"] = 4] = "NamedEntity";
|
||
})(EntityDecoderState || (EntityDecoderState = {}));
|
||
var DecodingMode;
|
||
(function(DecodingMode2) {
|
||
DecodingMode2[DecodingMode2["Legacy"] = 0] = "Legacy";
|
||
DecodingMode2[DecodingMode2["Strict"] = 1] = "Strict";
|
||
DecodingMode2[DecodingMode2["Attribute"] = 2] = "Attribute";
|
||
})(DecodingMode || (DecodingMode = {}));
|
||
class EntityDecoder {
|
||
constructor(decodeTree, emitCodePoint, errors) {
|
||
this.decodeTree = decodeTree;
|
||
this.emitCodePoint = emitCodePoint;
|
||
this.errors = errors;
|
||
this.state = EntityDecoderState.EntityStart;
|
||
this.consumed = 1;
|
||
this.result = 0;
|
||
this.treeIndex = 0;
|
||
this.excess = 1;
|
||
this.decodeMode = DecodingMode.Strict;
|
||
}
|
||
/** Resets the instance to make it reusable. */
|
||
startEntity(decodeMode) {
|
||
this.decodeMode = decodeMode;
|
||
this.state = EntityDecoderState.EntityStart;
|
||
this.result = 0;
|
||
this.treeIndex = 0;
|
||
this.excess = 1;
|
||
this.consumed = 1;
|
||
}
|
||
/**
|
||
* Write an entity to the decoder. This can be called multiple times with partial entities.
|
||
* If the entity is incomplete, the decoder will return -1.
|
||
*
|
||
* Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
|
||
* entity is incomplete, and resume when the next string is written.
|
||
*
|
||
* @param string The string containing the entity (or a continuation of the entity).
|
||
* @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
|
||
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
||
*/
|
||
write(str, offset) {
|
||
switch (this.state) {
|
||
case EntityDecoderState.EntityStart: {
|
||
if (str.charCodeAt(offset) === CharCodes$1.NUM) {
|
||
this.state = EntityDecoderState.NumericStart;
|
||
this.consumed += 1;
|
||
return this.stateNumericStart(str, offset + 1);
|
||
}
|
||
this.state = EntityDecoderState.NamedEntity;
|
||
return this.stateNamedEntity(str, offset);
|
||
}
|
||
case EntityDecoderState.NumericStart: {
|
||
return this.stateNumericStart(str, offset);
|
||
}
|
||
case EntityDecoderState.NumericDecimal: {
|
||
return this.stateNumericDecimal(str, offset);
|
||
}
|
||
case EntityDecoderState.NumericHex: {
|
||
return this.stateNumericHex(str, offset);
|
||
}
|
||
case EntityDecoderState.NamedEntity: {
|
||
return this.stateNamedEntity(str, offset);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Switches between the numeric decimal and hexadecimal states.
|
||
*
|
||
* Equivalent to the `Numeric character reference state` in the HTML spec.
|
||
*
|
||
* @param str The string containing the entity (or a continuation of the entity).
|
||
* @param offset The current offset.
|
||
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
||
*/
|
||
stateNumericStart(str, offset) {
|
||
if (offset >= str.length) {
|
||
return -1;
|
||
}
|
||
if ((str.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes$1.LOWER_X) {
|
||
this.state = EntityDecoderState.NumericHex;
|
||
this.consumed += 1;
|
||
return this.stateNumericHex(str, offset + 1);
|
||
}
|
||
this.state = EntityDecoderState.NumericDecimal;
|
||
return this.stateNumericDecimal(str, offset);
|
||
}
|
||
addToNumericResult(str, start, end2, base) {
|
||
if (start !== end2) {
|
||
const digitCount = end2 - start;
|
||
this.result = this.result * Math.pow(base, digitCount) + parseInt(str.substr(start, digitCount), base);
|
||
this.consumed += digitCount;
|
||
}
|
||
}
|
||
/**
|
||
* Parses a hexadecimal numeric entity.
|
||
*
|
||
* Equivalent to the `Hexademical character reference state` in the HTML spec.
|
||
*
|
||
* @param str The string containing the entity (or a continuation of the entity).
|
||
* @param offset The current offset.
|
||
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
||
*/
|
||
stateNumericHex(str, offset) {
|
||
const startIdx = offset;
|
||
while (offset < str.length) {
|
||
const char = str.charCodeAt(offset);
|
||
if (isNumber(char) || isHexadecimalCharacter(char)) {
|
||
offset += 1;
|
||
} else {
|
||
this.addToNumericResult(str, startIdx, offset, 16);
|
||
return this.emitNumericEntity(char, 3);
|
||
}
|
||
}
|
||
this.addToNumericResult(str, startIdx, offset, 16);
|
||
return -1;
|
||
}
|
||
/**
|
||
* Parses a decimal numeric entity.
|
||
*
|
||
* Equivalent to the `Decimal character reference state` in the HTML spec.
|
||
*
|
||
* @param str The string containing the entity (or a continuation of the entity).
|
||
* @param offset The current offset.
|
||
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
||
*/
|
||
stateNumericDecimal(str, offset) {
|
||
const startIdx = offset;
|
||
while (offset < str.length) {
|
||
const char = str.charCodeAt(offset);
|
||
if (isNumber(char)) {
|
||
offset += 1;
|
||
} else {
|
||
this.addToNumericResult(str, startIdx, offset, 10);
|
||
return this.emitNumericEntity(char, 2);
|
||
}
|
||
}
|
||
this.addToNumericResult(str, startIdx, offset, 10);
|
||
return -1;
|
||
}
|
||
/**
|
||
* Validate and emit a numeric entity.
|
||
*
|
||
* Implements the logic from the `Hexademical character reference start
|
||
* state` and `Numeric character reference end state` in the HTML spec.
|
||
*
|
||
* @param lastCp The last code point of the entity. Used to see if the
|
||
* entity was terminated with a semicolon.
|
||
* @param expectedLength The minimum number of characters that should be
|
||
* consumed. Used to validate that at least one digit
|
||
* was consumed.
|
||
* @returns The number of characters that were consumed.
|
||
*/
|
||
emitNumericEntity(lastCp, expectedLength) {
|
||
var _a2;
|
||
if (this.consumed <= expectedLength) {
|
||
(_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
|
||
return 0;
|
||
}
|
||
if (lastCp === CharCodes$1.SEMI) {
|
||
this.consumed += 1;
|
||
} else if (this.decodeMode === DecodingMode.Strict) {
|
||
return 0;
|
||
}
|
||
this.emitCodePoint(replaceCodePoint(this.result), this.consumed);
|
||
if (this.errors) {
|
||
if (lastCp !== CharCodes$1.SEMI) {
|
||
this.errors.missingSemicolonAfterCharacterReference();
|
||
}
|
||
this.errors.validateNumericCharacterReference(this.result);
|
||
}
|
||
return this.consumed;
|
||
}
|
||
/**
|
||
* Parses a named entity.
|
||
*
|
||
* Equivalent to the `Named character reference state` in the HTML spec.
|
||
*
|
||
* @param str The string containing the entity (or a continuation of the entity).
|
||
* @param offset The current offset.
|
||
* @returns The number of characters that were consumed, or -1 if the entity is incomplete.
|
||
*/
|
||
stateNamedEntity(str, offset) {
|
||
const { decodeTree } = this;
|
||
let current = decodeTree[this.treeIndex];
|
||
let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
|
||
for (; offset < str.length; offset++, this.excess++) {
|
||
const char = str.charCodeAt(offset);
|
||
this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
|
||
if (this.treeIndex < 0) {
|
||
return this.result === 0 || // If we are parsing an attribute
|
||
this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity,
|
||
(valueLength === 0 || // And there should be no invalid characters.
|
||
isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
|
||
}
|
||
current = decodeTree[this.treeIndex];
|
||
valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
|
||
if (valueLength !== 0) {
|
||
if (char === CharCodes$1.SEMI) {
|
||
return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
|
||
}
|
||
if (this.decodeMode !== DecodingMode.Strict) {
|
||
this.result = this.treeIndex;
|
||
this.consumed += this.excess;
|
||
this.excess = 0;
|
||
}
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
/**
|
||
* Emit a named entity that was not terminated with a semicolon.
|
||
*
|
||
* @returns The number of characters consumed.
|
||
*/
|
||
emitNotTerminatedNamedEntity() {
|
||
var _a2;
|
||
const { result, decodeTree } = this;
|
||
const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;
|
||
this.emitNamedEntityData(result, valueLength, this.consumed);
|
||
(_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.missingSemicolonAfterCharacterReference();
|
||
return this.consumed;
|
||
}
|
||
/**
|
||
* Emit a named entity.
|
||
*
|
||
* @param result The index of the entity in the decode tree.
|
||
* @param valueLength The number of bytes in the entity.
|
||
* @param consumed The number of characters consumed.
|
||
*
|
||
* @returns The number of characters consumed.
|
||
*/
|
||
emitNamedEntityData(result, valueLength, consumed) {
|
||
const { decodeTree } = this;
|
||
this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH : decodeTree[result + 1], consumed);
|
||
if (valueLength === 3) {
|
||
this.emitCodePoint(decodeTree[result + 2], consumed);
|
||
}
|
||
return consumed;
|
||
}
|
||
/**
|
||
* Signal to the parser that the end of the input was reached.
|
||
*
|
||
* Remaining data will be emitted and relevant errors will be produced.
|
||
*
|
||
* @returns The number of characters consumed.
|
||
*/
|
||
end() {
|
||
var _a2;
|
||
switch (this.state) {
|
||
case EntityDecoderState.NamedEntity: {
|
||
return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
|
||
}
|
||
// Otherwise, emit a numeric entity if we have one.
|
||
case EntityDecoderState.NumericDecimal: {
|
||
return this.emitNumericEntity(0, 2);
|
||
}
|
||
case EntityDecoderState.NumericHex: {
|
||
return this.emitNumericEntity(0, 3);
|
||
}
|
||
case EntityDecoderState.NumericStart: {
|
||
(_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
|
||
return 0;
|
||
}
|
||
case EntityDecoderState.EntityStart: {
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
function getDecoder(decodeTree) {
|
||
let ret = "";
|
||
const decoder = new EntityDecoder(decodeTree, (str) => ret += fromCodePoint(str));
|
||
return function decodeWithTrie(str, decodeMode) {
|
||
let lastIndex = 0;
|
||
let offset = 0;
|
||
while ((offset = str.indexOf("&", offset)) >= 0) {
|
||
ret += str.slice(lastIndex, offset);
|
||
decoder.startEntity(decodeMode);
|
||
const len = decoder.write(
|
||
str,
|
||
// Skip the "&"
|
||
offset + 1
|
||
);
|
||
if (len < 0) {
|
||
lastIndex = offset + decoder.end();
|
||
break;
|
||
}
|
||
lastIndex = offset + len;
|
||
offset = len === 0 ? lastIndex + 1 : lastIndex;
|
||
}
|
||
const result = ret + str.slice(lastIndex);
|
||
ret = "";
|
||
return result;
|
||
};
|
||
}
|
||
function determineBranch(decodeTree, current, nodeIdx, char) {
|
||
const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
|
||
const jumpOffset = current & BinTrieFlags.JUMP_TABLE;
|
||
if (branchCount === 0) {
|
||
return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1;
|
||
}
|
||
if (jumpOffset) {
|
||
const value = char - jumpOffset;
|
||
return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1;
|
||
}
|
||
let lo = nodeIdx;
|
||
let hi = lo + branchCount - 1;
|
||
while (lo <= hi) {
|
||
const mid = lo + hi >>> 1;
|
||
const midVal = decodeTree[mid];
|
||
if (midVal < char) {
|
||
lo = mid + 1;
|
||
} else if (midVal > char) {
|
||
hi = mid - 1;
|
||
} else {
|
||
return decodeTree[mid + branchCount];
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
getDecoder(htmlDecodeTree);
|
||
getDecoder(xmlDecodeTree);
|
||
const xmlReplacer = /["&'<>$\x80-\uFFFF]/g;
|
||
const xmlCodeMap = /* @__PURE__ */ new Map([
|
||
[34, """],
|
||
[38, "&"],
|
||
[39, "'"],
|
||
[60, "<"],
|
||
[62, ">"]
|
||
]);
|
||
const getCodePoint = (
|
||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||
String.prototype.codePointAt != null ? (str, index2) => str.codePointAt(index2) : (
|
||
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||
(c, index2) => (c.charCodeAt(index2) & 64512) === 55296 ? (c.charCodeAt(index2) - 55296) * 1024 + c.charCodeAt(index2 + 1) - 56320 + 65536 : c.charCodeAt(index2)
|
||
)
|
||
);
|
||
function encodeXML(str) {
|
||
let ret = "";
|
||
let lastIdx = 0;
|
||
let match;
|
||
while ((match = xmlReplacer.exec(str)) !== null) {
|
||
const i = match.index;
|
||
const char = str.charCodeAt(i);
|
||
const next2 = xmlCodeMap.get(char);
|
||
if (next2 !== void 0) {
|
||
ret += str.substring(lastIdx, i) + next2;
|
||
lastIdx = i + 1;
|
||
} else {
|
||
ret += `${str.substring(lastIdx, i)}&#x${getCodePoint(str, i).toString(16)};`;
|
||
lastIdx = xmlReplacer.lastIndex += Number((char & 64512) === 55296);
|
||
}
|
||
}
|
||
return ret + str.substr(lastIdx);
|
||
}
|
||
function getEscaper(regex, map2) {
|
||
return function escape(data2) {
|
||
let match;
|
||
let lastIdx = 0;
|
||
let result = "";
|
||
while (match = regex.exec(data2)) {
|
||
if (lastIdx !== match.index) {
|
||
result += data2.substring(lastIdx, match.index);
|
||
}
|
||
result += map2.get(match[0].charCodeAt(0));
|
||
lastIdx = match.index + 1;
|
||
}
|
||
return result + data2.substring(lastIdx);
|
||
};
|
||
}
|
||
const escapeAttribute = getEscaper(/["&\u00A0]/g, /* @__PURE__ */ new Map([
|
||
[34, """],
|
||
[38, "&"],
|
||
[160, " "]
|
||
]));
|
||
const escapeText = getEscaper(/[&<>\u00A0]/g, /* @__PURE__ */ new Map([
|
||
[38, "&"],
|
||
[60, "<"],
|
||
[62, ">"],
|
||
[160, " "]
|
||
]));
|
||
const elementNames = new Map([
|
||
"altGlyph",
|
||
"altGlyphDef",
|
||
"altGlyphItem",
|
||
"animateColor",
|
||
"animateMotion",
|
||
"animateTransform",
|
||
"clipPath",
|
||
"feBlend",
|
||
"feColorMatrix",
|
||
"feComponentTransfer",
|
||
"feComposite",
|
||
"feConvolveMatrix",
|
||
"feDiffuseLighting",
|
||
"feDisplacementMap",
|
||
"feDistantLight",
|
||
"feDropShadow",
|
||
"feFlood",
|
||
"feFuncA",
|
||
"feFuncB",
|
||
"feFuncG",
|
||
"feFuncR",
|
||
"feGaussianBlur",
|
||
"feImage",
|
||
"feMerge",
|
||
"feMergeNode",
|
||
"feMorphology",
|
||
"feOffset",
|
||
"fePointLight",
|
||
"feSpecularLighting",
|
||
"feSpotLight",
|
||
"feTile",
|
||
"feTurbulence",
|
||
"foreignObject",
|
||
"glyphRef",
|
||
"linearGradient",
|
||
"radialGradient",
|
||
"textPath"
|
||
].map((val2) => [val2.toLowerCase(), val2]));
|
||
const attributeNames = new Map([
|
||
"definitionURL",
|
||
"attributeName",
|
||
"attributeType",
|
||
"baseFrequency",
|
||
"baseProfile",
|
||
"calcMode",
|
||
"clipPathUnits",
|
||
"diffuseConstant",
|
||
"edgeMode",
|
||
"filterUnits",
|
||
"glyphRef",
|
||
"gradientTransform",
|
||
"gradientUnits",
|
||
"kernelMatrix",
|
||
"kernelUnitLength",
|
||
"keyPoints",
|
||
"keySplines",
|
||
"keyTimes",
|
||
"lengthAdjust",
|
||
"limitingConeAngle",
|
||
"markerHeight",
|
||
"markerUnits",
|
||
"markerWidth",
|
||
"maskContentUnits",
|
||
"maskUnits",
|
||
"numOctaves",
|
||
"pathLength",
|
||
"patternContentUnits",
|
||
"patternTransform",
|
||
"patternUnits",
|
||
"pointsAtX",
|
||
"pointsAtY",
|
||
"pointsAtZ",
|
||
"preserveAlpha",
|
||
"preserveAspectRatio",
|
||
"primitiveUnits",
|
||
"refX",
|
||
"refY",
|
||
"repeatCount",
|
||
"repeatDur",
|
||
"requiredExtensions",
|
||
"requiredFeatures",
|
||
"specularConstant",
|
||
"specularExponent",
|
||
"spreadMethod",
|
||
"startOffset",
|
||
"stdDeviation",
|
||
"stitchTiles",
|
||
"surfaceScale",
|
||
"systemLanguage",
|
||
"tableValues",
|
||
"targetX",
|
||
"targetY",
|
||
"textLength",
|
||
"viewBox",
|
||
"viewTarget",
|
||
"xChannelSelector",
|
||
"yChannelSelector",
|
||
"zoomAndPan"
|
||
].map((val2) => [val2.toLowerCase(), val2]));
|
||
const unencodedElements = /* @__PURE__ */ new Set([
|
||
"style",
|
||
"script",
|
||
"xmp",
|
||
"iframe",
|
||
"noembed",
|
||
"noframes",
|
||
"plaintext",
|
||
"noscript"
|
||
]);
|
||
function replaceQuotes(value) {
|
||
return value.replace(/"/g, """);
|
||
}
|
||
function formatAttributes(attributes2, opts) {
|
||
var _a2;
|
||
if (!attributes2)
|
||
return;
|
||
const encode = ((_a2 = opts.encodeEntities) !== null && _a2 !== void 0 ? _a2 : opts.decodeEntities) === false ? replaceQuotes : opts.xmlMode || opts.encodeEntities !== "utf8" ? encodeXML : escapeAttribute;
|
||
return Object.keys(attributes2).map((key) => {
|
||
var _a3, _b;
|
||
const value = (_a3 = attributes2[key]) !== null && _a3 !== void 0 ? _a3 : "";
|
||
if (opts.xmlMode === "foreign") {
|
||
key = (_b = attributeNames.get(key)) !== null && _b !== void 0 ? _b : key;
|
||
}
|
||
if (!opts.emptyAttrs && !opts.xmlMode && value === "") {
|
||
return key;
|
||
}
|
||
return `${key}="${encode(value)}"`;
|
||
}).join(" ");
|
||
}
|
||
const singleTag = /* @__PURE__ */ new Set([
|
||
"area",
|
||
"base",
|
||
"basefont",
|
||
"br",
|
||
"col",
|
||
"command",
|
||
"embed",
|
||
"frame",
|
||
"hr",
|
||
"img",
|
||
"input",
|
||
"isindex",
|
||
"keygen",
|
||
"link",
|
||
"meta",
|
||
"param",
|
||
"source",
|
||
"track",
|
||
"wbr"
|
||
]);
|
||
function render$1(node, options = {}) {
|
||
const nodes = "length" in node ? node : [node];
|
||
let output = "";
|
||
for (let i = 0; i < nodes.length; i++) {
|
||
output += renderNode(nodes[i], options);
|
||
}
|
||
return output;
|
||
}
|
||
function renderNode(node, options) {
|
||
switch (node.type) {
|
||
case Root:
|
||
return render$1(node.children, options);
|
||
// @ts-expect-error We don't use `Doctype` yet
|
||
case Doctype:
|
||
case Directive:
|
||
return renderDirective(node);
|
||
case Comment$1:
|
||
return renderComment(node);
|
||
case CDATA$1:
|
||
return renderCdata(node);
|
||
case Script:
|
||
case Style:
|
||
case Tag:
|
||
return renderTag(node, options);
|
||
case Text$1:
|
||
return renderText(node, options);
|
||
}
|
||
}
|
||
const foreignModeIntegrationPoints = /* @__PURE__ */ new Set([
|
||
"mi",
|
||
"mo",
|
||
"mn",
|
||
"ms",
|
||
"mtext",
|
||
"annotation-xml",
|
||
"foreignObject",
|
||
"desc",
|
||
"title"
|
||
]);
|
||
const foreignElements = /* @__PURE__ */ new Set(["svg", "math"]);
|
||
function renderTag(elem, opts) {
|
||
var _a2;
|
||
if (opts.xmlMode === "foreign") {
|
||
elem.name = (_a2 = elementNames.get(elem.name)) !== null && _a2 !== void 0 ? _a2 : elem.name;
|
||
if (elem.parent && foreignModeIntegrationPoints.has(elem.parent.name)) {
|
||
opts = { ...opts, xmlMode: false };
|
||
}
|
||
}
|
||
if (!opts.xmlMode && foreignElements.has(elem.name)) {
|
||
opts = { ...opts, xmlMode: "foreign" };
|
||
}
|
||
let tag = `<${elem.name}`;
|
||
const attribs = formatAttributes(elem.attribs, opts);
|
||
if (attribs) {
|
||
tag += ` ${attribs}`;
|
||
}
|
||
if (elem.children.length === 0 && (opts.xmlMode ? (
|
||
// In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags
|
||
opts.selfClosingTags !== false
|
||
) : (
|
||
// User explicitly asked for self-closing tags, even in HTML mode
|
||
opts.selfClosingTags && singleTag.has(elem.name)
|
||
))) {
|
||
if (!opts.xmlMode)
|
||
tag += " ";
|
||
tag += "/>";
|
||
} else {
|
||
tag += ">";
|
||
if (elem.children.length > 0) {
|
||
tag += render$1(elem.children, opts);
|
||
}
|
||
if (opts.xmlMode || !singleTag.has(elem.name)) {
|
||
tag += `</${elem.name}>`;
|
||
}
|
||
}
|
||
return tag;
|
||
}
|
||
function renderDirective(elem) {
|
||
return `<${elem.data}>`;
|
||
}
|
||
function renderText(elem, opts) {
|
||
var _a2;
|
||
let data2 = elem.data || "";
|
||
if (((_a2 = opts.encodeEntities) !== null && _a2 !== void 0 ? _a2 : opts.decodeEntities) !== false && !(!opts.xmlMode && elem.parent && unencodedElements.has(elem.parent.name))) {
|
||
data2 = opts.xmlMode || opts.encodeEntities !== "utf8" ? encodeXML(data2) : escapeText(data2);
|
||
}
|
||
return data2;
|
||
}
|
||
function renderCdata(elem) {
|
||
return `<![CDATA[${elem.children[0].data}]]>`;
|
||
}
|
||
function renderComment(elem) {
|
||
return `<!--${elem.data}-->`;
|
||
}
|
||
function getOuterHTML(node, options) {
|
||
return render$1(node, options);
|
||
}
|
||
function getInnerHTML(node, options) {
|
||
return hasChildren(node) ? node.children.map((node2) => getOuterHTML(node2, options)).join("") : "";
|
||
}
|
||
function getText(node) {
|
||
if (Array.isArray(node))
|
||
return node.map(getText).join("");
|
||
if (isTag(node))
|
||
return node.name === "br" ? "\n" : getText(node.children);
|
||
if (isCDATA(node))
|
||
return getText(node.children);
|
||
if (isText(node))
|
||
return node.data;
|
||
return "";
|
||
}
|
||
function textContent(node) {
|
||
if (Array.isArray(node))
|
||
return node.map(textContent).join("");
|
||
if (hasChildren(node) && !isComment(node)) {
|
||
return textContent(node.children);
|
||
}
|
||
if (isText(node))
|
||
return node.data;
|
||
return "";
|
||
}
|
||
function innerText(node) {
|
||
if (Array.isArray(node))
|
||
return node.map(innerText).join("");
|
||
if (hasChildren(node) && (node.type === ElementType.Tag || isCDATA(node))) {
|
||
return innerText(node.children);
|
||
}
|
||
if (isText(node))
|
||
return node.data;
|
||
return "";
|
||
}
|
||
function getChildren(elem) {
|
||
return hasChildren(elem) ? elem.children : [];
|
||
}
|
||
function getParent(elem) {
|
||
return elem.parent || null;
|
||
}
|
||
function getSiblings(elem) {
|
||
const parent2 = getParent(elem);
|
||
if (parent2 != null)
|
||
return getChildren(parent2);
|
||
const siblings2 = [elem];
|
||
let { prev: prev2, next: next2 } = elem;
|
||
while (prev2 != null) {
|
||
siblings2.unshift(prev2);
|
||
({ prev: prev2 } = prev2);
|
||
}
|
||
while (next2 != null) {
|
||
siblings2.push(next2);
|
||
({ next: next2 } = next2);
|
||
}
|
||
return siblings2;
|
||
}
|
||
function getAttributeValue(elem, name) {
|
||
var _a2;
|
||
return (_a2 = elem.attribs) === null || _a2 === void 0 ? void 0 : _a2[name];
|
||
}
|
||
function hasAttrib(elem, name) {
|
||
return elem.attribs != null && Object.prototype.hasOwnProperty.call(elem.attribs, name) && elem.attribs[name] != null;
|
||
}
|
||
function getName(elem) {
|
||
return elem.name;
|
||
}
|
||
function nextElementSibling(elem) {
|
||
let { next: next2 } = elem;
|
||
while (next2 !== null && !isTag(next2))
|
||
({ next: next2 } = next2);
|
||
return next2;
|
||
}
|
||
function prevElementSibling(elem) {
|
||
let { prev: prev2 } = elem;
|
||
while (prev2 !== null && !isTag(prev2))
|
||
({ prev: prev2 } = prev2);
|
||
return prev2;
|
||
}
|
||
function removeElement(elem) {
|
||
if (elem.prev)
|
||
elem.prev.next = elem.next;
|
||
if (elem.next)
|
||
elem.next.prev = elem.prev;
|
||
if (elem.parent) {
|
||
const childs = elem.parent.children;
|
||
const childsIndex = childs.lastIndexOf(elem);
|
||
if (childsIndex >= 0) {
|
||
childs.splice(childsIndex, 1);
|
||
}
|
||
}
|
||
elem.next = null;
|
||
elem.prev = null;
|
||
elem.parent = null;
|
||
}
|
||
function replaceElement(elem, replacement) {
|
||
const prev2 = replacement.prev = elem.prev;
|
||
if (prev2) {
|
||
prev2.next = replacement;
|
||
}
|
||
const next2 = replacement.next = elem.next;
|
||
if (next2) {
|
||
next2.prev = replacement;
|
||
}
|
||
const parent2 = replacement.parent = elem.parent;
|
||
if (parent2) {
|
||
const childs = parent2.children;
|
||
childs[childs.lastIndexOf(elem)] = replacement;
|
||
elem.parent = null;
|
||
}
|
||
}
|
||
function appendChild(parent2, child) {
|
||
removeElement(child);
|
||
child.next = null;
|
||
child.parent = parent2;
|
||
if (parent2.children.push(child) > 1) {
|
||
const sibling = parent2.children[parent2.children.length - 2];
|
||
sibling.next = child;
|
||
child.prev = sibling;
|
||
} else {
|
||
child.prev = null;
|
||
}
|
||
}
|
||
function append$1(elem, next2) {
|
||
removeElement(next2);
|
||
const { parent: parent2 } = elem;
|
||
const currNext = elem.next;
|
||
next2.next = currNext;
|
||
next2.prev = elem;
|
||
elem.next = next2;
|
||
next2.parent = parent2;
|
||
if (currNext) {
|
||
currNext.prev = next2;
|
||
if (parent2) {
|
||
const childs = parent2.children;
|
||
childs.splice(childs.lastIndexOf(currNext), 0, next2);
|
||
}
|
||
} else if (parent2) {
|
||
parent2.children.push(next2);
|
||
}
|
||
}
|
||
function prependChild(parent2, child) {
|
||
removeElement(child);
|
||
child.parent = parent2;
|
||
child.prev = null;
|
||
if (parent2.children.unshift(child) !== 1) {
|
||
const sibling = parent2.children[1];
|
||
sibling.prev = child;
|
||
child.next = sibling;
|
||
} else {
|
||
child.next = null;
|
||
}
|
||
}
|
||
function prepend$1(elem, prev2) {
|
||
removeElement(prev2);
|
||
const { parent: parent2 } = elem;
|
||
if (parent2) {
|
||
const childs = parent2.children;
|
||
childs.splice(childs.indexOf(elem), 0, prev2);
|
||
}
|
||
if (elem.prev) {
|
||
elem.prev.next = prev2;
|
||
}
|
||
prev2.parent = parent2;
|
||
prev2.prev = elem.prev;
|
||
prev2.next = elem;
|
||
elem.prev = prev2;
|
||
}
|
||
function filter$2(test, node, recurse = true, limit = Infinity) {
|
||
return find$2(test, Array.isArray(node) ? node : [node], recurse, limit);
|
||
}
|
||
function find$2(test, nodes, recurse, limit) {
|
||
const result = [];
|
||
const nodeStack = [nodes];
|
||
const indexStack = [0];
|
||
for (; ; ) {
|
||
if (indexStack[0] >= nodeStack[0].length) {
|
||
if (indexStack.length === 1) {
|
||
return result;
|
||
}
|
||
nodeStack.shift();
|
||
indexStack.shift();
|
||
continue;
|
||
}
|
||
const elem = nodeStack[0][indexStack[0]++];
|
||
if (test(elem)) {
|
||
result.push(elem);
|
||
if (--limit <= 0)
|
||
return result;
|
||
}
|
||
if (recurse && hasChildren(elem) && elem.children.length > 0) {
|
||
indexStack.unshift(0);
|
||
nodeStack.unshift(elem.children);
|
||
}
|
||
}
|
||
}
|
||
function findOneChild(test, nodes) {
|
||
return nodes.find(test);
|
||
}
|
||
function findOne(test, nodes, recurse = true) {
|
||
let elem = null;
|
||
for (let i = 0; i < nodes.length && !elem; i++) {
|
||
const node = nodes[i];
|
||
if (!isTag(node)) {
|
||
continue;
|
||
} else if (test(node)) {
|
||
elem = node;
|
||
} else if (recurse && node.children.length > 0) {
|
||
elem = findOne(test, node.children, true);
|
||
}
|
||
}
|
||
return elem;
|
||
}
|
||
function existsOne(test, nodes) {
|
||
return nodes.some((checked) => isTag(checked) && (test(checked) || existsOne(test, checked.children)));
|
||
}
|
||
function findAll(test, nodes) {
|
||
const result = [];
|
||
const nodeStack = [nodes];
|
||
const indexStack = [0];
|
||
for (; ; ) {
|
||
if (indexStack[0] >= nodeStack[0].length) {
|
||
if (nodeStack.length === 1) {
|
||
return result;
|
||
}
|
||
nodeStack.shift();
|
||
indexStack.shift();
|
||
continue;
|
||
}
|
||
const elem = nodeStack[0][indexStack[0]++];
|
||
if (!isTag(elem))
|
||
continue;
|
||
if (test(elem))
|
||
result.push(elem);
|
||
if (elem.children.length > 0) {
|
||
indexStack.unshift(0);
|
||
nodeStack.unshift(elem.children);
|
||
}
|
||
}
|
||
}
|
||
const Checks = {
|
||
tag_name(name) {
|
||
if (typeof name === "function") {
|
||
return (elem) => isTag(elem) && name(elem.name);
|
||
} else if (name === "*") {
|
||
return isTag;
|
||
}
|
||
return (elem) => isTag(elem) && elem.name === name;
|
||
},
|
||
tag_type(type) {
|
||
if (typeof type === "function") {
|
||
return (elem) => type(elem.type);
|
||
}
|
||
return (elem) => elem.type === type;
|
||
},
|
||
tag_contains(data2) {
|
||
if (typeof data2 === "function") {
|
||
return (elem) => isText(elem) && data2(elem.data);
|
||
}
|
||
return (elem) => isText(elem) && elem.data === data2;
|
||
}
|
||
};
|
||
function getAttribCheck(attrib, value) {
|
||
if (typeof value === "function") {
|
||
return (elem) => isTag(elem) && value(elem.attribs[attrib]);
|
||
}
|
||
return (elem) => isTag(elem) && elem.attribs[attrib] === value;
|
||
}
|
||
function combineFuncs(a, b) {
|
||
return (elem) => a(elem) || b(elem);
|
||
}
|
||
function compileTest(options) {
|
||
const funcs = Object.keys(options).map((key) => {
|
||
const value = options[key];
|
||
return Object.prototype.hasOwnProperty.call(Checks, key) ? Checks[key](value) : getAttribCheck(key, value);
|
||
});
|
||
return funcs.length === 0 ? null : funcs.reduce(combineFuncs);
|
||
}
|
||
function testElement(options, node) {
|
||
const test = compileTest(options);
|
||
return test ? test(node) : true;
|
||
}
|
||
function getElements(options, nodes, recurse, limit = Infinity) {
|
||
const test = compileTest(options);
|
||
return test ? filter$2(test, nodes, recurse, limit) : [];
|
||
}
|
||
function getElementById(id, nodes, recurse = true) {
|
||
if (!Array.isArray(nodes))
|
||
nodes = [nodes];
|
||
return findOne(getAttribCheck("id", id), nodes, recurse);
|
||
}
|
||
function getElementsByTagName(tagName, nodes, recurse = true, limit = Infinity) {
|
||
return filter$2(Checks["tag_name"](tagName), nodes, recurse, limit);
|
||
}
|
||
function getElementsByTagType(type, nodes, recurse = true, limit = Infinity) {
|
||
return filter$2(Checks["tag_type"](type), nodes, recurse, limit);
|
||
}
|
||
function removeSubsets(nodes) {
|
||
let idx = nodes.length;
|
||
while (--idx >= 0) {
|
||
const node = nodes[idx];
|
||
if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) {
|
||
nodes.splice(idx, 1);
|
||
continue;
|
||
}
|
||
for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
|
||
if (nodes.includes(ancestor)) {
|
||
nodes.splice(idx, 1);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return nodes;
|
||
}
|
||
var DocumentPosition;
|
||
(function(DocumentPosition2) {
|
||
DocumentPosition2[DocumentPosition2["DISCONNECTED"] = 1] = "DISCONNECTED";
|
||
DocumentPosition2[DocumentPosition2["PRECEDING"] = 2] = "PRECEDING";
|
||
DocumentPosition2[DocumentPosition2["FOLLOWING"] = 4] = "FOLLOWING";
|
||
DocumentPosition2[DocumentPosition2["CONTAINS"] = 8] = "CONTAINS";
|
||
DocumentPosition2[DocumentPosition2["CONTAINED_BY"] = 16] = "CONTAINED_BY";
|
||
})(DocumentPosition || (DocumentPosition = {}));
|
||
function compareDocumentPosition(nodeA, nodeB) {
|
||
const aParents = [];
|
||
const bParents = [];
|
||
if (nodeA === nodeB) {
|
||
return 0;
|
||
}
|
||
let current = hasChildren(nodeA) ? nodeA : nodeA.parent;
|
||
while (current) {
|
||
aParents.unshift(current);
|
||
current = current.parent;
|
||
}
|
||
current = hasChildren(nodeB) ? nodeB : nodeB.parent;
|
||
while (current) {
|
||
bParents.unshift(current);
|
||
current = current.parent;
|
||
}
|
||
const maxIdx = Math.min(aParents.length, bParents.length);
|
||
let idx = 0;
|
||
while (idx < maxIdx && aParents[idx] === bParents[idx]) {
|
||
idx++;
|
||
}
|
||
if (idx === 0) {
|
||
return DocumentPosition.DISCONNECTED;
|
||
}
|
||
const sharedParent = aParents[idx - 1];
|
||
const siblings2 = sharedParent.children;
|
||
const aSibling = aParents[idx];
|
||
const bSibling = bParents[idx];
|
||
if (siblings2.indexOf(aSibling) > siblings2.indexOf(bSibling)) {
|
||
if (sharedParent === nodeB) {
|
||
return DocumentPosition.FOLLOWING | DocumentPosition.CONTAINED_BY;
|
||
}
|
||
return DocumentPosition.FOLLOWING;
|
||
}
|
||
if (sharedParent === nodeA) {
|
||
return DocumentPosition.PRECEDING | DocumentPosition.CONTAINS;
|
||
}
|
||
return DocumentPosition.PRECEDING;
|
||
}
|
||
function uniqueSort(nodes) {
|
||
nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
|
||
nodes.sort((a, b) => {
|
||
const relative = compareDocumentPosition(a, b);
|
||
if (relative & DocumentPosition.PRECEDING) {
|
||
return -1;
|
||
} else if (relative & DocumentPosition.FOLLOWING) {
|
||
return 1;
|
||
}
|
||
return 0;
|
||
});
|
||
return nodes;
|
||
}
|
||
function getFeed(doc) {
|
||
const feedRoot = getOneElement(isValidFeed, doc);
|
||
return !feedRoot ? null : feedRoot.name === "feed" ? getAtomFeed(feedRoot) : getRssFeed(feedRoot);
|
||
}
|
||
function getAtomFeed(feedRoot) {
|
||
var _a2;
|
||
const childs = feedRoot.children;
|
||
const feed = {
|
||
type: "atom",
|
||
items: getElementsByTagName("entry", childs).map((item) => {
|
||
var _a3;
|
||
const { children: children2 } = item;
|
||
const entry = { media: getMediaElements(children2) };
|
||
addConditionally(entry, "id", "id", children2);
|
||
addConditionally(entry, "title", "title", children2);
|
||
const href2 = (_a3 = getOneElement("link", children2)) === null || _a3 === void 0 ? void 0 : _a3.attribs["href"];
|
||
if (href2) {
|
||
entry.link = href2;
|
||
}
|
||
const description = fetch("summary", children2) || fetch("content", children2);
|
||
if (description) {
|
||
entry.description = description;
|
||
}
|
||
const pubDate = fetch("updated", children2);
|
||
if (pubDate) {
|
||
entry.pubDate = new Date(pubDate);
|
||
}
|
||
return entry;
|
||
})
|
||
};
|
||
addConditionally(feed, "id", "id", childs);
|
||
addConditionally(feed, "title", "title", childs);
|
||
const href = (_a2 = getOneElement("link", childs)) === null || _a2 === void 0 ? void 0 : _a2.attribs["href"];
|
||
if (href) {
|
||
feed.link = href;
|
||
}
|
||
addConditionally(feed, "description", "subtitle", childs);
|
||
const updated = fetch("updated", childs);
|
||
if (updated) {
|
||
feed.updated = new Date(updated);
|
||
}
|
||
addConditionally(feed, "author", "email", childs, true);
|
||
return feed;
|
||
}
|
||
function getRssFeed(feedRoot) {
|
||
var _a2, _b;
|
||
const childs = (_b = (_a2 = getOneElement("channel", feedRoot.children)) === null || _a2 === void 0 ? void 0 : _a2.children) !== null && _b !== void 0 ? _b : [];
|
||
const feed = {
|
||
type: feedRoot.name.substr(0, 3),
|
||
id: "",
|
||
items: getElementsByTagName("item", feedRoot.children).map((item) => {
|
||
const { children: children2 } = item;
|
||
const entry = { media: getMediaElements(children2) };
|
||
addConditionally(entry, "id", "guid", children2);
|
||
addConditionally(entry, "title", "title", children2);
|
||
addConditionally(entry, "link", "link", children2);
|
||
addConditionally(entry, "description", "description", children2);
|
||
const pubDate = fetch("pubDate", children2) || fetch("dc:date", children2);
|
||
if (pubDate)
|
||
entry.pubDate = new Date(pubDate);
|
||
return entry;
|
||
})
|
||
};
|
||
addConditionally(feed, "title", "title", childs);
|
||
addConditionally(feed, "link", "link", childs);
|
||
addConditionally(feed, "description", "description", childs);
|
||
const updated = fetch("lastBuildDate", childs);
|
||
if (updated) {
|
||
feed.updated = new Date(updated);
|
||
}
|
||
addConditionally(feed, "author", "managingEditor", childs, true);
|
||
return feed;
|
||
}
|
||
const MEDIA_KEYS_STRING = ["url", "type", "lang"];
|
||
const MEDIA_KEYS_INT = [
|
||
"fileSize",
|
||
"bitrate",
|
||
"framerate",
|
||
"samplingrate",
|
||
"channels",
|
||
"duration",
|
||
"height",
|
||
"width"
|
||
];
|
||
function getMediaElements(where) {
|
||
return getElementsByTagName("media:content", where).map((elem) => {
|
||
const { attribs } = elem;
|
||
const media = {
|
||
medium: attribs["medium"],
|
||
isDefault: !!attribs["isDefault"]
|
||
};
|
||
for (const attrib of MEDIA_KEYS_STRING) {
|
||
if (attribs[attrib]) {
|
||
media[attrib] = attribs[attrib];
|
||
}
|
||
}
|
||
for (const attrib of MEDIA_KEYS_INT) {
|
||
if (attribs[attrib]) {
|
||
media[attrib] = parseInt(attribs[attrib], 10);
|
||
}
|
||
}
|
||
if (attribs["expression"]) {
|
||
media.expression = attribs["expression"];
|
||
}
|
||
return media;
|
||
});
|
||
}
|
||
function getOneElement(tagName, node) {
|
||
return getElementsByTagName(tagName, node, true, 1)[0];
|
||
}
|
||
function fetch(tagName, where, recurse = false) {
|
||
return textContent(getElementsByTagName(tagName, where, recurse, 1)).trim();
|
||
}
|
||
function addConditionally(obj, prop2, tagName, where, recurse = false) {
|
||
const val2 = fetch(tagName, where, recurse);
|
||
if (val2)
|
||
obj[prop2] = val2;
|
||
}
|
||
function isValidFeed(value) {
|
||
return value === "rss" || value === "feed" || value === "rdf:RDF";
|
||
}
|
||
const DomUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
get DocumentPosition() {
|
||
return DocumentPosition;
|
||
},
|
||
append: append$1,
|
||
appendChild,
|
||
compareDocumentPosition,
|
||
existsOne,
|
||
filter: filter$2,
|
||
find: find$2,
|
||
findAll,
|
||
findOne,
|
||
findOneChild,
|
||
getAttributeValue,
|
||
getChildren,
|
||
getElementById,
|
||
getElements,
|
||
getElementsByTagName,
|
||
getElementsByTagType,
|
||
getFeed,
|
||
getInnerHTML,
|
||
getName,
|
||
getOuterHTML,
|
||
getParent,
|
||
getSiblings,
|
||
getText,
|
||
hasAttrib,
|
||
hasChildren,
|
||
innerText,
|
||
isCDATA,
|
||
isComment,
|
||
isDocument,
|
||
isTag,
|
||
isText,
|
||
nextElementSibling,
|
||
prepend: prepend$1,
|
||
prependChild,
|
||
prevElementSibling,
|
||
removeElement,
|
||
removeSubsets,
|
||
replaceElement,
|
||
testElement,
|
||
textContent,
|
||
uniqueSort
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
function render(that, dom, options) {
|
||
if (!that)
|
||
return "";
|
||
return that(dom !== null && dom !== void 0 ? dom : that._root.children, null, void 0, options).toString();
|
||
}
|
||
function isOptions(dom, options) {
|
||
return typeof dom === "object" && dom != null && !("length" in dom) && !("type" in dom);
|
||
}
|
||
function html$1(dom, options) {
|
||
const toRender = isOptions(dom) ? (options = dom, void 0) : dom;
|
||
const opts = {
|
||
...this === null || this === void 0 ? void 0 : this._options,
|
||
...flattenOptions(options)
|
||
};
|
||
return render(this, toRender, opts);
|
||
}
|
||
function xml(dom) {
|
||
const options = { ...this._options, xmlMode: true };
|
||
return render(this, dom, options);
|
||
}
|
||
function text$1(elements) {
|
||
const elems = elements !== null && elements !== void 0 ? elements : this ? this.root() : [];
|
||
let ret = "";
|
||
for (let i = 0; i < elems.length; i++) {
|
||
ret += textContent(elems[i]);
|
||
}
|
||
return ret;
|
||
}
|
||
function parseHTML(data2, context, keepScripts = typeof context === "boolean" ? context : false) {
|
||
if (!data2 || typeof data2 !== "string") {
|
||
return null;
|
||
}
|
||
if (typeof context === "boolean") {
|
||
keepScripts = context;
|
||
}
|
||
const parsed = this.load(data2, this._options, false);
|
||
if (!keepScripts) {
|
||
parsed("script").remove();
|
||
}
|
||
return [...parsed.root()[0].children];
|
||
}
|
||
function root() {
|
||
return this(this._root);
|
||
}
|
||
function contains(container, contained) {
|
||
if (contained === container) {
|
||
return false;
|
||
}
|
||
let next2 = contained;
|
||
while (next2 && next2 !== next2.parent) {
|
||
next2 = next2.parent;
|
||
if (next2 === container) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
function extract$1(map2) {
|
||
return this.root().extract(map2);
|
||
}
|
||
function merge(arr1, arr2) {
|
||
if (!isArrayLike(arr1) || !isArrayLike(arr2)) {
|
||
return;
|
||
}
|
||
let newLength = arr1.length;
|
||
const len = +arr2.length;
|
||
for (let i = 0; i < len; i++) {
|
||
arr1[newLength++] = arr2[i];
|
||
}
|
||
arr1.length = newLength;
|
||
return arr1;
|
||
}
|
||
function isArrayLike(item) {
|
||
if (Array.isArray(item)) {
|
||
return true;
|
||
}
|
||
if (typeof item !== "object" || item === null || !("length" in item) || typeof item.length !== "number" || item.length < 0) {
|
||
return false;
|
||
}
|
||
for (let i = 0; i < item.length; i++) {
|
||
if (!(i in item)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
const staticMethods = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
contains,
|
||
extract: extract$1,
|
||
html: html$1,
|
||
merge,
|
||
parseHTML,
|
||
root,
|
||
text: text$1,
|
||
xml
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
function isCheerio(maybeCheerio) {
|
||
return maybeCheerio.cheerio != null;
|
||
}
|
||
function camelCase(str) {
|
||
return str.replace(/[._-](\w|$)/g, (_, x) => x.toUpperCase());
|
||
}
|
||
function cssCase(str) {
|
||
return str.replace(/[A-Z]/g, "-$&").toLowerCase();
|
||
}
|
||
function domEach(array, fn) {
|
||
const len = array.length;
|
||
for (let i = 0; i < len; i++)
|
||
fn(array[i], i);
|
||
return array;
|
||
}
|
||
var CharacterCodes;
|
||
(function(CharacterCodes2) {
|
||
CharacterCodes2[CharacterCodes2["LowerA"] = 97] = "LowerA";
|
||
CharacterCodes2[CharacterCodes2["LowerZ"] = 122] = "LowerZ";
|
||
CharacterCodes2[CharacterCodes2["UpperA"] = 65] = "UpperA";
|
||
CharacterCodes2[CharacterCodes2["UpperZ"] = 90] = "UpperZ";
|
||
CharacterCodes2[CharacterCodes2["Exclamation"] = 33] = "Exclamation";
|
||
})(CharacterCodes || (CharacterCodes = {}));
|
||
function isHtml(str) {
|
||
const tagStart = str.indexOf("<");
|
||
if (tagStart < 0 || tagStart > str.length - 3)
|
||
return false;
|
||
const tagChar = str.charCodeAt(tagStart + 1);
|
||
return (tagChar >= CharacterCodes.LowerA && tagChar <= CharacterCodes.LowerZ || tagChar >= CharacterCodes.UpperA && tagChar <= CharacterCodes.UpperZ || tagChar === CharacterCodes.Exclamation) && str.includes(">", tagStart + 2);
|
||
}
|
||
const hasOwn = Object.prototype.hasOwnProperty;
|
||
const rspace = /\s+/;
|
||
const dataAttrPrefix = "data-";
|
||
const rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i;
|
||
const rbrace = /^{[^]*}$|^\[[^]*]$/;
|
||
function getAttr(elem, name, xmlMode) {
|
||
var _a2;
|
||
if (!elem || !isTag(elem))
|
||
return void 0;
|
||
(_a2 = elem.attribs) !== null && _a2 !== void 0 ? _a2 : elem.attribs = {};
|
||
if (!name) {
|
||
return elem.attribs;
|
||
}
|
||
if (hasOwn.call(elem.attribs, name)) {
|
||
return !xmlMode && rboolean.test(name) ? name : elem.attribs[name];
|
||
}
|
||
if (elem.name === "option" && name === "value") {
|
||
return text$1(elem.children);
|
||
}
|
||
if (elem.name === "input" && (elem.attribs["type"] === "radio" || elem.attribs["type"] === "checkbox") && name === "value") {
|
||
return "on";
|
||
}
|
||
return void 0;
|
||
}
|
||
function setAttr(el, name, value) {
|
||
if (value === null) {
|
||
removeAttribute(el, name);
|
||
} else {
|
||
el.attribs[name] = `${value}`;
|
||
}
|
||
}
|
||
function attr(name, value) {
|
||
if (typeof name === "object" || value !== void 0) {
|
||
if (typeof value === "function") {
|
||
if (typeof name !== "string") {
|
||
{
|
||
throw new Error("Bad combination of arguments.");
|
||
}
|
||
}
|
||
return domEach(this, (el, i) => {
|
||
if (isTag(el))
|
||
setAttr(el, name, value.call(el, i, el.attribs[name]));
|
||
});
|
||
}
|
||
return domEach(this, (el) => {
|
||
if (!isTag(el))
|
||
return;
|
||
if (typeof name === "object") {
|
||
for (const objName of Object.keys(name)) {
|
||
const objValue = name[objName];
|
||
setAttr(el, objName, objValue);
|
||
}
|
||
} else {
|
||
setAttr(el, name, value);
|
||
}
|
||
});
|
||
}
|
||
return arguments.length > 1 ? this : getAttr(this[0], name, this.options.xmlMode);
|
||
}
|
||
function getProp(el, name, xmlMode) {
|
||
return name in el ? (
|
||
// @ts-expect-error TS doesn't like us accessing the value directly here.
|
||
el[name]
|
||
) : !xmlMode && rboolean.test(name) ? getAttr(el, name, false) !== void 0 : getAttr(el, name, xmlMode);
|
||
}
|
||
function setProp(el, name, value, xmlMode) {
|
||
if (name in el) {
|
||
el[name] = value;
|
||
} else {
|
||
setAttr(el, name, !xmlMode && rboolean.test(name) ? value ? "" : null : `${value}`);
|
||
}
|
||
}
|
||
function prop(name, value) {
|
||
var _a2;
|
||
if (typeof name === "string" && value === void 0) {
|
||
const el = this[0];
|
||
if (!el || !isTag(el))
|
||
return void 0;
|
||
switch (name) {
|
||
case "style": {
|
||
const property = this.css();
|
||
const keys = Object.keys(property);
|
||
for (let i = 0; i < keys.length; i++) {
|
||
property[i] = keys[i];
|
||
}
|
||
property.length = keys.length;
|
||
return property;
|
||
}
|
||
case "tagName":
|
||
case "nodeName": {
|
||
return el.name.toUpperCase();
|
||
}
|
||
case "href":
|
||
case "src": {
|
||
const prop2 = (_a2 = el.attribs) === null || _a2 === void 0 ? void 0 : _a2[name];
|
||
if (typeof URL !== "undefined" && (name === "href" && (el.tagName === "a" || el.tagName === "link") || name === "src" && (el.tagName === "img" || el.tagName === "iframe" || el.tagName === "audio" || el.tagName === "video" || el.tagName === "source")) && prop2 !== void 0 && this.options.baseURI) {
|
||
return new URL(prop2, this.options.baseURI).href;
|
||
}
|
||
return prop2;
|
||
}
|
||
case "innerText": {
|
||
return innerText(el);
|
||
}
|
||
case "textContent": {
|
||
return textContent(el);
|
||
}
|
||
case "outerHTML": {
|
||
return this.clone().wrap("<container />").parent().html();
|
||
}
|
||
case "innerHTML": {
|
||
return this.html();
|
||
}
|
||
default: {
|
||
return getProp(el, name, this.options.xmlMode);
|
||
}
|
||
}
|
||
}
|
||
if (typeof name === "object" || value !== void 0) {
|
||
if (typeof value === "function") {
|
||
if (typeof name === "object") {
|
||
throw new TypeError("Bad combination of arguments.");
|
||
}
|
||
return domEach(this, (el, i) => {
|
||
if (isTag(el)) {
|
||
setProp(el, name, value.call(el, i, getProp(el, name, this.options.xmlMode)), this.options.xmlMode);
|
||
}
|
||
});
|
||
}
|
||
return domEach(this, (el) => {
|
||
if (!isTag(el))
|
||
return;
|
||
if (typeof name === "object") {
|
||
for (const key of Object.keys(name)) {
|
||
const val2 = name[key];
|
||
setProp(el, key, val2, this.options.xmlMode);
|
||
}
|
||
} else {
|
||
setProp(el, name, value, this.options.xmlMode);
|
||
}
|
||
});
|
||
}
|
||
return void 0;
|
||
}
|
||
function setData(elem, name, value) {
|
||
var _a2;
|
||
(_a2 = elem.data) !== null && _a2 !== void 0 ? _a2 : elem.data = {};
|
||
if (typeof name === "object")
|
||
Object.assign(elem.data, name);
|
||
else if (typeof name === "string" && value !== void 0) {
|
||
elem.data[name] = value;
|
||
}
|
||
}
|
||
function readAllData(el) {
|
||
for (const domName of Object.keys(el.attribs)) {
|
||
if (!domName.startsWith(dataAttrPrefix)) {
|
||
continue;
|
||
}
|
||
const jsName = camelCase(domName.slice(dataAttrPrefix.length));
|
||
if (!hasOwn.call(el.data, jsName)) {
|
||
el.data[jsName] = parseDataValue(el.attribs[domName]);
|
||
}
|
||
}
|
||
return el.data;
|
||
}
|
||
function readData(el, name) {
|
||
const domName = dataAttrPrefix + cssCase(name);
|
||
const data2 = el.data;
|
||
if (hasOwn.call(data2, name)) {
|
||
return data2[name];
|
||
}
|
||
if (hasOwn.call(el.attribs, domName)) {
|
||
return data2[name] = parseDataValue(el.attribs[domName]);
|
||
}
|
||
return void 0;
|
||
}
|
||
function parseDataValue(value) {
|
||
if (value === "null")
|
||
return null;
|
||
if (value === "true")
|
||
return true;
|
||
if (value === "false")
|
||
return false;
|
||
const num = Number(value);
|
||
if (value === String(num))
|
||
return num;
|
||
if (rbrace.test(value)) {
|
||
try {
|
||
return JSON.parse(value);
|
||
} catch {
|
||
}
|
||
}
|
||
return value;
|
||
}
|
||
function data(name, value) {
|
||
var _a2;
|
||
const elem = this[0];
|
||
if (!elem || !isTag(elem))
|
||
return;
|
||
const dataEl = elem;
|
||
(_a2 = dataEl.data) !== null && _a2 !== void 0 ? _a2 : dataEl.data = {};
|
||
if (name == null) {
|
||
return readAllData(dataEl);
|
||
}
|
||
if (typeof name === "object" || value !== void 0) {
|
||
domEach(this, (el) => {
|
||
if (isTag(el)) {
|
||
if (typeof name === "object")
|
||
setData(el, name);
|
||
else
|
||
setData(el, name, value);
|
||
}
|
||
});
|
||
return this;
|
||
}
|
||
return readData(dataEl, name);
|
||
}
|
||
function val(value) {
|
||
const querying = arguments.length === 0;
|
||
const element = this[0];
|
||
if (!element || !isTag(element))
|
||
return querying ? void 0 : this;
|
||
switch (element.name) {
|
||
case "textarea": {
|
||
return this.text(value);
|
||
}
|
||
case "select": {
|
||
const option = this.find("option:selected");
|
||
if (!querying) {
|
||
if (this.attr("multiple") == null && typeof value === "object") {
|
||
return this;
|
||
}
|
||
this.find("option").removeAttr("selected");
|
||
const values = typeof value === "object" ? value : [value];
|
||
for (const val2 of values) {
|
||
this.find(`option[value="${val2}"]`).attr("selected", "");
|
||
}
|
||
return this;
|
||
}
|
||
return this.attr("multiple") ? option.toArray().map((el) => text$1(el.children)) : option.attr("value");
|
||
}
|
||
case "input":
|
||
case "option": {
|
||
return querying ? this.attr("value") : this.attr("value", value);
|
||
}
|
||
}
|
||
return void 0;
|
||
}
|
||
function removeAttribute(elem, name) {
|
||
if (!elem.attribs || !hasOwn.call(elem.attribs, name))
|
||
return;
|
||
delete elem.attribs[name];
|
||
}
|
||
function splitNames(names) {
|
||
return names ? names.trim().split(rspace) : [];
|
||
}
|
||
function removeAttr(name) {
|
||
const attrNames = splitNames(name);
|
||
for (const attrName of attrNames) {
|
||
domEach(this, (elem) => {
|
||
if (isTag(elem))
|
||
removeAttribute(elem, attrName);
|
||
});
|
||
}
|
||
return this;
|
||
}
|
||
function hasClass(className) {
|
||
return this.toArray().some((elem) => {
|
||
const clazz = isTag(elem) && elem.attribs["class"];
|
||
let idx = -1;
|
||
if (clazz && className.length > 0) {
|
||
while ((idx = clazz.indexOf(className, idx + 1)) > -1) {
|
||
const end2 = idx + className.length;
|
||
if ((idx === 0 || rspace.test(clazz[idx - 1])) && (end2 === clazz.length || rspace.test(clazz[end2]))) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
});
|
||
}
|
||
function addClass(value) {
|
||
if (typeof value === "function") {
|
||
return domEach(this, (el, i) => {
|
||
if (isTag(el)) {
|
||
const className = el.attribs["class"] || "";
|
||
addClass.call([el], value.call(el, i, className));
|
||
}
|
||
});
|
||
}
|
||
if (!value || typeof value !== "string")
|
||
return this;
|
||
const classNames = value.split(rspace);
|
||
const numElements = this.length;
|
||
for (let i = 0; i < numElements; i++) {
|
||
const el = this[i];
|
||
if (!isTag(el))
|
||
continue;
|
||
const className = getAttr(el, "class", false);
|
||
if (className) {
|
||
let setClass = ` ${className} `;
|
||
for (const cn of classNames) {
|
||
const appendClass = `${cn} `;
|
||
if (!setClass.includes(` ${appendClass}`))
|
||
setClass += appendClass;
|
||
}
|
||
setAttr(el, "class", setClass.trim());
|
||
} else {
|
||
setAttr(el, "class", classNames.join(" ").trim());
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
function removeClass(name) {
|
||
if (typeof name === "function") {
|
||
return domEach(this, (el, i) => {
|
||
if (isTag(el)) {
|
||
removeClass.call([el], name.call(el, i, el.attribs["class"] || ""));
|
||
}
|
||
});
|
||
}
|
||
const classes = splitNames(name);
|
||
const numClasses = classes.length;
|
||
const removeAll = arguments.length === 0;
|
||
return domEach(this, (el) => {
|
||
if (!isTag(el))
|
||
return;
|
||
if (removeAll) {
|
||
el.attribs["class"] = "";
|
||
} else {
|
||
const elClasses = splitNames(el.attribs["class"]);
|
||
let changed = false;
|
||
for (let j = 0; j < numClasses; j++) {
|
||
const index2 = elClasses.indexOf(classes[j]);
|
||
if (index2 >= 0) {
|
||
elClasses.splice(index2, 1);
|
||
changed = true;
|
||
j--;
|
||
}
|
||
}
|
||
if (changed) {
|
||
el.attribs["class"] = elClasses.join(" ");
|
||
}
|
||
}
|
||
});
|
||
}
|
||
function toggleClass(value, stateVal) {
|
||
if (typeof value === "function") {
|
||
return domEach(this, (el, i) => {
|
||
if (isTag(el)) {
|
||
toggleClass.call([el], value.call(el, i, el.attribs["class"] || "", stateVal), stateVal);
|
||
}
|
||
});
|
||
}
|
||
if (!value || typeof value !== "string")
|
||
return this;
|
||
const classNames = value.split(rspace);
|
||
const numClasses = classNames.length;
|
||
const state = typeof stateVal === "boolean" ? stateVal ? 1 : -1 : 0;
|
||
const numElements = this.length;
|
||
for (let i = 0; i < numElements; i++) {
|
||
const el = this[i];
|
||
if (!isTag(el))
|
||
continue;
|
||
const elementClasses = splitNames(el.attribs["class"]);
|
||
for (let j = 0; j < numClasses; j++) {
|
||
const index2 = elementClasses.indexOf(classNames[j]);
|
||
if (state >= 0 && index2 < 0) {
|
||
elementClasses.push(classNames[j]);
|
||
} else if (state <= 0 && index2 >= 0) {
|
||
elementClasses.splice(index2, 1);
|
||
}
|
||
}
|
||
el.attribs["class"] = elementClasses.join(" ");
|
||
}
|
||
return this;
|
||
}
|
||
const Attributes = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
addClass,
|
||
attr,
|
||
data,
|
||
hasClass,
|
||
prop,
|
||
removeAttr,
|
||
removeClass,
|
||
toggleClass,
|
||
val
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
var SelectorType;
|
||
(function(SelectorType2) {
|
||
SelectorType2["Attribute"] = "attribute";
|
||
SelectorType2["Pseudo"] = "pseudo";
|
||
SelectorType2["PseudoElement"] = "pseudo-element";
|
||
SelectorType2["Tag"] = "tag";
|
||
SelectorType2["Universal"] = "universal";
|
||
SelectorType2["Adjacent"] = "adjacent";
|
||
SelectorType2["Child"] = "child";
|
||
SelectorType2["Descendant"] = "descendant";
|
||
SelectorType2["Parent"] = "parent";
|
||
SelectorType2["Sibling"] = "sibling";
|
||
SelectorType2["ColumnCombinator"] = "column-combinator";
|
||
})(SelectorType || (SelectorType = {}));
|
||
var AttributeAction;
|
||
(function(AttributeAction2) {
|
||
AttributeAction2["Any"] = "any";
|
||
AttributeAction2["Element"] = "element";
|
||
AttributeAction2["End"] = "end";
|
||
AttributeAction2["Equals"] = "equals";
|
||
AttributeAction2["Exists"] = "exists";
|
||
AttributeAction2["Hyphen"] = "hyphen";
|
||
AttributeAction2["Not"] = "not";
|
||
AttributeAction2["Start"] = "start";
|
||
})(AttributeAction || (AttributeAction = {}));
|
||
const reName = /^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/;
|
||
const reEscape = /\\([\da-f]{1,6}\s?|(\s)|.)/gi;
|
||
const actionTypes = /* @__PURE__ */ new Map([
|
||
[126, AttributeAction.Element],
|
||
[94, AttributeAction.Start],
|
||
[36, AttributeAction.End],
|
||
[42, AttributeAction.Any],
|
||
[33, AttributeAction.Not],
|
||
[124, AttributeAction.Hyphen]
|
||
]);
|
||
const unpackPseudos = /* @__PURE__ */ new Set([
|
||
"has",
|
||
"not",
|
||
"matches",
|
||
"is",
|
||
"where",
|
||
"host",
|
||
"host-context"
|
||
]);
|
||
function isTraversal$1(selector) {
|
||
switch (selector.type) {
|
||
case SelectorType.Adjacent:
|
||
case SelectorType.Child:
|
||
case SelectorType.Descendant:
|
||
case SelectorType.Parent:
|
||
case SelectorType.Sibling:
|
||
case SelectorType.ColumnCombinator:
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|
||
const stripQuotesFromPseudos = /* @__PURE__ */ new Set(["contains", "icontains"]);
|
||
function funescape(_, escaped, escapedWhitespace) {
|
||
const high = parseInt(escaped, 16) - 65536;
|
||
return high !== high || escapedWhitespace ? escaped : high < 0 ? (
|
||
// BMP codepoint
|
||
String.fromCharCode(high + 65536)
|
||
) : (
|
||
// Supplemental Plane codepoint (surrogate pair)
|
||
String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320)
|
||
);
|
||
}
|
||
function unescapeCSS(str) {
|
||
return str.replace(reEscape, funescape);
|
||
}
|
||
function isQuote(c) {
|
||
return c === 39 || c === 34;
|
||
}
|
||
function isWhitespace$1(c) {
|
||
return c === 32 || c === 9 || c === 10 || c === 12 || c === 13;
|
||
}
|
||
function parse$2(selector) {
|
||
const subselects2 = [];
|
||
const endIndex = parseSelector(subselects2, `${selector}`, 0);
|
||
if (endIndex < selector.length) {
|
||
throw new Error(`Unmatched selector: ${selector.slice(endIndex)}`);
|
||
}
|
||
return subselects2;
|
||
}
|
||
function parseSelector(subselects2, selector, selectorIndex) {
|
||
let tokens = [];
|
||
function getName2(offset) {
|
||
const match = selector.slice(selectorIndex + offset).match(reName);
|
||
if (!match) {
|
||
throw new Error(`Expected name, found ${selector.slice(selectorIndex)}`);
|
||
}
|
||
const [name] = match;
|
||
selectorIndex += offset + name.length;
|
||
return unescapeCSS(name);
|
||
}
|
||
function stripWhitespace(offset) {
|
||
selectorIndex += offset;
|
||
while (selectorIndex < selector.length && isWhitespace$1(selector.charCodeAt(selectorIndex))) {
|
||
selectorIndex++;
|
||
}
|
||
}
|
||
function readValueWithParenthesis() {
|
||
selectorIndex += 1;
|
||
const start = selectorIndex;
|
||
let counter = 1;
|
||
for (; counter > 0 && selectorIndex < selector.length; selectorIndex++) {
|
||
if (selector.charCodeAt(selectorIndex) === 40 && !isEscaped(selectorIndex)) {
|
||
counter++;
|
||
} else if (selector.charCodeAt(selectorIndex) === 41 && !isEscaped(selectorIndex)) {
|
||
counter--;
|
||
}
|
||
}
|
||
if (counter) {
|
||
throw new Error("Parenthesis not matched");
|
||
}
|
||
return unescapeCSS(selector.slice(start, selectorIndex - 1));
|
||
}
|
||
function isEscaped(pos) {
|
||
let slashCount = 0;
|
||
while (selector.charCodeAt(--pos) === 92)
|
||
slashCount++;
|
||
return (slashCount & 1) === 1;
|
||
}
|
||
function ensureNotTraversal() {
|
||
if (tokens.length > 0 && isTraversal$1(tokens[tokens.length - 1])) {
|
||
throw new Error("Did not expect successive traversals.");
|
||
}
|
||
}
|
||
function addTraversal(type) {
|
||
if (tokens.length > 0 && tokens[tokens.length - 1].type === SelectorType.Descendant) {
|
||
tokens[tokens.length - 1].type = type;
|
||
return;
|
||
}
|
||
ensureNotTraversal();
|
||
tokens.push({ type });
|
||
}
|
||
function addSpecialAttribute(name, action) {
|
||
tokens.push({
|
||
type: SelectorType.Attribute,
|
||
name,
|
||
action,
|
||
value: getName2(1),
|
||
namespace: null,
|
||
ignoreCase: "quirks"
|
||
});
|
||
}
|
||
function finalizeSubselector() {
|
||
if (tokens.length && tokens[tokens.length - 1].type === SelectorType.Descendant) {
|
||
tokens.pop();
|
||
}
|
||
if (tokens.length === 0) {
|
||
throw new Error("Empty sub-selector");
|
||
}
|
||
subselects2.push(tokens);
|
||
}
|
||
stripWhitespace(0);
|
||
if (selector.length === selectorIndex) {
|
||
return selectorIndex;
|
||
}
|
||
loop: while (selectorIndex < selector.length) {
|
||
const firstChar = selector.charCodeAt(selectorIndex);
|
||
switch (firstChar) {
|
||
// Whitespace
|
||
case 32:
|
||
case 9:
|
||
case 10:
|
||
case 12:
|
||
case 13: {
|
||
if (tokens.length === 0 || tokens[0].type !== SelectorType.Descendant) {
|
||
ensureNotTraversal();
|
||
tokens.push({ type: SelectorType.Descendant });
|
||
}
|
||
stripWhitespace(1);
|
||
break;
|
||
}
|
||
// Traversals
|
||
case 62: {
|
||
addTraversal(SelectorType.Child);
|
||
stripWhitespace(1);
|
||
break;
|
||
}
|
||
case 60: {
|
||
addTraversal(SelectorType.Parent);
|
||
stripWhitespace(1);
|
||
break;
|
||
}
|
||
case 126: {
|
||
addTraversal(SelectorType.Sibling);
|
||
stripWhitespace(1);
|
||
break;
|
||
}
|
||
case 43: {
|
||
addTraversal(SelectorType.Adjacent);
|
||
stripWhitespace(1);
|
||
break;
|
||
}
|
||
// Special attribute selectors: .class, #id
|
||
case 46: {
|
||
addSpecialAttribute("class", AttributeAction.Element);
|
||
break;
|
||
}
|
||
case 35: {
|
||
addSpecialAttribute("id", AttributeAction.Equals);
|
||
break;
|
||
}
|
||
case 91: {
|
||
stripWhitespace(1);
|
||
let name;
|
||
let namespace = null;
|
||
if (selector.charCodeAt(selectorIndex) === 124) {
|
||
name = getName2(1);
|
||
} else if (selector.startsWith("*|", selectorIndex)) {
|
||
namespace = "*";
|
||
name = getName2(2);
|
||
} else {
|
||
name = getName2(0);
|
||
if (selector.charCodeAt(selectorIndex) === 124 && selector.charCodeAt(selectorIndex + 1) !== 61) {
|
||
namespace = name;
|
||
name = getName2(1);
|
||
}
|
||
}
|
||
stripWhitespace(0);
|
||
let action = AttributeAction.Exists;
|
||
const possibleAction = actionTypes.get(selector.charCodeAt(selectorIndex));
|
||
if (possibleAction) {
|
||
action = possibleAction;
|
||
if (selector.charCodeAt(selectorIndex + 1) !== 61) {
|
||
throw new Error("Expected `=`");
|
||
}
|
||
stripWhitespace(2);
|
||
} else if (selector.charCodeAt(selectorIndex) === 61) {
|
||
action = AttributeAction.Equals;
|
||
stripWhitespace(1);
|
||
}
|
||
let value = "";
|
||
let ignoreCase = null;
|
||
if (action !== "exists") {
|
||
if (isQuote(selector.charCodeAt(selectorIndex))) {
|
||
const quote = selector.charCodeAt(selectorIndex);
|
||
let sectionEnd = selectorIndex + 1;
|
||
while (sectionEnd < selector.length && (selector.charCodeAt(sectionEnd) !== quote || isEscaped(sectionEnd))) {
|
||
sectionEnd += 1;
|
||
}
|
||
if (selector.charCodeAt(sectionEnd) !== quote) {
|
||
throw new Error("Attribute value didn't end");
|
||
}
|
||
value = unescapeCSS(selector.slice(selectorIndex + 1, sectionEnd));
|
||
selectorIndex = sectionEnd + 1;
|
||
} else {
|
||
const valueStart = selectorIndex;
|
||
while (selectorIndex < selector.length && (!isWhitespace$1(selector.charCodeAt(selectorIndex)) && selector.charCodeAt(selectorIndex) !== 93 || isEscaped(selectorIndex))) {
|
||
selectorIndex += 1;
|
||
}
|
||
value = unescapeCSS(selector.slice(valueStart, selectorIndex));
|
||
}
|
||
stripWhitespace(0);
|
||
const forceIgnore = selector.charCodeAt(selectorIndex) | 32;
|
||
if (forceIgnore === 115) {
|
||
ignoreCase = false;
|
||
stripWhitespace(1);
|
||
} else if (forceIgnore === 105) {
|
||
ignoreCase = true;
|
||
stripWhitespace(1);
|
||
}
|
||
}
|
||
if (selector.charCodeAt(selectorIndex) !== 93) {
|
||
throw new Error("Attribute selector didn't terminate");
|
||
}
|
||
selectorIndex += 1;
|
||
const attributeSelector = {
|
||
type: SelectorType.Attribute,
|
||
name,
|
||
action,
|
||
value,
|
||
namespace,
|
||
ignoreCase
|
||
};
|
||
tokens.push(attributeSelector);
|
||
break;
|
||
}
|
||
case 58: {
|
||
if (selector.charCodeAt(selectorIndex + 1) === 58) {
|
||
tokens.push({
|
||
type: SelectorType.PseudoElement,
|
||
name: getName2(2).toLowerCase(),
|
||
data: selector.charCodeAt(selectorIndex) === 40 ? readValueWithParenthesis() : null
|
||
});
|
||
continue;
|
||
}
|
||
const name = getName2(1).toLowerCase();
|
||
let data2 = null;
|
||
if (selector.charCodeAt(selectorIndex) === 40) {
|
||
if (unpackPseudos.has(name)) {
|
||
if (isQuote(selector.charCodeAt(selectorIndex + 1))) {
|
||
throw new Error(`Pseudo-selector ${name} cannot be quoted`);
|
||
}
|
||
data2 = [];
|
||
selectorIndex = parseSelector(data2, selector, selectorIndex + 1);
|
||
if (selector.charCodeAt(selectorIndex) !== 41) {
|
||
throw new Error(`Missing closing parenthesis in :${name} (${selector})`);
|
||
}
|
||
selectorIndex += 1;
|
||
} else {
|
||
data2 = readValueWithParenthesis();
|
||
if (stripQuotesFromPseudos.has(name)) {
|
||
const quot = data2.charCodeAt(0);
|
||
if (quot === data2.charCodeAt(data2.length - 1) && isQuote(quot)) {
|
||
data2 = data2.slice(1, -1);
|
||
}
|
||
}
|
||
data2 = unescapeCSS(data2);
|
||
}
|
||
}
|
||
tokens.push({ type: SelectorType.Pseudo, name, data: data2 });
|
||
break;
|
||
}
|
||
case 44: {
|
||
finalizeSubselector();
|
||
tokens = [];
|
||
stripWhitespace(1);
|
||
break;
|
||
}
|
||
default: {
|
||
if (selector.startsWith("/*", selectorIndex)) {
|
||
const endIndex = selector.indexOf("*/", selectorIndex + 2);
|
||
if (endIndex < 0) {
|
||
throw new Error("Comment was not terminated");
|
||
}
|
||
selectorIndex = endIndex + 2;
|
||
if (tokens.length === 0) {
|
||
stripWhitespace(0);
|
||
}
|
||
break;
|
||
}
|
||
let namespace = null;
|
||
let name;
|
||
if (firstChar === 42) {
|
||
selectorIndex += 1;
|
||
name = "*";
|
||
} else if (firstChar === 124) {
|
||
name = "";
|
||
if (selector.charCodeAt(selectorIndex + 1) === 124) {
|
||
addTraversal(SelectorType.ColumnCombinator);
|
||
stripWhitespace(2);
|
||
break;
|
||
}
|
||
} else if (reName.test(selector.slice(selectorIndex))) {
|
||
name = getName2(0);
|
||
} else {
|
||
break loop;
|
||
}
|
||
if (selector.charCodeAt(selectorIndex) === 124 && selector.charCodeAt(selectorIndex + 1) !== 124) {
|
||
namespace = name;
|
||
if (selector.charCodeAt(selectorIndex + 1) === 42) {
|
||
name = "*";
|
||
selectorIndex += 2;
|
||
} else {
|
||
name = getName2(1);
|
||
}
|
||
}
|
||
tokens.push(name === "*" ? { type: SelectorType.Universal, namespace } : { type: SelectorType.Tag, name, namespace });
|
||
}
|
||
}
|
||
}
|
||
finalizeSubselector();
|
||
return selectorIndex;
|
||
}
|
||
function getDefaultExportFromCjs(x) {
|
||
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
||
}
|
||
var boolbase$1;
|
||
var hasRequiredBoolbase;
|
||
function requireBoolbase() {
|
||
if (hasRequiredBoolbase) return boolbase$1;
|
||
hasRequiredBoolbase = 1;
|
||
boolbase$1 = {
|
||
trueFunc: function trueFunc() {
|
||
return true;
|
||
},
|
||
falseFunc: function falseFunc() {
|
||
return false;
|
||
}
|
||
};
|
||
return boolbase$1;
|
||
}
|
||
var boolbaseExports = requireBoolbase();
|
||
const boolbase = /* @__PURE__ */ getDefaultExportFromCjs(boolbaseExports);
|
||
const procedure = /* @__PURE__ */ new Map([
|
||
[SelectorType.Universal, 50],
|
||
[SelectorType.Tag, 30],
|
||
[SelectorType.Attribute, 1],
|
||
[SelectorType.Pseudo, 0]
|
||
]);
|
||
function isTraversal(token) {
|
||
return !procedure.has(token.type);
|
||
}
|
||
const attributes = /* @__PURE__ */ new Map([
|
||
[AttributeAction.Exists, 10],
|
||
[AttributeAction.Equals, 8],
|
||
[AttributeAction.Not, 7],
|
||
[AttributeAction.Start, 6],
|
||
[AttributeAction.End, 6],
|
||
[AttributeAction.Any, 5]
|
||
]);
|
||
function sortByProcedure(arr) {
|
||
const procs = arr.map(getProcedure);
|
||
for (let i = 1; i < arr.length; i++) {
|
||
const procNew = procs[i];
|
||
if (procNew < 0)
|
||
continue;
|
||
for (let j = i - 1; j >= 0 && procNew < procs[j]; j--) {
|
||
const token = arr[j + 1];
|
||
arr[j + 1] = arr[j];
|
||
arr[j] = token;
|
||
procs[j + 1] = procs[j];
|
||
procs[j] = procNew;
|
||
}
|
||
}
|
||
}
|
||
function getProcedure(token) {
|
||
var _a2, _b;
|
||
let proc = (_a2 = procedure.get(token.type)) !== null && _a2 !== void 0 ? _a2 : -1;
|
||
if (token.type === SelectorType.Attribute) {
|
||
proc = (_b = attributes.get(token.action)) !== null && _b !== void 0 ? _b : 4;
|
||
if (token.action === AttributeAction.Equals && token.name === "id") {
|
||
proc = 9;
|
||
}
|
||
if (token.ignoreCase) {
|
||
proc >>= 1;
|
||
}
|
||
} else if (token.type === SelectorType.Pseudo) {
|
||
if (!token.data) {
|
||
proc = 3;
|
||
} else if (token.name === "has" || token.name === "contains") {
|
||
proc = 0;
|
||
} else if (Array.isArray(token.data)) {
|
||
proc = Math.min(...token.data.map((d) => Math.min(...d.map(getProcedure))));
|
||
if (proc < 0) {
|
||
proc = 0;
|
||
}
|
||
} else {
|
||
proc = 2;
|
||
}
|
||
}
|
||
return proc;
|
||
}
|
||
const reChars = /[-[\]{}()*+?.,\\^$|#\s]/g;
|
||
function escapeRegex(value) {
|
||
return value.replace(reChars, "\\$&");
|
||
}
|
||
const caseInsensitiveAttributes = /* @__PURE__ */ new Set([
|
||
"accept",
|
||
"accept-charset",
|
||
"align",
|
||
"alink",
|
||
"axis",
|
||
"bgcolor",
|
||
"charset",
|
||
"checked",
|
||
"clear",
|
||
"codetype",
|
||
"color",
|
||
"compact",
|
||
"declare",
|
||
"defer",
|
||
"dir",
|
||
"direction",
|
||
"disabled",
|
||
"enctype",
|
||
"face",
|
||
"frame",
|
||
"hreflang",
|
||
"http-equiv",
|
||
"lang",
|
||
"language",
|
||
"link",
|
||
"media",
|
||
"method",
|
||
"multiple",
|
||
"nohref",
|
||
"noresize",
|
||
"noshade",
|
||
"nowrap",
|
||
"readonly",
|
||
"rel",
|
||
"rev",
|
||
"rules",
|
||
"scope",
|
||
"scrolling",
|
||
"selected",
|
||
"shape",
|
||
"target",
|
||
"text",
|
||
"type",
|
||
"valign",
|
||
"valuetype",
|
||
"vlink"
|
||
]);
|
||
function shouldIgnoreCase(selector, options) {
|
||
return typeof selector.ignoreCase === "boolean" ? selector.ignoreCase : selector.ignoreCase === "quirks" ? !!options.quirksMode : !options.xmlMode && caseInsensitiveAttributes.has(selector.name);
|
||
}
|
||
const attributeRules = {
|
||
equals(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name } = data2;
|
||
let { value } = data2;
|
||
if (shouldIgnoreCase(data2, options)) {
|
||
value = value.toLowerCase();
|
||
return (elem) => {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return attr2 != null && attr2.length === value.length && attr2.toLowerCase() === value && next2(elem);
|
||
};
|
||
}
|
||
return (elem) => adapter.getAttributeValue(elem, name) === value && next2(elem);
|
||
},
|
||
hyphen(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name } = data2;
|
||
let { value } = data2;
|
||
const len = value.length;
|
||
if (shouldIgnoreCase(data2, options)) {
|
||
value = value.toLowerCase();
|
||
return function hyphenIC(elem) {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return attr2 != null && (attr2.length === len || attr2.charAt(len) === "-") && attr2.substr(0, len).toLowerCase() === value && next2(elem);
|
||
};
|
||
}
|
||
return function hyphen(elem) {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return attr2 != null && (attr2.length === len || attr2.charAt(len) === "-") && attr2.substr(0, len) === value && next2(elem);
|
||
};
|
||
},
|
||
element(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name, value } = data2;
|
||
if (/\s/.test(value)) {
|
||
return boolbase.falseFunc;
|
||
}
|
||
const regex = new RegExp(`(?:^|\\s)${escapeRegex(value)}(?:$|\\s)`, shouldIgnoreCase(data2, options) ? "i" : "");
|
||
return function element(elem) {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return attr2 != null && attr2.length >= value.length && regex.test(attr2) && next2(elem);
|
||
};
|
||
},
|
||
exists(next2, { name }, { adapter }) {
|
||
return (elem) => adapter.hasAttrib(elem, name) && next2(elem);
|
||
},
|
||
start(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name } = data2;
|
||
let { value } = data2;
|
||
const len = value.length;
|
||
if (len === 0) {
|
||
return boolbase.falseFunc;
|
||
}
|
||
if (shouldIgnoreCase(data2, options)) {
|
||
value = value.toLowerCase();
|
||
return (elem) => {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return attr2 != null && attr2.length >= len && attr2.substr(0, len).toLowerCase() === value && next2(elem);
|
||
};
|
||
}
|
||
return (elem) => {
|
||
var _a2;
|
||
return !!((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.startsWith(value)) && next2(elem);
|
||
};
|
||
},
|
||
end(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name } = data2;
|
||
let { value } = data2;
|
||
const len = -value.length;
|
||
if (len === 0) {
|
||
return boolbase.falseFunc;
|
||
}
|
||
if (shouldIgnoreCase(data2, options)) {
|
||
value = value.toLowerCase();
|
||
return (elem) => {
|
||
var _a2;
|
||
return ((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.substr(len).toLowerCase()) === value && next2(elem);
|
||
};
|
||
}
|
||
return (elem) => {
|
||
var _a2;
|
||
return !!((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.endsWith(value)) && next2(elem);
|
||
};
|
||
},
|
||
any(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name, value } = data2;
|
||
if (value === "") {
|
||
return boolbase.falseFunc;
|
||
}
|
||
if (shouldIgnoreCase(data2, options)) {
|
||
const regex = new RegExp(escapeRegex(value), "i");
|
||
return function anyIC(elem) {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return attr2 != null && attr2.length >= value.length && regex.test(attr2) && next2(elem);
|
||
};
|
||
}
|
||
return (elem) => {
|
||
var _a2;
|
||
return !!((_a2 = adapter.getAttributeValue(elem, name)) === null || _a2 === void 0 ? void 0 : _a2.includes(value)) && next2(elem);
|
||
};
|
||
},
|
||
not(next2, data2, options) {
|
||
const { adapter } = options;
|
||
const { name } = data2;
|
||
let { value } = data2;
|
||
if (value === "") {
|
||
return (elem) => !!adapter.getAttributeValue(elem, name) && next2(elem);
|
||
} else if (shouldIgnoreCase(data2, options)) {
|
||
value = value.toLowerCase();
|
||
return (elem) => {
|
||
const attr2 = adapter.getAttributeValue(elem, name);
|
||
return (attr2 == null || attr2.length !== value.length || attr2.toLowerCase() !== value) && next2(elem);
|
||
};
|
||
}
|
||
return (elem) => adapter.getAttributeValue(elem, name) !== value && next2(elem);
|
||
}
|
||
};
|
||
const whitespace = /* @__PURE__ */ new Set([9, 10, 12, 13, 32]);
|
||
const ZERO = "0".charCodeAt(0);
|
||
const NINE = "9".charCodeAt(0);
|
||
function parse$1(formula) {
|
||
formula = formula.trim().toLowerCase();
|
||
if (formula === "even") {
|
||
return [2, 0];
|
||
} else if (formula === "odd") {
|
||
return [2, 1];
|
||
}
|
||
let idx = 0;
|
||
let a = 0;
|
||
let sign = readSign();
|
||
let number = readNumber();
|
||
if (idx < formula.length && formula.charAt(idx) === "n") {
|
||
idx++;
|
||
a = sign * (number !== null && number !== void 0 ? number : 1);
|
||
skipWhitespace();
|
||
if (idx < formula.length) {
|
||
sign = readSign();
|
||
skipWhitespace();
|
||
number = readNumber();
|
||
} else {
|
||
sign = number = 0;
|
||
}
|
||
}
|
||
if (number === null || idx < formula.length) {
|
||
throw new Error(`n-th rule couldn't be parsed ('${formula}')`);
|
||
}
|
||
return [a, sign * number];
|
||
function readSign() {
|
||
if (formula.charAt(idx) === "-") {
|
||
idx++;
|
||
return -1;
|
||
}
|
||
if (formula.charAt(idx) === "+") {
|
||
idx++;
|
||
}
|
||
return 1;
|
||
}
|
||
function readNumber() {
|
||
const start = idx;
|
||
let value = 0;
|
||
while (idx < formula.length && formula.charCodeAt(idx) >= ZERO && formula.charCodeAt(idx) <= NINE) {
|
||
value = value * 10 + (formula.charCodeAt(idx) - ZERO);
|
||
idx++;
|
||
}
|
||
return idx === start ? null : value;
|
||
}
|
||
function skipWhitespace() {
|
||
while (idx < formula.length && whitespace.has(formula.charCodeAt(idx))) {
|
||
idx++;
|
||
}
|
||
}
|
||
}
|
||
function compile(parsed) {
|
||
const a = parsed[0];
|
||
const b = parsed[1] - 1;
|
||
if (b < 0 && a <= 0)
|
||
return boolbase.falseFunc;
|
||
if (a === -1)
|
||
return (index2) => index2 <= b;
|
||
if (a === 0)
|
||
return (index2) => index2 === b;
|
||
if (a === 1)
|
||
return b < 0 ? boolbase.trueFunc : (index2) => index2 >= b;
|
||
const absA = Math.abs(a);
|
||
const bMod = (b % absA + absA) % absA;
|
||
return a > 1 ? (index2) => index2 >= b && index2 % absA === bMod : (index2) => index2 <= b && index2 % absA === bMod;
|
||
}
|
||
function nthCheck(formula) {
|
||
return compile(parse$1(formula));
|
||
}
|
||
function getChildFunc(next2, adapter) {
|
||
return (elem) => {
|
||
const parent2 = adapter.getParent(elem);
|
||
return parent2 != null && adapter.isTag(parent2) && next2(elem);
|
||
};
|
||
}
|
||
const filters = {
|
||
contains(next2, text2, { adapter }) {
|
||
return function contains2(elem) {
|
||
return next2(elem) && adapter.getText(elem).includes(text2);
|
||
};
|
||
},
|
||
icontains(next2, text2, { adapter }) {
|
||
const itext = text2.toLowerCase();
|
||
return function icontains(elem) {
|
||
return next2(elem) && adapter.getText(elem).toLowerCase().includes(itext);
|
||
};
|
||
},
|
||
// Location specific methods
|
||
"nth-child"(next2, rule, { adapter, equals }) {
|
||
const func = nthCheck(rule);
|
||
if (func === boolbase.falseFunc)
|
||
return boolbase.falseFunc;
|
||
if (func === boolbase.trueFunc)
|
||
return getChildFunc(next2, adapter);
|
||
return function nthChild(elem) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
let pos = 0;
|
||
for (let i = 0; i < siblings2.length; i++) {
|
||
if (equals(elem, siblings2[i]))
|
||
break;
|
||
if (adapter.isTag(siblings2[i])) {
|
||
pos++;
|
||
}
|
||
}
|
||
return func(pos) && next2(elem);
|
||
};
|
||
},
|
||
"nth-last-child"(next2, rule, { adapter, equals }) {
|
||
const func = nthCheck(rule);
|
||
if (func === boolbase.falseFunc)
|
||
return boolbase.falseFunc;
|
||
if (func === boolbase.trueFunc)
|
||
return getChildFunc(next2, adapter);
|
||
return function nthLastChild(elem) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
let pos = 0;
|
||
for (let i = siblings2.length - 1; i >= 0; i--) {
|
||
if (equals(elem, siblings2[i]))
|
||
break;
|
||
if (adapter.isTag(siblings2[i])) {
|
||
pos++;
|
||
}
|
||
}
|
||
return func(pos) && next2(elem);
|
||
};
|
||
},
|
||
"nth-of-type"(next2, rule, { adapter, equals }) {
|
||
const func = nthCheck(rule);
|
||
if (func === boolbase.falseFunc)
|
||
return boolbase.falseFunc;
|
||
if (func === boolbase.trueFunc)
|
||
return getChildFunc(next2, adapter);
|
||
return function nthOfType(elem) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
let pos = 0;
|
||
for (let i = 0; i < siblings2.length; i++) {
|
||
const currentSibling = siblings2[i];
|
||
if (equals(elem, currentSibling))
|
||
break;
|
||
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === adapter.getName(elem)) {
|
||
pos++;
|
||
}
|
||
}
|
||
return func(pos) && next2(elem);
|
||
};
|
||
},
|
||
"nth-last-of-type"(next2, rule, { adapter, equals }) {
|
||
const func = nthCheck(rule);
|
||
if (func === boolbase.falseFunc)
|
||
return boolbase.falseFunc;
|
||
if (func === boolbase.trueFunc)
|
||
return getChildFunc(next2, adapter);
|
||
return function nthLastOfType(elem) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
let pos = 0;
|
||
for (let i = siblings2.length - 1; i >= 0; i--) {
|
||
const currentSibling = siblings2[i];
|
||
if (equals(elem, currentSibling))
|
||
break;
|
||
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === adapter.getName(elem)) {
|
||
pos++;
|
||
}
|
||
}
|
||
return func(pos) && next2(elem);
|
||
};
|
||
},
|
||
// TODO determine the actual root element
|
||
root(next2, _rule, { adapter }) {
|
||
return (elem) => {
|
||
const parent2 = adapter.getParent(elem);
|
||
return (parent2 == null || !adapter.isTag(parent2)) && next2(elem);
|
||
};
|
||
},
|
||
scope(next2, rule, options, context) {
|
||
const { equals } = options;
|
||
if (!context || context.length === 0) {
|
||
return filters["root"](next2, rule, options);
|
||
}
|
||
if (context.length === 1) {
|
||
return (elem) => equals(context[0], elem) && next2(elem);
|
||
}
|
||
return (elem) => context.includes(elem) && next2(elem);
|
||
},
|
||
hover: dynamicStatePseudo("isHovered"),
|
||
visited: dynamicStatePseudo("isVisited"),
|
||
active: dynamicStatePseudo("isActive")
|
||
};
|
||
function dynamicStatePseudo(name) {
|
||
return function dynamicPseudo(next2, _rule, { adapter }) {
|
||
const func = adapter[name];
|
||
if (typeof func !== "function") {
|
||
return boolbase.falseFunc;
|
||
}
|
||
return function active(elem) {
|
||
return func(elem) && next2(elem);
|
||
};
|
||
};
|
||
}
|
||
const pseudos = {
|
||
empty(elem, { adapter }) {
|
||
return !adapter.getChildren(elem).some((elem2) => (
|
||
// FIXME: `getText` call is potentially expensive.
|
||
adapter.isTag(elem2) || adapter.getText(elem2) !== ""
|
||
));
|
||
},
|
||
"first-child"(elem, { adapter, equals }) {
|
||
if (adapter.prevElementSibling) {
|
||
return adapter.prevElementSibling(elem) == null;
|
||
}
|
||
const firstChild = adapter.getSiblings(elem).find((elem2) => adapter.isTag(elem2));
|
||
return firstChild != null && equals(elem, firstChild);
|
||
},
|
||
"last-child"(elem, { adapter, equals }) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
for (let i = siblings2.length - 1; i >= 0; i--) {
|
||
if (equals(elem, siblings2[i]))
|
||
return true;
|
||
if (adapter.isTag(siblings2[i]))
|
||
break;
|
||
}
|
||
return false;
|
||
},
|
||
"first-of-type"(elem, { adapter, equals }) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
const elemName = adapter.getName(elem);
|
||
for (let i = 0; i < siblings2.length; i++) {
|
||
const currentSibling = siblings2[i];
|
||
if (equals(elem, currentSibling))
|
||
return true;
|
||
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === elemName) {
|
||
break;
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
"last-of-type"(elem, { adapter, equals }) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
const elemName = adapter.getName(elem);
|
||
for (let i = siblings2.length - 1; i >= 0; i--) {
|
||
const currentSibling = siblings2[i];
|
||
if (equals(elem, currentSibling))
|
||
return true;
|
||
if (adapter.isTag(currentSibling) && adapter.getName(currentSibling) === elemName) {
|
||
break;
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
"only-of-type"(elem, { adapter, equals }) {
|
||
const elemName = adapter.getName(elem);
|
||
return adapter.getSiblings(elem).every((sibling) => equals(elem, sibling) || !adapter.isTag(sibling) || adapter.getName(sibling) !== elemName);
|
||
},
|
||
"only-child"(elem, { adapter, equals }) {
|
||
return adapter.getSiblings(elem).every((sibling) => equals(elem, sibling) || !adapter.isTag(sibling));
|
||
}
|
||
};
|
||
function verifyPseudoArgs(func, name, subselect, argIndex) {
|
||
if (subselect === null) {
|
||
if (func.length > argIndex) {
|
||
throw new Error(`Pseudo-class :${name} requires an argument`);
|
||
}
|
||
} else if (func.length === argIndex) {
|
||
throw new Error(`Pseudo-class :${name} doesn't have any arguments`);
|
||
}
|
||
}
|
||
const aliases = {
|
||
// Links
|
||
"any-link": ":is(a, area, link)[href]",
|
||
link: ":any-link:not(:visited)",
|
||
// Forms
|
||
// https://html.spec.whatwg.org/multipage/scripting.html#disabled-elements
|
||
disabled: `:is(
|
||
:is(button, input, select, textarea, optgroup, option)[disabled],
|
||
optgroup[disabled] > option,
|
||
fieldset[disabled]:not(fieldset[disabled] legend:first-of-type *)
|
||
)`,
|
||
enabled: ":not(:disabled)",
|
||
checked: ":is(:is(input[type=radio], input[type=checkbox])[checked], option:selected)",
|
||
required: ":is(input, select, textarea)[required]",
|
||
optional: ":is(input, select, textarea):not([required])",
|
||
// JQuery extensions
|
||
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-option-selectedness
|
||
selected: "option:is([selected], select:not([multiple]):not(:has(> option[selected])) > :first-of-type)",
|
||
checkbox: "[type=checkbox]",
|
||
file: "[type=file]",
|
||
password: "[type=password]",
|
||
radio: "[type=radio]",
|
||
reset: "[type=reset]",
|
||
image: "[type=image]",
|
||
submit: "[type=submit]",
|
||
parent: ":not(:empty)",
|
||
header: ":is(h1, h2, h3, h4, h5, h6)",
|
||
button: ":is(button, input[type=button])",
|
||
input: ":is(input, textarea, select, button)",
|
||
text: "input:is(:not([type!='']), [type=text])"
|
||
};
|
||
const PLACEHOLDER_ELEMENT = {};
|
||
function ensureIsTag(next2, adapter) {
|
||
if (next2 === boolbase.falseFunc)
|
||
return boolbase.falseFunc;
|
||
return (elem) => adapter.isTag(elem) && next2(elem);
|
||
}
|
||
function getNextSiblings(elem, adapter) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
if (siblings2.length <= 1)
|
||
return [];
|
||
const elemIndex = siblings2.indexOf(elem);
|
||
if (elemIndex < 0 || elemIndex === siblings2.length - 1)
|
||
return [];
|
||
return siblings2.slice(elemIndex + 1).filter(adapter.isTag);
|
||
}
|
||
function copyOptions(options) {
|
||
return {
|
||
xmlMode: !!options.xmlMode,
|
||
lowerCaseAttributeNames: !!options.lowerCaseAttributeNames,
|
||
lowerCaseTags: !!options.lowerCaseTags,
|
||
quirksMode: !!options.quirksMode,
|
||
cacheResults: !!options.cacheResults,
|
||
pseudos: options.pseudos,
|
||
adapter: options.adapter,
|
||
equals: options.equals
|
||
};
|
||
}
|
||
const is$2 = (next2, token, options, context, compileToken2) => {
|
||
const func = compileToken2(token, copyOptions(options), context);
|
||
return func === boolbase.trueFunc ? next2 : func === boolbase.falseFunc ? boolbase.falseFunc : (elem) => func(elem) && next2(elem);
|
||
};
|
||
const subselects = {
|
||
is: is$2,
|
||
/**
|
||
* `:matches` and `:where` are aliases for `:is`.
|
||
*/
|
||
matches: is$2,
|
||
where: is$2,
|
||
not(next2, token, options, context, compileToken2) {
|
||
const func = compileToken2(token, copyOptions(options), context);
|
||
return func === boolbase.falseFunc ? next2 : func === boolbase.trueFunc ? boolbase.falseFunc : (elem) => !func(elem) && next2(elem);
|
||
},
|
||
has(next2, subselect, options, _context, compileToken2) {
|
||
const { adapter } = options;
|
||
const opts = copyOptions(options);
|
||
opts.relativeSelector = true;
|
||
const context = subselect.some((s) => s.some(isTraversal)) ? (
|
||
// Used as a placeholder. Will be replaced with the actual element.
|
||
[PLACEHOLDER_ELEMENT]
|
||
) : void 0;
|
||
const compiled = compileToken2(subselect, opts, context);
|
||
if (compiled === boolbase.falseFunc)
|
||
return boolbase.falseFunc;
|
||
const hasElement = ensureIsTag(compiled, adapter);
|
||
if (context && compiled !== boolbase.trueFunc) {
|
||
const { shouldTestNextSiblings = false } = compiled;
|
||
return (elem) => {
|
||
if (!next2(elem))
|
||
return false;
|
||
context[0] = elem;
|
||
const childs = adapter.getChildren(elem);
|
||
const nextElements = shouldTestNextSiblings ? [...childs, ...getNextSiblings(elem, adapter)] : childs;
|
||
return adapter.existsOne(hasElement, nextElements);
|
||
};
|
||
}
|
||
return (elem) => next2(elem) && adapter.existsOne(hasElement, adapter.getChildren(elem));
|
||
}
|
||
};
|
||
function compilePseudoSelector(next2, selector, options, context, compileToken2) {
|
||
var _a2;
|
||
const { name, data: data2 } = selector;
|
||
if (Array.isArray(data2)) {
|
||
if (!(name in subselects)) {
|
||
throw new Error(`Unknown pseudo-class :${name}(${data2})`);
|
||
}
|
||
return subselects[name](next2, data2, options, context, compileToken2);
|
||
}
|
||
const userPseudo = (_a2 = options.pseudos) === null || _a2 === void 0 ? void 0 : _a2[name];
|
||
const stringPseudo = typeof userPseudo === "string" ? userPseudo : aliases[name];
|
||
if (typeof stringPseudo === "string") {
|
||
if (data2 != null) {
|
||
throw new Error(`Pseudo ${name} doesn't have any arguments`);
|
||
}
|
||
const alias = parse$2(stringPseudo);
|
||
return subselects["is"](next2, alias, options, context, compileToken2);
|
||
}
|
||
if (typeof userPseudo === "function") {
|
||
verifyPseudoArgs(userPseudo, name, data2, 1);
|
||
return (elem) => userPseudo(elem, data2) && next2(elem);
|
||
}
|
||
if (name in filters) {
|
||
return filters[name](next2, data2, options, context);
|
||
}
|
||
if (name in pseudos) {
|
||
const pseudo = pseudos[name];
|
||
verifyPseudoArgs(pseudo, name, data2, 2);
|
||
return (elem) => pseudo(elem, options, data2) && next2(elem);
|
||
}
|
||
throw new Error(`Unknown pseudo-class :${name}`);
|
||
}
|
||
function getElementParent(node, adapter) {
|
||
const parent2 = adapter.getParent(node);
|
||
if (parent2 && adapter.isTag(parent2)) {
|
||
return parent2;
|
||
}
|
||
return null;
|
||
}
|
||
function compileGeneralSelector(next2, selector, options, context, compileToken2) {
|
||
const { adapter, equals } = options;
|
||
switch (selector.type) {
|
||
case SelectorType.PseudoElement: {
|
||
throw new Error("Pseudo-elements are not supported by css-select");
|
||
}
|
||
case SelectorType.ColumnCombinator: {
|
||
throw new Error("Column combinators are not yet supported by css-select");
|
||
}
|
||
case SelectorType.Attribute: {
|
||
if (selector.namespace != null) {
|
||
throw new Error("Namespaced attributes are not yet supported by css-select");
|
||
}
|
||
if (!options.xmlMode || options.lowerCaseAttributeNames) {
|
||
selector.name = selector.name.toLowerCase();
|
||
}
|
||
return attributeRules[selector.action](next2, selector, options);
|
||
}
|
||
case SelectorType.Pseudo: {
|
||
return compilePseudoSelector(next2, selector, options, context, compileToken2);
|
||
}
|
||
// Tags
|
||
case SelectorType.Tag: {
|
||
if (selector.namespace != null) {
|
||
throw new Error("Namespaced tag names are not yet supported by css-select");
|
||
}
|
||
let { name } = selector;
|
||
if (!options.xmlMode || options.lowerCaseTags) {
|
||
name = name.toLowerCase();
|
||
}
|
||
return function tag(elem) {
|
||
return adapter.getName(elem) === name && next2(elem);
|
||
};
|
||
}
|
||
// Traversal
|
||
case SelectorType.Descendant: {
|
||
if (options.cacheResults === false || typeof WeakSet === "undefined") {
|
||
return function descendant(elem) {
|
||
let current = elem;
|
||
while (current = getElementParent(current, adapter)) {
|
||
if (next2(current)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
const isFalseCache = /* @__PURE__ */ new WeakSet();
|
||
return function cachedDescendant(elem) {
|
||
let current = elem;
|
||
while (current = getElementParent(current, adapter)) {
|
||
if (!isFalseCache.has(current)) {
|
||
if (adapter.isTag(current) && next2(current)) {
|
||
return true;
|
||
}
|
||
isFalseCache.add(current);
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
case "_flexibleDescendant": {
|
||
return function flexibleDescendant(elem) {
|
||
let current = elem;
|
||
do {
|
||
if (next2(current))
|
||
return true;
|
||
} while (current = getElementParent(current, adapter));
|
||
return false;
|
||
};
|
||
}
|
||
case SelectorType.Parent: {
|
||
return function parent2(elem) {
|
||
return adapter.getChildren(elem).some((elem2) => adapter.isTag(elem2) && next2(elem2));
|
||
};
|
||
}
|
||
case SelectorType.Child: {
|
||
return function child(elem) {
|
||
const parent2 = adapter.getParent(elem);
|
||
return parent2 != null && adapter.isTag(parent2) && next2(parent2);
|
||
};
|
||
}
|
||
case SelectorType.Sibling: {
|
||
return function sibling(elem) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
for (let i = 0; i < siblings2.length; i++) {
|
||
const currentSibling = siblings2[i];
|
||
if (equals(elem, currentSibling))
|
||
break;
|
||
if (adapter.isTag(currentSibling) && next2(currentSibling)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
}
|
||
case SelectorType.Adjacent: {
|
||
if (adapter.prevElementSibling) {
|
||
return function adjacent(elem) {
|
||
const previous = adapter.prevElementSibling(elem);
|
||
return previous != null && next2(previous);
|
||
};
|
||
}
|
||
return function adjacent(elem) {
|
||
const siblings2 = adapter.getSiblings(elem);
|
||
let lastElement;
|
||
for (let i = 0; i < siblings2.length; i++) {
|
||
const currentSibling = siblings2[i];
|
||
if (equals(elem, currentSibling))
|
||
break;
|
||
if (adapter.isTag(currentSibling)) {
|
||
lastElement = currentSibling;
|
||
}
|
||
}
|
||
return !!lastElement && next2(lastElement);
|
||
};
|
||
}
|
||
case SelectorType.Universal: {
|
||
if (selector.namespace != null && selector.namespace !== "*") {
|
||
throw new Error("Namespaced universal selectors are not yet supported by css-select");
|
||
}
|
||
return next2;
|
||
}
|
||
}
|
||
}
|
||
function includesScopePseudo(t) {
|
||
return t.type === SelectorType.Pseudo && (t.name === "scope" || Array.isArray(t.data) && t.data.some((data2) => data2.some(includesScopePseudo)));
|
||
}
|
||
const DESCENDANT_TOKEN = { type: SelectorType.Descendant };
|
||
const FLEXIBLE_DESCENDANT_TOKEN = {
|
||
type: "_flexibleDescendant"
|
||
};
|
||
const SCOPE_TOKEN = {
|
||
type: SelectorType.Pseudo,
|
||
name: "scope",
|
||
data: null
|
||
};
|
||
function absolutize(token, { adapter }, context) {
|
||
const hasContext = !!(context === null || context === void 0 ? void 0 : context.every((e) => {
|
||
const parent2 = adapter.isTag(e) && adapter.getParent(e);
|
||
return e === PLACEHOLDER_ELEMENT || parent2 && adapter.isTag(parent2);
|
||
}));
|
||
for (const t of token) {
|
||
if (t.length > 0 && isTraversal(t[0]) && t[0].type !== SelectorType.Descendant) ;
|
||
else if (hasContext && !t.some(includesScopePseudo)) {
|
||
t.unshift(DESCENDANT_TOKEN);
|
||
} else {
|
||
continue;
|
||
}
|
||
t.unshift(SCOPE_TOKEN);
|
||
}
|
||
}
|
||
function compileToken(token, options, context) {
|
||
var _a2;
|
||
token.forEach(sortByProcedure);
|
||
context = (_a2 = options.context) !== null && _a2 !== void 0 ? _a2 : context;
|
||
const isArrayContext = Array.isArray(context);
|
||
const finalContext = context && (Array.isArray(context) ? context : [context]);
|
||
if (options.relativeSelector !== false) {
|
||
absolutize(token, options, finalContext);
|
||
} else if (token.some((t) => t.length > 0 && isTraversal(t[0]))) {
|
||
throw new Error("Relative selectors are not allowed when the `relativeSelector` option is disabled");
|
||
}
|
||
let shouldTestNextSiblings = false;
|
||
const query = token.map((rules) => {
|
||
if (rules.length >= 2) {
|
||
const [first2, second] = rules;
|
||
if (first2.type !== SelectorType.Pseudo || first2.name !== "scope") ;
|
||
else if (isArrayContext && second.type === SelectorType.Descendant) {
|
||
rules[1] = FLEXIBLE_DESCENDANT_TOKEN;
|
||
} else if (second.type === SelectorType.Adjacent || second.type === SelectorType.Sibling) {
|
||
shouldTestNextSiblings = true;
|
||
}
|
||
}
|
||
return compileRules(rules, options, finalContext);
|
||
}).reduce(reduceRules, boolbase.falseFunc);
|
||
query.shouldTestNextSiblings = shouldTestNextSiblings;
|
||
return query;
|
||
}
|
||
function compileRules(rules, options, context) {
|
||
var _a2;
|
||
return rules.reduce((previous, rule) => previous === boolbase.falseFunc ? boolbase.falseFunc : compileGeneralSelector(previous, rule, options, context, compileToken), (_a2 = options.rootFunc) !== null && _a2 !== void 0 ? _a2 : boolbase.trueFunc);
|
||
}
|
||
function reduceRules(a, b) {
|
||
if (b === boolbase.falseFunc || a === boolbase.trueFunc) {
|
||
return a;
|
||
}
|
||
if (a === boolbase.falseFunc || b === boolbase.trueFunc) {
|
||
return b;
|
||
}
|
||
return function combine(elem) {
|
||
return a(elem) || b(elem);
|
||
};
|
||
}
|
||
const defaultEquals = (a, b) => a === b;
|
||
const defaultOptions$1 = {
|
||
adapter: DomUtils,
|
||
equals: defaultEquals
|
||
};
|
||
function convertOptionFormats(options) {
|
||
var _a2, _b, _c, _d;
|
||
const opts = options !== null && options !== void 0 ? options : defaultOptions$1;
|
||
(_a2 = opts.adapter) !== null && _a2 !== void 0 ? _a2 : opts.adapter = DomUtils;
|
||
(_b = opts.equals) !== null && _b !== void 0 ? _b : opts.equals = (_d = (_c = opts.adapter) === null || _c === void 0 ? void 0 : _c.equals) !== null && _d !== void 0 ? _d : defaultEquals;
|
||
return opts;
|
||
}
|
||
function wrapCompile(func) {
|
||
return function addAdapter(selector, options, context) {
|
||
const opts = convertOptionFormats(options);
|
||
return func(selector, opts, context);
|
||
};
|
||
}
|
||
const _compileToken = wrapCompile(compileToken);
|
||
function prepareContext(elems, adapter, shouldTestNextSiblings = false) {
|
||
if (shouldTestNextSiblings) {
|
||
elems = appendNextSiblings(elems, adapter);
|
||
}
|
||
return Array.isArray(elems) ? adapter.removeSubsets(elems) : adapter.getChildren(elems);
|
||
}
|
||
function appendNextSiblings(elem, adapter) {
|
||
const elems = Array.isArray(elem) ? elem.slice(0) : [elem];
|
||
const elemsLength = elems.length;
|
||
for (let i = 0; i < elemsLength; i++) {
|
||
const nextSiblings = getNextSiblings(elems[i], adapter);
|
||
elems.push(...nextSiblings);
|
||
}
|
||
return elems;
|
||
}
|
||
const filterNames = /* @__PURE__ */ new Set([
|
||
"first",
|
||
"last",
|
||
"eq",
|
||
"gt",
|
||
"nth",
|
||
"lt",
|
||
"even",
|
||
"odd"
|
||
]);
|
||
function isFilter(s) {
|
||
if (s.type !== "pseudo")
|
||
return false;
|
||
if (filterNames.has(s.name))
|
||
return true;
|
||
if (s.name === "not" && Array.isArray(s.data)) {
|
||
return s.data.some((s2) => s2.some(isFilter));
|
||
}
|
||
return false;
|
||
}
|
||
function getLimit(filter2, data2, partLimit) {
|
||
const num = data2 != null ? parseInt(data2, 10) : NaN;
|
||
switch (filter2) {
|
||
case "first":
|
||
return 1;
|
||
case "nth":
|
||
case "eq":
|
||
return isFinite(num) ? num >= 0 ? num + 1 : Infinity : 0;
|
||
case "lt":
|
||
return isFinite(num) ? num >= 0 ? Math.min(num, partLimit) : Infinity : 0;
|
||
case "gt":
|
||
return isFinite(num) ? Infinity : 0;
|
||
case "odd":
|
||
return 2 * partLimit;
|
||
case "even":
|
||
return 2 * partLimit - 1;
|
||
case "last":
|
||
case "not":
|
||
return Infinity;
|
||
}
|
||
}
|
||
function getDocumentRoot(node) {
|
||
while (node.parent)
|
||
node = node.parent;
|
||
return node;
|
||
}
|
||
function groupSelectors(selectors) {
|
||
const filteredSelectors = [];
|
||
const plainSelectors = [];
|
||
for (const selector of selectors) {
|
||
if (selector.some(isFilter)) {
|
||
filteredSelectors.push(selector);
|
||
} else {
|
||
plainSelectors.push(selector);
|
||
}
|
||
}
|
||
return [plainSelectors, filteredSelectors];
|
||
}
|
||
const UNIVERSAL_SELECTOR = {
|
||
type: SelectorType.Universal,
|
||
namespace: null
|
||
};
|
||
const SCOPE_PSEUDO = {
|
||
type: SelectorType.Pseudo,
|
||
name: "scope",
|
||
data: null
|
||
};
|
||
function is$1(element, selector, options = {}) {
|
||
return some([element], selector, options);
|
||
}
|
||
function some(elements, selector, options = {}) {
|
||
if (typeof selector === "function")
|
||
return elements.some(selector);
|
||
const [plain, filtered] = groupSelectors(parse$2(selector));
|
||
return plain.length > 0 && elements.some(_compileToken(plain, options)) || filtered.some((sel) => filterBySelector(sel, elements, options).length > 0);
|
||
}
|
||
function filterByPosition(filter2, elems, data2, options) {
|
||
const num = typeof data2 === "string" ? parseInt(data2, 10) : NaN;
|
||
switch (filter2) {
|
||
case "first":
|
||
case "lt":
|
||
return elems;
|
||
case "last":
|
||
return elems.length > 0 ? [elems[elems.length - 1]] : elems;
|
||
case "nth":
|
||
case "eq":
|
||
return isFinite(num) && Math.abs(num) < elems.length ? [num < 0 ? elems[elems.length + num] : elems[num]] : [];
|
||
case "gt":
|
||
return isFinite(num) ? elems.slice(num + 1) : [];
|
||
case "even":
|
||
return elems.filter((_, i) => i % 2 === 0);
|
||
case "odd":
|
||
return elems.filter((_, i) => i % 2 === 1);
|
||
case "not": {
|
||
const filtered = new Set(filterParsed(data2, elems, options));
|
||
return elems.filter((e) => !filtered.has(e));
|
||
}
|
||
}
|
||
}
|
||
function filter$1(selector, elements, options = {}) {
|
||
return filterParsed(parse$2(selector), elements, options);
|
||
}
|
||
function filterParsed(selector, elements, options) {
|
||
if (elements.length === 0)
|
||
return [];
|
||
const [plainSelectors, filteredSelectors] = groupSelectors(selector);
|
||
let found;
|
||
if (plainSelectors.length) {
|
||
const filtered = filterElements(elements, plainSelectors, options);
|
||
if (filteredSelectors.length === 0) {
|
||
return filtered;
|
||
}
|
||
if (filtered.length) {
|
||
found = new Set(filtered);
|
||
}
|
||
}
|
||
for (let i = 0; i < filteredSelectors.length && (found === null || found === void 0 ? void 0 : found.size) !== elements.length; i++) {
|
||
const filteredSelector = filteredSelectors[i];
|
||
const missing = found ? elements.filter((e) => isTag(e) && !found.has(e)) : elements;
|
||
if (missing.length === 0)
|
||
break;
|
||
const filtered = filterBySelector(filteredSelector, elements, options);
|
||
if (filtered.length) {
|
||
if (!found) {
|
||
if (i === filteredSelectors.length - 1) {
|
||
return filtered;
|
||
}
|
||
found = new Set(filtered);
|
||
} else {
|
||
filtered.forEach((el) => found.add(el));
|
||
}
|
||
}
|
||
}
|
||
return typeof found !== "undefined" ? found.size === elements.length ? elements : (
|
||
// Filter elements to preserve order
|
||
elements.filter((el) => found.has(el))
|
||
) : [];
|
||
}
|
||
function filterBySelector(selector, elements, options) {
|
||
var _a2;
|
||
if (selector.some(isTraversal$1)) {
|
||
const root2 = (_a2 = options.root) !== null && _a2 !== void 0 ? _a2 : getDocumentRoot(elements[0]);
|
||
const opts = { ...options, context: elements, relativeSelector: false };
|
||
selector.push(SCOPE_PSEUDO);
|
||
return findFilterElements(root2, selector, opts, true, elements.length);
|
||
}
|
||
return findFilterElements(elements, selector, options, false, elements.length);
|
||
}
|
||
function select(selector, root2, options = {}, limit = Infinity) {
|
||
if (typeof selector === "function") {
|
||
return find$1(root2, selector);
|
||
}
|
||
const [plain, filtered] = groupSelectors(parse$2(selector));
|
||
const results = filtered.map((sel) => findFilterElements(root2, sel, options, true, limit));
|
||
if (plain.length) {
|
||
results.push(findElements(root2, plain, options, limit));
|
||
}
|
||
if (results.length === 0) {
|
||
return [];
|
||
}
|
||
if (results.length === 1) {
|
||
return results[0];
|
||
}
|
||
return uniqueSort(results.reduce((a, b) => [...a, ...b]));
|
||
}
|
||
function findFilterElements(root2, selector, options, queryForSelector, totalLimit) {
|
||
const filterIndex = selector.findIndex(isFilter);
|
||
const sub = selector.slice(0, filterIndex);
|
||
const filter2 = selector[filterIndex];
|
||
const partLimit = selector.length - 1 === filterIndex ? totalLimit : Infinity;
|
||
const limit = getLimit(filter2.name, filter2.data, partLimit);
|
||
if (limit === 0)
|
||
return [];
|
||
const elemsNoLimit = sub.length === 0 && !Array.isArray(root2) ? getChildren(root2).filter(isTag) : sub.length === 0 ? (Array.isArray(root2) ? root2 : [root2]).filter(isTag) : queryForSelector || sub.some(isTraversal$1) ? findElements(root2, [sub], options, limit) : filterElements(root2, [sub], options);
|
||
const elems = elemsNoLimit.slice(0, limit);
|
||
let result = filterByPosition(filter2.name, elems, filter2.data, options);
|
||
if (result.length === 0 || selector.length === filterIndex + 1) {
|
||
return result;
|
||
}
|
||
const remainingSelector = selector.slice(filterIndex + 1);
|
||
const remainingHasTraversal = remainingSelector.some(isTraversal$1);
|
||
if (remainingHasTraversal) {
|
||
if (isTraversal$1(remainingSelector[0])) {
|
||
const { type } = remainingSelector[0];
|
||
if (type === SelectorType.Sibling || type === SelectorType.Adjacent) {
|
||
result = prepareContext(result, DomUtils, true);
|
||
}
|
||
remainingSelector.unshift(UNIVERSAL_SELECTOR);
|
||
}
|
||
options = {
|
||
...options,
|
||
// Avoid absolutizing the selector
|
||
relativeSelector: false,
|
||
/*
|
||
* Add a custom root func, to make sure traversals don't match elements
|
||
* that aren't a part of the considered tree.
|
||
*/
|
||
rootFunc: (el) => result.includes(el)
|
||
};
|
||
} else if (options.rootFunc && options.rootFunc !== boolbaseExports.trueFunc) {
|
||
options = { ...options, rootFunc: boolbaseExports.trueFunc };
|
||
}
|
||
return remainingSelector.some(isFilter) ? findFilterElements(result, remainingSelector, options, false, totalLimit) : remainingHasTraversal ? (
|
||
// Query existing elements to resolve traversal.
|
||
findElements(result, [remainingSelector], options, totalLimit)
|
||
) : (
|
||
// If we don't have any more traversals, simply filter elements.
|
||
filterElements(result, [remainingSelector], options)
|
||
);
|
||
}
|
||
function findElements(root2, sel, options, limit) {
|
||
const query = _compileToken(sel, options, root2);
|
||
return find$1(root2, query, limit);
|
||
}
|
||
function find$1(root2, query, limit = Infinity) {
|
||
const elems = prepareContext(root2, DomUtils, query.shouldTestNextSiblings);
|
||
return find$2((node) => isTag(node) && query(node), elems, true, limit);
|
||
}
|
||
function filterElements(elements, sel, options) {
|
||
const els = (Array.isArray(elements) ? elements : [elements]).filter(isTag);
|
||
if (els.length === 0)
|
||
return els;
|
||
const query = _compileToken(sel, options);
|
||
return query === boolbaseExports.trueFunc ? els : els.filter(query);
|
||
}
|
||
const reSiblingSelector = /^\s*[+~]/;
|
||
function find(selectorOrHaystack) {
|
||
if (!selectorOrHaystack) {
|
||
return this._make([]);
|
||
}
|
||
if (typeof selectorOrHaystack !== "string") {
|
||
const haystack = isCheerio(selectorOrHaystack) ? selectorOrHaystack.toArray() : [selectorOrHaystack];
|
||
const context = this.toArray();
|
||
return this._make(haystack.filter((elem) => context.some((node) => contains(node, elem))));
|
||
}
|
||
return this._findBySelector(selectorOrHaystack, Number.POSITIVE_INFINITY);
|
||
}
|
||
function _findBySelector(selector, limit) {
|
||
var _a2;
|
||
const context = this.toArray();
|
||
const elems = reSiblingSelector.test(selector) ? context : this.children().toArray();
|
||
const options = {
|
||
context,
|
||
root: (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0],
|
||
// Pass options that are recognized by `cheerio-select`
|
||
xmlMode: this.options.xmlMode,
|
||
lowerCaseTags: this.options.lowerCaseTags,
|
||
lowerCaseAttributeNames: this.options.lowerCaseAttributeNames,
|
||
pseudos: this.options.pseudos,
|
||
quirksMode: this.options.quirksMode
|
||
};
|
||
return this._make(select(selector, elems, options, limit));
|
||
}
|
||
function _getMatcher(matchMap) {
|
||
return function(fn, ...postFns) {
|
||
return function(selector) {
|
||
var _a2;
|
||
let matched = matchMap(fn, this);
|
||
if (selector) {
|
||
matched = filterArray(matched, selector, this.options.xmlMode, (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0]);
|
||
}
|
||
return this._make(
|
||
// Post processing is only necessary if there is more than one element.
|
||
this.length > 1 && matched.length > 1 ? postFns.reduce((elems, fn2) => fn2(elems), matched) : matched
|
||
);
|
||
};
|
||
};
|
||
}
|
||
const _matcher = _getMatcher((fn, elems) => {
|
||
let ret = [];
|
||
for (let i = 0; i < elems.length; i++) {
|
||
const value = fn(elems[i]);
|
||
if (value.length > 0)
|
||
ret = ret.concat(value);
|
||
}
|
||
return ret;
|
||
});
|
||
const _singleMatcher = _getMatcher((fn, elems) => {
|
||
const ret = [];
|
||
for (let i = 0; i < elems.length; i++) {
|
||
const value = fn(elems[i]);
|
||
if (value !== null) {
|
||
ret.push(value);
|
||
}
|
||
}
|
||
return ret;
|
||
});
|
||
function _matchUntil(nextElem, ...postFns) {
|
||
let matches = null;
|
||
const innerMatcher = _getMatcher((nextElem2, elems) => {
|
||
const matched = [];
|
||
domEach(elems, (elem) => {
|
||
for (let next2; next2 = nextElem2(elem); elem = next2) {
|
||
if (matches === null || matches === void 0 ? void 0 : matches(next2, matched.length))
|
||
break;
|
||
matched.push(next2);
|
||
}
|
||
});
|
||
return matched;
|
||
})(nextElem, ...postFns);
|
||
return function(selector, filterSelector) {
|
||
matches = typeof selector === "string" ? (elem) => is$1(elem, selector, this.options) : selector ? getFilterFn(selector) : null;
|
||
const ret = innerMatcher.call(this, filterSelector);
|
||
matches = null;
|
||
return ret;
|
||
};
|
||
}
|
||
function _removeDuplicates(elems) {
|
||
return elems.length > 1 ? Array.from(new Set(elems)) : elems;
|
||
}
|
||
const parent = _singleMatcher(({ parent: parent2 }) => parent2 && !isDocument(parent2) ? parent2 : null, _removeDuplicates);
|
||
const parents = _matcher((elem) => {
|
||
const matched = [];
|
||
while (elem.parent && !isDocument(elem.parent)) {
|
||
matched.push(elem.parent);
|
||
elem = elem.parent;
|
||
}
|
||
return matched;
|
||
}, uniqueSort, (elems) => elems.reverse());
|
||
const parentsUntil = _matchUntil(({ parent: parent2 }) => parent2 && !isDocument(parent2) ? parent2 : null, uniqueSort, (elems) => elems.reverse());
|
||
function closest(selector) {
|
||
var _a2;
|
||
const set = [];
|
||
if (!selector) {
|
||
return this._make(set);
|
||
}
|
||
const selectOpts = {
|
||
xmlMode: this.options.xmlMode,
|
||
root: (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0]
|
||
};
|
||
const selectFn = typeof selector === "string" ? (elem) => is$1(elem, selector, selectOpts) : getFilterFn(selector);
|
||
domEach(this, (elem) => {
|
||
if (elem && !isDocument(elem) && !isTag(elem)) {
|
||
elem = elem.parent;
|
||
}
|
||
while (elem && isTag(elem)) {
|
||
if (selectFn(elem, 0)) {
|
||
if (!set.includes(elem)) {
|
||
set.push(elem);
|
||
}
|
||
break;
|
||
}
|
||
elem = elem.parent;
|
||
}
|
||
});
|
||
return this._make(set);
|
||
}
|
||
const next = _singleMatcher((elem) => nextElementSibling(elem));
|
||
const nextAll = _matcher((elem) => {
|
||
const matched = [];
|
||
while (elem.next) {
|
||
elem = elem.next;
|
||
if (isTag(elem))
|
||
matched.push(elem);
|
||
}
|
||
return matched;
|
||
}, _removeDuplicates);
|
||
const nextUntil = _matchUntil((el) => nextElementSibling(el), _removeDuplicates);
|
||
const prev = _singleMatcher((elem) => prevElementSibling(elem));
|
||
const prevAll = _matcher((elem) => {
|
||
const matched = [];
|
||
while (elem.prev) {
|
||
elem = elem.prev;
|
||
if (isTag(elem))
|
||
matched.push(elem);
|
||
}
|
||
return matched;
|
||
}, _removeDuplicates);
|
||
const prevUntil = _matchUntil((el) => prevElementSibling(el), _removeDuplicates);
|
||
const siblings = _matcher((elem) => getSiblings(elem).filter((el) => isTag(el) && el !== elem), uniqueSort);
|
||
const children = _matcher((elem) => getChildren(elem).filter(isTag), _removeDuplicates);
|
||
function contents() {
|
||
const elems = this.toArray().reduce((newElems, elem) => hasChildren(elem) ? newElems.concat(elem.children) : newElems, []);
|
||
return this._make(elems);
|
||
}
|
||
function each(fn) {
|
||
let i = 0;
|
||
const len = this.length;
|
||
while (i < len && fn.call(this[i], i, this[i]) !== false)
|
||
++i;
|
||
return this;
|
||
}
|
||
function map(fn) {
|
||
let elems = [];
|
||
for (let i = 0; i < this.length; i++) {
|
||
const el = this[i];
|
||
const val2 = fn.call(el, i, el);
|
||
if (val2 != null) {
|
||
elems = elems.concat(val2);
|
||
}
|
||
}
|
||
return this._make(elems);
|
||
}
|
||
function getFilterFn(match) {
|
||
if (typeof match === "function") {
|
||
return (el, i) => match.call(el, i, el);
|
||
}
|
||
if (isCheerio(match)) {
|
||
return (el) => Array.prototype.includes.call(match, el);
|
||
}
|
||
return function(el) {
|
||
return match === el;
|
||
};
|
||
}
|
||
function filter(match) {
|
||
var _a2;
|
||
return this._make(filterArray(this.toArray(), match, this.options.xmlMode, (_a2 = this._root) === null || _a2 === void 0 ? void 0 : _a2[0]));
|
||
}
|
||
function filterArray(nodes, match, xmlMode, root2) {
|
||
return typeof match === "string" ? filter$1(match, nodes, { xmlMode, root: root2 }) : nodes.filter(getFilterFn(match));
|
||
}
|
||
function is(selector) {
|
||
const nodes = this.toArray();
|
||
return typeof selector === "string" ? some(nodes.filter(isTag), selector, this.options) : selector ? nodes.some(getFilterFn(selector)) : false;
|
||
}
|
||
function not(match) {
|
||
let nodes = this.toArray();
|
||
if (typeof match === "string") {
|
||
const matches = new Set(filter$1(match, nodes, this.options));
|
||
nodes = nodes.filter((el) => !matches.has(el));
|
||
} else {
|
||
const filterFn = getFilterFn(match);
|
||
nodes = nodes.filter((el, i) => !filterFn(el, i));
|
||
}
|
||
return this._make(nodes);
|
||
}
|
||
function has(selectorOrHaystack) {
|
||
return this.filter(typeof selectorOrHaystack === "string" ? (
|
||
// Using the `:has` selector here short-circuits searches.
|
||
`:has(${selectorOrHaystack})`
|
||
) : (_, el) => this._make(el).find(selectorOrHaystack).length > 0);
|
||
}
|
||
function first() {
|
||
return this.length > 1 ? this._make(this[0]) : this;
|
||
}
|
||
function last() {
|
||
return this.length > 0 ? this._make(this[this.length - 1]) : this;
|
||
}
|
||
function eq(i) {
|
||
var _a2;
|
||
i = +i;
|
||
if (i === 0 && this.length <= 1)
|
||
return this;
|
||
if (i < 0)
|
||
i = this.length + i;
|
||
return this._make((_a2 = this[i]) !== null && _a2 !== void 0 ? _a2 : []);
|
||
}
|
||
function get(i) {
|
||
if (i == null) {
|
||
return this.toArray();
|
||
}
|
||
return this[i < 0 ? this.length + i : i];
|
||
}
|
||
function toArray() {
|
||
return Array.prototype.slice.call(this);
|
||
}
|
||
function index(selectorOrNeedle) {
|
||
let $haystack;
|
||
let needle;
|
||
if (selectorOrNeedle == null) {
|
||
$haystack = this.parent().children();
|
||
needle = this[0];
|
||
} else if (typeof selectorOrNeedle === "string") {
|
||
$haystack = this._make(selectorOrNeedle);
|
||
needle = this[0];
|
||
} else {
|
||
$haystack = this;
|
||
needle = isCheerio(selectorOrNeedle) ? selectorOrNeedle[0] : selectorOrNeedle;
|
||
}
|
||
return Array.prototype.indexOf.call($haystack, needle);
|
||
}
|
||
function slice(start, end2) {
|
||
return this._make(Array.prototype.slice.call(this, start, end2));
|
||
}
|
||
function end() {
|
||
var _a2;
|
||
return (_a2 = this.prevObject) !== null && _a2 !== void 0 ? _a2 : this._make([]);
|
||
}
|
||
function add(other, context) {
|
||
const selection = this._make(other, context);
|
||
const contents2 = uniqueSort([...this.get(), ...selection.get()]);
|
||
return this._make(contents2);
|
||
}
|
||
function addBack(selector) {
|
||
return this.prevObject ? this.add(selector ? this.prevObject.filter(selector) : this.prevObject) : this;
|
||
}
|
||
const Traversing = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
_findBySelector,
|
||
add,
|
||
addBack,
|
||
children,
|
||
closest,
|
||
contents,
|
||
each,
|
||
end,
|
||
eq,
|
||
filter,
|
||
filterArray,
|
||
find,
|
||
first,
|
||
get,
|
||
has,
|
||
index,
|
||
is,
|
||
last,
|
||
map,
|
||
next,
|
||
nextAll,
|
||
nextUntil,
|
||
not,
|
||
parent,
|
||
parents,
|
||
parentsUntil,
|
||
prev,
|
||
prevAll,
|
||
prevUntil,
|
||
siblings,
|
||
slice,
|
||
toArray
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
function getParse(parser) {
|
||
return function parse2(content, options, isDocument$1, context) {
|
||
if (typeof Buffer !== "undefined" && Buffer.isBuffer(content)) {
|
||
content = content.toString();
|
||
}
|
||
if (typeof content === "string") {
|
||
return parser(content, options, isDocument$1, context);
|
||
}
|
||
const doc = content;
|
||
if (!Array.isArray(doc) && isDocument(doc)) {
|
||
return doc;
|
||
}
|
||
const root2 = new Document([]);
|
||
update(doc, root2);
|
||
return root2;
|
||
};
|
||
}
|
||
function update(newChilds, parent2) {
|
||
const arr = Array.isArray(newChilds) ? newChilds : [newChilds];
|
||
if (parent2) {
|
||
parent2.children = arr;
|
||
} else {
|
||
parent2 = null;
|
||
}
|
||
for (let i = 0; i < arr.length; i++) {
|
||
const node = arr[i];
|
||
if (node.parent && node.parent.children !== arr) {
|
||
removeElement(node);
|
||
}
|
||
if (parent2) {
|
||
node.prev = arr[i - 1] || null;
|
||
node.next = arr[i + 1] || null;
|
||
} else {
|
||
node.prev = node.next = null;
|
||
}
|
||
node.parent = parent2;
|
||
}
|
||
return parent2;
|
||
}
|
||
function _makeDomArray(elem, clone2) {
|
||
if (elem == null) {
|
||
return [];
|
||
}
|
||
if (typeof elem === "string") {
|
||
return this._parse(elem, this.options, false, null).children.slice(0);
|
||
}
|
||
if ("length" in elem) {
|
||
if (elem.length === 1) {
|
||
return this._makeDomArray(elem[0], clone2);
|
||
}
|
||
const result = [];
|
||
for (let i = 0; i < elem.length; i++) {
|
||
const el = elem[i];
|
||
if (typeof el === "object") {
|
||
if (el == null) {
|
||
continue;
|
||
}
|
||
if (!("length" in el)) {
|
||
result.push(clone2 ? cloneNode(el, true) : el);
|
||
continue;
|
||
}
|
||
}
|
||
result.push(...this._makeDomArray(el, clone2));
|
||
}
|
||
return result;
|
||
}
|
||
return [clone2 ? cloneNode(elem, true) : elem];
|
||
}
|
||
function _insert(concatenator) {
|
||
return function(...elems) {
|
||
const lastIdx = this.length - 1;
|
||
return domEach(this, (el, i) => {
|
||
if (!hasChildren(el))
|
||
return;
|
||
const domSrc = typeof elems[0] === "function" ? elems[0].call(el, i, this._render(el.children)) : elems;
|
||
const dom = this._makeDomArray(domSrc, i < lastIdx);
|
||
concatenator(dom, el.children, el);
|
||
});
|
||
};
|
||
}
|
||
function uniqueSplice(array, spliceIdx, spliceCount, newElems, parent2) {
|
||
var _a2, _b;
|
||
const spliceArgs = [
|
||
spliceIdx,
|
||
spliceCount,
|
||
...newElems
|
||
];
|
||
const prev2 = spliceIdx === 0 ? null : array[spliceIdx - 1];
|
||
const next2 = spliceIdx + spliceCount >= array.length ? null : array[spliceIdx + spliceCount];
|
||
for (let idx = 0; idx < newElems.length; ++idx) {
|
||
const node = newElems[idx];
|
||
const oldParent = node.parent;
|
||
if (oldParent) {
|
||
const oldSiblings = oldParent.children;
|
||
const prevIdx = oldSiblings.indexOf(node);
|
||
if (prevIdx > -1) {
|
||
oldParent.children.splice(prevIdx, 1);
|
||
if (parent2 === oldParent && spliceIdx > prevIdx) {
|
||
spliceArgs[0]--;
|
||
}
|
||
}
|
||
}
|
||
node.parent = parent2;
|
||
if (node.prev) {
|
||
node.prev.next = (_a2 = node.next) !== null && _a2 !== void 0 ? _a2 : null;
|
||
}
|
||
if (node.next) {
|
||
node.next.prev = (_b = node.prev) !== null && _b !== void 0 ? _b : null;
|
||
}
|
||
node.prev = idx === 0 ? prev2 : newElems[idx - 1];
|
||
node.next = idx === newElems.length - 1 ? next2 : newElems[idx + 1];
|
||
}
|
||
if (prev2) {
|
||
prev2.next = newElems[0];
|
||
}
|
||
if (next2) {
|
||
next2.prev = newElems[newElems.length - 1];
|
||
}
|
||
return array.splice(...spliceArgs);
|
||
}
|
||
function appendTo(target) {
|
||
const appendTarget = isCheerio(target) ? target : this._make(target);
|
||
appendTarget.append(this);
|
||
return this;
|
||
}
|
||
function prependTo(target) {
|
||
const prependTarget = isCheerio(target) ? target : this._make(target);
|
||
prependTarget.prepend(this);
|
||
return this;
|
||
}
|
||
const append = _insert((dom, children2, parent2) => {
|
||
uniqueSplice(children2, children2.length, 0, dom, parent2);
|
||
});
|
||
const prepend = _insert((dom, children2, parent2) => {
|
||
uniqueSplice(children2, 0, 0, dom, parent2);
|
||
});
|
||
function _wrap(insert) {
|
||
return function(wrapper) {
|
||
const lastIdx = this.length - 1;
|
||
const lastParent = this.parents().last();
|
||
for (let i = 0; i < this.length; i++) {
|
||
const el = this[i];
|
||
const wrap2 = typeof wrapper === "function" ? wrapper.call(el, i, el) : typeof wrapper === "string" && !isHtml(wrapper) ? lastParent.find(wrapper).clone() : wrapper;
|
||
const [wrapperDom] = this._makeDomArray(wrap2, i < lastIdx);
|
||
if (!wrapperDom || !hasChildren(wrapperDom))
|
||
continue;
|
||
let elInsertLocation = wrapperDom;
|
||
let j = 0;
|
||
while (j < elInsertLocation.children.length) {
|
||
const child = elInsertLocation.children[j];
|
||
if (isTag(child)) {
|
||
elInsertLocation = child;
|
||
j = 0;
|
||
} else {
|
||
j++;
|
||
}
|
||
}
|
||
insert(el, elInsertLocation, [wrapperDom]);
|
||
}
|
||
return this;
|
||
};
|
||
}
|
||
const wrap = _wrap((el, elInsertLocation, wrapperDom) => {
|
||
const { parent: parent2 } = el;
|
||
if (!parent2)
|
||
return;
|
||
const siblings2 = parent2.children;
|
||
const index2 = siblings2.indexOf(el);
|
||
update([el], elInsertLocation);
|
||
uniqueSplice(siblings2, index2, 0, wrapperDom, parent2);
|
||
});
|
||
const wrapInner = _wrap((el, elInsertLocation, wrapperDom) => {
|
||
if (!hasChildren(el))
|
||
return;
|
||
update(el.children, elInsertLocation);
|
||
update(wrapperDom, el);
|
||
});
|
||
function unwrap(selector) {
|
||
this.parent(selector).not("body").each((_, el) => {
|
||
this._make(el).replaceWith(el.children);
|
||
});
|
||
return this;
|
||
}
|
||
function wrapAll(wrapper) {
|
||
const el = this[0];
|
||
if (el) {
|
||
const wrap2 = this._make(typeof wrapper === "function" ? wrapper.call(el, 0, el) : wrapper).insertBefore(el);
|
||
let elInsertLocation;
|
||
for (let i = 0; i < wrap2.length; i++) {
|
||
if (wrap2[i].type === "tag")
|
||
elInsertLocation = wrap2[i];
|
||
}
|
||
let j = 0;
|
||
while (elInsertLocation && j < elInsertLocation.children.length) {
|
||
const child = elInsertLocation.children[j];
|
||
if (child.type === "tag") {
|
||
elInsertLocation = child;
|
||
j = 0;
|
||
} else {
|
||
j++;
|
||
}
|
||
}
|
||
if (elInsertLocation)
|
||
this._make(elInsertLocation).append(this);
|
||
}
|
||
return this;
|
||
}
|
||
function after(...elems) {
|
||
const lastIdx = this.length - 1;
|
||
return domEach(this, (el, i) => {
|
||
if (!hasChildren(el) || !el.parent) {
|
||
return;
|
||
}
|
||
const siblings2 = el.parent.children;
|
||
const index2 = siblings2.indexOf(el);
|
||
if (index2 < 0)
|
||
return;
|
||
const domSrc = typeof elems[0] === "function" ? elems[0].call(el, i, this._render(el.children)) : elems;
|
||
const dom = this._makeDomArray(domSrc, i < lastIdx);
|
||
uniqueSplice(siblings2, index2 + 1, 0, dom, el.parent);
|
||
});
|
||
}
|
||
function insertAfter(target) {
|
||
if (typeof target === "string") {
|
||
target = this._make(target);
|
||
}
|
||
this.remove();
|
||
const clones = [];
|
||
for (const el of this._makeDomArray(target)) {
|
||
const clonedSelf = this.clone().toArray();
|
||
const { parent: parent2 } = el;
|
||
if (!parent2) {
|
||
continue;
|
||
}
|
||
const siblings2 = parent2.children;
|
||
const index2 = siblings2.indexOf(el);
|
||
if (index2 < 0)
|
||
continue;
|
||
uniqueSplice(siblings2, index2 + 1, 0, clonedSelf, parent2);
|
||
clones.push(...clonedSelf);
|
||
}
|
||
return this._make(clones);
|
||
}
|
||
function before(...elems) {
|
||
const lastIdx = this.length - 1;
|
||
return domEach(this, (el, i) => {
|
||
if (!hasChildren(el) || !el.parent) {
|
||
return;
|
||
}
|
||
const siblings2 = el.parent.children;
|
||
const index2 = siblings2.indexOf(el);
|
||
if (index2 < 0)
|
||
return;
|
||
const domSrc = typeof elems[0] === "function" ? elems[0].call(el, i, this._render(el.children)) : elems;
|
||
const dom = this._makeDomArray(domSrc, i < lastIdx);
|
||
uniqueSplice(siblings2, index2, 0, dom, el.parent);
|
||
});
|
||
}
|
||
function insertBefore(target) {
|
||
const targetArr = this._make(target);
|
||
this.remove();
|
||
const clones = [];
|
||
domEach(targetArr, (el) => {
|
||
const clonedSelf = this.clone().toArray();
|
||
const { parent: parent2 } = el;
|
||
if (!parent2) {
|
||
return;
|
||
}
|
||
const siblings2 = parent2.children;
|
||
const index2 = siblings2.indexOf(el);
|
||
if (index2 < 0)
|
||
return;
|
||
uniqueSplice(siblings2, index2, 0, clonedSelf, parent2);
|
||
clones.push(...clonedSelf);
|
||
});
|
||
return this._make(clones);
|
||
}
|
||
function remove(selector) {
|
||
const elems = selector ? this.filter(selector) : this;
|
||
domEach(elems, (el) => {
|
||
removeElement(el);
|
||
el.prev = el.next = el.parent = null;
|
||
});
|
||
return this;
|
||
}
|
||
function replaceWith(content) {
|
||
return domEach(this, (el, i) => {
|
||
const { parent: parent2 } = el;
|
||
if (!parent2) {
|
||
return;
|
||
}
|
||
const siblings2 = parent2.children;
|
||
const cont = typeof content === "function" ? content.call(el, i, el) : content;
|
||
const dom = this._makeDomArray(cont);
|
||
update(dom, null);
|
||
const index2 = siblings2.indexOf(el);
|
||
uniqueSplice(siblings2, index2, 1, dom, parent2);
|
||
if (!dom.includes(el)) {
|
||
el.parent = el.prev = el.next = null;
|
||
}
|
||
});
|
||
}
|
||
function empty() {
|
||
return domEach(this, (el) => {
|
||
if (!hasChildren(el))
|
||
return;
|
||
for (const child of el.children) {
|
||
child.next = child.prev = child.parent = null;
|
||
}
|
||
el.children.length = 0;
|
||
});
|
||
}
|
||
function html(str) {
|
||
if (str === void 0) {
|
||
const el = this[0];
|
||
if (!el || !hasChildren(el))
|
||
return null;
|
||
return this._render(el.children);
|
||
}
|
||
return domEach(this, (el) => {
|
||
if (!hasChildren(el))
|
||
return;
|
||
for (const child of el.children) {
|
||
child.next = child.prev = child.parent = null;
|
||
}
|
||
const content = isCheerio(str) ? str.toArray() : this._parse(`${str}`, this.options, false, el).children;
|
||
update(content, el);
|
||
});
|
||
}
|
||
function toString() {
|
||
return this._render(this);
|
||
}
|
||
function text(str) {
|
||
if (str === void 0) {
|
||
return text$1(this);
|
||
}
|
||
if (typeof str === "function") {
|
||
return domEach(this, (el, i) => this._make(el).text(str.call(el, i, text$1([el]))));
|
||
}
|
||
return domEach(this, (el) => {
|
||
if (!hasChildren(el))
|
||
return;
|
||
for (const child of el.children) {
|
||
child.next = child.prev = child.parent = null;
|
||
}
|
||
const textNode = new Text(`${str}`);
|
||
update(textNode, el);
|
||
});
|
||
}
|
||
function clone() {
|
||
const clone2 = Array.prototype.map.call(this.get(), (el) => cloneNode(el, true));
|
||
const root2 = new Document(clone2);
|
||
for (const node of clone2) {
|
||
node.parent = root2;
|
||
}
|
||
return this._make(clone2);
|
||
}
|
||
const Manipulation = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
_makeDomArray,
|
||
after,
|
||
append,
|
||
appendTo,
|
||
before,
|
||
clone,
|
||
empty,
|
||
html,
|
||
insertAfter,
|
||
insertBefore,
|
||
prepend,
|
||
prependTo,
|
||
remove,
|
||
replaceWith,
|
||
text,
|
||
toString,
|
||
unwrap,
|
||
wrap,
|
||
wrapAll,
|
||
wrapInner
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
function css(prop2, val2) {
|
||
if (prop2 != null && val2 != null || // When `prop` is a "plain" object
|
||
typeof prop2 === "object" && !Array.isArray(prop2)) {
|
||
return domEach(this, (el, i) => {
|
||
if (isTag(el)) {
|
||
setCss(el, prop2, val2, i);
|
||
}
|
||
});
|
||
}
|
||
if (this.length === 0) {
|
||
return void 0;
|
||
}
|
||
return getCss(this[0], prop2);
|
||
}
|
||
function setCss(el, prop2, value, idx) {
|
||
if (typeof prop2 === "string") {
|
||
const styles = getCss(el);
|
||
const val2 = typeof value === "function" ? value.call(el, idx, styles[prop2]) : value;
|
||
if (val2 === "") {
|
||
delete styles[prop2];
|
||
} else if (val2 != null) {
|
||
styles[prop2] = val2;
|
||
}
|
||
el.attribs["style"] = stringify(styles);
|
||
} else if (typeof prop2 === "object") {
|
||
const keys = Object.keys(prop2);
|
||
for (let i = 0; i < keys.length; i++) {
|
||
const k = keys[i];
|
||
setCss(el, k, prop2[k], i);
|
||
}
|
||
}
|
||
}
|
||
function getCss(el, prop2) {
|
||
if (!el || !isTag(el))
|
||
return;
|
||
const styles = parse(el.attribs["style"]);
|
||
if (typeof prop2 === "string") {
|
||
return styles[prop2];
|
||
}
|
||
if (Array.isArray(prop2)) {
|
||
const newStyles = {};
|
||
for (const item of prop2) {
|
||
if (styles[item] != null) {
|
||
newStyles[item] = styles[item];
|
||
}
|
||
}
|
||
return newStyles;
|
||
}
|
||
return styles;
|
||
}
|
||
function stringify(obj) {
|
||
return Object.keys(obj).reduce((str, prop2) => `${str}${str ? " " : ""}${prop2}: ${obj[prop2]};`, "");
|
||
}
|
||
function parse(styles) {
|
||
styles = (styles || "").trim();
|
||
if (!styles)
|
||
return {};
|
||
const obj = {};
|
||
let key;
|
||
for (const str of styles.split(";")) {
|
||
const n = str.indexOf(":");
|
||
if (n < 1 || n === str.length - 1) {
|
||
const trimmed = str.trimEnd();
|
||
if (trimmed.length > 0 && key !== void 0) {
|
||
obj[key] += `;${trimmed}`;
|
||
}
|
||
} else {
|
||
key = str.slice(0, n).trim();
|
||
obj[key] = str.slice(n + 1).trim();
|
||
}
|
||
}
|
||
return obj;
|
||
}
|
||
const Css = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
css
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
const submittableSelector = "input,select,textarea,keygen";
|
||
const r20 = /%20/g;
|
||
const rCRLF = /\r?\n/g;
|
||
function serialize() {
|
||
const arr = this.serializeArray();
|
||
const retArr = arr.map((data2) => `${encodeURIComponent(data2.name)}=${encodeURIComponent(data2.value)}`);
|
||
return retArr.join("&").replace(r20, "+");
|
||
}
|
||
function serializeArray() {
|
||
return this.map((_, elem) => {
|
||
const $elem = this._make(elem);
|
||
if (isTag(elem) && elem.name === "form") {
|
||
return $elem.find(submittableSelector).toArray();
|
||
}
|
||
return $elem.filter(submittableSelector).toArray();
|
||
}).filter(
|
||
// Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
|
||
'[name!=""]:enabled:not(:submit, :button, :image, :reset, :file):matches([checked], :not(:checkbox, :radio))'
|
||
).map((_, elem) => {
|
||
var _a2;
|
||
const $elem = this._make(elem);
|
||
const name = $elem.attr("name");
|
||
const value = (_a2 = $elem.val()) !== null && _a2 !== void 0 ? _a2 : "";
|
||
if (Array.isArray(value)) {
|
||
return value.map((val2) => (
|
||
/*
|
||
* We trim replace any line endings (e.g. `\r` or `\r\n` with `\r\n`) to guarantee consistency across platforms
|
||
* These can occur inside of `<textarea>'s`
|
||
*/
|
||
{ name, value: val2.replace(rCRLF, "\r\n") }
|
||
));
|
||
}
|
||
return { name, value: value.replace(rCRLF, "\r\n") };
|
||
}).toArray();
|
||
}
|
||
const Forms = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
serialize,
|
||
serializeArray
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
function getExtractDescr(descr) {
|
||
var _a2;
|
||
if (typeof descr === "string") {
|
||
return { selector: descr, value: "textContent" };
|
||
}
|
||
return {
|
||
selector: descr.selector,
|
||
value: (_a2 = descr.value) !== null && _a2 !== void 0 ? _a2 : "textContent"
|
||
};
|
||
}
|
||
function extract(map2) {
|
||
const ret = {};
|
||
for (const key in map2) {
|
||
const descr = map2[key];
|
||
const isArray = Array.isArray(descr);
|
||
const { selector, value } = getExtractDescr(isArray ? descr[0] : descr);
|
||
const fn = typeof value === "function" ? value : typeof value === "string" ? (el) => this._make(el).prop(value) : (el) => this._make(el).extract(value);
|
||
if (isArray) {
|
||
ret[key] = this._findBySelector(selector, Number.POSITIVE_INFINITY).map((_, el) => fn(el, key, ret)).get();
|
||
} else {
|
||
const $ = this._findBySelector(selector, 1);
|
||
ret[key] = $.length > 0 ? fn($[0], key, ret) : void 0;
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
const Extract = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
||
__proto__: null,
|
||
extract
|
||
}, Symbol.toStringTag, { value: "Module" }));
|
||
class Cheerio {
|
||
/**
|
||
* Instance of cheerio. Methods are specified in the modules. Usage of this
|
||
* constructor is not recommended. Please use `$.load` instead.
|
||
*
|
||
* @private
|
||
* @param elements - The new selection.
|
||
* @param root - Sets the root node.
|
||
* @param options - Options for the instance.
|
||
*/
|
||
constructor(elements, root2, options) {
|
||
this.length = 0;
|
||
this.options = options;
|
||
this._root = root2;
|
||
if (elements) {
|
||
for (let idx = 0; idx < elements.length; idx++) {
|
||
this[idx] = elements[idx];
|
||
}
|
||
this.length = elements.length;
|
||
}
|
||
}
|
||
}
|
||
Cheerio.prototype.cheerio = "[cheerio object]";
|
||
Cheerio.prototype.splice = Array.prototype.splice;
|
||
Cheerio.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
|
||
Object.assign(Cheerio.prototype, Attributes, Traversing, Manipulation, Css, Forms, Extract);
|
||
function getLoad(parse2, render2) {
|
||
return function load2(content, options, isDocument2 = true) {
|
||
if (content == null) {
|
||
throw new Error("cheerio.load() expects a string");
|
||
}
|
||
const internalOpts = flattenOptions(options);
|
||
const initialRoot = parse2(content, internalOpts, isDocument2, null);
|
||
class LoadedCheerio extends Cheerio {
|
||
_make(selector, context) {
|
||
const cheerio = initialize(selector, context);
|
||
cheerio.prevObject = this;
|
||
return cheerio;
|
||
}
|
||
_parse(content2, options2, isDocument3, context) {
|
||
return parse2(content2, options2, isDocument3, context);
|
||
}
|
||
_render(dom) {
|
||
return render2(dom, this.options);
|
||
}
|
||
}
|
||
function initialize(selector, context, root2 = initialRoot, opts) {
|
||
if (selector && isCheerio(selector))
|
||
return selector;
|
||
const options2 = flattenOptions(opts, internalOpts);
|
||
const r = typeof root2 === "string" ? [parse2(root2, options2, false, null)] : "length" in root2 ? root2 : [root2];
|
||
const rootInstance = isCheerio(r) ? r : new LoadedCheerio(r, null, options2);
|
||
rootInstance._root = rootInstance;
|
||
if (!selector) {
|
||
return new LoadedCheerio(void 0, rootInstance, options2);
|
||
}
|
||
const elements = typeof selector === "string" && isHtml(selector) ? (
|
||
// $(<html>)
|
||
parse2(selector, options2, false, null).children
|
||
) : isNode(selector) ? (
|
||
// $(dom)
|
||
[selector]
|
||
) : Array.isArray(selector) ? (
|
||
// $([dom])
|
||
selector
|
||
) : void 0;
|
||
const instance = new LoadedCheerio(elements, rootInstance, options2);
|
||
if (elements) {
|
||
return instance;
|
||
}
|
||
if (typeof selector !== "string") {
|
||
throw new TypeError("Unexpected type of selector");
|
||
}
|
||
let search = selector;
|
||
const searchContext = context ? (
|
||
// If we don't have a context, maybe we have a root, from loading
|
||
typeof context === "string" ? isHtml(context) ? (
|
||
// $('li', '<ul>...</ul>')
|
||
new LoadedCheerio([parse2(context, options2, false, null)], rootInstance, options2)
|
||
) : (
|
||
// $('li', 'ul')
|
||
(search = `${context} ${search}`, rootInstance)
|
||
) : isCheerio(context) ? (
|
||
// $('li', $)
|
||
context
|
||
) : (
|
||
// $('li', node), $('li', [nodes])
|
||
new LoadedCheerio(Array.isArray(context) ? context : [context], rootInstance, options2)
|
||
)
|
||
) : rootInstance;
|
||
if (!searchContext)
|
||
return instance;
|
||
return searchContext.find(search);
|
||
}
|
||
Object.assign(initialize, staticMethods, {
|
||
load: load2,
|
||
// `_root` and `_options` are used in static methods.
|
||
_root: initialRoot,
|
||
_options: internalOpts,
|
||
// Add `fn` for plugins
|
||
fn: LoadedCheerio.prototype,
|
||
// Add the prototype here to maintain `instanceof` behavior.
|
||
prototype: LoadedCheerio.prototype
|
||
});
|
||
return initialize;
|
||
};
|
||
}
|
||
function isNode(obj) {
|
||
return !!obj.name || obj.type === "root" || obj.type === "text" || obj.type === "comment";
|
||
}
|
||
var CharCodes;
|
||
(function(CharCodes2) {
|
||
CharCodes2[CharCodes2["Tab"] = 9] = "Tab";
|
||
CharCodes2[CharCodes2["NewLine"] = 10] = "NewLine";
|
||
CharCodes2[CharCodes2["FormFeed"] = 12] = "FormFeed";
|
||
CharCodes2[CharCodes2["CarriageReturn"] = 13] = "CarriageReturn";
|
||
CharCodes2[CharCodes2["Space"] = 32] = "Space";
|
||
CharCodes2[CharCodes2["ExclamationMark"] = 33] = "ExclamationMark";
|
||
CharCodes2[CharCodes2["Number"] = 35] = "Number";
|
||
CharCodes2[CharCodes2["Amp"] = 38] = "Amp";
|
||
CharCodes2[CharCodes2["SingleQuote"] = 39] = "SingleQuote";
|
||
CharCodes2[CharCodes2["DoubleQuote"] = 34] = "DoubleQuote";
|
||
CharCodes2[CharCodes2["Dash"] = 45] = "Dash";
|
||
CharCodes2[CharCodes2["Slash"] = 47] = "Slash";
|
||
CharCodes2[CharCodes2["Zero"] = 48] = "Zero";
|
||
CharCodes2[CharCodes2["Nine"] = 57] = "Nine";
|
||
CharCodes2[CharCodes2["Semi"] = 59] = "Semi";
|
||
CharCodes2[CharCodes2["Lt"] = 60] = "Lt";
|
||
CharCodes2[CharCodes2["Eq"] = 61] = "Eq";
|
||
CharCodes2[CharCodes2["Gt"] = 62] = "Gt";
|
||
CharCodes2[CharCodes2["Questionmark"] = 63] = "Questionmark";
|
||
CharCodes2[CharCodes2["UpperA"] = 65] = "UpperA";
|
||
CharCodes2[CharCodes2["LowerA"] = 97] = "LowerA";
|
||
CharCodes2[CharCodes2["UpperF"] = 70] = "UpperF";
|
||
CharCodes2[CharCodes2["LowerF"] = 102] = "LowerF";
|
||
CharCodes2[CharCodes2["UpperZ"] = 90] = "UpperZ";
|
||
CharCodes2[CharCodes2["LowerZ"] = 122] = "LowerZ";
|
||
CharCodes2[CharCodes2["LowerX"] = 120] = "LowerX";
|
||
CharCodes2[CharCodes2["OpeningSquareBracket"] = 91] = "OpeningSquareBracket";
|
||
})(CharCodes || (CharCodes = {}));
|
||
var State;
|
||
(function(State2) {
|
||
State2[State2["Text"] = 1] = "Text";
|
||
State2[State2["BeforeTagName"] = 2] = "BeforeTagName";
|
||
State2[State2["InTagName"] = 3] = "InTagName";
|
||
State2[State2["InSelfClosingTag"] = 4] = "InSelfClosingTag";
|
||
State2[State2["BeforeClosingTagName"] = 5] = "BeforeClosingTagName";
|
||
State2[State2["InClosingTagName"] = 6] = "InClosingTagName";
|
||
State2[State2["AfterClosingTagName"] = 7] = "AfterClosingTagName";
|
||
State2[State2["BeforeAttributeName"] = 8] = "BeforeAttributeName";
|
||
State2[State2["InAttributeName"] = 9] = "InAttributeName";
|
||
State2[State2["AfterAttributeName"] = 10] = "AfterAttributeName";
|
||
State2[State2["BeforeAttributeValue"] = 11] = "BeforeAttributeValue";
|
||
State2[State2["InAttributeValueDq"] = 12] = "InAttributeValueDq";
|
||
State2[State2["InAttributeValueSq"] = 13] = "InAttributeValueSq";
|
||
State2[State2["InAttributeValueNq"] = 14] = "InAttributeValueNq";
|
||
State2[State2["BeforeDeclaration"] = 15] = "BeforeDeclaration";
|
||
State2[State2["InDeclaration"] = 16] = "InDeclaration";
|
||
State2[State2["InProcessingInstruction"] = 17] = "InProcessingInstruction";
|
||
State2[State2["BeforeComment"] = 18] = "BeforeComment";
|
||
State2[State2["CDATASequence"] = 19] = "CDATASequence";
|
||
State2[State2["InSpecialComment"] = 20] = "InSpecialComment";
|
||
State2[State2["InCommentLike"] = 21] = "InCommentLike";
|
||
State2[State2["BeforeSpecialS"] = 22] = "BeforeSpecialS";
|
||
State2[State2["BeforeSpecialT"] = 23] = "BeforeSpecialT";
|
||
State2[State2["SpecialStartSequence"] = 24] = "SpecialStartSequence";
|
||
State2[State2["InSpecialTag"] = 25] = "InSpecialTag";
|
||
State2[State2["InEntity"] = 26] = "InEntity";
|
||
})(State || (State = {}));
|
||
function isWhitespace(c) {
|
||
return c === CharCodes.Space || c === CharCodes.NewLine || c === CharCodes.Tab || c === CharCodes.FormFeed || c === CharCodes.CarriageReturn;
|
||
}
|
||
function isEndOfTagSection(c) {
|
||
return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);
|
||
}
|
||
function isASCIIAlpha(c) {
|
||
return c >= CharCodes.LowerA && c <= CharCodes.LowerZ || c >= CharCodes.UpperA && c <= CharCodes.UpperZ;
|
||
}
|
||
var QuoteType;
|
||
(function(QuoteType2) {
|
||
QuoteType2[QuoteType2["NoValue"] = 0] = "NoValue";
|
||
QuoteType2[QuoteType2["Unquoted"] = 1] = "Unquoted";
|
||
QuoteType2[QuoteType2["Single"] = 2] = "Single";
|
||
QuoteType2[QuoteType2["Double"] = 3] = "Double";
|
||
})(QuoteType || (QuoteType = {}));
|
||
const Sequences = {
|
||
Cdata: new Uint8Array([67, 68, 65, 84, 65, 91]),
|
||
// CDATA[
|
||
CdataEnd: new Uint8Array([93, 93, 62]),
|
||
// ]]>
|
||
CommentEnd: new Uint8Array([45, 45, 62]),
|
||
// `-->`
|
||
ScriptEnd: new Uint8Array([60, 47, 115, 99, 114, 105, 112, 116]),
|
||
// `<\/script`
|
||
StyleEnd: new Uint8Array([60, 47, 115, 116, 121, 108, 101]),
|
||
// `</style`
|
||
TitleEnd: new Uint8Array([60, 47, 116, 105, 116, 108, 101]),
|
||
// `</title`
|
||
TextareaEnd: new Uint8Array([
|
||
60,
|
||
47,
|
||
116,
|
||
101,
|
||
120,
|
||
116,
|
||
97,
|
||
114,
|
||
101,
|
||
97
|
||
])
|
||
// `</textarea`
|
||
};
|
||
class Tokenizer {
|
||
constructor({ xmlMode = false, decodeEntities = true }, cbs) {
|
||
this.cbs = cbs;
|
||
this.state = State.Text;
|
||
this.buffer = "";
|
||
this.sectionStart = 0;
|
||
this.index = 0;
|
||
this.entityStart = 0;
|
||
this.baseState = State.Text;
|
||
this.isSpecial = false;
|
||
this.running = true;
|
||
this.offset = 0;
|
||
this.currentSequence = void 0;
|
||
this.sequenceIndex = 0;
|
||
this.xmlMode = xmlMode;
|
||
this.decodeEntities = decodeEntities;
|
||
this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));
|
||
}
|
||
reset() {
|
||
this.state = State.Text;
|
||
this.buffer = "";
|
||
this.sectionStart = 0;
|
||
this.index = 0;
|
||
this.baseState = State.Text;
|
||
this.currentSequence = void 0;
|
||
this.running = true;
|
||
this.offset = 0;
|
||
}
|
||
write(chunk) {
|
||
this.offset += this.buffer.length;
|
||
this.buffer = chunk;
|
||
this.parse();
|
||
}
|
||
end() {
|
||
if (this.running)
|
||
this.finish();
|
||
}
|
||
pause() {
|
||
this.running = false;
|
||
}
|
||
resume() {
|
||
this.running = true;
|
||
if (this.index < this.buffer.length + this.offset) {
|
||
this.parse();
|
||
}
|
||
}
|
||
stateText(c) {
|
||
if (c === CharCodes.Lt || !this.decodeEntities && this.fastForwardTo(CharCodes.Lt)) {
|
||
if (this.index > this.sectionStart) {
|
||
this.cbs.ontext(this.sectionStart, this.index);
|
||
}
|
||
this.state = State.BeforeTagName;
|
||
this.sectionStart = this.index;
|
||
} else if (this.decodeEntities && c === CharCodes.Amp) {
|
||
this.startEntity();
|
||
}
|
||
}
|
||
stateSpecialStartSequence(c) {
|
||
const isEnd = this.sequenceIndex === this.currentSequence.length;
|
||
const isMatch = isEnd ? (
|
||
// If we are at the end of the sequence, make sure the tag name has ended
|
||
isEndOfTagSection(c)
|
||
) : (
|
||
// Otherwise, do a case-insensitive comparison
|
||
(c | 32) === this.currentSequence[this.sequenceIndex]
|
||
);
|
||
if (!isMatch) {
|
||
this.isSpecial = false;
|
||
} else if (!isEnd) {
|
||
this.sequenceIndex++;
|
||
return;
|
||
}
|
||
this.sequenceIndex = 0;
|
||
this.state = State.InTagName;
|
||
this.stateInTagName(c);
|
||
}
|
||
/** Look for an end tag. For <title> tags, also decode entities. */
|
||
stateInSpecialTag(c) {
|
||
if (this.sequenceIndex === this.currentSequence.length) {
|
||
if (c === CharCodes.Gt || isWhitespace(c)) {
|
||
const endOfText = this.index - this.currentSequence.length;
|
||
if (this.sectionStart < endOfText) {
|
||
const actualIndex = this.index;
|
||
this.index = endOfText;
|
||
this.cbs.ontext(this.sectionStart, endOfText);
|
||
this.index = actualIndex;
|
||
}
|
||
this.isSpecial = false;
|
||
this.sectionStart = endOfText + 2;
|
||
this.stateInClosingTagName(c);
|
||
return;
|
||
}
|
||
this.sequenceIndex = 0;
|
||
}
|
||
if ((c | 32) === this.currentSequence[this.sequenceIndex]) {
|
||
this.sequenceIndex += 1;
|
||
} else if (this.sequenceIndex === 0) {
|
||
if (this.currentSequence === Sequences.TitleEnd) {
|
||
if (this.decodeEntities && c === CharCodes.Amp) {
|
||
this.startEntity();
|
||
}
|
||
} else if (this.fastForwardTo(CharCodes.Lt)) {
|
||
this.sequenceIndex = 1;
|
||
}
|
||
} else {
|
||
this.sequenceIndex = Number(c === CharCodes.Lt);
|
||
}
|
||
}
|
||
stateCDATASequence(c) {
|
||
if (c === Sequences.Cdata[this.sequenceIndex]) {
|
||
if (++this.sequenceIndex === Sequences.Cdata.length) {
|
||
this.state = State.InCommentLike;
|
||
this.currentSequence = Sequences.CdataEnd;
|
||
this.sequenceIndex = 0;
|
||
this.sectionStart = this.index + 1;
|
||
}
|
||
} else {
|
||
this.sequenceIndex = 0;
|
||
this.state = State.InDeclaration;
|
||
this.stateInDeclaration(c);
|
||
}
|
||
}
|
||
/**
|
||
* When we wait for one specific character, we can speed things up
|
||
* by skipping through the buffer until we find it.
|
||
*
|
||
* @returns Whether the character was found.
|
||
*/
|
||
fastForwardTo(c) {
|
||
while (++this.index < this.buffer.length + this.offset) {
|
||
if (this.buffer.charCodeAt(this.index - this.offset) === c) {
|
||
return true;
|
||
}
|
||
}
|
||
this.index = this.buffer.length + this.offset - 1;
|
||
return false;
|
||
}
|
||
/**
|
||
* Comments and CDATA end with `-->` and `]]>`.
|
||
*
|
||
* Their common qualities are:
|
||
* - Their end sequences have a distinct character they start with.
|
||
* - That character is then repeated, so we have to check multiple repeats.
|
||
* - All characters but the start character of the sequence can be skipped.
|
||
*/
|
||
stateInCommentLike(c) {
|
||
if (c === this.currentSequence[this.sequenceIndex]) {
|
||
if (++this.sequenceIndex === this.currentSequence.length) {
|
||
if (this.currentSequence === Sequences.CdataEnd) {
|
||
this.cbs.oncdata(this.sectionStart, this.index, 2);
|
||
} else {
|
||
this.cbs.oncomment(this.sectionStart, this.index, 2);
|
||
}
|
||
this.sequenceIndex = 0;
|
||
this.sectionStart = this.index + 1;
|
||
this.state = State.Text;
|
||
}
|
||
} else if (this.sequenceIndex === 0) {
|
||
if (this.fastForwardTo(this.currentSequence[0])) {
|
||
this.sequenceIndex = 1;
|
||
}
|
||
} else if (c !== this.currentSequence[this.sequenceIndex - 1]) {
|
||
this.sequenceIndex = 0;
|
||
}
|
||
}
|
||
/**
|
||
* HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.
|
||
*
|
||
* XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).
|
||
* We allow anything that wouldn't end the tag.
|
||
*/
|
||
isTagStartChar(c) {
|
||
return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);
|
||
}
|
||
startSpecial(sequence, offset) {
|
||
this.isSpecial = true;
|
||
this.currentSequence = sequence;
|
||
this.sequenceIndex = offset;
|
||
this.state = State.SpecialStartSequence;
|
||
}
|
||
stateBeforeTagName(c) {
|
||
if (c === CharCodes.ExclamationMark) {
|
||
this.state = State.BeforeDeclaration;
|
||
this.sectionStart = this.index + 1;
|
||
} else if (c === CharCodes.Questionmark) {
|
||
this.state = State.InProcessingInstruction;
|
||
this.sectionStart = this.index + 1;
|
||
} else if (this.isTagStartChar(c)) {
|
||
const lower = c | 32;
|
||
this.sectionStart = this.index;
|
||
if (this.xmlMode) {
|
||
this.state = State.InTagName;
|
||
} else if (lower === Sequences.ScriptEnd[2]) {
|
||
this.state = State.BeforeSpecialS;
|
||
} else if (lower === Sequences.TitleEnd[2]) {
|
||
this.state = State.BeforeSpecialT;
|
||
} else {
|
||
this.state = State.InTagName;
|
||
}
|
||
} else if (c === CharCodes.Slash) {
|
||
this.state = State.BeforeClosingTagName;
|
||
} else {
|
||
this.state = State.Text;
|
||
this.stateText(c);
|
||
}
|
||
}
|
||
stateInTagName(c) {
|
||
if (isEndOfTagSection(c)) {
|
||
this.cbs.onopentagname(this.sectionStart, this.index);
|
||
this.sectionStart = -1;
|
||
this.state = State.BeforeAttributeName;
|
||
this.stateBeforeAttributeName(c);
|
||
}
|
||
}
|
||
stateBeforeClosingTagName(c) {
|
||
if (isWhitespace(c)) ;
|
||
else if (c === CharCodes.Gt) {
|
||
this.state = State.Text;
|
||
} else {
|
||
this.state = this.isTagStartChar(c) ? State.InClosingTagName : State.InSpecialComment;
|
||
this.sectionStart = this.index;
|
||
}
|
||
}
|
||
stateInClosingTagName(c) {
|
||
if (c === CharCodes.Gt || isWhitespace(c)) {
|
||
this.cbs.onclosetag(this.sectionStart, this.index);
|
||
this.sectionStart = -1;
|
||
this.state = State.AfterClosingTagName;
|
||
this.stateAfterClosingTagName(c);
|
||
}
|
||
}
|
||
stateAfterClosingTagName(c) {
|
||
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
|
||
this.state = State.Text;
|
||
this.sectionStart = this.index + 1;
|
||
}
|
||
}
|
||
stateBeforeAttributeName(c) {
|
||
if (c === CharCodes.Gt) {
|
||
this.cbs.onopentagend(this.index);
|
||
if (this.isSpecial) {
|
||
this.state = State.InSpecialTag;
|
||
this.sequenceIndex = 0;
|
||
} else {
|
||
this.state = State.Text;
|
||
}
|
||
this.sectionStart = this.index + 1;
|
||
} else if (c === CharCodes.Slash) {
|
||
this.state = State.InSelfClosingTag;
|
||
} else if (!isWhitespace(c)) {
|
||
this.state = State.InAttributeName;
|
||
this.sectionStart = this.index;
|
||
}
|
||
}
|
||
stateInSelfClosingTag(c) {
|
||
if (c === CharCodes.Gt) {
|
||
this.cbs.onselfclosingtag(this.index);
|
||
this.state = State.Text;
|
||
this.sectionStart = this.index + 1;
|
||
this.isSpecial = false;
|
||
} else if (!isWhitespace(c)) {
|
||
this.state = State.BeforeAttributeName;
|
||
this.stateBeforeAttributeName(c);
|
||
}
|
||
}
|
||
stateInAttributeName(c) {
|
||
if (c === CharCodes.Eq || isEndOfTagSection(c)) {
|
||
this.cbs.onattribname(this.sectionStart, this.index);
|
||
this.sectionStart = this.index;
|
||
this.state = State.AfterAttributeName;
|
||
this.stateAfterAttributeName(c);
|
||
}
|
||
}
|
||
stateAfterAttributeName(c) {
|
||
if (c === CharCodes.Eq) {
|
||
this.state = State.BeforeAttributeValue;
|
||
} else if (c === CharCodes.Slash || c === CharCodes.Gt) {
|
||
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
|
||
this.sectionStart = -1;
|
||
this.state = State.BeforeAttributeName;
|
||
this.stateBeforeAttributeName(c);
|
||
} else if (!isWhitespace(c)) {
|
||
this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);
|
||
this.state = State.InAttributeName;
|
||
this.sectionStart = this.index;
|
||
}
|
||
}
|
||
stateBeforeAttributeValue(c) {
|
||
if (c === CharCodes.DoubleQuote) {
|
||
this.state = State.InAttributeValueDq;
|
||
this.sectionStart = this.index + 1;
|
||
} else if (c === CharCodes.SingleQuote) {
|
||
this.state = State.InAttributeValueSq;
|
||
this.sectionStart = this.index + 1;
|
||
} else if (!isWhitespace(c)) {
|
||
this.sectionStart = this.index;
|
||
this.state = State.InAttributeValueNq;
|
||
this.stateInAttributeValueNoQuotes(c);
|
||
}
|
||
}
|
||
handleInAttributeValue(c, quote) {
|
||
if (c === quote || !this.decodeEntities && this.fastForwardTo(quote)) {
|
||
this.cbs.onattribdata(this.sectionStart, this.index);
|
||
this.sectionStart = -1;
|
||
this.cbs.onattribend(quote === CharCodes.DoubleQuote ? QuoteType.Double : QuoteType.Single, this.index + 1);
|
||
this.state = State.BeforeAttributeName;
|
||
} else if (this.decodeEntities && c === CharCodes.Amp) {
|
||
this.startEntity();
|
||
}
|
||
}
|
||
stateInAttributeValueDoubleQuotes(c) {
|
||
this.handleInAttributeValue(c, CharCodes.DoubleQuote);
|
||
}
|
||
stateInAttributeValueSingleQuotes(c) {
|
||
this.handleInAttributeValue(c, CharCodes.SingleQuote);
|
||
}
|
||
stateInAttributeValueNoQuotes(c) {
|
||
if (isWhitespace(c) || c === CharCodes.Gt) {
|
||
this.cbs.onattribdata(this.sectionStart, this.index);
|
||
this.sectionStart = -1;
|
||
this.cbs.onattribend(QuoteType.Unquoted, this.index);
|
||
this.state = State.BeforeAttributeName;
|
||
this.stateBeforeAttributeName(c);
|
||
} else if (this.decodeEntities && c === CharCodes.Amp) {
|
||
this.startEntity();
|
||
}
|
||
}
|
||
stateBeforeDeclaration(c) {
|
||
if (c === CharCodes.OpeningSquareBracket) {
|
||
this.state = State.CDATASequence;
|
||
this.sequenceIndex = 0;
|
||
} else {
|
||
this.state = c === CharCodes.Dash ? State.BeforeComment : State.InDeclaration;
|
||
}
|
||
}
|
||
stateInDeclaration(c) {
|
||
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
|
||
this.cbs.ondeclaration(this.sectionStart, this.index);
|
||
this.state = State.Text;
|
||
this.sectionStart = this.index + 1;
|
||
}
|
||
}
|
||
stateInProcessingInstruction(c) {
|
||
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
|
||
this.cbs.onprocessinginstruction(this.sectionStart, this.index);
|
||
this.state = State.Text;
|
||
this.sectionStart = this.index + 1;
|
||
}
|
||
}
|
||
stateBeforeComment(c) {
|
||
if (c === CharCodes.Dash) {
|
||
this.state = State.InCommentLike;
|
||
this.currentSequence = Sequences.CommentEnd;
|
||
this.sequenceIndex = 2;
|
||
this.sectionStart = this.index + 1;
|
||
} else {
|
||
this.state = State.InDeclaration;
|
||
}
|
||
}
|
||
stateInSpecialComment(c) {
|
||
if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {
|
||
this.cbs.oncomment(this.sectionStart, this.index, 0);
|
||
this.state = State.Text;
|
||
this.sectionStart = this.index + 1;
|
||
}
|
||
}
|
||
stateBeforeSpecialS(c) {
|
||
const lower = c | 32;
|
||
if (lower === Sequences.ScriptEnd[3]) {
|
||
this.startSpecial(Sequences.ScriptEnd, 4);
|
||
} else if (lower === Sequences.StyleEnd[3]) {
|
||
this.startSpecial(Sequences.StyleEnd, 4);
|
||
} else {
|
||
this.state = State.InTagName;
|
||
this.stateInTagName(c);
|
||
}
|
||
}
|
||
stateBeforeSpecialT(c) {
|
||
const lower = c | 32;
|
||
if (lower === Sequences.TitleEnd[3]) {
|
||
this.startSpecial(Sequences.TitleEnd, 4);
|
||
} else if (lower === Sequences.TextareaEnd[3]) {
|
||
this.startSpecial(Sequences.TextareaEnd, 4);
|
||
} else {
|
||
this.state = State.InTagName;
|
||
this.stateInTagName(c);
|
||
}
|
||
}
|
||
startEntity() {
|
||
this.baseState = this.state;
|
||
this.state = State.InEntity;
|
||
this.entityStart = this.index;
|
||
this.entityDecoder.startEntity(this.xmlMode ? DecodingMode.Strict : this.baseState === State.Text || this.baseState === State.InSpecialTag ? DecodingMode.Legacy : DecodingMode.Attribute);
|
||
}
|
||
stateInEntity() {
|
||
const length = this.entityDecoder.write(this.buffer, this.index - this.offset);
|
||
if (length >= 0) {
|
||
this.state = this.baseState;
|
||
if (length === 0) {
|
||
this.index = this.entityStart;
|
||
}
|
||
} else {
|
||
this.index = this.offset + this.buffer.length - 1;
|
||
}
|
||
}
|
||
/**
|
||
* Remove data that has already been consumed from the buffer.
|
||
*/
|
||
cleanup() {
|
||
if (this.running && this.sectionStart !== this.index) {
|
||
if (this.state === State.Text || this.state === State.InSpecialTag && this.sequenceIndex === 0) {
|
||
this.cbs.ontext(this.sectionStart, this.index);
|
||
this.sectionStart = this.index;
|
||
} else if (this.state === State.InAttributeValueDq || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueNq) {
|
||
this.cbs.onattribdata(this.sectionStart, this.index);
|
||
this.sectionStart = this.index;
|
||
}
|
||
}
|
||
}
|
||
shouldContinue() {
|
||
return this.index < this.buffer.length + this.offset && this.running;
|
||
}
|
||
/**
|
||
* Iterates through the buffer, calling the function corresponding to the current state.
|
||
*
|
||
* States that are more likely to be hit are higher up, as a performance improvement.
|
||
*/
|
||
parse() {
|
||
while (this.shouldContinue()) {
|
||
const c = this.buffer.charCodeAt(this.index - this.offset);
|
||
switch (this.state) {
|
||
case State.Text: {
|
||
this.stateText(c);
|
||
break;
|
||
}
|
||
case State.SpecialStartSequence: {
|
||
this.stateSpecialStartSequence(c);
|
||
break;
|
||
}
|
||
case State.InSpecialTag: {
|
||
this.stateInSpecialTag(c);
|
||
break;
|
||
}
|
||
case State.CDATASequence: {
|
||
this.stateCDATASequence(c);
|
||
break;
|
||
}
|
||
case State.InAttributeValueDq: {
|
||
this.stateInAttributeValueDoubleQuotes(c);
|
||
break;
|
||
}
|
||
case State.InAttributeName: {
|
||
this.stateInAttributeName(c);
|
||
break;
|
||
}
|
||
case State.InCommentLike: {
|
||
this.stateInCommentLike(c);
|
||
break;
|
||
}
|
||
case State.InSpecialComment: {
|
||
this.stateInSpecialComment(c);
|
||
break;
|
||
}
|
||
case State.BeforeAttributeName: {
|
||
this.stateBeforeAttributeName(c);
|
||
break;
|
||
}
|
||
case State.InTagName: {
|
||
this.stateInTagName(c);
|
||
break;
|
||
}
|
||
case State.InClosingTagName: {
|
||
this.stateInClosingTagName(c);
|
||
break;
|
||
}
|
||
case State.BeforeTagName: {
|
||
this.stateBeforeTagName(c);
|
||
break;
|
||
}
|
||
case State.AfterAttributeName: {
|
||
this.stateAfterAttributeName(c);
|
||
break;
|
||
}
|
||
case State.InAttributeValueSq: {
|
||
this.stateInAttributeValueSingleQuotes(c);
|
||
break;
|
||
}
|
||
case State.BeforeAttributeValue: {
|
||
this.stateBeforeAttributeValue(c);
|
||
break;
|
||
}
|
||
case State.BeforeClosingTagName: {
|
||
this.stateBeforeClosingTagName(c);
|
||
break;
|
||
}
|
||
case State.AfterClosingTagName: {
|
||
this.stateAfterClosingTagName(c);
|
||
break;
|
||
}
|
||
case State.BeforeSpecialS: {
|
||
this.stateBeforeSpecialS(c);
|
||
break;
|
||
}
|
||
case State.BeforeSpecialT: {
|
||
this.stateBeforeSpecialT(c);
|
||
break;
|
||
}
|
||
case State.InAttributeValueNq: {
|
||
this.stateInAttributeValueNoQuotes(c);
|
||
break;
|
||
}
|
||
case State.InSelfClosingTag: {
|
||
this.stateInSelfClosingTag(c);
|
||
break;
|
||
}
|
||
case State.InDeclaration: {
|
||
this.stateInDeclaration(c);
|
||
break;
|
||
}
|
||
case State.BeforeDeclaration: {
|
||
this.stateBeforeDeclaration(c);
|
||
break;
|
||
}
|
||
case State.BeforeComment: {
|
||
this.stateBeforeComment(c);
|
||
break;
|
||
}
|
||
case State.InProcessingInstruction: {
|
||
this.stateInProcessingInstruction(c);
|
||
break;
|
||
}
|
||
case State.InEntity: {
|
||
this.stateInEntity();
|
||
break;
|
||
}
|
||
}
|
||
this.index++;
|
||
}
|
||
this.cleanup();
|
||
}
|
||
finish() {
|
||
if (this.state === State.InEntity) {
|
||
this.entityDecoder.end();
|
||
this.state = this.baseState;
|
||
}
|
||
this.handleTrailingData();
|
||
this.cbs.onend();
|
||
}
|
||
/** Handle any trailing data. */
|
||
handleTrailingData() {
|
||
const endIndex = this.buffer.length + this.offset;
|
||
if (this.sectionStart >= endIndex) {
|
||
return;
|
||
}
|
||
if (this.state === State.InCommentLike) {
|
||
if (this.currentSequence === Sequences.CdataEnd) {
|
||
this.cbs.oncdata(this.sectionStart, endIndex, 0);
|
||
} else {
|
||
this.cbs.oncomment(this.sectionStart, endIndex, 0);
|
||
}
|
||
} else if (this.state === State.InTagName || this.state === State.BeforeAttributeName || this.state === State.BeforeAttributeValue || this.state === State.AfterAttributeName || this.state === State.InAttributeName || this.state === State.InAttributeValueSq || this.state === State.InAttributeValueDq || this.state === State.InAttributeValueNq || this.state === State.InClosingTagName) ;
|
||
else {
|
||
this.cbs.ontext(this.sectionStart, endIndex);
|
||
}
|
||
}
|
||
emitCodePoint(cp, consumed) {
|
||
if (this.baseState !== State.Text && this.baseState !== State.InSpecialTag) {
|
||
if (this.sectionStart < this.entityStart) {
|
||
this.cbs.onattribdata(this.sectionStart, this.entityStart);
|
||
}
|
||
this.sectionStart = this.entityStart + consumed;
|
||
this.index = this.sectionStart - 1;
|
||
this.cbs.onattribentity(cp);
|
||
} else {
|
||
if (this.sectionStart < this.entityStart) {
|
||
this.cbs.ontext(this.sectionStart, this.entityStart);
|
||
}
|
||
this.sectionStart = this.entityStart + consumed;
|
||
this.index = this.sectionStart - 1;
|
||
this.cbs.ontextentity(cp, this.sectionStart);
|
||
}
|
||
}
|
||
}
|
||
const formTags = /* @__PURE__ */ new Set([
|
||
"input",
|
||
"option",
|
||
"optgroup",
|
||
"select",
|
||
"button",
|
||
"datalist",
|
||
"textarea"
|
||
]);
|
||
const pTag = /* @__PURE__ */ new Set(["p"]);
|
||
const tableSectionTags = /* @__PURE__ */ new Set(["thead", "tbody"]);
|
||
const ddtTags = /* @__PURE__ */ new Set(["dd", "dt"]);
|
||
const rtpTags = /* @__PURE__ */ new Set(["rt", "rp"]);
|
||
const openImpliesClose = /* @__PURE__ */ new Map([
|
||
["tr", /* @__PURE__ */ new Set(["tr", "th", "td"])],
|
||
["th", /* @__PURE__ */ new Set(["th"])],
|
||
["td", /* @__PURE__ */ new Set(["thead", "th", "td"])],
|
||
["body", /* @__PURE__ */ new Set(["head", "link", "script"])],
|
||
["li", /* @__PURE__ */ new Set(["li"])],
|
||
["p", pTag],
|
||
["h1", pTag],
|
||
["h2", pTag],
|
||
["h3", pTag],
|
||
["h4", pTag],
|
||
["h5", pTag],
|
||
["h6", pTag],
|
||
["select", formTags],
|
||
["input", formTags],
|
||
["output", formTags],
|
||
["button", formTags],
|
||
["datalist", formTags],
|
||
["textarea", formTags],
|
||
["option", /* @__PURE__ */ new Set(["option"])],
|
||
["optgroup", /* @__PURE__ */ new Set(["optgroup", "option"])],
|
||
["dd", ddtTags],
|
||
["dt", ddtTags],
|
||
["address", pTag],
|
||
["article", pTag],
|
||
["aside", pTag],
|
||
["blockquote", pTag],
|
||
["details", pTag],
|
||
["div", pTag],
|
||
["dl", pTag],
|
||
["fieldset", pTag],
|
||
["figcaption", pTag],
|
||
["figure", pTag],
|
||
["footer", pTag],
|
||
["form", pTag],
|
||
["header", pTag],
|
||
["hr", pTag],
|
||
["main", pTag],
|
||
["nav", pTag],
|
||
["ol", pTag],
|
||
["pre", pTag],
|
||
["section", pTag],
|
||
["table", pTag],
|
||
["ul", pTag],
|
||
["rt", rtpTags],
|
||
["rp", rtpTags],
|
||
["tbody", tableSectionTags],
|
||
["tfoot", tableSectionTags]
|
||
]);
|
||
const voidElements = /* @__PURE__ */ new Set([
|
||
"area",
|
||
"base",
|
||
"basefont",
|
||
"br",
|
||
"col",
|
||
"command",
|
||
"embed",
|
||
"frame",
|
||
"hr",
|
||
"img",
|
||
"input",
|
||
"isindex",
|
||
"keygen",
|
||
"link",
|
||
"meta",
|
||
"param",
|
||
"source",
|
||
"track",
|
||
"wbr"
|
||
]);
|
||
const foreignContextElements = /* @__PURE__ */ new Set(["math", "svg"]);
|
||
const htmlIntegrationElements = /* @__PURE__ */ new Set([
|
||
"mi",
|
||
"mo",
|
||
"mn",
|
||
"ms",
|
||
"mtext",
|
||
"annotation-xml",
|
||
"foreignobject",
|
||
"desc",
|
||
"title"
|
||
]);
|
||
const reNameEnd = /\s|\//;
|
||
class Parser {
|
||
constructor(cbs, options = {}) {
|
||
var _a2, _b, _c, _d, _e, _f;
|
||
this.options = options;
|
||
this.startIndex = 0;
|
||
this.endIndex = 0;
|
||
this.openTagStart = 0;
|
||
this.tagname = "";
|
||
this.attribname = "";
|
||
this.attribvalue = "";
|
||
this.attribs = null;
|
||
this.stack = [];
|
||
this.buffers = [];
|
||
this.bufferOffset = 0;
|
||
this.writeIndex = 0;
|
||
this.ended = false;
|
||
this.cbs = cbs !== null && cbs !== void 0 ? cbs : {};
|
||
this.htmlMode = !this.options.xmlMode;
|
||
this.lowerCaseTagNames = (_a2 = options.lowerCaseTags) !== null && _a2 !== void 0 ? _a2 : this.htmlMode;
|
||
this.lowerCaseAttributeNames = (_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : this.htmlMode;
|
||
this.recognizeSelfClosing = (_c = options.recognizeSelfClosing) !== null && _c !== void 0 ? _c : !this.htmlMode;
|
||
this.tokenizer = new ((_d = options.Tokenizer) !== null && _d !== void 0 ? _d : Tokenizer)(this.options, this);
|
||
this.foreignContext = [!this.htmlMode];
|
||
(_f = (_e = this.cbs).onparserinit) === null || _f === void 0 ? void 0 : _f.call(_e, this);
|
||
}
|
||
// Tokenizer event handlers
|
||
/** @internal */
|
||
ontext(start, endIndex) {
|
||
var _a2, _b;
|
||
const data2 = this.getSlice(start, endIndex);
|
||
this.endIndex = endIndex - 1;
|
||
(_b = (_a2 = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a2, data2);
|
||
this.startIndex = endIndex;
|
||
}
|
||
/** @internal */
|
||
ontextentity(cp, endIndex) {
|
||
var _a2, _b;
|
||
this.endIndex = endIndex - 1;
|
||
(_b = (_a2 = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a2, fromCodePoint(cp));
|
||
this.startIndex = endIndex;
|
||
}
|
||
/**
|
||
* Checks if the current tag is a void element. Override this if you want
|
||
* to specify your own additional void elements.
|
||
*/
|
||
isVoidElement(name) {
|
||
return this.htmlMode && voidElements.has(name);
|
||
}
|
||
/** @internal */
|
||
onopentagname(start, endIndex) {
|
||
this.endIndex = endIndex;
|
||
let name = this.getSlice(start, endIndex);
|
||
if (this.lowerCaseTagNames) {
|
||
name = name.toLowerCase();
|
||
}
|
||
this.emitOpenTag(name);
|
||
}
|
||
emitOpenTag(name) {
|
||
var _a2, _b, _c, _d;
|
||
this.openTagStart = this.startIndex;
|
||
this.tagname = name;
|
||
const impliesClose = this.htmlMode && openImpliesClose.get(name);
|
||
if (impliesClose) {
|
||
while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {
|
||
const element = this.stack.shift();
|
||
(_b = (_a2 = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a2, element, true);
|
||
}
|
||
}
|
||
if (!this.isVoidElement(name)) {
|
||
this.stack.unshift(name);
|
||
if (this.htmlMode) {
|
||
if (foreignContextElements.has(name)) {
|
||
this.foreignContext.unshift(true);
|
||
} else if (htmlIntegrationElements.has(name)) {
|
||
this.foreignContext.unshift(false);
|
||
}
|
||
}
|
||
}
|
||
(_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, name);
|
||
if (this.cbs.onopentag)
|
||
this.attribs = {};
|
||
}
|
||
endOpenTag(isImplied) {
|
||
var _a2, _b;
|
||
this.startIndex = this.openTagStart;
|
||
if (this.attribs) {
|
||
(_b = (_a2 = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a2, this.tagname, this.attribs, isImplied);
|
||
this.attribs = null;
|
||
}
|
||
if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {
|
||
this.cbs.onclosetag(this.tagname, true);
|
||
}
|
||
this.tagname = "";
|
||
}
|
||
/** @internal */
|
||
onopentagend(endIndex) {
|
||
this.endIndex = endIndex;
|
||
this.endOpenTag(false);
|
||
this.startIndex = endIndex + 1;
|
||
}
|
||
/** @internal */
|
||
onclosetag(start, endIndex) {
|
||
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
||
this.endIndex = endIndex;
|
||
let name = this.getSlice(start, endIndex);
|
||
if (this.lowerCaseTagNames) {
|
||
name = name.toLowerCase();
|
||
}
|
||
if (this.htmlMode && (foreignContextElements.has(name) || htmlIntegrationElements.has(name))) {
|
||
this.foreignContext.shift();
|
||
}
|
||
if (!this.isVoidElement(name)) {
|
||
const pos = this.stack.indexOf(name);
|
||
if (pos !== -1) {
|
||
for (let index2 = 0; index2 <= pos; index2++) {
|
||
const element = this.stack.shift();
|
||
(_b = (_a2 = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a2, element, index2 !== pos);
|
||
}
|
||
} else if (this.htmlMode && name === "p") {
|
||
this.emitOpenTag("p");
|
||
this.closeCurrentTag(true);
|
||
}
|
||
} else if (this.htmlMode && name === "br") {
|
||
(_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, "br");
|
||
(_f = (_e = this.cbs).onopentag) === null || _f === void 0 ? void 0 : _f.call(_e, "br", {}, true);
|
||
(_h = (_g = this.cbs).onclosetag) === null || _h === void 0 ? void 0 : _h.call(_g, "br", false);
|
||
}
|
||
this.startIndex = endIndex + 1;
|
||
}
|
||
/** @internal */
|
||
onselfclosingtag(endIndex) {
|
||
this.endIndex = endIndex;
|
||
if (this.recognizeSelfClosing || this.foreignContext[0]) {
|
||
this.closeCurrentTag(false);
|
||
this.startIndex = endIndex + 1;
|
||
} else {
|
||
this.onopentagend(endIndex);
|
||
}
|
||
}
|
||
closeCurrentTag(isOpenImplied) {
|
||
var _a2, _b;
|
||
const name = this.tagname;
|
||
this.endOpenTag(isOpenImplied);
|
||
if (this.stack[0] === name) {
|
||
(_b = (_a2 = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a2, name, !isOpenImplied);
|
||
this.stack.shift();
|
||
}
|
||
}
|
||
/** @internal */
|
||
onattribname(start, endIndex) {
|
||
this.startIndex = start;
|
||
const name = this.getSlice(start, endIndex);
|
||
this.attribname = this.lowerCaseAttributeNames ? name.toLowerCase() : name;
|
||
}
|
||
/** @internal */
|
||
onattribdata(start, endIndex) {
|
||
this.attribvalue += this.getSlice(start, endIndex);
|
||
}
|
||
/** @internal */
|
||
onattribentity(cp) {
|
||
this.attribvalue += fromCodePoint(cp);
|
||
}
|
||
/** @internal */
|
||
onattribend(quote, endIndex) {
|
||
var _a2, _b;
|
||
this.endIndex = endIndex;
|
||
(_b = (_a2 = this.cbs).onattribute) === null || _b === void 0 ? void 0 : _b.call(_a2, this.attribname, this.attribvalue, quote === QuoteType.Double ? '"' : quote === QuoteType.Single ? "'" : quote === QuoteType.NoValue ? void 0 : null);
|
||
if (this.attribs && !Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) {
|
||
this.attribs[this.attribname] = this.attribvalue;
|
||
}
|
||
this.attribvalue = "";
|
||
}
|
||
getInstructionName(value) {
|
||
const index2 = value.search(reNameEnd);
|
||
let name = index2 < 0 ? value : value.substr(0, index2);
|
||
if (this.lowerCaseTagNames) {
|
||
name = name.toLowerCase();
|
||
}
|
||
return name;
|
||
}
|
||
/** @internal */
|
||
ondeclaration(start, endIndex) {
|
||
this.endIndex = endIndex;
|
||
const value = this.getSlice(start, endIndex);
|
||
if (this.cbs.onprocessinginstruction) {
|
||
const name = this.getInstructionName(value);
|
||
this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);
|
||
}
|
||
this.startIndex = endIndex + 1;
|
||
}
|
||
/** @internal */
|
||
onprocessinginstruction(start, endIndex) {
|
||
this.endIndex = endIndex;
|
||
const value = this.getSlice(start, endIndex);
|
||
if (this.cbs.onprocessinginstruction) {
|
||
const name = this.getInstructionName(value);
|
||
this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);
|
||
}
|
||
this.startIndex = endIndex + 1;
|
||
}
|
||
/** @internal */
|
||
oncomment(start, endIndex, offset) {
|
||
var _a2, _b, _c, _d;
|
||
this.endIndex = endIndex;
|
||
(_b = (_a2 = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a2, this.getSlice(start, endIndex - offset));
|
||
(_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c);
|
||
this.startIndex = endIndex + 1;
|
||
}
|
||
/** @internal */
|
||
oncdata(start, endIndex, offset) {
|
||
var _a2, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
||
this.endIndex = endIndex;
|
||
const value = this.getSlice(start, endIndex - offset);
|
||
if (!this.htmlMode || this.options.recognizeCDATA) {
|
||
(_b = (_a2 = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a2);
|
||
(_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value);
|
||
(_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e);
|
||
} else {
|
||
(_h = (_g = this.cbs).oncomment) === null || _h === void 0 ? void 0 : _h.call(_g, `[CDATA[${value}]]`);
|
||
(_k = (_j = this.cbs).oncommentend) === null || _k === void 0 ? void 0 : _k.call(_j);
|
||
}
|
||
this.startIndex = endIndex + 1;
|
||
}
|
||
/** @internal */
|
||
onend() {
|
||
var _a2, _b;
|
||
if (this.cbs.onclosetag) {
|
||
this.endIndex = this.startIndex;
|
||
for (let index2 = 0; index2 < this.stack.length; index2++) {
|
||
this.cbs.onclosetag(this.stack[index2], true);
|
||
}
|
||
}
|
||
(_b = (_a2 = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a2);
|
||
}
|
||
/**
|
||
* Resets the parser to a blank state, ready to parse a new HTML document
|
||
*/
|
||
reset() {
|
||
var _a2, _b, _c, _d;
|
||
(_b = (_a2 = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a2);
|
||
this.tokenizer.reset();
|
||
this.tagname = "";
|
||
this.attribname = "";
|
||
this.attribs = null;
|
||
this.stack.length = 0;
|
||
this.startIndex = 0;
|
||
this.endIndex = 0;
|
||
(_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this);
|
||
this.buffers.length = 0;
|
||
this.foreignContext.length = 0;
|
||
this.foreignContext.unshift(!this.htmlMode);
|
||
this.bufferOffset = 0;
|
||
this.writeIndex = 0;
|
||
this.ended = false;
|
||
}
|
||
/**
|
||
* Resets the parser, then parses a complete document and
|
||
* pushes it to the handler.
|
||
*
|
||
* @param data Document to parse.
|
||
*/
|
||
parseComplete(data2) {
|
||
this.reset();
|
||
this.end(data2);
|
||
}
|
||
getSlice(start, end2) {
|
||
while (start - this.bufferOffset >= this.buffers[0].length) {
|
||
this.shiftBuffer();
|
||
}
|
||
let slice2 = this.buffers[0].slice(start - this.bufferOffset, end2 - this.bufferOffset);
|
||
while (end2 - this.bufferOffset > this.buffers[0].length) {
|
||
this.shiftBuffer();
|
||
slice2 += this.buffers[0].slice(0, end2 - this.bufferOffset);
|
||
}
|
||
return slice2;
|
||
}
|
||
shiftBuffer() {
|
||
this.bufferOffset += this.buffers[0].length;
|
||
this.writeIndex--;
|
||
this.buffers.shift();
|
||
}
|
||
/**
|
||
* Parses a chunk of data and calls the corresponding callbacks.
|
||
*
|
||
* @param chunk Chunk to parse.
|
||
*/
|
||
write(chunk) {
|
||
var _a2, _b;
|
||
if (this.ended) {
|
||
(_b = (_a2 = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a2, new Error(".write() after done!"));
|
||
return;
|
||
}
|
||
this.buffers.push(chunk);
|
||
if (this.tokenizer.running) {
|
||
this.tokenizer.write(chunk);
|
||
this.writeIndex++;
|
||
}
|
||
}
|
||
/**
|
||
* Parses the end of the buffer and clears the stack, calls onend.
|
||
*
|
||
* @param chunk Optional final chunk to parse.
|
||
*/
|
||
end(chunk) {
|
||
var _a2, _b;
|
||
if (this.ended) {
|
||
(_b = (_a2 = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a2, new Error(".end() after done!"));
|
||
return;
|
||
}
|
||
if (chunk)
|
||
this.write(chunk);
|
||
this.ended = true;
|
||
this.tokenizer.end();
|
||
}
|
||
/**
|
||
* Pauses parsing. The parser won't emit events until `resume` is called.
|
||
*/
|
||
pause() {
|
||
this.tokenizer.pause();
|
||
}
|
||
/**
|
||
* Resumes parsing after `pause` was called.
|
||
*/
|
||
resume() {
|
||
this.tokenizer.resume();
|
||
while (this.tokenizer.running && this.writeIndex < this.buffers.length) {
|
||
this.tokenizer.write(this.buffers[this.writeIndex++]);
|
||
}
|
||
if (this.ended)
|
||
this.tokenizer.end();
|
||
}
|
||
/**
|
||
* Alias of `write`, for backwards compatibility.
|
||
*
|
||
* @param chunk Chunk to parse.
|
||
* @deprecated
|
||
*/
|
||
parseChunk(chunk) {
|
||
this.write(chunk);
|
||
}
|
||
/**
|
||
* Alias of `end`, for backwards compatibility.
|
||
*
|
||
* @param chunk Optional final chunk to parse.
|
||
* @deprecated
|
||
*/
|
||
done(chunk) {
|
||
this.end(chunk);
|
||
}
|
||
}
|
||
function parseDocument(data2, options) {
|
||
const handler = new DomHandler(void 0, options);
|
||
new Parser(handler, options).end(data2);
|
||
return handler.root;
|
||
}
|
||
const load = getLoad(getParse(parseDocument), render$1);
|
||
var Levels = /* @__PURE__ */ ((Levels2) => {
|
||
Levels2[Levels2["None"] = 0] = "None";
|
||
Levels2[Levels2["H1"] = 1] = "H1";
|
||
Levels2[Levels2["H2"] = 2] = "H2";
|
||
Levels2[Levels2["H3"] = 3] = "H3";
|
||
Levels2[Levels2["H4"] = 4] = "H4";
|
||
Levels2[Levels2["H5"] = 5] = "H5";
|
||
Levels2[Levels2["H6"] = 6] = "H6";
|
||
Levels2[Levels2["Block"] = 7] = "Block";
|
||
Levels2[Levels2["List"] = 8] = "List";
|
||
Levels2[Levels2["ListItem"] = 9] = "ListItem";
|
||
return Levels2;
|
||
})(Levels || {});
|
||
const defaultSelectorRules = {
|
||
"div,p": ({ $node }) => ({
|
||
queue: $node.children()
|
||
}),
|
||
"h1,h2,h3,h4,h5,h6": ({ $node, getContent }) => ({
|
||
...getContent($node.contents())
|
||
}),
|
||
"ul,ol": ({ $node }) => ({
|
||
queue: $node.children(),
|
||
nesting: true
|
||
}),
|
||
li: ({ $node, getContent }) => {
|
||
const queue = $node.children().filter("ul,ol");
|
||
let content;
|
||
if ($node.contents().first().is("div,p")) {
|
||
content = getContent($node.children().first());
|
||
} else {
|
||
let $contents = $node.contents();
|
||
const i = $contents.index(queue);
|
||
if (i >= 0) $contents = $contents.slice(0, i);
|
||
content = getContent($contents);
|
||
}
|
||
return {
|
||
queue,
|
||
nesting: true,
|
||
...content
|
||
};
|
||
},
|
||
"table,pre,p>img:only-child": ({ $node, getContent }) => ({
|
||
...getContent($node)
|
||
})
|
||
};
|
||
const defaultOptions = {
|
||
selector: "h1,h2,h3,h4,h5,h6,ul,ol,li,table,pre,p>img:only-child",
|
||
selectorRules: defaultSelectorRules
|
||
};
|
||
const MARKMAP_COMMENT_PREFIX = "markmap: ";
|
||
const SELECTOR_HEADING = /^h[1-6]$/;
|
||
const SELECTOR_LIST = /^[uo]l$/;
|
||
const SELECTOR_LIST_ITEM = /^li$/;
|
||
function getLevel(tagName) {
|
||
if (SELECTOR_HEADING.test(tagName)) return +tagName[1];
|
||
if (SELECTOR_LIST.test(tagName)) return 8;
|
||
if (SELECTOR_LIST_ITEM.test(tagName)) return 9;
|
||
return 7;
|
||
}
|
||
function parseHtml(html2, opts) {
|
||
const options = {
|
||
...defaultOptions,
|
||
...opts
|
||
};
|
||
const $ = load(html2);
|
||
let $root = $("body");
|
||
if (!$root.length) $root = $.root();
|
||
let id = 0;
|
||
const rootNode = {
|
||
id,
|
||
tag: "",
|
||
html: "",
|
||
level: 0,
|
||
parent: 0,
|
||
childrenLevel: 0,
|
||
children: []
|
||
};
|
||
const headingStack = [];
|
||
let skippingHeading = 0;
|
||
checkNodes($root.children());
|
||
return rootNode;
|
||
function addChild(props) {
|
||
var _a2;
|
||
const { parent: parent2 } = props;
|
||
const node = {
|
||
id: ++id,
|
||
tag: props.tagName,
|
||
level: props.level,
|
||
html: props.html,
|
||
childrenLevel: 0,
|
||
children: props.nesting ? [] : void 0,
|
||
parent: parent2.id
|
||
};
|
||
if ((_a2 = props.comments) == null ? void 0 : _a2.length) {
|
||
node.comments = props.comments;
|
||
}
|
||
if (Object.keys(props.data || {}).length) {
|
||
node.data = props.data;
|
||
}
|
||
if (parent2.children) {
|
||
if (parent2.childrenLevel === 0 || parent2.childrenLevel > node.level) {
|
||
parent2.children = [];
|
||
parent2.childrenLevel = node.level;
|
||
}
|
||
if (parent2.childrenLevel === node.level) {
|
||
parent2.children.push(node);
|
||
}
|
||
}
|
||
return node;
|
||
}
|
||
function getCurrentHeading(level) {
|
||
let heading;
|
||
while ((heading = headingStack[headingStack.length - 1]) && heading.level >= level) {
|
||
headingStack.pop();
|
||
}
|
||
return heading || rootNode;
|
||
}
|
||
function getContent($node) {
|
||
var _a2;
|
||
const result = extractMagicComments($node);
|
||
const html22 = (_a2 = $.html(result.$node)) == null ? void 0 : _a2.trimEnd();
|
||
return { comments: result.comments, html: html22 };
|
||
}
|
||
function extractMagicComments($node) {
|
||
const comments = [];
|
||
$node = $node.filter((_, child) => {
|
||
if (child.type === "comment") {
|
||
const data2 = child.data.trim();
|
||
if (data2.startsWith(MARKMAP_COMMENT_PREFIX)) {
|
||
comments.push(data2.slice(MARKMAP_COMMENT_PREFIX.length).trim());
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
});
|
||
return { $node, comments };
|
||
}
|
||
function checkNodes($els, node) {
|
||
$els.each((_, child) => {
|
||
var _a2;
|
||
const $child = $(child);
|
||
const rule = (_a2 = Object.entries(options.selectorRules).find(
|
||
([selector]) => $child.is(selector)
|
||
)) == null ? void 0 : _a2[1];
|
||
const result = rule == null ? void 0 : rule({ $node: $child, $, getContent });
|
||
if ((result == null ? void 0 : result.queue) && !result.nesting) {
|
||
checkNodes(result.queue, node);
|
||
return;
|
||
}
|
||
const level = getLevel(child.tagName);
|
||
if (!result) {
|
||
if (level <= 6) {
|
||
skippingHeading = level;
|
||
}
|
||
return;
|
||
}
|
||
if (skippingHeading > 0 && level > skippingHeading) return;
|
||
if (!$child.is(options.selector)) return;
|
||
skippingHeading = 0;
|
||
const isHeading = level <= 6;
|
||
let data2 = {
|
||
// If the child is an inline element and expected to be a separate node,
|
||
// data from the closest `<p>` should be included, e.g. `<p data-lines><img /></p>`
|
||
...$child.closest("p").data(),
|
||
...$child.data()
|
||
};
|
||
let html22 = result.html || "";
|
||
if ($child.is("ol>li") && (node == null ? void 0 : node.children)) {
|
||
const start = +($child.parent().attr("start") || 1);
|
||
const listIndex = start + node.children.length;
|
||
html22 = `${listIndex}. ${html22}`;
|
||
data2 = {
|
||
...data2,
|
||
listIndex
|
||
};
|
||
}
|
||
const childNode = addChild({
|
||
parent: node || getCurrentHeading(level),
|
||
nesting: !!result.queue || isHeading,
|
||
tagName: child.tagName,
|
||
level,
|
||
html: html22,
|
||
comments: result.comments,
|
||
data: data2
|
||
});
|
||
if (isHeading) headingStack.push(childNode);
|
||
if (result.queue) checkNodes(result.queue, childNode);
|
||
});
|
||
}
|
||
}
|
||
function convertNode(htmlRoot) {
|
||
return walkTree(htmlRoot, (htmlNode, next2) => {
|
||
const node = {
|
||
content: htmlNode.html,
|
||
children: next2() || []
|
||
};
|
||
if (htmlNode.data) {
|
||
node.payload = {
|
||
tag: htmlNode.tag,
|
||
...htmlNode.data
|
||
};
|
||
}
|
||
if (htmlNode.comments) {
|
||
if (htmlNode.comments.includes("foldAll")) {
|
||
node.payload = { ...node.payload, fold: 2 };
|
||
} else if (htmlNode.comments.includes("fold")) {
|
||
node.payload = { ...node.payload, fold: 1 };
|
||
}
|
||
}
|
||
return node;
|
||
});
|
||
}
|
||
function buildTree(html2, opts) {
|
||
const htmlRoot = parseHtml(html2, opts);
|
||
return convertNode(htmlRoot);
|
||
}
|
||
export {
|
||
Levels,
|
||
buildTree,
|
||
convertNode,
|
||
defaultOptions,
|
||
parseHtml
|
||
};
|