{"version":3,"sources":["jsdelivr-header.js","/npm/fast-html-parser@1.0.0/index.js"],"names":[],"mappings":"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","file":"/npm/fast-html-parser@1.0.0/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/fast-html-parser@1.0.0/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","require('apollojs');\n\nvar entities = require('entities');\n\n/**\n * Node Class as base class for TextNode and HTMLElement.\n */\nfunction Node() {\n\n}\n$declare(Node, {\n\n});\n$defenum(Node, {\n  ELEMENT_NODE:  1,\n  TEXT_NODE:     3\n});\n\n/**\n * TextNode to contain a text element in DOM tree.\n * @param {string} value [description]\n */\nfunction TextNode(value) {\n  this.rawText = value;\n}\n$inherit(TextNode, Node, {\n\n  /**\n   * Node Type declaration.\n   * @type {Number}\n   */\n  nodeType: Node.TEXT_NODE,\n\n  /**\n   * Get unescaped text value of current node and its children.\n   * @return {string} text content\n   */\n  get text() {\n    return entities.decodeHTML5(this.rawText);\n  },\n\n  /**\n   * Detect if the node contains only white space.\n   * @return {bool}\n   */\n  get isWhitespace() {\n    return /^(\\s|&nbsp;)*$/.test(this.rawText);\n  }\n\n});\n\nvar kBlockElements = {\n  div: true,\n  p: true,\n  // ul: true,\n  // ol: true,\n  li: true,\n  // table: true,\n  // tr: true,\n  td: true,\n  section: true,\n  br: true\n};\n\n/**\n * HTMLElement, which contains a set of children.\n * Note: this is a minimalist implementation, no complete tree\n *   structure provided (no parentNode, nextSibling,\n *   previousSibling etc).\n * @param {string} name     tagName\n * @param {Object} keyAttrs id and class attribute\n * @param {Object} rawAttrs attributes in string\n */\nfunction HTMLElement(name, keyAttrs, rawAttrs) {\n  this.tagName = name;\n  this.rawAttrs = rawAttrs || '';\n  // this.parentNode = null;\n  this.childNodes = [];\n  if (keyAttrs.id)\n    this.id = keyAttrs.id;\n  if (keyAttrs.class)\n    this.classNames = keyAttrs.class.split(/\\s+/);\n  else\n    this.classNames = [];\n}\n$inherit(HTMLElement, Node, {\n\n  /**\n   * Node Type declaration.\n   * @type {Number}\n   */\n  nodeType: Node.ELEMENT_NODE,\n\n  /**\n   * Get unescaped text value of current node and its children.\n   * @return {string} text content\n   */\n  get text() {\n    return entities.decodeHTML5(this.rawText);\n  },\n\n  /**\n   * Get escpaed (as-it) text value of current node and its children.\n   * @return {string} text content\n   */\n  get rawText() {\n    var res = '';\n    for (var i = 0; i < this.childNodes.length; i++)\n      res += this.childNodes[i].rawText;\n    return res;\n  },\n\n  /**\n   * Get structured Text (with '\\n' etc.)\n   * @return {string} structured text\n   */\n  get structuredText() {\n    var currentBlock = [];\n    var blocks = [currentBlock];\n    function dfs(node) {\n      if (node.nodeType === Node.ELEMENT_NODE) {\n        if (kBlockElements[node.tagName]) {\n          if (currentBlock.length > 0)\n            blocks.push(currentBlock = []);\n          node.childNodes.forEach(dfs);\n          if (currentBlock.length > 0)\n            blocks.push(currentBlock = []);\n        } else {\n          node.childNodes.forEach(dfs);\n        }\n      } else if (node.nodeType === Node.TEXT_NODE) {\n        if (node.isWhitespace) {\n          // Whitespace node, postponed output\n          currentBlock.prependWhitespace = true;\n        } else {\n          var text = node.text;\n          if (currentBlock.prependWhitespace) {\n            text = ' ' + text;\n            currentBlock.prependWhitespace = false;\n          }\n          currentBlock.push(text);\n        }\n      }\n    }\n    dfs(this);\n    return blocks\n        .map(function(block) {\n          // Normalize each line's whitespace\n          return block.join('').trim().replace(/\\s{2,}/g, ' ');\n        })\n        .join('\\n').trimRight();\n  },\n\n  /**\n   * Trim element from right (in block) after seeing pattern in a TextNode.\n   * @param  {RegExp} pattern pattern to find\n   * @return {HTMLElement}    reference to current node\n   */\n  trimRight: function(pattern) {\n    function dfs(node) {\n      for (var i = 0; i < node.childNodes.length; i++) {\n        var childNode = node.childNodes[i];\n        if (childNode.nodeType === Node.ELEMENT_NODE) {\n          dfs(childNode);\n        } else {\n          var index = childNode.rawText.search(pattern);\n          if (index > -1) {\n            childNode.rawText = childNode.rawText.substr(0, index);\n            // trim all following nodes.\n            node.childNodes.length = i+1;\n          }\n        }\n      }\n    }\n    dfs(this);\n    return this;\n  },\n\n  /**\n   * Get DOM structure\n   * @return {string} strucutre\n   */\n  get structure() {\n    var res = [];\n    var indention = 0;\n    function write(str) {\n      res.push('  '.repeat(indention) + str);\n    }\n    function dfs(node) {\n      var idStr = node.id ? ('#' + node.id) : '';\n      var classStr = node.classNames.length ? ('.' + node.classNames.join('.')) : '';\n      write(node.tagName + idStr + classStr);\n      indention++;\n      for (var i = 0; i < node.childNodes.length; i++) {\n        var childNode = node.childNodes[i];\n        if (childNode.nodeType === Node.ELEMENT_NODE) {\n          dfs(childNode);\n        } else if (childNode.nodeType === Node.TEXT_NODE) {\n          if (!childNode.isWhitespace)\n            write('#text');\n        }\n      }\n      indention--;\n    }\n    dfs(this);\n    return res.join('\\n');\n  },\n\n  /**\n   * Remove whitespaces in this sub tree.\n   * @return {HTMLElement} pointer to this\n   */\n  removeWhitespace: function() {\n    var i = 0, o = 0;\n    for (; i < this.childNodes.length; i++) {\n      var node = this.childNodes[i];\n      if (node.nodeType === Node.TEXT_NODE) {\n        if (node.isWhitespace)\n          continue;\n        node.rawText = node.rawText.trim();\n      } else if (node.nodeType === Node.ELEMENT_NODE) {\n        node.removeWhitespace();\n      }\n      this.childNodes[o++] = node;\n    }\n    this.childNodes.length = o;\n    return this;\n  },\n\n  /**\n   * Query CSS selector to find matching nodes.\n   * @param  {string}         selector Simplified CSS selector\n   * @param  {Matcher}        selector A Matcher instance\n   * @return {HTMLElement[]}  matching elements\n   */\n  querySelectorAll: function(selector) {\n    var matcher;\n    if (selector instanceof Matcher) {\n      matcher = selector;\n      matcher.reset();\n    } else {\n      matcher = new Matcher(selector);\n    }\n    var res = [];\n    var stack = [];\n    for (var i = 0; i < this.childNodes.length; i++) {\n      stack.push([this.childNodes[i], 0, false]);\n      while (stack.length) {\n        var state = stack.back;\n        var el = state[0];\n        if (state[1] === 0) {\n          // Seen for first time.\n          if (el.nodeType !== Node.ELEMENT_NODE) {\n            stack.pop();\n            continue;\n          }\n          if (state[2] = matcher.advance(el)) {\n            if (matcher.matched) {\n              res.push(el);\n              // no need to go further.\n              matcher.rewind();\n              stack.pop();\n              continue;\n            }\n          }\n        }\n        if (state[1] < el.childNodes.length) {\n          stack.push([el.childNodes[state[1]++], 0, false]);\n        } else {\n          if (state[2])\n            matcher.rewind();\n          stack.pop();\n        }\n      }\n    }\n    return res;\n  },\n\n  /**\n   * Query CSS Selector to find matching node.\n   * @param  {string}         selector Simplified CSS selector\n   * @param  {Matcher}        selector A Matcher instance\n   * @return {HTMLElement}    matching node\n   */\n  querySelector: function(selector) {\n    var matcher;\n    if (selector instanceof Matcher) {\n      matcher = selector;\n      matcher.reset();\n    } else {\n      matcher = new Matcher(selector);\n    }\n    var stack = [];\n    for (var i = 0; i < this.childNodes.length; i++) {\n      stack.push([this.childNodes[i], 0, false]);\n      while (stack.length) {\n        var state = stack.back;\n        var el = state[0];\n        if (state[1] === 0) {\n          // Seen for first time.\n          if (el.nodeType !== Node.ELEMENT_NODE) {\n            stack.pop();\n            continue;\n          }\n          if (state[2] = matcher.advance(el)) {\n            if (matcher.matched) {\n              return el;\n            }\n          }\n        }\n        if (state[1] < el.childNodes.length) {\n          stack.push([el.childNodes[state[1]++], 0, false]);\n        } else {\n          if (state[2])\n            matcher.rewind();\n          stack.pop();\n        }\n      }\n    }\n    return null;\n  },\n\n  /**\n   * Append a child node to childNodes\n   * @param  {Node} node node to append\n   * @return {Node}      node appended\n   */\n  appendChild: function(node) {\n    // node.parentNode = this;\n    this.childNodes.push(node);\n    return node;\n  },\n\n  /**\n   * Get first child node\n   * @return {Node} first child node\n   */\n  get firstChild() {\n    return this.childNodes.front;\n  },\n\n  /**\n   * Get last child node\n   * @return {Node} last child node\n   */\n  get lastChild() {\n    return this.childNodes.back;\n  },\n\n  /**\n   * Get attributes\n   * @return {Object} parsed and unescaped attributes\n   */\n  get attributes() {\n    if (this._attrs)\n      return this._attrs;\n    this._attrs = {};\n    var attrs = this.rawAttributes;\n    for (var key in attrs) {\n      this._attrs[key] = entities.decodeHTML5(attrs[key]);\n    }\n    return this._attrs;\n  },\n\n  /**\n   * Get escaped (as-it) attributes\n   * @return {Object} parsed attributes\n   */\n  get rawAttributes() {\n    if (this._rawAttrs)\n      return this._rawAttrs;\n    var attrs = {};\n    if (this.rawAttrs) {\n      var re = /\\b([a-z][a-z0-9\\-]*)\\s*=\\s*(\"([^\"]+)\"|'([^']+)'|(\\S+))/ig;\n      for (var match; match = re.exec(this.rawAttrs); )\n        attrs[match[1]] = match[3] || match[4] || match[5];\n    }\n    this._rawAttrs = attrs;\n    return attrs;\n  }\n\n});\n$define(HTMLElement, {\n  __wrap: function(el) {\n    el.childNodes.forEach(function(node) {\n      if (node.rawText) {\n        $wrap(node, TextNode);\n      } else {\n        $wrap(node, HTMLElement);\n      }\n    });\n  }\n});\n\n/**\n * Cache to store generated match functions\n * @type {Object}\n */\nvar gMatchFunctionCache = {};\n\n/**\n * Matcher class to make CSS match\n * @param {string} selector Selector\n */\nfunction Matcher(selector) {\n  this.matchers = selector.split(' ').map(function(matcher) {\n    if (gMatchFunctionCache[matcher])\n      return gMatchFunctionCache[matcher];\n    var parts = matcher.split('.');\n    var tagName = parts[0];\n    var classes = parts.slice(1).sort();\n    var source = '';\n    if (tagName && tagName != '*') {\n      if (tagName[0] == '#')\n        source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';\n      else\n        source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';\n    }\n    if (classes.length > 0)\n      source += 'for (var cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;';\n    source += 'return true;';\n    return gMatchFunctionCache[matcher] = new Function('el', source);\n  });\n  this.nextMatch = 0;\n}\n$declare(Matcher, {\n  /**\n   * Trying to advance match pointer\n   * @param  {HTMLElement} el element to make the match\n   * @return {bool}           true when pointer advanced.\n   */\n  advance: function(el) {\n    if (this.nextMatch < this.matchers.length &&\n        this.matchers[this.nextMatch](el)) {\n      this.nextMatch++;\n      return true;\n    }\n    return false;\n  },\n  /**\n   * Rewind the match pointer\n   */\n  rewind: function() {\n    this.nextMatch--;\n  },\n  /**\n   * Trying to determine if match made.\n   * @return {bool} true when the match is made\n   */\n  get matched() {\n    return this.nextMatch == this.matchers.length;\n  },\n  /**\n   * Rest match pointer.\n   * @return {[type]} [description]\n   */\n  reset: function() {\n    this.nextMatch = 0;\n  }\n});\n$define(Matcher, {\n  /**\n   * flush cache to free memory\n   */\n  flushCache: function() {\n    gMatchFunctionCache = {};\n  }\n});\n\nvar kMarkupPattern = /<!--[^]*?(?=-->)-->|<(\\/?)([a-z][a-z0-9]*)\\s*([^>]*?)(\\/?)>/ig;\nvar kAttributePattern = /\\b(id|class)\\s*=\\s*(\"([^\"]+)\"|'([^']+)'|(\\S+))/ig;\nvar kSelfClosingElements = {\n  meta: true,\n  img: true,\n  link: true,\n  input: true,\n  area: true,\n  br: true,\n  hr: true\n};\nvar kElementsClosedByOpening = {\n  li: {li: true},\n  p: {p: true, div: true},\n  td: {td: true, th: true},\n  th: {td: true, th: true}\n};\nvar kElementsClosedByClosing = {\n  li: {ul: true, ol: true},\n  p: {div: true},\n  td: {tr: true, table: true},\n  th: {tr: true, table: true}\n};\nvar kBlockTextElements = {\n  script: true,\n  noscript: true,\n  style: true,\n  pre: true\n};\n\n/**\n * Parses HTML and returns a root element\n */\nmodule.exports = {\n\n  Matcher: Matcher,\n  Node: Node,\n  HTMLElement: HTMLElement,\n  TextNode: TextNode,\n\n  /**\n   * Parse a chuck of HTML source.\n   * @param  {string} data      html\n   * @return {HTMLElement}      root element\n   */\n  parse: function(data, options) {\n\n    var root = new HTMLElement(null, {});\n    var currentParent = root;\n    var stack = [root];\n    var lastTextPos = -1;\n\n    options = options || {};\n\n    for (var match, text; match = kMarkupPattern.exec(data); ) {\n      if (lastTextPos > -1) {\n        if (lastTextPos + match[0].length < kMarkupPattern.lastIndex) {\n          // if has content\n          text = data.substring(lastTextPos, kMarkupPattern.lastIndex - match[0].length);\n          currentParent.appendChild(new TextNode(text));\n        }\n      }\n      lastTextPos = kMarkupPattern.lastIndex;\n      if (match[0][1] == '!') {\n        // this is a comment\n        continue;\n      }\n      if (options.lowerCaseTagName)\n        match[2] = match[2].toLowerCase();\n      if (!match[1]) {\n        // not </ tags\n        var attrs = {};\n        for (var attMatch; attMatch = kAttributePattern.exec(match[3]); )\n          attrs[attMatch[1]] = attMatch[3] || attMatch[4] || attMatch[5];\n        // console.log(attrs);\n        if (!match[4] && kElementsClosedByOpening[currentParent.tagName]) {\n          if (kElementsClosedByOpening[currentParent.tagName][match[2]]) {\n            stack.pop();\n            currentParent = stack.back;\n          }\n        }\n        currentParent = currentParent.appendChild(\n            new HTMLElement(match[2], attrs, match[3]));\n        stack.push(currentParent);\n        if (kBlockTextElements[match[2]]) {\n          // a little test to find next </script> or </style> ...\n          var closeMarkup = '</' + match[2] + '>';\n          var index = data.indexOf(closeMarkup, kMarkupPattern.lastIndex);\n          if (options[match[2]]) {\n            if (index == -1) {\n              // there is no matching ending for the text element.\n              text = data.substr(kMarkupPattern.lastIndex);\n            } else {\n              text = data.substring(kMarkupPattern.lastIndex, index);\n            }\n            if (text.length > 0)\n              currentParent.appendChild(new TextNode(text));\n          }\n          if (index == -1) {\n            lastTextPos = kMarkupPattern.lastIndex = data.length + 1;\n          } else {\n            lastTextPos = kMarkupPattern.lastIndex = index + closeMarkup.length;\n            match[1] = true;\n          }\n        }\n      }\n      if (match[1] || match[4] ||\n          kSelfClosingElements[match[2]]) {\n        // </ or /> or <br> etc.\n        while (true) {\n          if (currentParent.tagName == match[2]) {\n            stack.pop();\n            currentParent = stack.back;\n            break;\n          } else {\n            // Trying to close current tag, and move on\n            if (kElementsClosedByClosing[currentParent.tagName]) {\n              if (kElementsClosedByClosing[currentParent.tagName][match[2]]) {\n                stack.pop();\n                currentParent = stack.back;\n                continue;\n              }\n            }\n            // Use aggressive strategy to handle unmatching markups.\n            break;\n          }\n        }\n      }\n    }\n\n    return root;\n\n  }\n\n};\n"]}