node(s) and append them into the `nodes` variable.
// Some articles' DOM structures might look like
//
var brNodes = doc.querySelectorAll("div > br");
if (brNodes.length) {
var set = new Set(nodes);
[].forEach.call(brNodes, function (node) {
set.add(node.parentNode);
});
nodes = Array.from(set);
}
var score = 0;
// This is a little cheeky, we use the accumulator 'score' to decide what to return from
// this callback:
return [].some.call(nodes, function (node) {
if (!options.visibilityChecker(node)) {
return false;
}
var matchString = node.className + " " + node.id;
if (REGEXPS.unlikelyCandidates.test(matchString) &&
!REGEXPS.okMaybeItsACandidate.test(matchString)) {
return false;
}
if (node.matches("li p")) {
return false;
}
var textContentLength = node.textContent.trim().length;
if (textContentLength < options.minContentLength) {
return false;
}
score += Math.sqrt(textContentLength - options.minContentLength);
if (score > options.minScore) {
return true;
}
return false;
});
}
if (true) {
/* global module */
module.exports = isProbablyReaderable;
}
/***/ }),
/***/ "./node_modules/@mozilla/readability/Readability.js":
/***/ ((module) => {
/*
* Copyright (c) 2010 Arc90 Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This code is heavily based on Arc90's readability.js (1.7.1) script
* available at: http://code.google.com/p/arc90labs-readability
*/
/**
* Public constructor.
* @param {HTMLDocument} doc The document to parse.
* @param {Object} options The options object.
*/
function Readability(doc, options) {
// In some older versions, people passed a URI as the first argument. Cope:
if (options && options.documentElement) {
doc = options;
options = arguments[2];
} else if (!doc || !doc.documentElement) {
throw new Error("First argument to Readability constructor should be a document object.");
}
options = options || {};
this._doc = doc;
this._docJSDOMParser = this._doc.firstChild.__JSDOMParser__;
this._articleTitle = null;
this._articleByline = null;
this._articleDir = null;
this._articleSiteName = null;
this._attempts = [];
// Configurable options
this._debug = !!options.debug;
this._maxElemsToParse = options.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE;
this._nbTopCandidates = options.nbTopCandidates || this.DEFAULT_N_TOP_CANDIDATES;
this._charThreshold = options.charThreshold || this.DEFAULT_CHAR_THRESHOLD;
this._classesToPreserve = this.CLASSES_TO_PRESERVE.concat(options.classesToPreserve || []);
this._keepClasses = !!options.keepClasses;
this._serializer = options.serializer || function(el) {
return el.innerHTML;
};
this._disableJSONLD = !!options.disableJSONLD;
this._allowedVideoRegex = options.allowedVideoRegex || this.REGEXPS.videos;
// Start with all flags set
this._flags = this.FLAG_STRIP_UNLIKELYS |
this.FLAG_WEIGHT_CLASSES |
this.FLAG_CLEAN_CONDITIONALLY;
// Control whether log messages are sent to the console
if (this._debug) {
let logNode = function(node) {
if (node.nodeType == node.TEXT_NODE) {
return `${node.nodeName} ("${node.textContent}")`;
}
let attrPairs = Array.from(node.attributes || [], function(attr) {
return `${attr.name}="${attr.value}"`;
}).join(" ");
return `<${node.localName} ${attrPairs}>`;
};
this.log = function () {
if (typeof console !== "undefined") {
let args = Array.from(arguments, arg => {
if (arg && arg.nodeType == this.ELEMENT_NODE) {
return logNode(arg);
}
return arg;
});
args.unshift("Reader: (Readability)");
console.log.apply(console, args);
} else if (typeof dump !== "undefined") {
/* global dump */
var msg = Array.prototype.map.call(arguments, function(x) {
return (x && x.nodeName) ? logNode(x) : x;
}).join(" ");
dump("Reader: (Readability) " + msg + "\n");
}
};
} else {
this.log = function () {};
}
}
Readability.prototype = {
FLAG_STRIP_UNLIKELYS: 0x1,
FLAG_WEIGHT_CLASSES: 0x2,
FLAG_CLEAN_CONDITIONALLY: 0x4,
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
ELEMENT_NODE: 1,
TEXT_NODE: 3,
// Max number of nodes supported by this parser. Default: 0 (no limit)
DEFAULT_MAX_ELEMS_TO_PARSE: 0,
// The number of top candidates to consider when analysing how
// tight the competition is among candidates.
DEFAULT_N_TOP_CANDIDATES: 5,
// Element tags to score by default.
DEFAULT_TAGS_TO_SCORE: "section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","),
// The default number of chars an article must have in order to return a result
DEFAULT_CHAR_THRESHOLD: 500,
// All of the regular expressions in use within readability.
// Defined up here so we don't instantiate them repeatedly in loops.
REGEXPS: {
// NOTE: These two regular expressions are duplicated in
// Readability-readerable.js. Please keep both copies in sync.
unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
okMaybeItsACandidate: /and|article|body|column|content|main|shadow/i,
positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,
negative: /-ad-|hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i,
extraneous: /print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i,
byline: /byline|author|dateline|writtenby|p-author/i,
replaceFonts: /<(\/?)font[^>]*>/gi,
normalize: /\s{2,}/g,
videos: /\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i,
shareElements: /(\b|_)(share|sharedaddy)(\b|_)/i,
nextLink: /(next|weiter|continue|>([^\|]|$)|»([^\|]|$))/i,
prevLink: /(prev|earl|old|new|<|«)/i,
tokenize: /\W+/g,
whitespace: /^\s*$/,
hasContent: /\S$/,
hashUrl: /^#.+/,
srcsetUrl: /(\S+)(\s+[\d.]+[xw])?(\s*(?:,|$))/g,
b64DataUrl: /^data:\s*([^\s;,]+)\s*;\s*base64\s*,/i,
// See: https://schema.org/Article
jsonLdArticleTypes: /^Article|AdvertiserContentArticle|NewsArticle|AnalysisNewsArticle|AskPublicNewsArticle|BackgroundNewsArticle|OpinionNewsArticle|ReportageNewsArticle|ReviewNewsArticle|Report|SatiricalArticle|ScholarlyArticle|MedicalScholarlyArticle|SocialMediaPosting|BlogPosting|LiveBlogPosting|DiscussionForumPosting|TechArticle|APIReference$/
},
UNLIKELY_ROLES: [ "menu", "menubar", "complementary", "navigation", "alert", "alertdialog", "dialog" ],
DIV_TO_P_ELEMS: new Set([ "BLOCKQUOTE", "DL", "DIV", "IMG", "OL", "P", "PRE", "TABLE", "UL" ]),
ALTER_TO_DIV_EXCEPTIONS: ["DIV", "ARTICLE", "SECTION", "P"],
PRESENTATIONAL_ATTRIBUTES: [ "align", "background", "bgcolor", "border", "cellpadding", "cellspacing", "frame", "hspace", "rules", "style", "valign", "vspace" ],
DEPRECATED_SIZE_ATTRIBUTE_ELEMS: [ "TABLE", "TH", "TD", "HR", "PRE" ],
// The commented out elements qualify as phrasing content but tend to be
// removed by readability when put into paragraphs, so we ignore them here.
PHRASING_ELEMS: [
// "CANVAS", "IFRAME", "SVG", "VIDEO",
"ABBR", "AUDIO", "B", "BDO", "BR", "BUTTON", "CITE", "CODE", "DATA",
"DATALIST", "DFN", "EM", "EMBED", "I", "IMG", "INPUT", "KBD", "LABEL",
"MARK", "MATH", "METER", "NOSCRIPT", "OBJECT", "OUTPUT", "PROGRESS", "Q",
"RUBY", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRONG", "SUB",
"SUP", "TEXTAREA", "TIME", "VAR", "WBR"
],
// These are the classes that readability sets itself.
CLASSES_TO_PRESERVE: [ "page" ],
// These are the list of HTML entities that need to be escaped.
HTML_ESCAPE_MAP: {
"lt": "<",
"gt": ">",
"amp": "&",
"quot": '"',
"apos": "'",
},
/**
* Run any post-process modifications to article content as necessary.
*
* @param Element
* @return void
**/
_postProcessContent: function(articleContent) {
// Readability cannot open relative uris so we convert them to absolute uris.
this._fixRelativeUris(articleContent);
this._simplifyNestedElements(articleContent);
if (!this._keepClasses) {
// Remove classes.
this._cleanClasses(articleContent);
}
},
/**
* Iterates over a NodeList, calls `filterFn` for each node and removes node
* if function returned `true`.
*
* If function is not passed, removes all the nodes in node list.
*
* @param NodeList nodeList The nodes to operate on
* @param Function filterFn the function to use as a filter
* @return void
*/
_removeNodes: function(nodeList, filterFn) {
// Avoid ever operating on live node lists.
if (this._docJSDOMParser && nodeList._isLiveNodeList) {
throw new Error("Do not pass live node lists to _removeNodes");
}
for (var i = nodeList.length - 1; i >= 0; i--) {
var node = nodeList[i];
var parentNode = node.parentNode;
if (parentNode) {
if (!filterFn || filterFn.call(this, node, i, nodeList)) {
parentNode.removeChild(node);
}
}
}
},
/**
* Iterates over a NodeList, and calls _setNodeTag for each node.
*
* @param NodeList nodeList The nodes to operate on
* @param String newTagName the new tag name to use
* @return void
*/
_replaceNodeTags: function(nodeList, newTagName) {
// Avoid ever operating on live node lists.
if (this._docJSDOMParser && nodeList._isLiveNodeList) {
throw new Error("Do not pass live node lists to _replaceNodeTags");
}
for (const node of nodeList) {
this._setNodeTag(node, newTagName);
}
},
/**
* Iterate over a NodeList, which doesn't natively fully implement the Array
* interface.
*
* For convenience, the current object context is applied to the provided
* iterate function.
*
* @param NodeList nodeList The NodeList.
* @param Function fn The iterate function.
* @return void
*/
_forEachNode: function(nodeList, fn) {
Array.prototype.forEach.call(nodeList, fn, this);
},
/**
* Iterate over a NodeList, and return the first node that passes
* the supplied test function
*
* For convenience, the current object context is applied to the provided
* test function.
*
* @param NodeList nodeList The NodeList.
* @param Function fn The test function.
* @return void
*/
_findNode: function(nodeList, fn) {
return Array.prototype.find.call(nodeList, fn, this);
},
/**
* Iterate over a NodeList, return true if any of the provided iterate
* function calls returns true, false otherwise.
*
* For convenience, the current object context is applied to the
* provided iterate function.
*
* @param NodeList nodeList The NodeList.
* @param Function fn The iterate function.
* @return Boolean
*/
_someNode: function(nodeList, fn) {
return Array.prototype.some.call(nodeList, fn, this);
},
/**
* Iterate over a NodeList, return true if all of the provided iterate
* function calls return true, false otherwise.
*
* For convenience, the current object context is applied to the
* provided iterate function.
*
* @param NodeList nodeList The NodeList.
* @param Function fn The iterate function.
* @return Boolean
*/
_everyNode: function(nodeList, fn) {
return Array.prototype.every.call(nodeList, fn, this);
},
/**
* Concat all nodelists passed as arguments.
*
* @return ...NodeList
* @return Array
*/
_concatNodeLists: function() {
var slice = Array.prototype.slice;
var args = slice.call(arguments);
var nodeLists = args.map(function(list) {
return slice.call(list);
});
return Array.prototype.concat.apply([], nodeLists);
},
_getAllNodesWithTag: function(node, tagNames) {
if (node.querySelectorAll) {
return node.querySelectorAll(tagNames.join(","));
}
return [].concat.apply([], tagNames.map(function(tag) {
var collection = node.getElementsByTagName(tag);
return Array.isArray(collection) ? collection : Array.from(collection);
}));
},
/**
* Removes the class="" attribute from every element in the given
* subtree, except those that match CLASSES_TO_PRESERVE and
* the classesToPreserve array from the options object.
*
* @param Element
* @return void
*/
_cleanClasses: function(node) {
var classesToPreserve = this._classesToPreserve;
var className = (node.getAttribute("class") || "")
.split(/\s+/)
.filter(function(cls) {
return classesToPreserve.indexOf(cls) != -1;
})
.join(" ");
if (className) {
node.setAttribute("class", className);
} else {
node.removeAttribute("class");
}
for (node = node.firstElementChild; node; node = node.nextElementSibling) {
this._cleanClasses(node);
}
},
/**
* Converts each
and
uri in the given element to an absolute URI,
* ignoring #ref URIs.
*
* @param Element
* @return void
*/
_fixRelativeUris: function(articleContent) {
var baseURI = this._doc.baseURI;
var documentURI = this._doc.documentURI;
function toAbsoluteURI(uri) {
// Leave hash links alone if the base URI matches the document URI:
if (baseURI == documentURI && uri.charAt(0) == "#") {
return uri;
}
// Otherwise, resolve against base URI:
try {
return new URL(uri, baseURI).href;
} catch (ex) {
// Something went wrong, just return the original:
}
return uri;
}
var links = this._getAllNodesWithTag(articleContent, ["a"]);
this._forEachNode(links, function(link) {
var href = link.getAttribute("href");
if (href) {
// Remove links with javascript: URIs, since
// they won't work after scripts have been removed from the page.
if (href.indexOf("javascript:") === 0) {
// if the link only contains simple text content, it can be converted to a text node
if (link.childNodes.length === 1 && link.childNodes[0].nodeType === this.TEXT_NODE) {
var text = this._doc.createTextNode(link.textContent);
link.parentNode.replaceChild(text, link);
} else {
// if the link has multiple children, they should all be preserved
var container = this._doc.createElement("span");
while (link.firstChild) {
container.appendChild(link.firstChild);
}
link.parentNode.replaceChild(container, link);
}
} else {
link.setAttribute("href", toAbsoluteURI(href));
}
}
});
var medias = this._getAllNodesWithTag(articleContent, [
"img", "picture", "figure", "video", "audio", "source"
]);
this._forEachNode(medias, function(media) {
var src = media.getAttribute("src");
var poster = media.getAttribute("poster");
var srcset = media.getAttribute("srcset");
if (src) {
media.setAttribute("src", toAbsoluteURI(src));
}
if (poster) {
media.setAttribute("poster", toAbsoluteURI(poster));
}
if (srcset) {
var newSrcset = srcset.replace(this.REGEXPS.srcsetUrl, function(_, p1, p2, p3) {
return toAbsoluteURI(p1) + (p2 || "") + p3;
});
media.setAttribute("srcset", newSrcset);
}
});
},
_simplifyNestedElements: function(articleContent) {
var node = articleContent;
while (node) {
if (node.parentNode && ["DIV", "SECTION"].includes(node.tagName) && !(node.id && node.id.startsWith("readability"))) {
if (this._isElementWithoutContent(node)) {
node = this._removeAndGetNext(node);
continue;
} else if (this._hasSingleTagInsideElement(node, "DIV") || this._hasSingleTagInsideElement(node, "SECTION")) {
var child = node.children[0];
for (var i = 0; i < node.attributes.length; i++) {
child.setAttribute(node.attributes[i].name, node.attributes[i].value);
}
node.parentNode.replaceChild(child, node);
node = child;
continue;
}
}
node = this._getNextNode(node);
}
},
/**
* Get the article title as an H1.
*
* @return string
**/
_getArticleTitle: function() {
var doc = this._doc;
var curTitle = "";
var origTitle = "";
try {
curTitle = origTitle = doc.title.trim();
// If they had an element with id "title" in their HTML
if (typeof curTitle !== "string")
curTitle = origTitle = this._getInnerText(doc.getElementsByTagName("title")[0]);
} catch (e) {/* ignore exceptions setting the title. */}
var titleHadHierarchicalSeparators = false;
function wordCount(str) {
return str.split(/\s+/).length;
}
// If there's a separator in the title, first remove the final part
if ((/ [\|\-\\\/>»] /).test(curTitle)) {
titleHadHierarchicalSeparators = / [\\\/>»] /.test(curTitle);
curTitle = origTitle.replace(/(.*)[\|\-\\\/>»] .*/gi, "$1");
// If the resulting title is too short (3 words or fewer), remove
// the first part instead:
if (wordCount(curTitle) < 3)
curTitle = origTitle.replace(/[^\|\-\\\/>»]*[\|\-\\\/>»](.*)/gi, "$1");
} else if (curTitle.indexOf(": ") !== -1) {
// Check if we have an heading containing this exact string, so we
// could assume it's the full title.
var headings = this._concatNodeLists(
doc.getElementsByTagName("h1"),
doc.getElementsByTagName("h2")
);
var trimmedTitle = curTitle.trim();
var match = this._someNode(headings, function(heading) {
return heading.textContent.trim() === trimmedTitle;
});
// If we don't, let's extract the title out of the original title string.
if (!match) {
curTitle = origTitle.substring(origTitle.lastIndexOf(":") + 1);
// If the title is now too short, try the first colon instead:
if (wordCount(curTitle) < 3) {
curTitle = origTitle.substring(origTitle.indexOf(":") + 1);
// But if we have too many words before the colon there's something weird
// with the titles and the H tags so let's just use the original title instead
} else if (wordCount(origTitle.substr(0, origTitle.indexOf(":"))) > 5) {
curTitle = origTitle;
}
}
} else if (curTitle.length > 150 || curTitle.length < 15) {
var hOnes = doc.getElementsByTagName("h1");
if (hOnes.length === 1)
curTitle = this._getInnerText(hOnes[0]);
}
curTitle = curTitle.trim().replace(this.REGEXPS.normalize, " ");
// If we now have 4 words or fewer as our title, and either no
// 'hierarchical' separators (\, /, > or ») were found in the original
// title or we decreased the number of words by more than 1 word, use
// the original title.
var curTitleWordCount = wordCount(curTitle);
if (curTitleWordCount <= 4 &&
(!titleHadHierarchicalSeparators ||
curTitleWordCount != wordCount(origTitle.replace(/[\|\-\\\/>»]+/g, "")) - 1)) {
curTitle = origTitle;
}
return curTitle;
},
/**
* Prepare the HTML document for readability to scrape it.
* This includes things like stripping javascript, CSS, and handling terrible markup.
*
* @return void
**/
_prepDocument: function() {
var doc = this._doc;
// Remove all style tags in head
this._removeNodes(this._getAllNodesWithTag(doc, ["style"]));
if (doc.body) {
this._replaceBrs(doc.body);
}
this._replaceNodeTags(this._getAllNodesWithTag(doc, ["font"]), "SPAN");
},
/**
* Finds the next node, starting from the given node, and ignoring
* whitespace in between. If the given node is an element, the same node is
* returned.
*/
_nextNode: function (node) {
var next = node;
while (next
&& (next.nodeType != this.ELEMENT_NODE)
&& this.REGEXPS.whitespace.test(next.textContent)) {
next = next.nextSibling;
}
return next;
},
/**
* Replaces 2 or more successive
elements with a single .
* Whitespace between
elements are ignored. For example:
*
foo
bar
abc
* will become:
*
*/
_replaceBrs: function (elem) {
this._forEachNode(this._getAllNodesWithTag(elem, ["br"]), function(br) {
var next = br.nextSibling;
// Whether 2 or more
elements have been found and replaced with a
// block.
var replaced = false;
// If we find a
chain, remove the
s until we hit another node
// or non-whitespace. This leaves behind the first
in the chain
// (which will be replaced with a
later).
while ((next = this._nextNode(next)) && (next.tagName == "BR")) {
replaced = true;
var brSibling = next.nextSibling;
next.parentNode.removeChild(next);
next = brSibling;
}
// If we removed a
chain, replace the remaining
with a
. Add
// all sibling nodes as children of the
until we hit another
// chain.
if (replaced) {
var p = this._doc.createElement("p");
br.parentNode.replaceChild(p, br);
next = p.nextSibling;
while (next) {
// If we've hit another
, we're done adding children to this
.
if (next.tagName == "BR") {
var nextElem = this._nextNode(next.nextSibling);
if (nextElem && nextElem.tagName == "BR")
break;
}
if (!this._isPhrasingContent(next))
break;
// Otherwise, make this node a child of the new
.
var sibling = next.nextSibling;
p.appendChild(next);
next = sibling;
}
while (p.lastChild && this._isWhitespace(p.lastChild)) {
p.removeChild(p.lastChild);
}
if (p.parentNode.tagName === "P")
this._setNodeTag(p.parentNode, "DIV");
}
});
},
_setNodeTag: function (node, tag) {
this.log("_setNodeTag", node, tag);
if (this._docJSDOMParser) {
node.localName = tag.toLowerCase();
node.tagName = tag.toUpperCase();
return node;
}
var replacement = node.ownerDocument.createElement(tag);
while (node.firstChild) {
replacement.appendChild(node.firstChild);
}
node.parentNode.replaceChild(replacement, node);
if (node.readability)
replacement.readability = node.readability;
for (var i = 0; i < node.attributes.length; i++) {
try {
replacement.setAttribute(node.attributes[i].name, node.attributes[i].value);
} catch (ex) {
/* it's possible for setAttribute() to throw if the attribute name
* isn't a valid XML Name. Such attributes can however be parsed from
* source in HTML docs, see https://github.com/whatwg/html/issues/4275,
* so we can hit them here and then throw. We don't care about such
* attributes so we ignore them.
*/
}
}
return replacement;
},
/**
* Prepare the article node for display. Clean out any inline styles,
* iframes, forms, strip extraneous
tags, etc.
*
* @param Element
* @return void
**/
_prepArticle: function(articleContent) {
this._cleanStyles(articleContent);
// Check for data tables before we continue, to avoid removing items in
// those tables, which will often be isolated even though they're
// visually linked to other content-ful elements (text, images, etc.).
this._markDataTables(articleContent);
this._fixLazyImages(articleContent);
// Clean out junk from the article content
this._cleanConditionally(articleContent, "form");
this._cleanConditionally(articleContent, "fieldset");
this._clean(articleContent, "object");
this._clean(articleContent, "embed");
this._clean(articleContent, "footer");
this._clean(articleContent, "link");
this._clean(articleContent, "aside");
// Clean out elements with little content that have "share" in their id/class combinations from final top candidates,
// which means we don't remove the top candidates even they have "share".
var shareElementThreshold = this.DEFAULT_CHAR_THRESHOLD;
this._forEachNode(articleContent.children, function (topCandidate) {
this._cleanMatchedNodes(topCandidate, function (node, matchString) {
return this.REGEXPS.shareElements.test(matchString) && node.textContent.length < shareElementThreshold;
});
});
this._clean(articleContent, "iframe");
this._clean(articleContent, "input");
this._clean(articleContent, "textarea");
this._clean(articleContent, "select");
this._clean(articleContent, "button");
this._cleanHeaders(articleContent);
// Do these last as the previous stuff may have removed junk
// that will affect these
this._cleanConditionally(articleContent, "table");
this._cleanConditionally(articleContent, "ul");
this._cleanConditionally(articleContent, "div");
// replace H1 with H2 as H1 should be only title that is displayed separately
this._replaceNodeTags(this._getAllNodesWithTag(articleContent, ["h1"]), "h2");
// Remove extra paragraphs
this._removeNodes(this._getAllNodesWithTag(articleContent, ["p"]), function (paragraph) {
var imgCount = paragraph.getElementsByTagName("img").length;
var embedCount = paragraph.getElementsByTagName("embed").length;
var objectCount = paragraph.getElementsByTagName("object").length;
// At this point, nasty iframes have been removed, only remain embedded video ones.
var iframeCount = paragraph.getElementsByTagName("iframe").length;
var totalCount = imgCount + embedCount + objectCount + iframeCount;
return totalCount === 0 && !this._getInnerText(paragraph, false);
});
this._forEachNode(this._getAllNodesWithTag(articleContent, ["br"]), function(br) {
var next = this._nextNode(br.nextSibling);
if (next && next.tagName == "P")
br.parentNode.removeChild(br);
});
// Remove single-cell tables
this._forEachNode(this._getAllNodesWithTag(articleContent, ["table"]), function(table) {
var tbody = this._hasSingleTagInsideElement(table, "TBODY") ? table.firstElementChild : table;
if (this._hasSingleTagInsideElement(tbody, "TR")) {
var row = tbody.firstElementChild;
if (this._hasSingleTagInsideElement(row, "TD")) {
var cell = row.firstElementChild;
cell = this._setNodeTag(cell, this._everyNode(cell.childNodes, this._isPhrasingContent) ? "P" : "DIV");
table.parentNode.replaceChild(cell, table);
}
}
});
},
/**
* Initialize a node with the readability object. Also checks the
* className/id for special names to add to its score.
*
* @param Element
* @return void
**/
_initializeNode: function(node) {
node.readability = {"contentScore": 0};
switch (node.tagName) {
case "DIV":
node.readability.contentScore += 5;
break;
case "PRE":
case "TD":
case "BLOCKQUOTE":
node.readability.contentScore += 3;
break;
case "ADDRESS":
case "OL":
case "UL":
case "DL":
case "DD":
case "DT":
case "LI":
case "FORM":
node.readability.contentScore -= 3;
break;
case "H1":
case "H2":
case "H3":
case "H4":
case "H5":
case "H6":
case "TH":
node.readability.contentScore -= 5;
break;
}
node.readability.contentScore += this._getClassWeight(node);
},
_removeAndGetNext: function(node) {
var nextNode = this._getNextNode(node, true);
node.parentNode.removeChild(node);
return nextNode;
},
/**
* Traverse the DOM from node to node, starting at the node passed in.
* Pass true for the second parameter to indicate this node itself
* (and its kids) are going away, and we want the next node over.
*
* Calling this in a loop will traverse the DOM depth-first.
*/
_getNextNode: function(node, ignoreSelfAndKids) {
// First check for kids if those aren't being ignored
if (!ignoreSelfAndKids && node.firstElementChild) {
return node.firstElementChild;
}
// Then for siblings...
if (node.nextElementSibling) {
return node.nextElementSibling;
}
// And finally, move up the parent chain *and* find a sibling
// (because this is depth-first traversal, we will have already
// seen the parent nodes themselves).
do {
node = node.parentNode;
} while (node && !node.nextElementSibling);
return node && node.nextElementSibling;
},
// compares second text to first one
// 1 = same text, 0 = completely different text
// works the way that it splits both texts into words and then finds words that are unique in second text
// the result is given by the lower length of unique parts
_textSimilarity: function(textA, textB) {
var tokensA = textA.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean);
var tokensB = textB.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean);
if (!tokensA.length || !tokensB.length) {
return 0;
}
var uniqTokensB = tokensB.filter(token => !tokensA.includes(token));
var distanceB = uniqTokensB.join(" ").length / tokensB.join(" ").length;
return 1 - distanceB;
},
_checkByline: function(node, matchString) {
if (this._articleByline) {
return false;
}
if (node.getAttribute !== undefined) {
var rel = node.getAttribute("rel");
var itemprop = node.getAttribute("itemprop");
}
if ((rel === "author" || (itemprop && itemprop.indexOf("author") !== -1) || this.REGEXPS.byline.test(matchString)) && this._isValidByline(node.textContent)) {
this._articleByline = node.textContent.trim();
return true;
}
return false;
},
_getNodeAncestors: function(node, maxDepth) {
maxDepth = maxDepth || 0;
var i = 0, ancestors = [];
while (node.parentNode) {
ancestors.push(node.parentNode);
if (maxDepth && ++i === maxDepth)
break;
node = node.parentNode;
}
return ancestors;
},
/***
* grabArticle - Using a variety of metrics (content score, classname, element types), find the content that is
* most likely to be the stuff a user wants to read. Then return it wrapped up in a div.
*
* @param page a document to run upon. Needs to be a full document, complete with body.
* @return Element
**/
_grabArticle: function (page) {
this.log("**** grabArticle ****");
var doc = this._doc;
var isPaging = page !== null;
page = page ? page : this._doc.body;
// We can't grab an article if we don't have a page!
if (!page) {
this.log("No body found in document. Abort.");
return null;
}
var pageCacheHtml = page.innerHTML;
while (true) {
this.log("Starting grabArticle loop");
var stripUnlikelyCandidates = this._flagIsActive(this.FLAG_STRIP_UNLIKELYS);
// First, node prepping. Trash nodes that look cruddy (like ones with the
// class name "comment", etc), and turn divs into P tags where they have been
// used inappropriately (as in, where they contain no other block level elements.)
var elementsToScore = [];
var node = this._doc.documentElement;
let shouldRemoveTitleHeader = true;
while (node) {
if (node.tagName === "HTML") {
this._articleLang = node.getAttribute("lang");
}
var matchString = node.className + " " + node.id;
if (!this._isProbablyVisible(node)) {
this.log("Removing hidden node - " + matchString);
node = this._removeAndGetNext(node);
continue;
}
// User is not able to see elements applied with both "aria-modal = true" and "role = dialog"
if (node.getAttribute("aria-modal") == "true" && node.getAttribute("role") == "dialog") {
node = this._removeAndGetNext(node);
continue;
}
// Check to see if this node is a byline, and remove it if it is.
if (this._checkByline(node, matchString)) {
node = this._removeAndGetNext(node);
continue;
}
if (shouldRemoveTitleHeader && this._headerDuplicatesTitle(node)) {
this.log("Removing header: ", node.textContent.trim(), this._articleTitle.trim());
shouldRemoveTitleHeader = false;
node = this._removeAndGetNext(node);
continue;
}
// Remove unlikely candidates
if (stripUnlikelyCandidates) {
if (this.REGEXPS.unlikelyCandidates.test(matchString) &&
!this.REGEXPS.okMaybeItsACandidate.test(matchString) &&
!this._hasAncestorTag(node, "table") &&
!this._hasAncestorTag(node, "code") &&
node.tagName !== "BODY" &&
node.tagName !== "A") {
this.log("Removing unlikely candidate - " + matchString);
node = this._removeAndGetNext(node);
continue;
}
if (this.UNLIKELY_ROLES.includes(node.getAttribute("role"))) {
this.log("Removing content with role " + node.getAttribute("role") + " - " + matchString);
node = this._removeAndGetNext(node);
continue;
}
}
// Remove DIV, SECTION, and HEADER nodes without any content(e.g. text, image, video, or iframe).
if ((node.tagName === "DIV" || node.tagName === "SECTION" || node.tagName === "HEADER" ||
node.tagName === "H1" || node.tagName === "H2" || node.tagName === "H3" ||
node.tagName === "H4" || node.tagName === "H5" || node.tagName === "H6") &&
this._isElementWithoutContent(node)) {
node = this._removeAndGetNext(node);
continue;
}
if (this.DEFAULT_TAGS_TO_SCORE.indexOf(node.tagName) !== -1) {
elementsToScore.push(node);
}
// Turn all divs that don't have children block level elements into p's
if (node.tagName === "DIV") {
// Put phrasing content into paragraphs.
var p = null;
var childNode = node.firstChild;
while (childNode) {
var nextSibling = childNode.nextSibling;
if (this._isPhrasingContent(childNode)) {
if (p !== null) {
p.appendChild(childNode);
} else if (!this._isWhitespace(childNode)) {
p = doc.createElement("p");
node.replaceChild(p, childNode);
p.appendChild(childNode);
}
} else if (p !== null) {
while (p.lastChild && this._isWhitespace(p.lastChild)) {
p.removeChild(p.lastChild);
}
p = null;
}
childNode = nextSibling;
}
// Sites like http://mobile.slate.com encloses each paragraph with a DIV
// element. DIVs with only a P element inside and no text content can be
// safely converted into plain P elements to avoid confusing the scoring
// algorithm with DIVs with are, in practice, paragraphs.
if (this._hasSingleTagInsideElement(node, "P") && this._getLinkDensity(node) < 0.25) {
var newNode = node.children[0];
node.parentNode.replaceChild(newNode, node);
node = newNode;
elementsToScore.push(node);
} else if (!this._hasChildBlockElement(node)) {
node = this._setNodeTag(node, "P");
elementsToScore.push(node);
}
}
node = this._getNextNode(node);
}
/**
* Loop through all paragraphs, and assign a score to them based on how content-y they look.
* Then add their score to their parent node.
*
* A score is determined by things like number of commas, class names, etc. Maybe eventually link density.
**/
var candidates = [];
this._forEachNode(elementsToScore, function(elementToScore) {
if (!elementToScore.parentNode || typeof(elementToScore.parentNode.tagName) === "undefined")
return;
// If this paragraph is less than 25 characters, don't even count it.
var innerText = this._getInnerText(elementToScore);
if (innerText.length < 25)
return;
// Exclude nodes with no ancestor.
var ancestors = this._getNodeAncestors(elementToScore, 5);
if (ancestors.length === 0)
return;
var contentScore = 0;
// Add a point for the paragraph itself as a base.
contentScore += 1;
// Add points for any commas within this paragraph.
contentScore += innerText.split(",").length;
// For every 100 characters in this paragraph, add another point. Up to 3 points.
contentScore += Math.min(Math.floor(innerText.length / 100), 3);
// Initialize and score ancestors.
this._forEachNode(ancestors, function(ancestor, level) {
if (!ancestor.tagName || !ancestor.parentNode || typeof(ancestor.parentNode.tagName) === "undefined")
return;
if (typeof(ancestor.readability) === "undefined") {
this._initializeNode(ancestor);
candidates.push(ancestor);
}
// Node score divider:
// - parent: 1 (no division)
// - grandparent: 2
// - great grandparent+: ancestor level * 3
if (level === 0)
var scoreDivider = 1;
else if (level === 1)
scoreDivider = 2;
else
scoreDivider = level * 3;
ancestor.readability.contentScore += contentScore / scoreDivider;
});
});
// After we've calculated scores, loop through all of the possible
// candidate nodes we found and find the one with the highest score.
var topCandidates = [];
for (var c = 0, cl = candidates.length; c < cl; c += 1) {
var candidate = candidates[c];
// Scale the final candidates score based on link density. Good content
// should have a relatively small link density (5% or less) and be mostly
// unaffected by this operation.
var candidateScore = candidate.readability.contentScore * (1 - this._getLinkDensity(candidate));
candidate.readability.contentScore = candidateScore;
this.log("Candidate:", candidate, "with score " + candidateScore);
for (var t = 0; t < this._nbTopCandidates; t++) {
var aTopCandidate = topCandidates[t];
if (!aTopCandidate || candidateScore > aTopCandidate.readability.contentScore) {
topCandidates.splice(t, 0, candidate);
if (topCandidates.length > this._nbTopCandidates)
topCandidates.pop();
break;
}
}
}
var topCandidate = topCandidates[0] || null;
var neededToCreateTopCandidate = false;
var parentOfTopCandidate;
// If we still have no top candidate, just use the body as a last resort.
// We also have to copy the body node so it is something we can modify.
if (topCandidate === null || topCandidate.tagName === "BODY") {
// Move all of the page's children into topCandidate
topCandidate = doc.createElement("DIV");
neededToCreateTopCandidate = true;
// Move everything (not just elements, also text nodes etc.) into the container
// so we even include text directly in the body:
while (page.firstChild) {
this.log("Moving child out:", page.firstChild);
topCandidate.appendChild(page.firstChild);
}
page.appendChild(topCandidate);
this._initializeNode(topCandidate);
} else if (topCandidate) {
// Find a better top candidate node if it contains (at least three) nodes which belong to `topCandidates` array
// and whose scores are quite closed with current `topCandidate` node.
var alternativeCandidateAncestors = [];
for (var i = 1; i < topCandidates.length; i++) {
if (topCandidates[i].readability.contentScore / topCandidate.readability.contentScore >= 0.75) {
alternativeCandidateAncestors.push(this._getNodeAncestors(topCandidates[i]));
}
}
var MINIMUM_TOPCANDIDATES = 3;
if (alternativeCandidateAncestors.length >= MINIMUM_TOPCANDIDATES) {
parentOfTopCandidate = topCandidate.parentNode;
while (parentOfTopCandidate.tagName !== "BODY") {
var listsContainingThisAncestor = 0;
for (var ancestorIndex = 0; ancestorIndex < alternativeCandidateAncestors.length && listsContainingThisAncestor < MINIMUM_TOPCANDIDATES; ancestorIndex++) {
listsContainingThisAncestor += Number(alternativeCandidateAncestors[ancestorIndex].includes(parentOfTopCandidate));
}
if (listsContainingThisAncestor >= MINIMUM_TOPCANDIDATES) {
topCandidate = parentOfTopCandidate;
break;
}
parentOfTopCandidate = parentOfTopCandidate.parentNode;
}
}
if (!topCandidate.readability) {
this._initializeNode(topCandidate);
}
// Because of our bonus system, parents of candidates might have scores
// themselves. They get half of the node. There won't be nodes with higher
// scores than our topCandidate, but if we see the score going *up* in the first
// few steps up the tree, that's a decent sign that there might be more content
// lurking in other places that we want to unify in. The sibling stuff
// below does some of that - but only if we've looked high enough up the DOM
// tree.
parentOfTopCandidate = topCandidate.parentNode;
var lastScore = topCandidate.readability.contentScore;
// The scores shouldn't get too low.
var scoreThreshold = lastScore / 3;
while (parentOfTopCandidate.tagName !== "BODY") {
if (!parentOfTopCandidate.readability) {
parentOfTopCandidate = parentOfTopCandidate.parentNode;
continue;
}
var parentScore = parentOfTopCandidate.readability.contentScore;
if (parentScore < scoreThreshold)
break;
if (parentScore > lastScore) {
// Alright! We found a better parent to use.
topCandidate = parentOfTopCandidate;
break;
}
lastScore = parentOfTopCandidate.readability.contentScore;
parentOfTopCandidate = parentOfTopCandidate.parentNode;
}
// If the top candidate is the only child, use parent instead. This will help sibling
// joining logic when adjacent content is actually located in parent's sibling node.
parentOfTopCandidate = topCandidate.parentNode;
while (parentOfTopCandidate.tagName != "BODY" && parentOfTopCandidate.children.length == 1) {
topCandidate = parentOfTopCandidate;
parentOfTopCandidate = topCandidate.parentNode;
}
if (!topCandidate.readability) {
this._initializeNode(topCandidate);
}
}
// Now that we have the top candidate, look through its siblings for content
// that might also be related. Things like preambles, content split by ads
// that we removed, etc.
var articleContent = doc.createElement("DIV");
if (isPaging)
articleContent.id = "readability-content";
var siblingScoreThreshold = Math.max(10, topCandidate.readability.contentScore * 0.2);
// Keep potential top candidate's parent node to try to get text direction of it later.
parentOfTopCandidate = topCandidate.parentNode;
var siblings = parentOfTopCandidate.children;
for (var s = 0, sl = siblings.length; s < sl; s++) {
var sibling = siblings[s];
var append = false;
this.log("Looking at sibling node:", sibling, sibling.readability ? ("with score " + sibling.readability.contentScore) : "");
this.log("Sibling has score", sibling.readability ? sibling.readability.contentScore : "Unknown");
if (sibling === topCandidate) {
append = true;
} else {
var contentBonus = 0;
// Give a bonus if sibling nodes and top candidates have the example same classname
if (sibling.className === topCandidate.className && topCandidate.className !== "")
contentBonus += topCandidate.readability.contentScore * 0.2;
if (sibling.readability &&
((sibling.readability.contentScore + contentBonus) >= siblingScoreThreshold)) {
append = true;
} else if (sibling.nodeName === "P") {
var linkDensity = this._getLinkDensity(sibling);
var nodeContent = this._getInnerText(sibling);
var nodeLength = nodeContent.length;
if (nodeLength > 80 && linkDensity < 0.25) {
append = true;
} else if (nodeLength < 80 && nodeLength > 0 && linkDensity === 0 &&
nodeContent.search(/\.( |$)/) !== -1) {
append = true;
}
}
}
if (append) {
this.log("Appending node:", sibling);
if (this.ALTER_TO_DIV_EXCEPTIONS.indexOf(sibling.nodeName) === -1) {
// We have a node that isn't a common block level element, like a form or td tag.
// Turn it into a div so it doesn't get filtered out later by accident.
this.log("Altering sibling:", sibling, "to div.");
sibling = this._setNodeTag(sibling, "DIV");
}
articleContent.appendChild(sibling);
// Fetch children again to make it compatible
// with DOM parsers without live collection support.
siblings = parentOfTopCandidate.children;
// siblings is a reference to the children array, and
// sibling is removed from the array when we call appendChild().
// As a result, we must revisit this index since the nodes
// have been shifted.
s -= 1;
sl -= 1;
}
}
if (this._debug)
this.log("Article content pre-prep: " + articleContent.innerHTML);
// So we have all of the content that we need. Now we clean it up for presentation.
this._prepArticle(articleContent);
if (this._debug)
this.log("Article content post-prep: " + articleContent.innerHTML);
if (neededToCreateTopCandidate) {
// We already created a fake div thing, and there wouldn't have been any siblings left
// for the previous loop, so there's no point trying to create a new div, and then
// move all the children over. Just assign IDs and class names here. No need to append
// because that already happened anyway.
topCandidate.id = "readability-page-1";
topCandidate.className = "page";
} else {
var div = doc.createElement("DIV");
div.id = "readability-page-1";
div.className = "page";
while (articleContent.firstChild) {
div.appendChild(articleContent.firstChild);
}
articleContent.appendChild(div);
}
if (this._debug)
this.log("Article content after paging: " + articleContent.innerHTML);
var parseSuccessful = true;
// Now that we've gone through the full algorithm, check to see if
// we got any meaningful content. If we didn't, we may need to re-run
// grabArticle with different flags set. This gives us a higher likelihood of
// finding the content, and the sieve approach gives us a higher likelihood of
// finding the -right- content.
var textLength = this._getInnerText(articleContent, true).length;
if (textLength < this._charThreshold) {
parseSuccessful = false;
page.innerHTML = pageCacheHtml;
if (this._flagIsActive(this.FLAG_STRIP_UNLIKELYS)) {
this._removeFlag(this.FLAG_STRIP_UNLIKELYS);
this._attempts.push({articleContent: articleContent, textLength: textLength});
} else if (this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) {
this._removeFlag(this.FLAG_WEIGHT_CLASSES);
this._attempts.push({articleContent: articleContent, textLength: textLength});
} else if (this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) {
this._removeFlag(this.FLAG_CLEAN_CONDITIONALLY);
this._attempts.push({articleContent: articleContent, textLength: textLength});
} else {
this._attempts.push({articleContent: articleContent, textLength: textLength});
// No luck after removing flags, just return the longest text we found during the different loops
this._attempts.sort(function (a, b) {
return b.textLength - a.textLength;
});
// But first check if we actually have something
if (!this._attempts[0].textLength) {
return null;
}
articleContent = this._attempts[0].articleContent;
parseSuccessful = true;
}
}
if (parseSuccessful) {
// Find out text direction from ancestors of final top candidate.
var ancestors = [parentOfTopCandidate, topCandidate].concat(this._getNodeAncestors(parentOfTopCandidate));
this._someNode(ancestors, function(ancestor) {
if (!ancestor.tagName)
return false;
var articleDir = ancestor.getAttribute("dir");
if (articleDir) {
this._articleDir = articleDir;
return true;
}
return false;
});
return articleContent;
}
}
},
/**
* Check whether the input string could be a byline.
* This verifies that the input is a string, and that the length
* is less than 100 chars.
*
* @param possibleByline {string} - a string to check whether its a byline.
* @return Boolean - whether the input string is a byline.
*/
_isValidByline: function(byline) {
if (typeof byline == "string" || byline instanceof String) {
byline = byline.trim();
return (byline.length > 0) && (byline.length < 100);
}
return false;
},
/**
* Converts some of the common HTML entities in string to their corresponding characters.
*
* @param str {string} - a string to unescape.
* @return string without HTML entity.
*/
_unescapeHtmlEntities: function(str) {
if (!str) {
return str;
}
var htmlEscapeMap = this.HTML_ESCAPE_MAP;
return str.replace(/&(quot|amp|apos|lt|gt);/g, function(_, tag) {
return htmlEscapeMap[tag];
}).replace(/(?:x([0-9a-z]{1,4})|([0-9]{1,4}));/gi, function(_, hex, numStr) {
var num = parseInt(hex || numStr, hex ? 16 : 10);
return String.fromCharCode(num);
});
},
/**
* Try to extract metadata from JSON-LD object.
* For now, only Schema.org objects of type Article or its subtypes are supported.
* @return Object with any metadata that could be extracted (possibly none)
*/
_getJSONLD: function (doc) {
var scripts = this._getAllNodesWithTag(doc, ["script"]);
var metadata;
this._forEachNode(scripts, function(jsonLdElement) {
if (!metadata && jsonLdElement.getAttribute("type") === "application/ld+json") {
try {
// Strip CDATA markers if present
var content = jsonLdElement.textContent.replace(/^\s*\s*$/g, "");
var parsed = JSON.parse(content);
if (
!parsed["@context"] ||
!parsed["@context"].match(/^https?\:\/\/schema\.org$/)
) {
return;
}
if (!parsed["@type"] && Array.isArray(parsed["@graph"])) {
parsed = parsed["@graph"].find(function(it) {
return (it["@type"] || "").match(
this.REGEXPS.jsonLdArticleTypes
);
});
}
if (
!parsed ||
!parsed["@type"] ||
!parsed["@type"].match(this.REGEXPS.jsonLdArticleTypes)
) {
return;
}
metadata = {};
if (typeof parsed.name === "string" && typeof parsed.headline === "string" && parsed.name !== parsed.headline) {
// we have both name and headline element in the JSON-LD. They should both be the same but some websites like aktualne.cz
// put their own name into "name" and the article title to "headline" which confuses Readability. So we try to check if either
// "name" or "headline" closely matches the html title, and if so, use that one. If not, then we use "name" by default.
var title = this._getArticleTitle();
var nameMatches = this._textSimilarity(parsed.name, title) > 0.75;
var headlineMatches = this._textSimilarity(parsed.headline, title) > 0.75;
if (headlineMatches && !nameMatches) {
metadata.title = parsed.headline;
} else {
metadata.title = parsed.name;
}
} else if (typeof parsed.name === "string") {
metadata.title = parsed.name.trim();
} else if (typeof parsed.headline === "string") {
metadata.title = parsed.headline.trim();
}
if (parsed.author) {
if (typeof parsed.author.name === "string") {
metadata.byline = parsed.author.name.trim();
} else if (Array.isArray(parsed.author) && parsed.author[0] && typeof parsed.author[0].name === "string") {
metadata.byline = parsed.author
.filter(function(author) {
return author && typeof author.name === "string";
})
.map(function(author) {
return author.name.trim();
})
.join(", ");
}
}
if (typeof parsed.description === "string") {
metadata.excerpt = parsed.description.trim();
}
if (
parsed.publisher &&
typeof parsed.publisher.name === "string"
) {
metadata.siteName = parsed.publisher.name.trim();
}
return;
} catch (err) {
this.log(err.message);
}
}
});
return metadata ? metadata : {};
},
/**
* Attempts to get excerpt and byline metadata for the article.
*
* @param {Object} jsonld — object containing any metadata that
* could be extracted from JSON-LD object.
*
* @return Object with optional "excerpt" and "byline" properties
*/
_getArticleMetadata: function(jsonld) {
var metadata = {};
var values = {};
var metaElements = this._doc.getElementsByTagName("meta");
// property is a space-separated list of values
var propertyPattern = /\s*(dc|dcterm|og|twitter)\s*:\s*(author|creator|description|title|site_name)\s*/gi;
// name is a single value
var namePattern = /^\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\s*[\.:]\s*)?(author|creator|description|title|site_name)\s*$/i;
// Find description tags.
this._forEachNode(metaElements, function(element) {
var elementName = element.getAttribute("name");
var elementProperty = element.getAttribute("property");
var content = element.getAttribute("content");
if (!content) {
return;
}
var matches = null;
var name = null;
if (elementProperty) {
matches = elementProperty.match(propertyPattern);
if (matches) {
// Convert to lowercase, and remove any whitespace
// so we can match below.
name = matches[0].toLowerCase().replace(/\s/g, "");
// multiple authors
values[name] = content.trim();
}
}
if (!matches && elementName && namePattern.test(elementName)) {
name = elementName;
if (content) {
// Convert to lowercase, remove any whitespace, and convert dots
// to colons so we can match below.
name = name.toLowerCase().replace(/\s/g, "").replace(/\./g, ":");
values[name] = content.trim();
}
}
});
// get title
metadata.title = jsonld.title ||
values["dc:title"] ||
values["dcterm:title"] ||
values["og:title"] ||
values["weibo:article:title"] ||
values["weibo:webpage:title"] ||
values["title"] ||
values["twitter:title"];
if (!metadata.title) {
metadata.title = this._getArticleTitle();
}
// get author
metadata.byline = jsonld.byline ||
values["dc:creator"] ||
values["dcterm:creator"] ||
values["author"];
// get description
metadata.excerpt = jsonld.excerpt ||
values["dc:description"] ||
values["dcterm:description"] ||
values["og:description"] ||
values["weibo:article:description"] ||
values["weibo:webpage:description"] ||
values["description"] ||
values["twitter:description"];
// get site name
metadata.siteName = jsonld.siteName ||
values["og:site_name"];
// in many sites the meta value is escaped with HTML entities,
// so here we need to unescape it
metadata.title = this._unescapeHtmlEntities(metadata.title);
metadata.byline = this._unescapeHtmlEntities(metadata.byline);
metadata.excerpt = this._unescapeHtmlEntities(metadata.excerpt);
metadata.siteName = this._unescapeHtmlEntities(metadata.siteName);
return metadata;
},
/**
* Check if node is image, or if node contains exactly only one image
* whether as a direct child or as its descendants.
*
* @param Element
**/
_isSingleImage: function(node) {
if (node.tagName === "IMG") {
return true;
}
if (node.children.length !== 1 || node.textContent.trim() !== "") {
return false;
}
return this._isSingleImage(node.children[0]);
},
/**
* Find all
\n \n \n\n";
// Exports
/* harmony default export */ const chapter_html = (code);
;// CONCATENATED MODULE: ./src/save/index.html.j2
// Module
var index_html_code = "\n\n \n \n \n \n \n \n \n \n {{ bookname }}\n \n \n \n
{{ bookname }}
\n
{{ author }}
\n
\n {% if cover -%}\n
![]()
\n {%- endif %} \n {% if introductionHTML -%}\n
\n
简介
\n
{{ introductionHTML }}
\n
\n {%- endif %}\n
\n
\n
\n {% for sectionObj in sectionsObj -%}\n
\n {% if sectionObj.sectionName %}\n
{{ sectionObj.sectionName }}
\n {% endif %}\n {% for chapter in sectionObj.chpaters -%}\n
\n {%- endfor %}\n
\n {%- endfor %} \n
\n \n";
// Exports
/* harmony default export */ const index_html = (index_html_code);
;// CONCATENATED MODULE: ./src/save/section.html.j2
// Module
var section_html_code = "\n\n \n \n \n \n \n {{ sectionName }}\n \n \n {{ sectionName }}
\n \n\n";
// Exports
/* harmony default export */ const section_html = (section_html_code);
;// CONCATENATED MODULE: external "nunjucks"
const external_nunjucks_namespaceObject = nunjucks;
;// CONCATENATED MODULE: ./src/save/epub.ts
const env = new external_nunjucks_namespaceObject.Environment(undefined, { autoescape: false });
const section = new external_nunjucks_namespaceObject.Template(section_html, env, undefined, true);
const chapterTemplt = new external_nunjucks_namespaceObject.Template(chapter_html, env, undefined, true);
const index = new external_nunjucks_namespaceObject.Template(index_html, env, undefined, true);
function getDateString() {
const date = new Date();
const year = date.getFullYear();
const _monty = new Date().getMonth() + 1;
const monty = _monty < 10 ? `0${_monty}` : _monty;
const _day = date.getDate();
const day = _day < 10 ? `0${_day}` : _day;
return `${year}-${monty}-${day}`;
}
const uuid = (0,misc/* randomUUID */.HP)();
const content_opf = `
urn:uuid:${uuid}
${getDateString()}
${new Date()
.toISOString()
.replace(/\.\d\d\dZ$/, "Z")}
`;
const toc_ncx = `
`;
const TOC_xhtml = `
Table of Contents
目录
`;
const nav_xhtml = `
ePub Nav
`;
const getCoverXhtml = (coverName) => `
Cover
`;
const getInfoXhtml = (title, author) => `
信息页
${title}
${author ? `作者:${author}
` : ""}
`;
const getMessageXhtml = (book) => `
信息页
制作信息
题名:${book.bookname}
作者:${book.author}
${book.introductionHTML
? `
简介:${book.introductionHTML.outerHTML}`
: ""}
${book.additionalMetadate.tags
? `
Tag列表:${book.additionalMetadate.tags.join("、")}
`
: ""}
`;
class EPUB extends Options {
contentOpf = new DOMParser().parseFromString(content_opf, "application/xml");
metadata = this.contentOpf.querySelector("metadata");
manifest = this.contentOpf.querySelector("manifest");
spine = this.contentOpf.querySelector("spine");
guide = this.contentOpf.querySelector("guide");
ncx = new DOMParser().parseFromString(toc_ncx, "application/xml");
navMap = this.ncx.querySelector("navMap");
navHtml = new DOMParser().parseFromString(nav_xhtml, "application/xhtml+xml");
navHtmlToc = this.navHtml.getElementById("toc");
toc = new DOMParser().parseFromString(TOC_xhtml, "application/xhtml+xml");
tocBody = this.toc.body;
book;
chapters;
epubZip;
constructor(book, streamZip, options) {
super();
const self = this;
this.book = book;
this.chapters = this.book.chapters;
const zipFilename = `[${this.book.author}]${this.book.bookname}.epub`;
this.epubZip = new FflateZip(zipFilename, streamZip, "application/epub+zip");
loglevel_default().debug("[save-epub]保存epub基本文件");
saveEpubMimetype();
if (options) {
Object.assign(this, options);
}
async function saveEpubMimetype() {
await self.epubZip.file("mimetype", new Blob(["application/epub+zip"]), true);
await self.epubZip.file("META-INF/container.xml", new Blob([
`
`,
]));
}
}
static genChapterHtmlFile(chapterObj) {
const _htmlText = chapterTemplt.render({
chapterUrl: chapterObj.chapterUrl,
chapterName: chapterObj.chapterName,
outerHTML: chapterObj.contentHTML?.outerHTML ?? "",
});
const htmlText = (0,dom/* convertHTMLtoXHTML */.fI)(_htmlText);
return new Blob([
``,
htmlText
.replaceAll("data-src-address", "src")
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, "")
.replace('', ''),
], {
type: "application/xhtml+xml",
});
}
async saveEpub() {
const self = this;
loglevel_default().debug("[save-epub]保存样式文件");
await saveStyle();
loglevel_default().debug("[save-epub]更新Metadata");
await updateMetadata();
if (this.book.additionalMetadate.attachments) {
loglevel_default().debug("[save]保存书籍附件");
for (const bookAttachment of this.book.additionalMetadate.attachments) {
await this.addAttachment(bookAttachment);
}
}
loglevel_default().debug("[save-epub]保存仅标题章节文件");
await saveStubChapters(this.chapters);
loglevel_default().debug("[save-epub]保存目录文件");
await saveToC();
await saveZipFiles();
await this.epubZip.generateAsync();
async function saveStyle() {
await self.epubZip.file("OEBPS/style.css", new Blob([self.mainStyleText]));
await self.epubZip.file("OEBPS/sgc-toc.css", new Blob([sgc_toc/* default */.Z]));
}
async function updateMetadata() {
const title = self.contentOpf.createElement("dc:title");
title.textContent = self.book.bookname;
self.metadata.appendChild(title);
self.ncx.querySelector("docTitle > text").innerHTML =
(0,dom/* escapeHTML */.r)(self.book.bookname);
const author = self.contentOpf.createElement("dc:creator");
author.setAttribute("id", "cre");
author.textContent = self.book.author;
self.metadata.appendChild(author);
const authorMeta = self.contentOpf.createElement("meta");
authorMeta.setAttribute("refines", "#cre");
authorMeta.setAttribute("property", "role");
authorMeta.setAttribute("scheme", "marc:relators");
authorMeta.textContent = "aut";
self.metadata.appendChild(authorMeta);
const source = self.contentOpf.createElement("dc:source");
source.textContent = self.book.bookUrl;
self.metadata.appendChild(source);
const language = self.contentOpf.createElement("dc:language");
language.textContent = self.book.additionalMetadate.language ?? "zh";
self.metadata.appendChild(language);
if (self.book.introduction) {
const introduction = self.contentOpf.createElement("dc:description");
introduction.textContent = self.book.introduction;
self.metadata.appendChild(introduction);
}
if (self.book.additionalMetadate.cover) {
await self.addAttachment(self.book.additionalMetadate.cover);
const cover = self.contentOpf.createElement("meta");
cover.setAttribute("name", "cover");
cover.setAttribute("content", self.book.additionalMetadate.cover.name);
self.metadata.appendChild(cover);
await self.epubZip.file("OEBPS/cover.xhtml", new Blob([getCoverXhtml(self.book.additionalMetadate.cover.name)], {
type: "application/xhtml+xml",
}));
}
else {
self.manifest.querySelector('item[id="cover.xhtml"]')?.remove();
self.spine.querySelector('itemref[idref="cover.xhtml"]')?.remove();
self.guide.querySelector('reference[type="cover"]')?.remove();
}
if (self.book.additionalMetadate.tags) {
for (const _tag of self.book.additionalMetadate.tags) {
const tag = self.contentOpf.createElement("dc:subject");
tag.textContent = _tag;
self.metadata.appendChild(tag);
}
}
await self.epubZip.file("OEBPS/info.xhtml", new Blob([
getInfoXhtml(self.book.bookname, self.book.author)
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], {
type: "application/xhtml+xml",
}));
await self.epubZip.file("OEBPS/message.xhtml", new Blob([
(0,dom/* convertHTMLtoXHTML */.fI)(getMessageXhtml(self.book))
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], {
type: "application/xhtml+xml",
}));
}
async function saveStubChapters(chapters) {
chapters = chapters.filter((c) => c.status !== main/* Status */.qb.saved);
for (const c of chapters) {
if (c.status === main/* Status */.qb.finished) {
await self.addChapter(c);
}
else {
await self.addChapter(c, "Stub");
}
}
}
async function saveToC() {
loglevel_default().debug("[save-epub]对 chapters 排序");
self.chapters.sort(self.chapterSort);
const sectionsListObj = (0,save_misc/* getSectionsObj */.f)(self.chapters, self.chapterSort);
let i = 0;
let sectionNumberG = null;
let sectionNavPoint;
let sectionTOCDiv;
const navHtmlTocOl = self.navHtml.createElement("ol");
self.navHtmlToc.appendChild(navHtmlTocOl);
let sectionNavOl;
for (const sectionObj of sectionsListObj) {
const { sectionName, sectionNumber, chpaters } = sectionObj;
if (sectionNumber !== sectionNumberG) {
const sectionNumberToSave = self.getChapterNumberToSave(chpaters[0], self.chapters);
const sectionHtmlFileName = `No${sectionNumberToSave}Section.xhtml`;
if (sectionName) {
sectionNumberG = sectionNumber;
loglevel_default().debug(`[save-epub]保存卷HTML文件:${sectionName}`);
const sectionHTMLBlob = genSectionHtmlFile(sectionName);
await self.epubZip.file(`OEBPS/${sectionHtmlFileName}`, sectionHTMLBlob);
appendManifest(sectionHtmlFileName);
appendSpine(sectionHtmlFileName);
i++;
const navPoint = genNavPoint(i, sectionName, sectionHtmlFileName);
if (sectionNavPoint) {
self.navMap.appendChild(sectionNavPoint);
}
sectionNavPoint = navPoint;
const li = genNavHtmlLi(sectionName, sectionHtmlFileName);
sectionNavOl = self.navHtml.createElement("ol");
li.appendChild(sectionNavOl);
navHtmlTocOl.appendChild(li);
const div = genTocDiv("sgc-toc-level-1", sectionName, sectionHtmlFileName);
if (sectionTOCDiv) {
self.tocBody.appendChild(sectionTOCDiv);
}
sectionTOCDiv = div;
}
}
for (const chpater of chpaters) {
const chapterHtmlFileName = chpater.chapterHtmlFileName;
if (sectionName) {
appendSpine(chapterHtmlFileName);
i++;
const navPoint = genNavPoint(i, chpater.chapterName ?? "", chapterHtmlFileName);
sectionNavPoint?.appendChild(navPoint);
sectionNavOl?.appendChild(genNavHtmlLi(chpater.chapterName ?? "", chapterHtmlFileName));
const div = genTocDiv("sgc-toc-level-2", chpater.chapterName ?? "", chapterHtmlFileName);
sectionTOCDiv?.appendChild(div);
}
else {
appendSpine(chapterHtmlFileName);
i++;
const navPoint = genNavPoint(i, chpater.chapterName ?? "", chapterHtmlFileName);
self.navMap.appendChild(navPoint);
navHtmlTocOl.appendChild(genNavHtmlLi(chpater.chapterName ?? "", chapterHtmlFileName));
const div = genTocDiv("sgc-toc-level-2", chpater.chapterName ?? "", chapterHtmlFileName);
self.tocBody.appendChild(div);
}
}
}
if (sectionNavPoint) {
self.navMap.appendChild(sectionNavPoint);
}
if (sectionTOCDiv) {
self.tocBody.appendChild(sectionTOCDiv);
}
await self.epubZip.file("OEBPS/content.opf", new Blob([
new XMLSerializer()
.serializeToString(self.contentOpf)
.replaceAll('xmlns=""', "")
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], { type: "application/oebps-package+xml" }));
await self.epubZip.file("OEBPS/toc.ncx", new Blob([
new XMLSerializer()
.serializeToString(self.ncx)
.replaceAll('xmlns=""', "")
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], { type: "application/x-dtbncx+xml" }));
await self.epubZip.file("OEBPS/nav.xhtml", new Blob([
new XMLSerializer()
.serializeToString(self.navHtml)
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], {
type: "application/xhtml+xml",
}));
await self.epubZip.file("OEBPS/TOC.xhtml", new Blob([
new XMLSerializer()
.serializeToString(self.toc)
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], { type: "application/xhtml+xml" }));
function appendManifest(htmlFileName) {
const item = self.contentOpf.createElement("item");
item.id = htmlFileName;
item.setAttribute("href", htmlFileName);
item.setAttribute("media-type", "application/xhtml+xml");
if (!self.manifest.querySelector(`itme[id="${htmlFileName}"]`)) {
self.manifest.appendChild(item);
}
}
function appendSpine(htmlFileName) {
const itemref = self.contentOpf.createElement("itemref");
itemref.setAttribute("idref", htmlFileName);
self.spine.appendChild(itemref);
}
function genNavPoint(num, name, htmlFileName) {
const navPoint = self.ncx.createElement("navPoint");
navPoint.id = `navPoint-${num}`;
navPoint.setAttribute("playOrder", num.toString());
const navLabel = self.ncx.createElement("navLabel");
const text = self.ncx.createElement("text");
text.textContent = name;
const content = self.ncx.createElement("content");
content.setAttribute("src", htmlFileName);
navLabel.appendChild(text);
navPoint.appendChild(navLabel);
navPoint.appendChild(content);
return navPoint;
}
function genNavHtmlLi(name, htmlFileName) {
const li = self.navHtml.createElement("li");
const a = self.navHtml.createElement("a");
a.textContent = name;
a.href = htmlFileName;
li.appendChild(a);
return li;
}
function genTocDiv(className, name, htmlFileName) {
const div = self.toc.createElement("div");
div.className = className;
const a = self.toc.createElement("a");
a.href = htmlFileName;
a.innerText = name;
div.appendChild(a);
return div;
}
function genSectionHtmlFile(sectionName) {
const _htmlText = section.render({ sectionName: sectionName });
const htmlText = (0,dom/* convertHTMLtoXHTML */.fI)(_htmlText);
return new Blob([
``,
htmlText
.replaceAll("data-src-address", "src")
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, "")
.replace('', ''),
], {
type: "application/xhtml+xml",
});
}
}
async function saveZipFiles() {
loglevel_default().debug("[save-zip]保存元数据文本");
const metaDateText = self.genMetaDateTxt(self.book);
await self.epubZip.file("OEBPS/info.txt", new Blob([metaDateText], { type: "text/plain;charset=utf-8" }));
loglevel_default().debug("[save-zip]保存web样式");
await self.epubZip.file("OEBPS/web.css", new Blob([web/* default */.Z], { type: "text/css;charset=utf-8" }));
modifyTocStyleText();
await self.epubZip.file("OEBPS/toc.css", new Blob([self.tocStyleText], { type: "text/css;charset=utf-8" }));
await self.epubZip.file("OEBPS/web.js", new Blob([
`if (typeof fetch === "function" && !navigator.userAgent.includes("calibre-viewer") && navigator.userAgent.startsWith("Mozilla/5.0")) {
const link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = "web.css";
document.head.append(link);
}`,
], { type: "application/javascript" }));
loglevel_default().debug("[save-zip]开始生成并保存 index.html");
await saveIndex();
loglevel_default().debug("[save-zip]开始保存 Meta Data Json");
await saveMetaJson();
function modifyTocStyleText() {
if (self.book.additionalMetadate.cover) {
self.tocStyleText = `${self.tocStyleText}
.info {
display: grid;
grid-template-columns: 30% 70%;
}`;
}
else {
self.tocStyleText = `${self.tocStyleText}
.info {
display: grid;
grid-template-columns: 100%;
}`;
}
}
async function saveIndex() {
loglevel_default().debug("[save]对 chapters 排序");
self.chapters.sort(self.chapterSort);
const sectionsListObj = (0,save_misc/* getSectionsObj */.f)(self.chapters, self.chapterSort);
const _indexHtmlText = index.render({
creationDate: Date.now(),
bookname: self.book.bookname,
author: self.book.author,
cover: self.book.additionalMetadate.cover,
introductionHTML: self.book.introductionHTML?.outerHTML,
bookUrl: self.book.bookUrl,
sectionsObj: Object.values(sectionsListObj),
Status: main/* Status */.qb,
});
const indexHtmlText = (0,dom/* convertHTMLtoXHTML */.fI)(_indexHtmlText);
await self.epubZip.file("OEBPS/index.xhtml", new Blob([
indexHtmlText
.replaceAll("data-src-address", "src")
.replaceAll(/[\u{0000}-\u{001f}]/gu, "")
.replaceAll(/[\u{007f}-\u{009f}]/gu, ""),
], {
type: "application/xhtml+xml; charset=UTF-8",
}));
}
async function saveMetaJson() {
await self.epubZip.file("OEBPS/book.json", new Blob([JSON.stringify(self.book)], {
type: "application/json; charset=utf-8",
}));
await self.epubZip.file("OEBPS/chapters.json", new Blob([JSON.stringify(self.book.chapters)], {
type: "application/json; charset=utf-8",
}));
}
}
}
async addChapter(chapter, suffix = "") {
const chapterName = this.getchapterName(chapter);
const chapterNumberToSave = this.getChapterNumberToSave(chapter, this.chapters);
const chapterHtmlFileName = `No${chapterNumberToSave}Chapter${suffix}.xhtml`;
chapter.chapterHtmlFileName = chapterHtmlFileName;
loglevel_default().debug(`[save-epub]保存章HTML文件:${chapterName}`);
const chapterHTMLBlob = EPUB.genChapterHtmlFile(chapter);
await this.epubZip.file(`OEBPS/${chapterHtmlFileName}`, chapterHTMLBlob);
const item = this.contentOpf.createElement("item");
item.id = chapterHtmlFileName;
item.setAttribute("href", chapterHtmlFileName);
item.setAttribute("media-type", "application/xhtml+xml");
if (!this.manifest.querySelector(`item[id="${chapterHtmlFileName}"]`)) {
this.manifest.appendChild(item);
}
if (chapter.contentImages && chapter.contentImages.length !== 0) {
loglevel_default().debug(`[save-epub]保存章节附件:${chapterName}`);
for (const attachment of chapter.contentImages) {
await this.addAttachment(attachment);
}
}
}
async addAttachment(attachment) {
if (attachment.status === main/* Status */.qb.finished && attachment.Blob) {
loglevel_default().debug(`[save-epub]添加附件,文件名:${attachment.name},对象`, attachment.Blob);
await this.epubZip.file(`OEBPS/${attachment.name}`, attachment.Blob);
const item = this.contentOpf.createElement("item");
item.id = attachment.name;
item.setAttribute("href", attachment.name);
const mimetype = (0,misc/* extensionToMimetype */.z9)(attachment.name.substring(attachment.name.lastIndexOf(".") + 1));
item.setAttribute("media-type", mimetype);
if (!this.manifest.querySelector(`item[id="${attachment.name}"]`)) {
this.manifest.appendChild(item);
}
}
else if (attachment.status === main/* Status */.qb.saved) {
loglevel_default().debug(`[save-epub]附件${attachment.name}已添加`);
}
else {
loglevel_default().warn(`[save-epub]添加附件${attachment.name}失败,该附件未完成或内容为空。`);
loglevel_default().warn(attachment);
}
}
}
;// CONCATENATED MODULE: ./src/save/txt.ts
class TXT extends Options {
book;
savedTextArray = [];
saveFileNameBase;
constructor(book, options) {
super();
this.book = book;
this.saveFileNameBase = `[${this.book.author}]${this.book.bookname}`;
if (options) {
Object.assign(this, options);
}
}
saveTxt() {
const chapters = this.book.chapters;
const metaDateText = this.genMetaDateTxt(this.book);
this.savedTextArray.push(metaDateText);
loglevel_default().debug("[save]对 chapters 排序");
chapters.sort(this.chapterSort);
const sections = [];
for (const chapterTemp of chapters) {
const chapterName = this.getchapterName(chapterTemp);
if (chapterTemp.sectionName &&
!sections.includes(chapterTemp.sectionName)) {
sections.push(chapterTemp.sectionName);
const sectionText = this.genSectionText(chapterTemp.sectionName);
this.savedTextArray.push(sectionText);
}
const chapterText = this.genChapterText(chapterName, chapterTemp.contentText ?? "");
this.savedTextArray.push(chapterText);
if (!setting/* enableDebug */.Cy.value) {
chapterTemp.contentText = null;
}
}
loglevel_default().info("[save]保存TXT文件");
const savedText = this.savedTextArray.join("\n").replaceAll("\n", "\r\n");
(0,FileSaver_min.saveAs)(new Blob([savedText], { type: "text/plain;charset=utf-8" }), `${this.saveFileNameBase}.txt`);
}
}
;// CONCATENATED MODULE: ./src/save/raw.ts
class Raw {
book;
epubZip;
constructor(book) {
this.book = book;
if (this.book.saveType.raw instanceof Object) {
const zipFilename = `[${this.book.author}]${this.book.bookname}.${this.book.saveType.raw.ext}`;
this.epubZip = new FflateZip(zipFilename, false, (0,misc/* extensionToMimetype */.z9)(this.book.saveType.raw.ext));
}
else {
throw new Error("init raw save zip failed!");
}
}
async saveRaw() {
const attachments = this.book.additionalMetadate.attachments;
const tasks = attachments?.map(async (attach) => {
if (attach.Blob) {
await this.epubZip.file(attach.name, attach.Blob, attach.comments === "nocompress");
}
}) ?? [];
await Promise.all(tasks);
await this.epubZip.generateAsync();
}
}
;// CONCATENATED MODULE: ./src/save/save.ts
class SaveBook {
saveType;
txt;
epub;
raw;
constructor(book, streamZip, options) {
const _options = {};
if (options !== undefined) {
Object.assign(_options, options);
}
if (book.saveOptions !== undefined) {
Object.assign(_options, book.saveOptions);
}
this.saveType = book.saveType;
this.txt = new TXT(book, _options);
this.epub = new EPUB(book, streamZip, _options);
if (this.saveType.raw instanceof Object) {
this.raw = new Raw(book);
}
}
static saveLog() {
(0,FileSaver_min.saveAs)(new Blob([log/* logText */.KC], { type: "text/plain; charset=UTF-8" }), "debug.log");
}
async addChapter(chapter) {
await this.epub.addChapter(chapter);
if (!setting/* enableDebug */.Cy.value) {
chapter.contentRaw = null;
chapter.contentHTML = null;
chapter.contentImages = null;
}
if (chapter.contentImages && chapter.contentImages.length !== 0) {
for (const attachment of chapter.contentImages) {
attachment.status = main/* Status */.qb.saved;
if (!setting/* enableDebug */.Cy.value) {
attachment.Blob = null;
}
}
}
chapter.status = main/* Status */.qb.saved;
}
async save() {
if (this.saveType.txt) {
this.saveTxt();
}
if (setting/* enableDebug */.Cy.value) {
SaveBook.saveLog();
}
if (this.saveType.epub) {
await this.saveEpub();
}
if (this.saveType.raw instanceof Object) {
await this.saveRaw();
}
}
saveTxt() {
this.txt.saveTxt();
}
async saveEpub() {
await this.epub.saveEpub();
}
async saveRaw() {
await this.raw.saveRaw();
}
}
;// CONCATENATED MODULE: ./src/stat.ts
const statKeyName = "novel-downloader-22932304826849026";
const domain = document.location.hostname;
async function getStatData() {
const _data = (await (0,GM/* _GM_getValue */.QG)(statKeyName));
let statData;
if (_data) {
statData = JSON.parse(_data);
}
else {
statData = { success: {}, failed: {} };
}
return statData;
}
const saveData = async (statData) => {
const dataJSON = JSON.stringify(statData);
await (0,GM/* _GM_setValue */._u)(statKeyName, dataJSON);
return statData;
};
const dataPlus = async (key) => {
const statData = await getStatData();
const tmpData = statData[key];
if (tmpData[domain]) {
tmpData[domain] = tmpData[domain] + 1;
}
else {
tmpData[domain] = 1;
}
return saveData(statData);
};
const successPlus = () => {
return dataPlus("success");
};
const failedPlus = () => {
return dataPlus("failed");
};
const printStat = async () => {
const statData = await getStatData();
loglevel_default().info("[stat]小说下载器脚本运行情况统计:");
loglevel_default().info(statData);
for (const k in statData) {
if (Object.prototype.hasOwnProperty.call(statData, k)) {
loglevel_default().info(`[stat]${k}:`);
const subData = statData[k];
for (const j in subData) {
if (Object.prototype.hasOwnProperty.call(subData, j)) {
loglevel_default().info(` ${j}: ${subData[j]}`);
}
}
}
}
};
const resetStat = () => {
const statData = { success: {}, failed: {} };
return saveData(statData);
};
// EXTERNAL MODULE: ./src/ui/progress.ts + 1 modules
var progress = __webpack_require__("./src/ui/progress.ts");
;// CONCATENATED MODULE: ./src/rules.ts
class BaseRuleClass {
attachmentMode = "TM";
charset = document.characterSet;
concurrencyLimit = 10;
streamZip = false;
needLogin = false;
nsfw = false;
maxRunLimit;
saveOptions;
book;
saveType;
bcWorker = new BroadcastChannel("novel-downloader-worker");
bcWorkerMessages = [];
audio;
constructor() {
const broadcastChannelWorker = this.bcWorker;
const messages = this.bcWorkerMessages;
broadcastChannelWorker.onmessage = (ev) => {
const message = ev.data;
if (message.type === "ping") {
const pong = {
type: "pong",
src: message.workerId,
workerId: window.workerId,
url: document.location.href,
};
broadcastChannelWorker.postMessage(pong);
}
if (message.type === "pong") {
messages.push(message);
}
if (message.type === "close") {
loglevel_default().debug(`${window.workerId} has closed!`);
}
};
}
async run() {
loglevel_default().info(`[run]下载开始`);
const self = this;
try {
await self.preHook();
await initBook();
const saveBookObj = initSave(self.book);
await saveHook();
await self.initChapters(self.book, saveBookObj).catch((error) => {
if (error instanceof main/* ExpectError */.K2) {
console.warn(error);
}
else {
throw error;
}
});
await save(saveBookObj);
self.postHook();
return self.book;
}
catch (error) {
self.catchError(error);
}
async function initBook() {
if (window._book &&
window._url === document.location.href) {
self.book = window._book;
}
else {
self.book = await self.bookParse();
window._book = self.book;
window._url = document.location.href;
}
loglevel_default().debug("[book]Book object:\n" + JSON.stringify(self.book));
}
function initSave(book) {
loglevel_default().debug("[run]保存数据");
if (setting/* enableCustomSaveOptions */.EI &&
typeof unsafeWindow.saveOptions === "object" &&
saveOptionsValidate(unsafeWindow.saveOptions)) {
const saveOptions = unsafeWindow.saveOptions;
if (saveOptions) {
loglevel_default().info("[run]发现自定义保存参数,内容如下\n", saveOptions);
return new SaveBook(book, self.streamZip, saveOptions);
}
}
return new SaveBook(book, self.streamZip);
}
async function saveHook() {
if (setting/* enableSaveToArchiveOrg */.CA &&
!self.needLogin &&
self.book?.bookUrl &&
window.localStorageExpired.get(`${self.book.bookUrl}_saveToArchiveOrg`) === undefined &&
(await (0,setting/* getCustomEnableSaveToArchiveOrg */.Qd)())) {
console.log("[saveToArchiveOrg]保存当前书页至 archive.org");
try {
window.localStorageExpired.set(`${self.book.bookUrl}_saveToArchiveOrg`, true, 86400);
}
catch (error) {
}
(0,misc/* saveToArchiveOrg */.K$)(self.book.bookUrl).then((r) => loglevel_default().info(r));
if (self.book.ToCUrl) {
(0,misc/* saveToArchiveOrg */.K$)(self.book.ToCUrl).then((r) => loglevel_default().info(r));
}
}
}
async function save(saveObj) {
loglevel_default().debug("[run]开始保存文件");
await saveObj.save();
}
}
async preHook() {
const self = this;
if (!(await preTest())) {
const alertText = `当前网站目前最多允许${self.maxRunLimit}个下载任务同时进行。\n请待其它下载任务完成后,再行尝试。`;
alert(alertText);
loglevel_default().info(`[run]${alertText}`);
throw new main/* ExpectError */.K2(alertText);
}
self.audio = new Audio("data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU3LjcxLjEwMAAAAAAAAAAAAAAA/+M4wAAAAAAAAAAAAEluZm8AAAAPAAAAEAAABVgANTU1NTU1Q0NDQ0NDUFBQUFBQXl5eXl5ea2tra2tra3l5eXl5eYaGhoaGhpSUlJSUlKGhoaGhoaGvr6+vr6+8vLy8vLzKysrKysrX19fX19fX5eXl5eXl8vLy8vLy////////AAAAAExhdmM1Ny44OQAAAAAAAAAAAAAAACQCgAAAAAAAAAVY82AhbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+MYxAALACwAAP/AADwQKVE9YWDGPkQWpT66yk4+zIiYPoTUaT3tnU487uNhOvEmQDaCm1Yz1c6DPjbs6zdZVBk0pdGpMzxF/+MYxA8L0DU0AP+0ANkwmYaAMkOKDDjmYoMtwNMyDxMzDHE/MEsLow9AtDnBlQgDhTx+Eye0GgMHoCyDC8gUswJcMVMABBGj/+MYxBoK4DVpQP8iAtVmDk7LPgi8wvDzI4/MWAwK1T7rxOQwtsItMMQBazAowc4wZMC5MF4AeQAGDpruNuMEzyfjLBJhACU+/+MYxCkJ4DVcAP8MAO9J9THVg6oxRMGNMIqCCTAEwzwwBkINOPAs/iwjgBnMepYyId0PhWo+80PXMVsBFzD/AiwwfcKGMEJB/+MYxDwKKDVkAP8eAF8wMwIxMlpU/OaDPLpNKkEw4dRoBh6qP2FC8jCJQFcweQIPMHOBtTBoAVcwOoCNMYDI0u0Dd8ANTIsy/+MYxE4KUDVsAP8eAFBVpgVVPjdGeTEWQr0wdcDtMCeBgDBkgRgwFYB7Pv/zqx0yQQMCCgKNgonHKj6RRVkxM0GwML0AhDAN/+MYxF8KCDVwAP8MAIHZMDDA3DArAQo3K+TF5WOBDQw0lgcKQUJxhT5sxRcwQQI+EIPWMA7AVBoTABgTgzfBN+ajn3c0lZMe/+MYxHEJyDV0AP7MAA4eEwsqP/PDmzC/gNcwXUGaMBVBIwMEsmB6gaxhVuGkpoqMZMQjooTBwM0+S8FTMC0BcjBTgPwwOQDm/+MYxIQKKDV4AP8WADAzAKQwI4CGPhWOEwCFAiBAYQnQMT+uwXUeGzjBWQVkwTcENMBzA2zAGgFEJfSPkPSZzPXgqFy2h0xB/+MYxJYJCDV8AP7WAE0+7kK7MQrATDAvQRIwOADKMBuA9TAYQNM3AiOSPjGxowgHMKFGcBNMQU1FMy45OS41VVU/31eYM4sK/+MYxKwJaDV8AP7SAI4y1Yq0MmOIADGwBZwwlgIJMztCM0qU5TQPG/MSkn8yEROzCdAxECVMQU1FMy45OS41VTe7Ohk+Pqcx/+MYxMEJMDWAAP6MADVLDFUx+4J6Mq7NsjN2zXo8V5fjVJCXNOhwM0vTCDAxFpMYYQU+RlVMQU1FMy45OS41VVVVVVVVVVVV/+MYxNcJADWAAP7EAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxOsJwDWEAP7SAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxPMLoDV8AP+eAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxPQL0DVcAP+0AFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");
self.audio.loop = true;
await self.audio.play();
window.onbeforeunload = (e) => {
e.preventDefault();
const confirmationText = "您正尝试离开本页面,当前页面有下载任务正在运行,是否确认离开?";
return (e.returnValue = confirmationText);
};
window.downloading = true;
async function preTest() {
const broadcastChannelWorker = self.bcWorker;
const messages = self.bcWorkerMessages;
const ping = {
type: "ping",
workerId: window.workerId,
url: document.location.href,
};
broadcastChannelWorker.postMessage(ping);
await (0,misc/* sleep */._v)(300);
const workers = messages
.filter((m) => m.type === "pong" &&
m.src === window.workerId &&
m.workerId !== window.workerId)
.map((m) => ({
id: m.workerId,
url: m.url,
}));
loglevel_default().info(JSON.stringify(workers, undefined, 4));
const nowRunning = workers.length;
loglevel_default().info(`[preTest]nowRunning: ${nowRunning}`);
if (self.maxRunLimit) {
return nowRunning < self.maxRunLimit;
}
else {
return true;
}
}
}
async initChapters(book, saveBookObj) {
const self = this;
loglevel_default().info(`[initChapters]开始初始化章节`);
Object.entries(self).forEach((kv) => loglevel_default().info(`[initChapters] ${kv[0]}: ${kv[1]}`));
const chapters = getChapters(book);
if (chapters.length === 0) {
loglevel_default().error(`[initChapters]初始化章节出错,未找到需初始化章节`);
return [];
}
progress.vm.totalChapterNumber = chapters.length;
if (self.concurrencyLimit === 1) {
for (const chapter of chapters) {
if (window.failedCount > 10) {
if (!window.stopFlag.aborted) {
window.stopController.abort();
console.error("连续十章下载失败,放弃本次下载。\n请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/404-novel-project/novel-downloader");
alert("连续十章下载失败,放弃本次下载。\n请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/404-novel-project/novel-downloader");
(0,log/* saveLogTextToFile */.qS)();
}
}
if (window.stopFlag.aborted) {
throw new main/* ExpectError */.K2("[chapter]收到停止信号,停止继续下载。");
}
try {
let chapterObj = await chapter.init();
chapterObj = await postChapterParseHook(chapterObj, saveBookObj);
}
catch (error) {
loglevel_default().error(error);
loglevel_default().trace(error);
}
}
}
else {
const asyncHandle = async (curChapter) => {
if (window.failedCount > 10) {
if (!window.stopFlag.aborted) {
window.stopController.abort();
console.error("连续十章下载失败,放弃本次下载。\n请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/404-novel-project/novel-downloader");
alert("连续十章下载失败,放弃本次下载。\n请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/404-novel-project/novel-downloader");
(0,log/* saveLogTextToFile */.qS)();
}
}
if (curChapter === undefined) {
return null;
}
try {
let chapterObj = await curChapter.init();
chapterObj = await postChapterParseHook(chapterObj, saveBookObj);
return chapterObj;
}
catch (error) {
loglevel_default().error(error);
loglevel_default().trace(error);
}
};
await (0,misc/* concurrencyRun */.C1)(chapters, self.concurrencyLimit, asyncHandle, {
signal: window.stopFlag,
reason: "[chapter]收到停止信号,停止继续下载。",
});
}
loglevel_default().info(`[initChapters]章节初始化完毕`);
return chapters;
function getChapters(_book) {
function isEnable() {
if (setting/* enableCustomChapterFilter */.Td &&
typeof unsafeWindow.chapterFilter === "function") {
let text = "[initChapters]发现自定义筛选函数,自定义筛选函数内容如下:\n";
text += unsafeWindow.chapterFilter?.toString();
loglevel_default().info(text);
return true;
}
else {
return false;
}
}
function _filter(chapter) {
let b = true;
try {
const u = unsafeWindow.chapterFilter?.(chapter);
if (typeof u === "boolean") {
b = u;
}
}
catch (error) {
loglevel_default().error("运行自定义筛选函数时出错。", error);
loglevel_default().trace(error);
}
return b;
}
let _chapters = _book.chapters.filter((chapter) => chapter.status === main/* Status */.qb.pending);
const enabled = isEnable();
if (enabled) {
loglevel_default().debug("[initChapters]筛选需下载章节");
_chapters = _chapters.filter((chapter) => _filter(chapter));
}
return _chapters;
}
async function postChapterParseHook(chapter, saveObj) {
if (chapter.contentHTML !== undefined) {
await saveObj.addChapter(chapter);
progress.vm.finishedChapterNumber++;
}
return chapter;
}
}
postHook() {
const self = this;
(0,attachments/* clearAttachmentClassCache */.pN)();
self.audio?.pause();
self.audio?.remove();
const closeMessage = {
type: "close",
workerId: window.workerId,
url: document.location.href,
};
self.bcWorker.postMessage(closeMessage);
self.bcWorker.onmessage = null;
self.bcWorker.close();
self.bcWorkerMessages.splice(0, self.bcWorkerMessages.length);
window.onbeforeunload = null;
window.downloading = false;
progress.vm.reset();
window._book = undefined;
window._url = undefined;
postCallback();
successPlus().then(() => {
printStat();
});
function postCallback() {
if (setting/* enableCustomFinishCallback */.Vo &&
typeof unsafeWindow.customFinishCallback ===
"function") {
const customFinishCallback = unsafeWindow
.customFinishCallback;
if (customFinishCallback) {
loglevel_default().info(`发现自定义结束回调函数,内容如下:\n${customFinishCallback.toString()}`);
customFinishCallback();
}
}
}
}
catchError(error) {
const self = this;
loglevel_default().error(error);
loglevel_default().trace(error);
self.postHook();
if (!(error instanceof main/* ExpectError */.K2)) {
document.getElementById("button-div")?.remove();
loglevel_default().error("运行过程出错,请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/404-novel-project/novel-downloader");
failedPlus();
alert("运行过程出错,请附上相关日志至支持地址进行反馈。\n支持地址:https://github.com/404-novel-project/novel-downloader");
window.open("https://github.com/404-novel-project/novel-downloader/issues");
(0,log/* saveLogTextToFile */.qS)();
}
}
}
/***/ }),
/***/ "./src/rules/biquge/mht.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ mht: () => (/* binding */ mht)
/* harmony export */ });
/* harmony import */ var _onePage_template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules/biquge/template.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/lib/cleanDOM.ts");
const mht = () => (0,_onePage_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
...(0,_template__WEBPACK_IMPORTED_MODULE_1__/* .baseOnePage */ .FG)((introDom) => introDom, 5),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const ngetHtmlDOM = (input, charset, init) => {
const test = async (response) => {
const resp = response.clone();
const text = await resp.text();
return text.includes('');
};
return (0,_lib_http__WEBPACK_IMPORTED_MODULE_2__/* .getHtmlDOM */ .dL)(input, charset, init, test);
};
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_3__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: "#content",
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_4__.rm)("p[data-id]", true, content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__/* .htmlTrim */ .iA)(content);
return content;
},
getNextPage: (doc) => doc.querySelector(".bottem2 > a:nth-child(4)")
.href,
continueCondition: (_content, nextLink) => new URL(nextLink).pathname.includes("_"),
enableCleanDOM: false,
getHtmlDomFunc: ngetHtmlDOM,
});
return contentRaw;
},
contentPatch: (dom) => dom,
});
/***/ }),
/***/ "./src/rules/biquge/multiIndexNextPage.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ c226ks: () => (/* binding */ c226ks),
/* harmony export */ znlzd: () => (/* binding */ znlzd)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/biquge/template.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
const znlzd = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkBiqugeMultiIndexNextPage */ .HW)((dom) => dom, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div", true, content);
return content;
}, (doc) => doc.querySelector("div.section-opt:nth-child(1) > a:nth-child(5)")?.href ?? "", (_content, nextLink) => {
if (nextLink === "") {
return false;
}
const pathname = nextLink.split("/").slice(-1)[0];
return pathname.includes("_");
}, 3);
const c226ks = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkBiqugeMultiIndexNextPage */ .HW)((introDom) => introDom, (content) => content, (doc) => doc.querySelector("section.g-content-nav > a:nth-child(3)").href, (_content, nextLink) => {
const pathname = nextLink.split("/").slice(-1)[0];
return pathname.includes("_");
});
/***/ }),
/***/ "./src/rules/biquge/nextPage.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ mijiashe: () => (/* binding */ mijiashe),
/* harmony export */ xinwanben: () => (/* binding */ xinwanben),
/* harmony export */ ywggzy: () => (/* binding */ ywggzy)
/* harmony export */ });
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/biquge/template.ts");
const xinwanben = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkBiqugeNextPage */ .B4)((introDom) => {
const _bookname = introDom.innerHTML.match(/《(.*)》/);
let bookname;
if (_bookname?.length === 2) {
bookname = _bookname[1];
}
const adList = [
"还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!",
"小说免费阅读地址:",
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rm2 */ .vS)(adList, introDom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)([`${bookname}小说简介:`], introDom);
return introDom;
}, (content) => {
const filters = [
"手机用户输入地址",
"提示:浏览器搜索",
"把本站分享那些需要的小伙伴!找不到书请留言!",
"【完本神站】",
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rm2 */ .vS)(filters, content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_2__/* .htmlTrim */ .iA)(content);
return content;
}, (doc) => doc.querySelector("#next_url").href, (_content, nextLink) => new URL(nextLink).pathname.includes("_"));
const mijiashe = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkBiqugeNextPage */ .B4)((introDom) => {
const _bookname = introDom.innerHTML.match(/《(.*)》/);
let bookname;
if (_bookname?.length === 2) {
bookname = _bookname[1];
}
const adList = [
"还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!",
"小说免费阅读地址:",
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rm2 */ .vS)(adList, introDom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)([`${bookname}小说简介:`], introDom);
return introDom;
}, (content) => {
const filters = [
"谨记我们的网址,祝大家阅读愉快!别忘了多多宣传宣传。",
"【提示】:如果觉得此文不错,请推荐给更多小伙伴吧!分享也是一种享受。",
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rm2 */ .vS)(filters, content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_2__/* .htmlTrim */ .iA)(content);
return content;
}, (doc) => doc.querySelector("#next_url").href, (_content, nextLink) => new URL(nextLink).pathname.includes("_"));
const ywggzy = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkBiqugeNextPage */ .B4)((initroDom) => initroDom, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)(".posterror", false, content);
return content;
}, (doc) => doc.querySelector("div.section-opt:nth-child(1) > a:nth-child(5)")?.href ?? "", (_content, nextLink) => new URL(nextLink).pathname.includes("_"));
/***/ }),
/***/ "./src/rules/biquge/onePage.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ b5200: () => (/* binding */ b5200),
/* harmony export */ biquwx: () => (/* binding */ biquwx),
/* harmony export */ bxwx333: () => (/* binding */ bxwx333),
/* harmony export */ c25zw: () => (/* binding */ c25zw),
/* harmony export */ common: () => (/* binding */ common),
/* harmony export */ dijiubook: () => (/* binding */ dijiubook),
/* harmony export */ gebiqu: () => (/* binding */ gebiqu),
/* harmony export */ la42zw: () => (/* binding */ la42zw),
/* harmony export */ lewenn: () => (/* binding */ lewenn),
/* harmony export */ luoqiuzw: () => (/* binding */ luoqiuzw),
/* harmony export */ lusetxt: () => (/* binding */ lusetxt),
/* harmony export */ ranwen: () => (/* binding */ ranwen),
/* harmony export */ shuquge: () => (/* binding */ shuquge),
/* harmony export */ tycqxs: () => (/* binding */ tycqxs),
/* harmony export */ xbiquge: () => (/* binding */ xbiquge),
/* harmony export */ xbiqugeLa: () => (/* binding */ xbiqugeLa),
/* harmony export */ xyb3: () => (/* binding */ xyb3),
/* harmony export */ yqxs: () => (/* binding */ yqxs),
/* harmony export */ yruan: () => (/* binding */ yruan)
/* harmony export */ });
/* harmony import */ var _lib_misc__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/misc.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules/biquge/template.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/cleanDOM.ts");
const commonContentPatch = (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[style]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[align]", true, content);
return content;
};
const common = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, commonContentPatch);
const gebiqu = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([/如果您喜欢.+,别忘记分享给朋友/g], introDom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)('a[href^="http://down.gebiqu.com"]', false, introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([/"www.gashuw.com"/g], content);
return content;
});
const luoqiuzw = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => {
const ad = content.firstElementChild;
if (ad.innerText.includes("天才一秒记住本站地址:")) {
ad.remove();
}
const ads = ["记住网址m.luoqiuxzw.com"];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)(ads, content);
return content;
});
const biquwx = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([
/本站提示:各位书友要是觉得《.+》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!/,
], introDom);
return introDom;
}, (content) => content, 1);
const tycqxs = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("a", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)(["推荐都市大神老施新书:"], content);
return content;
});
const dijiubook = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)(["本书网址:"], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("a", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)('img[src$="alipay.png"]', true, content);
return content;
}, 1, (classThis) => {
classThis.maxRunLimit = 1;
const chapterParse = classThis.chapterParse;
classThis.chapterParse = async (...args) => {
const obj = await chapterParse(...args);
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_2__/* .sleep */ ._v)(3000 * Math.random());
return obj;
};
return classThis;
}, (chapter) => {
const url = new URL(chapter.chapterUrl);
if (url.host === "m.dijiuben.com" || url.href.endsWith(".apk")) {
return;
}
else {
return chapter;
}
});
const c25zw = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
introDom.querySelector("font")?.parentElement?.remove();
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)(["简介:"], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)(".bottem", false, content);
return content;
});
const xbiquge = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([/笔趣阁 www.xbiquge.tw,最快更新.+ !/], content);
return content;
});
const yruan = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["本站提示:各位书友要是觉得"], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("b", true, content);
return content;
}, 3);
const ranwen = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!"], introDom);
return introDom;
}, (content) => content);
const b5200 = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => content, 1);
const bxwx333 = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => {
content.querySelector("#xuanchuan")?.parentElement?.remove();
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[style]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)(".bottem2", true, content);
return content;
}, undefined, undefined, undefined, "#zjneirong");
const xbiqugeLa = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
introDom.querySelector("font")?.parentElement?.remove();
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["手机站全新改版升级地址"], content);
return content;
}, 1);
const shuquge = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
document.querySelector(".noshow")?.classList.remove("noshow");
if (document.querySelector(".showall")) {
document.querySelector(".showall").innerHTML = "";
}
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([
/作者:.+所写的《.+》无弹窗免费全文阅读为转载作品,章节由网友发布。/,
/推荐地址:https?:\/\/www\.ishuquge\.org\/txt\/\d+\/index\.html/g,
], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["请记住本书首发域名:", "www.ishuquge.org"], content);
return content;
}, 1);
const lusetxt = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["无弹窗免费全文阅读为转载作品", "无弹窗推荐地址", "简介:"], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[style]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[align]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["https://www.lvsewx.com/books", "请记住本书首发域名"], content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_3__/* .htmlTrim */ .iA)(content);
return content;
});
const yqxs = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)(["
简介:"], introDom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["推荐地址:"], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)('div[align="center"]', false, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["//www.yqxsge.cc/html/", "请记住本书首发域名"], content);
return content;
});
const lewenn = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([
/各位书友要是觉得《.*》还不错的话请不要忘记向您QQ群和微博里的朋友推荐哦!/,
], introDom);
return introDom;
}, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)('div[align="center"]', false, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)(["//www.lewenn.net/lw", "1秒记住乐文小说网"], content);
return content;
});
const xyb3 = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[style]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div[align]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rm2 */ .vS)([
"由于各种问题yb3.cc地址更改为xyb3.net请大家收藏新地址避免迷路",
"网页版章节内容慢,请下载好阅小说app阅读最新内容",
"请退出转码页面,请下载好阅小说app 阅读最新章节。",
"https://www.xyb3.net",
], content);
return content;
});
const la42zw = () => (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkBiquge */ .Hb)((introDom) => introDom, (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("div#content > p:first-child", false, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__/* .rms */ .up)([
"首发网址https://m.42zw.la",
"记住网址m.42zw.la",
"一秒记住https://m.42zw.la"
], content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_0__.rm)("br", true, content);
return content;
});
/***/ }),
/***/ "./src/rules/biquge/template.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ B4: () => (/* binding */ mkBiqugeNextPage),
/* harmony export */ FG: () => (/* binding */ baseOnePage),
/* harmony export */ HW: () => (/* binding */ mkBiqugeMultiIndexNextPage),
/* harmony export */ Hb: () => (/* binding */ mkBiquge)
/* harmony export */ });
/* unused harmony exports baseMultiIndex, mkBiqugeMultiIndex */
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _onePage_template__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules/onePage/template.ts");
/* harmony import */ var _onePageWithMultiIndexPage_template__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/rules/onePageWithMultiIndexPage/template.ts");
function base(introDomPatch, concurrencyLimit, overRide, postHook) {
return {
bookUrl: document.location.href,
bookname: document.querySelector("#info h1, .info h2, .info h1").innerText
.trim()
.replace(/最新章节$/, ""),
author: document.querySelector("#info > p:nth-child(2), #info > div:nth-child(2), .info .author, .small > span:nth-child(1), .info .fix > p:nth-child(1)").innerText
.replace(/作(\s+)?者[::]/, "")
.trim(),
introDom: document.querySelector("#intro, .intro, .book-intro, .desc"),
introDomPatch,
coverUrl: document.querySelector("#fmimg > img, .info > .cover > img, .book-boxs > .img > img, .imgbox > img")?.src ?? null,
postHook: (chapter) => {
if (chapter.sectionName) {
if (chapter.sectionName.includes("《")) {
chapter.sectionName = chapter.sectionName
.replace(`《${chapter.bookname}》`, "")
.trim();
}
else {
chapter.sectionName = chapter.sectionName
.replace(chapter.bookname, "")
.trim();
}
}
if (postHook) {
return postHook(chapter);
}
return chapter;
},
concurrencyLimit,
overrideConstructor: (classThis) => {
const rawBookParse = classThis.bookParse;
classThis.bookParse = async () => {
const book = (await Reflect.apply(rawBookParse, classThis, []));
const chapters = book.chapters;
book.chapters = (0,_lib_rule__WEBPACK_IMPORTED_MODULE_0__/* .deDuplicate */ .uh)(chapters);
return book;
};
if (overRide) {
overRide(classThis);
}
return classThis;
},
};
}
function baseOnePage(introDomPatch, concurrencyLimit, overRide, postHook) {
return {
...base(introDomPatch, concurrencyLimit, overRide, postHook),
aList: document.querySelectorAll("#list a, .listmain a, .book-item a"),
sections: document.querySelectorAll("#list dt, .listmain dt, .layout-tit"),
getSName: (sElem) => {
const b = sElem.querySelector("b");
if (b) {
return b.innerText;
}
return sElem.innerText;
},
};
}
function baseMultiIndex(introDomPatch, concurrencyLimit, overRide, postHook) {
return {
...base(introDomPatch, concurrencyLimit, overRide, postHook),
getIndexUrls: () => Array.from(document.querySelectorAll('select[name="pageselect"] > option')).map((o) => document.location.origin + o.getAttribute("value")),
getAList: (doc) => {
const sectionList = Array.from(doc.querySelectorAll("ul.section-list.fix, ul.list")).slice(-1)[0];
if (!sectionList) {
throw new Error("获取章节列表失败!");
}
return sectionList.querySelectorAll("li > a");
},
};
}
function mkBiquge(introDomPatch, contentPatch, concurrencyLimit, overRide, postHook, chapterContenSelector = "#content") {
return (0,_onePage_template__WEBPACK_IMPORTED_MODULE_1__/* .mkRuleClass */ .x)({
...baseOnePage(introDomPatch, concurrencyLimit, overRide, postHook),
getContent: (doc) => doc.querySelector(chapterContenSelector),
contentPatch,
});
}
function mkBiqugeNextPage(introDomPatch, contentPatch, getNextPage, continueCondition, concurrencyLimit, overRide, postHook, chapterContenSelector = "#content") {
return (0,_onePage_template__WEBPACK_IMPORTED_MODULE_1__/* .mkRuleClass */ .x)({
...baseOnePage(introDomPatch, concurrencyLimit, overRide, postHook),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_0__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: chapterContenSelector,
contentPatch,
getNextPage,
continueCondition,
enableCleanDOM: false,
});
return contentRaw;
},
contentPatch: (dom) => dom,
});
}
function mkBiqugeMultiIndexNextPage(introDomPatch, contentPatch, getNextPage, continueCondition, concurrencyLimit, overRide, postHook, chapterContenSelector = "#content") {
return (0,_onePageWithMultiIndexPage_template__WEBPACK_IMPORTED_MODULE_2__/* .mkRuleClass */ .x)({
...baseMultiIndex(introDomPatch, concurrencyLimit, overRide, postHook),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_0__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: chapterContenSelector,
contentPatch,
getNextPage,
continueCondition,
enableCleanDOM: false,
});
return contentRaw;
},
contentPatch: (dom) => dom,
});
}
function mkBiqugeMultiIndex(introDomPatch, contentPatch, concurrencyLimit, overRide, postHook, chapterContenSelector = "#content") {
return mkRuleClassMultiIndex({
...baseMultiIndex(introDomPatch, concurrencyLimit, overRide, postHook),
getContent: (doc) => doc.querySelector(chapterContenSelector),
contentPatch,
});
}
/***/ }),
/***/ "./src/rules/mbtxt/mbtxt.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ mbtxt: () => (/* binding */ mbtxt)
/* harmony export */ });
/* harmony import */ var _onePage_template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
const mbtxt = () => (0,_onePage_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".booktitle").innerText.trim(),
author: document.querySelector("a.red").innerText.trim(),
introDom: document.querySelector(".bookintro"),
introDomPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)(".visible-xs", true, dom);
return dom;
},
coverUrl: document.querySelector(".bookcover > img")?.src,
aList: document.querySelectorAll("#list-chapterAll > dd > a"),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: ".readcontent",
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)(".kongwen", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)(".readmiddle", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)(".text-danger.text-center", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)(["-->>"], content);
return content;
},
getNextPage: (doc) => doc.querySelector("#linkNext")?.href ?? "",
continueCondition: (content, nextLink) => {
if (nextLink === "") {
return false;
}
return nextLink.includes("_");
},
enableCleanDOM: false,
});
return contentRaw;
},
contentPatch: (dom) => dom,
});
/***/ }),
/***/ "./src/rules/mbtxt/quanshuzhai.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ quanshuzhai: () => (/* binding */ quanshuzhai)
/* harmony export */ });
/* harmony import */ var _onePage_template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const quanshuzhai = () => (0,_onePage_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".booktitle").innerText.trim(),
author: document.querySelector("a.red").innerText.trim(),
introDom: document.querySelector(".bookintro"),
introDomPatch: (dom) => dom,
coverUrl: null,
aList: document.querySelectorAll("#list-chapterAll > dd > a"),
getContent: (doc) => doc.querySelector(".readcontent"),
contentPatch: (dom) => dom,
});
/***/ }),
/***/ "./src/rules/onePage/256wxc.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ c256wxc: () => (/* binding */ c256wxc)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const c256wxc = (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".art_tit").innerText.trim(),
author: (document.querySelector("span.bookinfo:nth-child(1) > a") ??
document.querySelector("span.bookinfo:nth-child(1)")).innerText
.replace(/^作者:/, "")
.trim(),
introDom: document.querySelector(".infotype > p"),
introDomPatch: (introDom) => introDom,
coverUrl: null,
aList: document.querySelectorAll(".catalog > li > a"),
getContent: (doc) => doc.querySelector(".book_con"),
contentPatch: (content) => content,
});
/***/ }),
/***/ "./src/rules/onePage/630shu.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ c630shu: () => (/* binding */ c630shu)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const c630shu = (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("#info > h1").innerText.trim(),
author: document.querySelector("div.options > span.item:nth-child(1) > a").innerText.trim(),
introDom: document.querySelector("#intro"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector(".img_in > img").src,
aList: document.querySelectorAll(".zjlist > dd > a"),
getContent: (doc) => doc.querySelector("#content"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)([/恋上你看书网 WWW.630SHU.NET ,最快更新.+最新章节!/], content);
return content;
},
});
/***/ }),
/***/ "./src/rules/onePage/aixdzs.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ aixdzs: () => (/* binding */ aixdzs)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const aixdzs = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".d_info > h1").innerText.trim(),
author: document.querySelector(".d_ac > ul:nth-child(1) > li:nth-child(1) > a:nth-child(2)").innerText.trim(),
introDom: document.querySelector(".d_co"),
introDomPatch: (dom) => dom,
coverUrl: document.querySelector(".d_af > img").src,
aList: document.querySelectorAll("#i-chapter li.chapter > a"),
sections: document.querySelectorAll("#i-chapter li.volume"),
getSName: (dom) => dom.innerText.trim(),
getContent: (doc) => doc.querySelector(".content"),
contentPatch: (dom) => dom,
});
/***/ }),
/***/ "./src/rules/onePage/boqugew.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ boqugew: () => (/* binding */ boqugew)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const boqugew = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("h1.bookTitle").innerText.trim(),
author: document.querySelector("p.booktag > a:first-child").innerText.replace(/作(\s+)?者[::]/, "").trim(),
introDom: document.querySelector("p#bookIntro"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector("img.img-thumbnail").src,
aList: document.querySelectorAll("div#list-chapterAll > dl > dd > a"),
getContent: (doc) => doc.querySelector("div#htmlContent"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)([
"记住网址m.boqugew.com",
"一秒记住http://m.boqugew.com",
"首发网址http://m.boqugew.com"
], content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("br", true, content);
return content;
},
});
/***/ }),
/***/ "./src/rules/onePage/colorful-fantasybooks.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ fantasybooks: () => (/* binding */ fantasybooks)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const fantasybooks = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".works-intro-title > strong").innerText.trim(),
author: document.querySelector(".works-intro-digi > span:nth-child(1) > em:nth-child(1)").innerText.trim(),
introDom: document.querySelector(".works-intro-short"),
introDomPatch: (dom) => dom,
coverUrl: document.querySelector(".works-cover > img")
.src,
aList: document.querySelectorAll(".works-chapter-list .works-chapter-item > a"),
sections: document.querySelectorAll(".vloume"),
getSName: (sElem) => sElem.innerText.trim(),
getContent: (doc) => doc.querySelector("#content_cust"),
contentPatch: (content) => {
Array.from(content.children)
.filter((node) => node.nodeName === "SPAN" && node.childNodes.length > 15)
.map((span) => {
const div = document.createElement("div");
div.innerHTML = span.innerHTML;
Array.from(div.querySelectorAll("p"))
.filter((node) => node.childElementCount === 1 &&
node.children[0].nodeName === "BR")
.forEach((pbrp) => pbrp.remove());
span.replaceWith(div);
});
return content;
},
concurrencyLimit: 3,
nsfw: true,
});
/***/ }),
/***/ "./src/rules/onePage/dizishu.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ dizishu: () => (/* binding */ dizishu)
/* harmony export */ });
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const dizishu = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".book-text > h1").innerText.trim(),
author: document.querySelector(".book-text > span").innerText
.replace("著", "")
.trim(),
introDom: document.querySelector(".intro"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector("#fengmian img")
?.src,
aList: document.querySelectorAll("#list > .book-chapter-list .cf li > a"),
sections: document.querySelectorAll("#list > .book-chapter-list > h3"),
getSName: (sElem) => sElem.innerText.trim(),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
const script1 = Array.from(doc.querySelectorAll("script"))
.filter((s) => s.innerHTML.includes("chapterid="))?.[0]
?.innerHTML.split("\n")
.filter((line) => !(line.includes("cpstr=") ||
line.includes("get_content()") ||
line.includes("xid=")))
.join("\n");
const script2 = Array.from(doc.querySelectorAll("script"))
.filter((s) => s.innerHTML.includes("ssid"))?.[0]
?.innerHTML.split("\n")
.filter((line) => line.includes("var ssid") || line.includes("var hou"))
.join("\n");
const request = new Function(`${script2};${script1};
const xid=Math.floor(bookid/1000);
const url = \`${document.location.origin}/files/article/html\${ssid}/\${xid}/\${bookid}/\${chapterid}\${hou}\`;
return new Request(url, {
headers: {
accept: "text/plain, */*; q=0.01",
"x-requested-with": "XMLHttpRequest",
},
referrer: "${document.location.origin}",
method: "GET",
mode: "cors",
credentials: "include",
});`)();
const text = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getText */ .Q)(request, charset);
const cctxt = new Function(`${text};return cctxt;`)();
if (cctxt) {
const contentRaw = document.createElement("div");
contentRaw.innerHTML = cctxt;
return contentRaw;
}
else {
return null;
}
},
contentPatch: (content) => content,
overrideConstructor: (classThis) => {
const rawBookParse = classThis.bookParse;
classThis.bookParse = async () => {
const book = (await Reflect.apply(rawBookParse, classThis, []));
const chapters = book.chapters;
book.chapters = (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .deDuplicate */ .uh)(chapters);
return book;
};
return classThis;
},
});
/***/ }),
/***/ "./src/rules/onePage/guidaye.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ guidaye: () => (/* binding */ guidaye)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules/onePage/template.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_0__);
const guidaye = async () => {
const getAList = async () => {
const num = +document.querySelector("div.pager > span:nth-child(1)").innerText
.replace(/页次:.+\//g, "")
.trim();
const sid = document.querySelector("div#bookiddata").dataset.sid ||
"";
const api = "https://b.guidaye.com/e/extend/bookpage/pages.php?id=" + sid;
const htm = document.createElement("div");
_log__WEBPACK_IMPORTED_MODULE_0___default().info("[guidaye]" + "作品编号: " + sid + ", 列表页数: " + num);
for (let i = 0; i < num; i++) {
_log__WEBPACK_IMPORTED_MODULE_0___default().info("获取列表:" + i);
const resp = await fetch(api, {
method: "POST",
mode: "cors",
cache: "no-cache",
credentials: "same-origin",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
},
body: "pageNum=" + i,
});
if (!resp.ok) {
_log__WEBPACK_IMPORTED_MODULE_0___default().error("获取列表错误:" + resp.status);
}
const result = (await resp.json());
result.list.forEach((list) => {
const ul = document.createElement("a");
ul.href = list.pic;
ul.innerText = list.title;
htm.appendChild(ul);
return;
});
}
_log__WEBPACK_IMPORTED_MODULE_0___default().info("[guidaye]列表生成完毕");
return htm.querySelectorAll("a");
};
return (0,_template__WEBPACK_IMPORTED_MODULE_1__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("div.book-describe > h1").innerText.trim(),
author: document.querySelector("div.book-describe > p").innerText
.trim()
.replace(/作者:|作品集/g, ""),
introDom: document.querySelector("div.describe-html"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector("div.book-img > img")
.src,
aList: await getAList(),
getContent: (doc) => doc.querySelector("div#nr1"),
contentPatch: (content) => {
return content;
},
});
};
/***/ }),
/***/ "./src/rules/onePage/hongxiuzhao.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
hongxiuzhao: () => (/* binding */ hongxiuzhao)
});
// EXTERNAL MODULE: ./src/rules/onePage/template.ts
var template = __webpack_require__("./src/rules/onePage/template.ts");
// EXTERNAL MODULE: ./src/lib/dom.ts
var lib_dom = __webpack_require__("./src/lib/dom.ts");
;// CONCATENATED MODULE: ./src/rules/lib/hongxiuzhao.ts
const table = {
"\ue2a9": "\u5634",
"\ue2ba": "\u4e0b",
"\ue2bb": "\u5934",
"\ue2d1": "\u4f53",
"\ue321": "\u515a",
"\ue2a5": "\u5165",
"\ue2b4": "\u7c97",
"\ue2c4": "\u63a8",
"\ue316": "\u6237",
"\ue310": "\u9017",
"\ue2a1": "\u5598",
"\ue2a8": "\u8ff7",
"\ue2cd": "\u94bb",
"\ue307": "\u542e",
"\ue30c": "\u7684",
"\ue315": "\u8482",
"\ue298": "\u9053",
"\ue2ca": "\u5e72",
"\ue2ad": "\u803b",
"\ue2ef": "\u817f",
"\ue294": "\u786c",
"\ue2c9": "\u4e73",
"\ue2c5": "\u7cbe",
"\ue2fc": "\u7f69",
"\ue317": "\u80a5",
"\ue309": "\u8131",
"\ue2e4": "\u6f0f",
"\ue320": "\u5171",
"\ue2ae": "\u88f8",
"\ue2b7": "\u6d41",
"\ue2b1": "\u8179",
"\ue313": "\u80c0",
"\ue2b0": "\u81c0",
"\ue2e0": "\u8272",
"\ue2d0": "\u9a9a",
"\ue312": "\u6d1e",
"\ue2c7": "\u54ac",
"\ue2de": "\u6839",
"\ue304": "\u5c3b",
"\ue2a7": "\u7fd8",
"\ue2f0": "\u7231",
"\ue2db": "\u830e",
"\ue2ed": "\u6c9f",
"\ue2a2": "\u7ffb",
"\ue29a": "\u6345",
"\ue2e7": "\u5c3f",
"\ue2d3": "\u638f",
"\ue2b8": "\u6deb",
"\ue2ea": "\u60c5",
"\ue2ce": "\u6f6e",
"\ue2c1": "\u9634",
"\ue2b3": "\u8089",
"\ue2d8": "\u88e4",
"\ue2bc": "\u63d2",
"\ue290": "\u64cd",
"\ue29d": "\u634f",
"\ue322": "\u4e60",
"\ue29c": "\u8eab",
"\ue2d6": "\u53c9",
"\ue30b": "\u53e3",
"\ue2e5": "\u75d2",
"\ue30d": "\u889c",
"\ue2a3": "\u63e1",
"\ue2ff": "\u8f6f",
"\ue2f3": "\u6db2",
"\ue306": "\u4ea4",
"\ue2d9": "\u62d4",
"\ue2dc": "\u4e30",
"\ue301": "\u67d4",
"\ue311": "\u8170",
"\ue303": "\u5439",
"\ue305": "\u7206",
"\ue2ec": "\u8bf1",
"\ue2e2": "\u9f9f",
"\ue2c2": "\u811a",
"\ue2f1": "\u575a",
"\ue2bd": "\u8214",
"\ue2e6": "\u9876",
"\ue30f": "\u5987",
"\ue2b9": "\u5507",
"\ue2bf": "\u5c44",
"\ue2c6": "\u5a9a",
"\ue30a": "\u9732",
"\ue2f7": "\u7a74",
"\ue2ab": "\u6478",
"\ue2c3": "\u5c04",
"\ue30e": "\u547b",
"\ue2ee": "\u543b",
"\ue299": "\u6bdb",
"\ue2f4": "\u5973",
"\ue2fb": "\u64a9",
"\ue2cc": "\u6b32",
"\ue2dd": "\u542b",
"\ue2be": "\u6e29",
"\ue295": "\u5978",
"\ue308": "\u6c34",
"\ue2af": "\u5f04",
"\ue2b2": "\u9e21",
"\ue2da": "\u5149",
"\ue2f8": "\u767d",
"\ue314": "\u554a",
"\ue2e9": "\u52c3",
"\ue2c8": "\u8210",
"\ue291": "\u5ae9",
"\ue29e": "\u82de",
"\ue2b5": "\u80a4",
"\ue2c0": "\u7ea4",
"\ue2f6": "\u5c4c",
"\ue2f9": "\u8dc3",
"\ue2e1": "\u80f8",
"\ue2f5": "\u5c3c",
"\ue2eb": "\u808f",
"\ue2cb": "\u629a",
"\ue2df": "\u6d6a",
"\ue300": "\u871c",
"\ue2d4": "\u6ee1",
"\ue2aa": "\u6252",
"\ue302": "\u6413",
"\ue292": "\u62b1",
"\ue2e8": "\u8361",
"\ue29f": "\u80a1",
"\ue293": "\u63c9",
"\ue2cf": "\u505a",
"\ue29b": "\u50ac",
"\ue2fd": "\u88d9",
"\ue2b6": "\u633a",
"\ue297": "\u5904",
"\ue2fa": "\u5976",
"\ue323": "\u4ea7",
"\ue2e3": "\u836f",
"\ue2d7": "\u6027",
"\ue2a0": "\u63f4",
"\ue2d2": "\u623f",
"\ue2d5": "\u9633",
"\ue2fe": "\u6ed1",
"\ue296": "\u5438",
"\ue2ac": "\u67de",
};
;// CONCATENATED MODULE: ./src/rules/onePage/hongxiuzhao.ts
const hongxiuzhao = () => (0,template/* mkRuleClass */.x)({
bookUrl: document.location.href,
bookname: document
.querySelector(".m-bookdetail div.f-fl > h1")
?.innerText.trim() ?? "",
author: document
.querySelector(".author > a:nth-child(1)")
?.innerText.trim() ?? "",
introDom: document.querySelector(".summery") ?? undefined,
introDomPatch: (dom) => {
(0,lib_dom.rm)("strong", false, dom);
(0,lib_dom.rm)("em", false, dom);
return dom;
},
coverUrl: document.querySelector(".cover > img")?.src,
additionalMetadatePatch: (additionalMetadate) => {
additionalMetadate.tags = Array.from(document.querySelectorAll(".tags > a")).map((a) => a.innerText.trim());
return additionalMetadate;
},
aList: document.querySelectorAll(".m-chapters li > a"),
getContent: (doc) => doc.querySelector(".article-content"),
contentPatch: (content) => {
(0,lib_dom.rm)("mark", true, content);
(0,lib_dom.rm)("h1", true, content);
(0,lib_dom.rm)("ins", true, content);
(0,lib_dom.rm)("script", true, content);
(0,lib_dom.rm)("p[style]", true, content);
(0,lib_dom.rm)('a[href="https://hongxiuzh.com"]', true, content);
for (const k in table) {
content.innerHTML = content.innerHTML.replaceAll(k, table[k]);
}
return content;
},
});
/***/ }),
/***/ "./src/rules/onePage/original/akatsuki.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ akatsuki: () => (/* binding */ akatsuki)
/* harmony export */ });
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const akatsuki = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.origin + document.location.pathname,
bookname: document.querySelector("#LookNovel").innerText.trim(),
author: document.querySelector(".box.story > h3.font-bb:nth-last-of-type(1) > a").innerText.trim(),
introDom: document.querySelector(".box.story.body-normal > .body-normal > div"),
introDomPatch: (dom) => dom,
coverUrl: document.querySelector("div.font-bb > center > img")
?.src ?? null,
aList: document.querySelectorAll("table.list td > a"),
sections: document.querySelectorAll("table.list td[colspan] > b"),
getSName: (sElem) => sElem.innerText.trim(),
getContent: (doc) => {
doc.querySelectorAll("center > img").forEach((img) => {
const parent = img.parentElement;
parent?.replaceWith(img);
});
const contentRaw = document.createElement("div");
const nodes = Array.from(doc.querySelectorAll(".body-novel, .body-novel + hr"));
if (nodes.length > 1) {
const previous = nodes[0].previousElementSibling;
if (previous?.nodeName.toLowerCase() === "div") {
nodes.unshift(previous);
}
}
for (const node of nodes) {
if (node instanceof HTMLDivElement && node.className === "body-novel") {
contentRaw.appendChild((0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_1__/* .convertBr */ .Q3)(node, true));
}
else {
contentRaw.appendChild(node);
}
}
return contentRaw;
},
contentPatch: (content) => content,
concurrencyLimit: 2,
language: "ja",
});
/***/ }),
/***/ "./src/rules/onePage/original/alphapolis.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ alphapolis: () => (/* binding */ alphapolis)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const alphapolis = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("h2.title").innerText.trim(),
author: document.querySelector("div.author > span:nth-child(1) > a:nth-child(1)").innerText.trim(),
introDom: document.querySelector(".abstract"),
introDomPatch: (dom) => dom,
coverUrl: document.querySelector("div.cover > a > img")
?.src ?? null,
additionalMetadatePatch: (additionalMetadate) => {
additionalMetadate.tags = Array.from(document.querySelectorAll(".content-tags > .tag > a")).map((a) => a.innerText.trim());
return additionalMetadate;
},
aList: document.querySelectorAll(".episodes > .episode > a"),
getAName: (aElem) => aElem.querySelector(".title")?.innerText.trim(),
sections: document.querySelectorAll(".episodes > h3"),
getSName: (sElem) => sElem.innerText.trim(),
getContent: (doc) => doc.querySelector("#novelBoby"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .insertBrBeforeText */ .DF)(content);
return content;
},
language: "ja",
});
/***/ }),
/***/ "./src/rules/onePage/original/houhuayuan.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ houhuayuan: () => (/* binding */ houhuayuan)
/* harmony export */ });
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const houhuayuan = () => {
const seriesbox = document.querySelector(".seriesbox");
let bookUrl;
let bookname;
let author = document.querySelector("h3.author")?.innerText
.replace(/♥|作者: /g, "")
.trim();
if (author === "") {
author = "佚名";
}
const aList = [];
if (seriesbox) {
const lis = seriesbox.querySelectorAll("ul.serieslist-ul > li");
for (const li of Array.from(lis)) {
if (li.className === "serieslist-li") {
const a = li.querySelector("a");
if (a) {
aList.push(a);
}
}
else if (li.className === "serieslist-li-current") {
const a = document.createElement("a");
a.innerText = document.querySelector(".entry-title").innerText.trim();
a.href = document.location.href;
aList.push(a);
}
}
const aFirst = aList[0];
bookname = aFirst.innerText
.replace(/第.+章$|\s序$/, "")
.trim();
bookUrl = aFirst.href;
}
else {
bookUrl = document.location.href;
bookname = document.querySelector(".entry-title").innerText.trim();
const a = document.createElement("a");
a.innerText = bookname;
a.href = bookUrl;
aList.push(a);
}
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl,
bookname,
author,
aList,
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
const pageLinks = doc.querySelectorAll(".page-links > a.post-page-numbers");
if (pageLinks) {
const content = document.createElement("div");
const _content0 = doc.querySelector("header + div.entry-content");
if (_content0) {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .childNodesCopy */ .vR)(_content0, content);
}
const pageUrls = Array.from(pageLinks).map((a) => a.href);
for (const url of pageUrls) {
const docc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(url, charset);
const _content1 = docc.querySelector("header + div.entry-content");
if (_content1) {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .childNodesCopy */ .vR)(_content1, content);
}
}
return content;
}
else {
return doc.querySelector("header + div.entry-content");
}
},
contentPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)('div[id^="stage-"]', true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)('div[id^="zhaoz-"]', true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("div.seriesbox", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("fieldset", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("div.wpulike", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)(".simplefavorite-button", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)(".page-links", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .rm2 */ .vS)([" – 蔷薇后花园", " – 黑沼泽俱乐部"], dom);
Array.from(dom.querySelectorAll("img")).forEach((img) => (img.src = img.getAttribute("data-src") ?? ""));
return dom;
},
nsfw: true,
});
};
/***/ }),
/***/ "./src/rules/onePage/original/kakuyomu.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ kakuyomu: () => (/* binding */ kakuyomu)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const kakuyomu = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("#workTitle > a").innerText.trim(),
author: document.querySelector("#workAuthor-activityName > a").innerText.trim(),
introDom: document.querySelector("#introduction"),
introDomPatch: (dom) => dom,
coverUrl: null,
additionalMetadatePatch: (additionalMetadate) => {
additionalMetadate.tags = Array.from(document.querySelectorAll("#workMeta-tags > li > a")).map((a) => a.innerText);
return additionalMetadate;
},
aList: document.querySelectorAll("li.widget-toc-episode > a"),
getAName: (dom) => dom.querySelector("span.widget-toc-episode-titleLabel").innerText.trim(),
sections: document.querySelectorAll("li.widget-toc-chapter > span"),
getSName: (dom) => dom.innerText.trim(),
getContent: (dom) => dom.querySelector(".widget-episodeBody"),
contentPatch: (dom) => dom,
language: "ja",
});
/***/ }),
/***/ "./src/rules/onePage/original/masiro.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ masiro: () => (/* binding */ masiro)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const masiro = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".novel-title").innerText.trim(),
author: document.querySelector(".author > a").innerText.trim(),
introDom: document.querySelector(".brief"),
introDomPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)(["简介:"], dom);
return dom;
},
coverUrl: document.querySelector("div.mailbox-attachment-icon > a > img.img").src,
additionalMetadatePatch: (additionalMetadate) => {
additionalMetadate.tags = Array.from(document.querySelectorAll("div.n-detail > div.tags a")).map((a) => a.innerText);
return additionalMetadate;
},
aList: document.querySelectorAll("a.to-read"),
getAName: (aElem) => aElem.querySelector('span[style^="overflow: hidden;"]').innerText.trim(),
getIsVIP: (aElem) => {
let isVIP = false;
let isPaid = false;
const small = aElem.querySelector("small");
if (small) {
const text = small.innerText.trim();
if (text !== "") {
isVIP = true;
if (text === "已购") {
isPaid = true;
}
}
}
return { isVIP, isPaid };
},
sections: document.querySelectorAll("li.chapter-box > span + b"),
getSName: (dom) => dom.innerText.trim(),
getContent: (dom) => dom.querySelector("div.box-body.nvl-content"),
contentPatch: (dom) => dom,
concurrencyLimit: 3,
needLogin: true,
});
/***/ }),
/***/ "./src/rules/onePage/original/syosetu.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ syosetu: () => (/* binding */ syosetu),
/* harmony export */ syosetuOrg: () => (/* binding */ syosetuOrg)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const syosetu = () => {
const getIntroDom = () => {
const a = document.querySelector("#novel_ex > .more");
if (a) {
a.click();
}
return document.querySelector("#novel_ex");
};
const getAList = () => {
const _aList = document.querySelectorAll("dl.novel_sublist2 dd.subtitle > a");
if (_aList.length !== 0) {
return _aList;
}
else {
const a = document.createElement("a");
a.href = document.location.href;
a.innerText = document.querySelector(".novel_title")?.innerText;
return [a];
}
};
const getNsfw = () => {
const host = document.location.host;
return host === "novel18.syosetu.com";
};
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".novel_title").innerText.trim(),
author: document.querySelector(".novel_writername > a, .novel_writername").innerText
.replace("作者:", "")
.trim(),
introDom: getIntroDom(),
introDomPatch: (dom) => dom,
coverUrl: null,
aList: getAList(),
sections: document.querySelectorAll("div.chapter_title"),
getSName: (dom) => dom.innerText.trim(),
getContent: (dom) => {
const content = document.createElement("div");
const novelP = dom.querySelector("#novel_p");
const novelHonbun = dom.querySelector("#novel_honbun");
const novelA = dom.querySelector("#novel_a");
if (novelP) {
content.appendChild(novelP);
const hr = dom.createElement("hr");
content.appendChild(hr);
}
if (novelHonbun) {
content.appendChild(novelHonbun);
}
if (novelA) {
const hr = dom.createElement("hr");
content.appendChild(hr);
content.appendChild(novelA);
}
return content;
},
contentPatch: (dom) => dom,
nsfw: getNsfw(),
needLogin: getNsfw(),
language: "ja",
});
};
const syosetuOrg = () => {
const getAList = () => {
const _aList = document.querySelectorAll('tr[class^="bgcolor"] > td > a');
if (_aList.length !== 0) {
return _aList;
}
else {
const a = document.createElement("a");
a.href = document.location.href;
a.innerText = document.querySelector("div.ss:nth-child(1) > p:nth-child(1) > span:nth-child(1) > a:nth-child(1)")?.innerText;
return [a];
}
};
const aList = getAList();
const getIntroDom = () => {
if (aList.length === 1 &&
aList[0].href === document.location.href) {
return undefined;
}
return document.querySelector("div.ss:nth-child(2)");
};
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector('div.ss > span[itemprop="name"], div.ss:nth-child(1) > p:nth-child(1) > span:nth-child(1) > a:nth-child(1)').innerText.trim(),
author: document.querySelector('div.ss span[itemprop="author"] > a, div.ss:nth-child(1) > p:nth-child(1) > a:nth-child(2)')?.innerText.trim(),
introDom: getIntroDom(),
introDomPatch: (dom) => dom,
coverUrl: null,
additionalMetadatePatch: (additionalMetadate) => {
additionalMetadate.tags = Array.from(document.querySelectorAll('span[itemprop="keywords"] > a, a.alert_color')).map((a) => a.innerText);
return additionalMetadate;
},
aList,
sections: document.querySelectorAll('div.ss > table > tbody > tr > td[colspan="2"] > strong'),
getSName: (dom) => dom.innerText.trim(),
getContent: (doc) => {
if (aList.length === 1 &&
aList[0].href === document.location.href) {
return doc.querySelector("div#maind > div.ss:nth-child(2)");
}
return doc.querySelector("div#maind > div.ss:nth-child(1)");
},
contentPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("p:nth-child(1)", false, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div.novelnavi", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)('div[style*="text-align:right;"]', true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div#maegaki_open", true, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div#atogaki_open", true, dom);
dom.querySelectorAll('a[name="img"]').forEach((a) => {
const img = document.createElement("img");
img.src = a.href;
img.alt = a.innerText;
a.replaceWith(img);
});
return dom;
},
language: "ja",
});
};
/***/ }),
/***/ "./src/rules/onePage/qbtrcc.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ qbtrcc: () => (/* binding */ qbtrcc)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const qbtrcc = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("div.infos > h1").innerText.trim(),
author: document.querySelector("div.infos > div.date > span").innerText.replace("作者:", "").trim(),
introDom: document.querySelector("div.infos > p"),
introDomPatch: (introDom) => introDom,
coverUrl: "https://www.qbtr.cc/skin/default/images/bbb2.png",
aList: document.querySelectorAll("ul.clearfix > li > a"),
getContent: (doc) => doc.querySelector("div.read_chapterDetail"),
contentPatch: (content) => content,
});
/***/ }),
/***/ "./src/rules/onePage/qzxsw.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ qzxsw: () => (/* binding */ qzxsw)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const qzxsw = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("div.introduce > h1").innerText.trim(),
author: document.querySelector("div.introduce > p.bq > span:nth-child(2) > a").innerText.trim(),
introDom: document.querySelector("div.introduce > p.jj"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector("div.pic > img").src,
aList: document.querySelectorAll("div.ml_list > ul > li > a"),
getContent: (doc) => doc.querySelector(".articlecontent"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)([
"一秒记住m.quanzhifashi。com",
"m.quanzhifashi.com",
"http://m.quanzhifashi.com首发"
], content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("br", true, content);
return content;
},
});
/***/ }),
/***/ "./src/rules/onePage/soxscc.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ soxscc: () => (/* binding */ soxscc)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
const soxscc = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".xiaoshuo > h1").innerText.trim(),
author: document.querySelector(".xiaoshuo > h6:nth-child(3) > a").innerText.trim(),
introDom: document.querySelector("#intro"),
introDomPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("span.tags", false, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("q", true, dom);
return dom;
},
coverUrl: document.querySelector(".book_cover > img")
.src,
aList: document.querySelectorAll("div.novel_list[id] dd > a"),
sections: document.querySelectorAll("div.novel_list[id] dl > dt:nth-child(1) > b:nth-child(1)"),
getSName: (sElem) => sElem.innerText.trim(),
getContent: (doc) => doc.querySelector("div.content[id]"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rm2 */ .vS)([
"最新章节地址:",
"全文阅读地址:",
"txt下载地址:",
"手机阅读:",
'为了方便下次阅读,你可以点击下方的"收藏"记录本次',
"请向你的朋友(QQ、博客、微信等方式)推荐本书",
"您可以在百度里搜索",
], content);
return content;
},
});
/***/ }),
/***/ "./src/rules/onePage/template.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ x: () => (/* binding */ mkRuleClass)
/* harmony export */ });
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules.ts");
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/main/main.ts");
function mkRuleClass({ bookUrl, bookname, author, introDom, introDomPatch, coverUrl, additionalMetadatePatch, aList, getAName, getIsVIP, sections, getSName, postHook, getContentFromUrl, getContent, contentPatch, concurrencyLimit, needLogin, nsfw, cleanDomOptions, overrideConstructor, language, }) {
return class extends _rules__WEBPACK_IMPORTED_MODULE_0__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
if (concurrencyLimit) {
this.concurrencyLimit = concurrencyLimit;
}
if (needLogin) {
this.needLogin = needLogin;
}
if (nsfw) {
this.nsfw = nsfw;
}
if (overrideConstructor) {
overrideConstructor(this);
}
}
async bookParse() {
let introduction = null;
let introductionHTML = null;
if (introDom && introDomPatch) {
[introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_1__/* .introDomHandle */ .SN)(introDom, introDomPatch);
}
const additionalMetadate = {
language: language ?? "zh",
};
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_2__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_3___default().error(error));
}
if (additionalMetadatePatch) {
Object.assign(additionalMetadate, additionalMetadatePatch(additionalMetadate));
}
const chapters = [];
let chapterNumber = 0;
let sectionNumber = 0;
let sectionChapterNumber = 0;
let sectionName = null;
let hasSection = false;
if (sections &&
sections instanceof NodeList &&
typeof getSName === "function") {
hasSection = true;
}
for (const aElem of Array.from(aList)) {
let chapterName;
if (getAName) {
chapterName = getAName(aElem);
}
else {
chapterName = aElem.innerText.trim();
}
const chapterUrl = aElem.href;
if (hasSection && sections && getSName) {
const _sectionName = (0,_lib_rule__WEBPACK_IMPORTED_MODULE_1__/* .getSectionName */ .$d)(aElem, sections, getSName);
if (_sectionName !== sectionName) {
sectionName = _sectionName;
sectionNumber++;
sectionChapterNumber = 0;
}
}
chapterNumber++;
sectionChapterNumber++;
let isVIP = false;
let isPaid = false;
if (getIsVIP) {
({ isVIP, isPaid } = getIsVIP(aElem));
}
let chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_4__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP,
isPaid,
sectionName,
sectionNumber: hasSection ? sectionNumber : null,
sectionChapterNumber: hasSection ? sectionChapterNumber : null,
chapterParse: this.chapterParse,
charset: this.charset,
options: { bookname },
});
if (isVIP && !isPaid) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_5__/* .Status */ .qb.aborted;
}
if (typeof postHook === "function") {
chapter = postHook(chapter);
}
if (chapter) {
chapters.push(chapter);
}
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_6__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
let content;
if (typeof getContentFromUrl === "function") {
content = await getContentFromUrl(chapterUrl, chapterName, charset);
}
else if (typeof getContent === "function") {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_7__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
content = getContent(doc);
}
else {
throw Error("未发现 getContentFromUrl 或 getContent");
}
if (content) {
content = contentPatch(content);
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_8__/* .cleanDOM */ .zM)(content, "TM", cleanDomOptions);
return {
chapterName,
contentRaw: content,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
}
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
};
}
/***/ }),
/***/ "./src/rules/onePage/tianyabooks.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ tianyabooks: () => (/* binding */ tianyabooks)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const tianyabooks = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".book > h1")?.innerText
.replace(/[《》]/g, "")
.trim(),
author: document.querySelector(".book > h2 > a").innerText.trim(),
introDom: document.querySelector(".description"),
introDomPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("h3", false, dom);
return dom;
},
coverUrl: null,
aList: document.querySelectorAll(".book > dl > dd > a"),
sections: document.querySelectorAll(".book > dl > dt"),
getSName: (dom) => dom.innerText.trim(),
getContent: (doc) => doc.querySelector("#main"),
contentPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div.crumb", false, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("h1", false, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)('p[align="center"]', false, dom);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("table", true, dom);
return dom;
},
});
/***/ }),
/***/ "./src/rules/onePage/trxs.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ trxs: () => (/* binding */ trxs)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const trxs = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".infos > h1").innerText
.split("(")[0]
.trim(),
author: document.querySelector(".date > span > a, .date > span").innerText
.replace("作者:", "")
.trim(),
introDom: document.querySelector(".infos > p"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector(".pic > img").src,
aList: document.querySelectorAll("div.book_list > ul.clearfix > li > a"),
getContent: (doc) => doc.querySelector(".read_chapterDetail"),
contentPatch: (content) => content,
});
/***/ }),
/***/ "./src/rules/onePage/uukanshu.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ uukanshu: () => (/* binding */ uukanshu)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
const uukanshu = () => {
const button = document.querySelector('span[onclick="javascript:reverse(this);"]');
const reverse = unsafeWindow.reverse;
if (button.innerText === "顺序排列") {
reverse(button);
}
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("dd.jieshao_content > h1 > a").innerText
.replace("最新章节", "")
.trim(),
author: document.querySelector("dd.jieshao_content > h2 > a").innerText.trim(),
introDom: document.querySelector("dd.jieshao_content > h3"),
introDomPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)([
/^.+简介:\s+www\.uukanshu\.com\s+/,
/\s+https:\/\/www\.uukanshu\.com/,
/-+/,
], dom);
return dom;
},
coverUrl: document.querySelector("a.bookImg > img")
.src,
aList: document.querySelectorAll("#chapterList > li > a"),
sections: document.querySelectorAll("#chapterList > li.volume"),
getSName: (sElem) => sElem.innerText.trim(),
getContent: (doc) => doc.querySelector("#contentbox"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)(".ad_content", true, content);
const adReplace = [
/[UuUu]+看书\s*[ww]+.[UuUu]+[kk][aa][nn][ss][hh][UuUu].[nn][ee][tt]/g,
/[UuUu]+看书\s*[ww]+.[UuUu]+[kk][aa][nn][ss][hh][UuUu].[cCc][oOo][mMm]/g,
/[UU]*看书[(\\(].*?[)\\)]文字首发。/,
/请记住本书首发域名:。?/g,
/笔趣阁手机版阅读网址:/g,
/小说网手机版阅读网址:/g,
/https:\/\//g,
/http:\/\//g,
/UU看书\s+欢迎广大书友光临阅读,最新、最快、最火的连载作品尽在UU看书!UU看书。;?/g,
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .rms */ .up)(adReplace, content);
return content;
},
});
};
/***/ }),
/***/ "./src/rules/onePage/wanben.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ wanben: () => (/* binding */ wanben)
/* harmony export */ });
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const wanben = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".detailTitle > h1").innerText.trim(),
author: document.querySelector(".writer > a").innerText.trim(),
introDom: document.querySelector(".detailTopMid > table:nth-child(3) > tbody:nth-child(1) > tr:nth-child(3) > td:nth-child(2)"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector(".detailTopLeft > img")?.src,
aList: document.querySelectorAll(".chapter li > a"),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_1__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: "div.readerCon",
contentPatch: (content, doc) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("div[style]", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("a", true, content);
const ads = [
"【提示】:如果觉得此文不错,请推荐给更多小伙伴吧!分享也是一种享受。",
"【看书助手】",
"百万热门书籍终身无广告免费阅读",
"【完本神站】",
"一秒记住、永不丢失!"
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .rm2 */ .vS)(ads, content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_3__/* .htmlTrim */ .iA)(content);
return content;
},
getNextPage: (doc) => doc.querySelector(".readPage > a:nth-child(3)")
.href,
continueCondition: (_content, nextLink) => {
const pathname = nextLink.split("/").slice(-1)[0];
return pathname.includes("_");
},
enableCleanDOM: false,
});
return contentRaw;
},
contentPatch: (content) => content,
});
/***/ }),
/***/ "./src/rules/onePage/westnovel.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ westnovel: () => (/* binding */ westnovel)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const westnovel = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector(".btitle > h1 > a").innerText.trim(),
author: document.querySelector(".btitle > em:nth-child(2)").innerText
.replace("作者:", "")
.trim(),
introDom: document.querySelector(".intro-p > p:nth-child(1)"),
introDomPatch: (introDom) => introDom,
coverUrl: document.querySelector(".img-img")?.src,
aList: document.querySelectorAll(".chapterlist > dd > a"),
getContent: (doc) => doc.querySelector("#BookText"),
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div.ads", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("div.link", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__.rm)("h4", true, content);
return content;
},
});
/***/ }),
/***/ "./src/rules/onePage/xbyuan.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ xbyuan: () => (/* binding */ xbyuan)
/* harmony export */ });
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePage/template.ts");
const $ = (selector) => document.querySelector(selector);
const $$ = (selector) => document.querySelectorAll(selector);
const xbyuan = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: location.href,
bookname: $("#info h1").innerText.trim(),
author: $("#info .small > span").innerText.trim(),
introDom: $("#intro > p"),
introDomPatch: (_) => _,
coverUrl: $("#fmimg img").src,
aList: $$("#list dl")[1].querySelectorAll("a"),
async getContentFromUrl(chapterUrl, chapterName, charset) {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_1__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: "#nr_content > p",
contentPatch(content, doc) {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__.rm)("a", true, content);
const ads = [
"精华书阁",
"最新章节!",
"最快更新,为了您下次还能查看到本书的最快更新,请务必保存好书签!",
"https://www.xbyuan.com",
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .rm2 */ .vS)(ads, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .rms */ .up)(["(本章未完,请点击下一页继续阅读)"], content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_3__/* .htmlTrim */ .iA)(content);
return content;
},
getNextPage(doc) {
return doc.querySelector("#nexturl").href;
},
continueCondition(content, nextLink) {
const pathname = nextLink.split("/").slice(-1)[0];
return pathname.includes("_");
},
});
return contentRaw;
},
contentPatch: (content) => {
content.innerHTML = content.innerHTML
.replaceAll("「", "“")
.replaceAll("」", "”");
return content;
},
});
/***/ }),
/***/ "./src/rules/onePageWithMultiIndexPage/baihexs.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ baihexs: () => (/* binding */ baihexs)
/* harmony export */ });
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePageWithMultiIndexPage/template.ts");
const baihexs = () => {
const bookUrl = document.location.href;
const bookId = /(\d+)\/?$/.exec(document.location.href)?.[1];
if (!bookId) {
throw Error("获取书籍信息出错!");
}
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl,
bookname: document.querySelector(".block_txt2 > h2 > a").innerText.trim(),
author: document.querySelector(".block_txt2 > p:nth-child(4)").innerText
.replace("作者:", "")
.trim(),
introDom: document.querySelector(".intro_info"),
introDomPatch: (dom) => dom,
coverUrl: document.querySelector(".block_img2 > img")
?.src,
getIndexUrls: async () => {
const contentPageUrl = `${document.location.origin}/wapbook-${bookId}`;
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(contentPageUrl + "/", document.characterSet);
const a = doc.querySelector("div.page > a:nth-last-child(1)");
const maxNumber = /(\d+)\/?$/.exec(a.href)?.[1];
if (!maxNumber) {
throw Error("获取章节列表时出错!");
}
const indexUrls = [];
for (let i = 1; i <= parseInt(maxNumber, 10); i++) {
const url = contentPageUrl + `_${i}/`;
indexUrls.push(url);
}
return indexUrls;
},
getAList: (doc) => doc.querySelectorAll(".chapter > li > a"),
getContent: (doc) => doc.querySelector("#nr1"),
contentPatch: (dom) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_2__/* .rm2 */ .vS)(["请您牢记:百合小说网"], dom);
return dom;
},
concurrencyLimit: 3,
});
};
/***/ }),
/***/ "./src/rules/onePageWithMultiIndexPage/original/novelup.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ novelup: () => (/* binding */ novelup)
/* harmony export */ });
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePageWithMultiIndexPage/template.ts");
const novelup = () => {
const bookUrl = document.location.origin + document.location.pathname;
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl,
bookname: document.querySelector("#section_episode_info_table > div:nth-child(2) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(2)").innerText.trim(),
author: document.querySelector("#section_episode_info_table > div:nth-child(2) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > a:nth-child(1)").innerText.trim(),
introDom: document.querySelector(".novel_synopsis"),
introDomPatch: (dom) => {
Array.from(dom.querySelectorAll("p")).forEach((p) => {
const div = document.createElement("div");
div.innerHTML = p.innerHTML.split("\n").join("
");
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .insertBrBeforeText */ .DF)(div);
p.replaceWith(div);
});
return dom;
},
coverUrl: document.querySelector(".novel_cover img")?.src ??
null,
getIndexPages: async () => {
const indexPages = [];
let nextUrl = bookUrl;
do {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_2__/* .getHtmlDOM */ .dL)(nextUrl);
indexPages.push(doc);
nextUrl =
doc.querySelector("div.move_set:nth-child(4) > div:nth-child(3) > a")?.href ?? null;
} while (nextUrl);
return indexPages;
},
getAList: (doc) => doc.querySelectorAll(".episode_list li > .episode_link > a"),
getSections: (doc) => doc.querySelectorAll(".episode_list li.chapter"),
getSName: (sElem) => sElem.querySelector("cite")?.innerText.trim() ?? "",
getContent: (doc) => doc.querySelector(".content"),
contentPatch: (content) => {
Array.from(content.querySelectorAll("p")).forEach((p) => {
const div = document.createElement("div");
div.innerHTML = p.innerHTML.split("\n").join("
");
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_1__/* .insertBrBeforeText */ .DF)(div);
p.replaceWith(div);
});
return content;
},
language: "ja",
});
};
/***/ }),
/***/ "./src/rules/onePageWithMultiIndexPage/ptwxz.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ ptwxz: () => (/* binding */ ptwxz)
/* harmony export */ });
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePageWithMultiIndexPage/template.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/dom.ts");
const ptwxz = () => (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document
.querySelector("#info h1")
?.innerText.trim() ?? "",
author: document
.querySelector("#info > p:nth-child(2) > a:nth-child(1)")
?.innerText.trim() ?? "",
introDom: document.querySelector("#intro") ?? undefined,
introDomPatch: (dom) => dom,
coverUrl: document.querySelector("#fmimg > img")?.src ?? null,
getIndexUrls: async () => {
const base = document.location.pathname;
const listUrlBase = document.location.origin + "/list" + base;
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(listUrlBase, document.characterSet);
return Array.from(doc.querySelectorAll("#indexselect > option")).map((o) => document.location.origin + o.getAttribute("value"));
},
getAList: (doc) => doc.querySelectorAll('a[rel="chapter"]'),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: "#booktxt",
contentPatch: (content) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__/* .rm2 */ .vS)(["本章未完,點選下一頁繼續閱讀。"], content);
return content;
},
getNextPage: (doc) => doc.querySelector("#next_url")?.href ?? "",
continueCondition: (content, nextLink) => {
if (nextLink === "") {
return false;
}
return nextLink.includes("_");
},
enableCleanDOM: false,
});
return contentRaw;
},
contentPatch: (dom) => dom,
});
/***/ }),
/***/ "./src/rules/onePageWithMultiIndexPage/template.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ x: () => (/* binding */ mkRuleClass)
/* harmony export */ });
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_misc__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/misc.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules.ts");
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/main/main.ts");
function mkRuleClass({ bookUrl, bookname, author, introDom, introDomPatch, coverUrl, getIndexUrls, getIndexPages, getAList, getAName, getIsVIP, getSections, getSName, postHook, getContentFromUrl, getContent, contentPatch, concurrencyLimit, needLogin, nsfw, cleanDomOptions, overrideConstructor, language, }) {
return class extends _rules__WEBPACK_IMPORTED_MODULE_0__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
if (concurrencyLimit) {
this.concurrencyLimit = concurrencyLimit;
}
if (needLogin) {
this.needLogin = needLogin;
}
if (nsfw) {
this.nsfw = nsfw;
}
if (overrideConstructor) {
overrideConstructor(this);
}
}
async bookParse() {
let [introduction, introductionHTML] = [null, null];
if (introDom && introDomPatch) {
[introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_1__/* .introDomHandle */ .SN)(introDom, introDomPatch);
}
const additionalMetadate = {
language: language ?? "zh",
};
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_2__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_3___default().error(error));
}
let indexPages;
if (typeof getIndexPages === "function") {
indexPages = await getIndexPages();
}
else if (typeof getIndexUrls === "function") {
const indexUrls = await getIndexUrls();
const _indexPage = [];
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_4__/* .concurrencyRun */ .C1)(indexUrls, this.concurrencyLimit, async (url) => {
_log__WEBPACK_IMPORTED_MODULE_3___default().info(`[BookParse]抓取目录页:${url}`);
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_5__/* .getHtmlDomWithRetry */ .rf)(url, this.charset);
_indexPage.push([doc, url]);
return doc;
});
indexPages = _indexPage
.sort((a, b) => {
const aUrl = a[1];
const bUrl = b[1];
return indexUrls.indexOf(aUrl) - indexUrls.indexOf(bUrl);
})
.map((l) => l[0]);
}
else {
throw Error("未发现 getIndexUrls 或 getIndexPages");
}
const chapters = [];
let chapterNumber = 0;
let sectionNumber = 0;
let sectionChapterNumber = 0;
let sectionName = null;
for (const doc of indexPages) {
if (!doc) {
continue;
}
let sections;
let hasSection;
if (typeof getSections === "function") {
sections = getSections(doc);
hasSection = true;
}
const aList = getAList(doc);
for (const aElem of Array.from(aList)) {
let chapterName;
if (getAName) {
chapterName = getAName(aElem);
}
else {
chapterName = aElem.innerText.trim();
}
const chapterUrl = aElem.href;
if (hasSection && sections && getSName) {
const _sectionName = (0,_lib_rule__WEBPACK_IMPORTED_MODULE_1__/* .getSectionName */ .$d)(aElem, sections, getSName);
if (_sectionName !== null && _sectionName !== sectionName) {
sectionName = _sectionName;
sectionNumber++;
sectionChapterNumber = 0;
}
}
chapterNumber++;
sectionChapterNumber++;
let isVIP = false;
let isPaid = false;
if (getIsVIP) {
({ isVIP, isPaid } = getIsVIP(aElem));
}
let chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_6__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP,
isPaid,
sectionName,
sectionNumber: hasSection ? sectionNumber : null,
sectionChapterNumber: hasSection ? sectionChapterNumber : null,
chapterParse: this.chapterParse,
charset: this.charset,
options: { bookname },
});
if (isVIP && !isPaid) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_7__/* .Status */ .qb.aborted;
}
if (typeof postHook === "function") {
chapter = postHook(chapter);
}
if (chapter) {
chapters.push(chapter);
}
}
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_8__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
let content;
if (typeof getContentFromUrl === "function") {
content = await getContentFromUrl(chapterUrl, chapterName, charset);
}
else if (typeof getContent === "function") {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_5__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
content = getContent(doc);
}
else {
throw Error("未发现 getContentFromUrl 或 getContent");
}
if (content) {
content = contentPatch(content);
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_9__/* .cleanDOM */ .zM)(content, "TM", cleanDomOptions);
return {
chapterName,
contentRaw: content,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
}
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
};
}
/***/ }),
/***/ "./src/rules/onePageWithMultiIndexPage/wanben.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ wanben: () => (/* binding */ wanben)
/* harmony export */ });
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _template__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules/onePageWithMultiIndexPage/template.ts");
const wanben = () => {
const getIntroDom = () => {
const a = document.querySelector(".bookInfo > a");
if (a) {
a.click();
a.remove();
}
return document.querySelector(".bookInfo");
};
return (0,_template__WEBPACK_IMPORTED_MODULE_0__/* .mkRuleClass */ .x)({
bookUrl: document.location.href,
bookname: document.querySelector("div.bookPhr > h2").innerText.trim(),
author: document.querySelector("div.bookPhrMid > p:nth-child(1)").innerText
.replace("作者:", "")
.trim(),
introDom: getIntroDom(),
introDomPatch: (dom) => dom,
coverUrl: document.querySelector("div.bookImg > img")
?.src,
getIndexUrls: async () => {
const contentPageUrl = document.querySelector("#contentbox > div.detailDiv > div.category > a").href;
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(contentPageUrl, document.characterSet);
const aList = doc.querySelectorAll("div.pageBg div.pagenum a");
const indexUrls = Array.from(aList).map((a) => a.href);
return indexUrls;
},
getAList: (doc) => doc.querySelectorAll("div.chapterDiv > div.chapterList > ul > a"),
getContentFromUrl: async (chapterUrl, chapterName, charset) => {
const { contentRaw } = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .nextPageParse */ .I2)({
chapterName,
chapterUrl,
charset,
selector: "div.raderCon",
contentPatch: (content, doc) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__.rm)("script", true, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__.rm)("[style]", true, content);
const ads = [
"【提示】:如果觉得此文不错,请推荐给更多小伙伴吧!分享也是一种享受。",
"【看书助手】",
"【完本神站】",
"百万热门书籍终身无广告免费阅读",
];
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__/* .rm2 */ .vS)(ads, content);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_4__/* .htmlTrim */ .iA)(content);
return content;
},
getNextPage: (doc) => doc.querySelector("div.page > a:nth-child(3)")
.href,
continueCondition: (_content, nextLink) => {
const pathname = nextLink.split("/").slice(-1)[0];
return pathname.includes("_");
},
enableCleanDOM: false,
});
return contentRaw;
},
contentPatch: (dom) => dom,
});
};
/***/ }),
/***/ "./src/rules/special/original/17k.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ C17k: () => (/* binding */ C17k)
/* harmony export */ });
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/main.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules.ts");
class C17k extends _rules__WEBPACK_IMPORTED_MODULE_0__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
this.charset = "UTF-8";
this.concurrencyLimit = 5;
}
async bookParse() {
const bookUrl = document.location.href.replace("/list/", "/book/");
const bookname = document.querySelector("h1.Title").innerText.trim();
const author = document.querySelector("div.Author > a").innerText.trim();
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(bookUrl, undefined);
const introDom = doc.querySelector("#bookInfo p.intro > a");
const [introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .introDomHandle */ .SN)(introDom);
const additionalMetadate = {};
const coverUrl = doc.querySelector("#bookCover img.book").src;
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_3__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_4___default().error(error));
}
const chapters = [];
const sections = document.querySelectorAll("dl.Volume");
let chapterNumber = 0;
for (let i = 0; i < sections.length; i++) {
const s = sections[i];
const sectionNumber = i + 1;
const sectionName = s.querySelector("dt > span.tit").innerText.trim();
let sectionChapterNumber = 0;
const cs = s.querySelectorAll("dd > a");
for (const a of Array.from(cs)) {
const span = a.firstElementChild;
chapterNumber++;
sectionChapterNumber++;
const chapterName = span.innerText.trim();
const chapterUrl = a.href;
const isVIP = () => {
return !!span?.className.includes("vip");
};
const isPaid = () => {
return false;
};
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_5__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP: isVIP(),
isPaid: isPaid(),
sectionName,
sectionNumber,
sectionChapterNumber,
chapterParse: this.chapterParse,
charset: this.charset,
options: {},
});
const isLogin = () => {
return false;
};
if (isVIP() && !(isLogin() && chapter.isPaid)) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_6__/* .Status */ .qb.aborted;
}
chapters.push(chapter);
}
}
const book = new _main_Book__WEBPACK_IMPORTED_MODULE_7__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
book.ToCUrl = document.location.href;
return book;
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
async function publicChapter() {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
chapterName = doc.querySelector("#readArea > div.readAreaBox.content > h1").innerText.trim();
const content = doc.querySelector("#readArea > div.readAreaBox.content > div.p");
if (content) {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_8__.rm)("p.copy", false, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_8__.rm)("#banner_content", false, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_8__.rm)("div.qrcode", false, content);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_8__.rm)("div.chapter_text_ad", false, content);
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_9__/* .cleanDOM */ .zM)(content, "TM");
return {
chapterName,
contentRaw: content,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
}
else {
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
}
async function vipChapter() {
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
if (isVIP) {
return vipChapter();
}
else {
return publicChapter();
}
}
}
/***/ }),
/***/ "./src/rules/special/original/bilibili.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ MangaBilibili: () => (/* binding */ MangaBilibili)
/* harmony export */ });
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_misc__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/lib/misc.ts");
/* harmony import */ var _lib_hash__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/lib/hash.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _main_Attachment__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/main/Attachment.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/main/main.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules.ts");
class MangaBilibili extends _rules__WEBPACK_IMPORTED_MODULE_0__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "naive";
this.concurrencyLimit = 1;
this.streamZip = true;
}
async bookParse() {
const _comic_id = /\/mc(\d+)$/.exec(document.location.pathname)?.[1];
if (!_comic_id) {
throw new Error("获取 comic_id 失败!");
}
const comic_id = parseInt(_comic_id);
const signIn = await isSignin(comic_id);
const detail = await getDetail(comic_id);
const bookUrl = document.location.href;
const bookname = detail.title;
const author = detail.author_name.join(", ");
const introduction = detail.evaluate;
const introductionHTML = document.createElement("div");
introductionHTML.innerText = detail.evaluate;
const additionalMetadate = {};
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_1__/* .getAttachment */ .FG)(detail.vertical_cover, this.attachmentMode, "vertical_cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_2___default().error(error));
additionalMetadate.tags = detail.styles;
additionalMetadate.attachments = [];
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_1__/* .getAttachment */ .FG)(detail.horizontal_cover, this.attachmentMode, "horizontal_cover-")
.then((coverClass) => {
additionalMetadate.attachments?.push(coverClass);
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_2___default().error(error));
const chapters = detail.ep_list.map((ep) => {
const chapterUrl = `https://manga.bilibili.com/mc${comic_id}/${ep.id}?from=manga_detail`;
const chapterNumber = ep.ord;
const chapterName = [ep.short_title.trim(), ep.title.trim()].join(" ");
const isVIP = ep.pay_gold !== 0;
const isPaid = isVIP ? !ep.is_locked : true;
const options = {
comic_id,
ep_id: ep.id,
};
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_3__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP,
isPaid,
sectionName: null,
sectionNumber: null,
sectionChapterNumber: null,
chapterParse: this.chapterParse,
charset: this.charset,
options,
});
if (ep.is_locked || ep.type === 6) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_4__/* .Status */ .qb.aborted;
}
return chapter;
});
return new _main_Book__WEBPACK_IMPORTED_MODULE_5__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
async function isSignin(comic_id) {
const body = { comic_id };
const resp = await fetch("https://manga.bilibili.com/twirp/bookshelf.v1.Bookshelf/HasFavorite?device=pc&platform=web", {
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify(body),
method: "POST",
});
return resp.ok;
}
async function getDetail(comic_id) {
const url = "https://manga.bilibili.com/twirp/comic.v1.Comic/ComicDetail?device=pc&platform=web";
const body = {
comic_id,
};
const headers = {
accept: "application/json, text/plain, */*",
"content-type": "application/json;charset=UTF-8",
};
const init = {
headers,
body: JSON.stringify(body),
method: "POST",
};
const resp = await fetch(url, init);
const data = (await resp.json());
if (data.code === 0) {
return data.data;
}
else {
throw new Error("获取目录失败!");
}
}
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const paths = await getImageIndex(options.ep_id);
const _outs = [];
const worker = async (path) => {
const obj = await getImage(path);
const out = {
path,
obj,
};
_outs.push(out);
return out;
};
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_6__/* .concurrencyRun */ .C1)(paths, 3, worker);
_outs.sort((a, b) => paths.indexOf(a.path) - paths.indexOf(b.path));
const outs = _outs.map((out) => out.obj);
const dom = document.createElement("div");
outs.forEach((o) => {
const p = document.createElement("p");
p.appendChild(o.dom);
dom.appendChild(p);
});
const text = outs.map((o) => o.text).join("\n\n");
const images = outs.map((o) => o.images);
return {
chapterName,
contentRaw: dom,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
async function getImageIndex(ep_id) {
const url = "https://manga.bilibili.com/twirp/comic.v1.Comic/GetImageIndex?device=pc&platform=web";
const body = {
ep_id,
};
const headers = {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
};
const init = {
headers,
body: JSON.stringify(body),
method: "POST",
mode: "cors",
credentials: "include",
};
const resp = await fetch(url, init);
const data = (await resp.json());
if (data.code === 0) {
const images = data.data.images;
return images.map((i) => i.path);
}
else {
throw new Error(`抓取章节图片索引失败! ep_id: ${ep_id}, code: ${data.code}, mes: ${data.msg}`);
}
}
async function getImage(path) {
const token = await getImageToken(path);
if (token) {
const img = await getImage(token);
const _dom = document.createElement("img");
_dom.setAttribute("data-src-address", img.name);
_dom.alt = img.url;
const _text = ``;
_log__WEBPACK_IMPORTED_MODULE_2___default().info(`ep_id: ${options.ep_id}, path: ${path} 抓取成功!`);
return {
dom: _dom,
text: _text,
images: img,
};
}
throw new Error("获取图片 " + path + " 失败!");
async function getImageToken(path) {
const url = "https://manga.bilibili.com/twirp/comic.v1.Comic/ImageToken?device=pc&platform=web";
const body = {
urls: JSON.stringify([path]),
};
const headers = {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
};
const init = {
headers,
body: JSON.stringify(body),
method: "POST",
referrer: chapterUrl,
};
const resp = await fetch(url, init);
const data = (await resp.json());
if (data.code === 0) {
return data.data[0];
}
}
async function getImage(_token) {
const url = _token.url + "?token=" + _token.token;
const headers = {
Accept: "application/json, text/plain, */*",
};
const init = {
headers,
method: "GET",
};
const resp = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_7__/* .fetchWithRetry */ .q4)(url, init);
const blob = await resp.blob();
const hash = await (0,_lib_hash__WEBPACK_IMPORTED_MODULE_8__/* .calculateSha1 */ .K)(blob);
const ext = await (0,_lib_attachments__WEBPACK_IMPORTED_MODULE_1__/* .getExt */ .r6)(blob, url);
const name = ["cm-", hash, ".", ext].join("");
const imgClass = new _main_Attachment__WEBPACK_IMPORTED_MODULE_9__/* .AttachmentClass */ .J(url, name, "naive");
imgClass.Blob = blob;
imgClass.status = _main_main__WEBPACK_IMPORTED_MODULE_4__/* .Status */ .qb.finished;
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_1__/* .putAttachmentClassCache */ .dK)(imgClass);
return imgClass;
}
}
}
}
/***/ }),
/***/ "./src/rules/special/original/ciweimao.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Duread: () => (/* binding */ Duread),
/* harmony export */ Shubl: () => (/* binding */ Shubl)
/* harmony export */ });
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("crypto-js");
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/main/main.ts");
/* harmony import */ var _main_Attachment__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__("./src/main/Attachment.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules.ts");
class Shubl extends _rules__WEBPACK_IMPORTED_MODULE_1__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
this.concurrencyLimit = 1;
this.maxRunLimit = 1;
}
async bookParse() {
const bookUrl = document.location.href;
const bookname = document.querySelector(".book-title > span").innerText.trim();
const author = document.querySelector("div.username").innerText.trim();
const introDom = document.querySelector(".book-brief");
const [introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .introDomHandle */ .SN)(introDom, (introDomI) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__/* .rms */ .up)(["简介:"], introDomI);
return introDomI;
});
const additionalMetadate = {};
const coverUrl = document.querySelector(".book-img")
.src;
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_4__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
}
additionalMetadate.tags = Array.from(document.querySelectorAll("div.row > span.tag")).map((span) => span.innerText.trim());
const chapters = [];
const chapterTitleList = Array.from(document.querySelectorAll("#chapter_list > div.chapter > div.chapter-title")).map((div) => div.innerText.trim());
const articlesList = document.querySelectorAll("#chapter_list > div.chapter > div.articles");
const sectionLength = chapterTitleList.length;
let chapterNumber = 0;
for (let i = 0; i < sectionLength; i++) {
const s = articlesList[i];
const sectionNumber = i + 1;
const sectionName = chapterTitleList[i];
let sectionChapterNumber = 0;
const cs = s.querySelectorAll("span.chapter_item");
for (const c of Array.from(cs)) {
chapterNumber++;
sectionChapterNumber++;
const a = c.querySelector("a");
if (a) {
const chapterName = a.innerText.trim();
const chapterUrl = a.href;
const isVIP = () => {
return c.childElementCount === 2;
};
const isPaid = () => {
return isVIP() && c.querySelector("i")?.className === "unlock";
};
const isLogin = () => {
return (document.querySelector("#header > div.container > div.right.pull-right")?.childElementCount === 3);
};
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_6__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP: isVIP(),
isPaid: isPaid(),
sectionName,
sectionNumber,
sectionChapterNumber,
chapterParse: this.chapterParse,
charset: this.charset,
options: {},
});
if (isVIP() && !(isLogin() && isPaid())) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_7__/* .Status */ .qb.aborted;
}
chapters.push(chapter);
}
}
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_8__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const rootPath = "https://www.shubl.com/";
const [parentWidth, setFontSize] = [939.2, "18"];
return getChapter({
chapterUrl,
chapterName,
isVIP,
isPaid,
charset,
options,
rootPath,
parentWidth,
setFontSize,
});
}
}
class Duread extends _rules__WEBPACK_IMPORTED_MODULE_1__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
this.concurrencyLimit = 1;
this.maxRunLimit = 1;
}
async bookParse() {
const bookUrl = document.location.href;
const bookname = document.querySelector(".book-title > span").innerText.trim();
const author = document.querySelector("div.username").innerText.trim();
const introDom = document.querySelector(".book-brief");
const [introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .introDomHandle */ .SN)(introDom, (introDomI) => {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__/* .rms */ .up)(["简介:"], introDomI);
return introDomI;
});
const additionalMetadate = {};
const coverUrl = document.querySelector(".book-img")
.src;
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_4__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
}
additionalMetadate.tags = Array.from(document.querySelectorAll("div.row > span.tag")).map((span) => span.innerText.trim());
const chapters = [];
const chapterTitleList = Array.from(document.querySelectorAll("#chapter_list > div.chapter > div.chapter-title")).map((div) => div.innerText.trim());
const articlesList = document.querySelectorAll("#chapter_list > div.chapter > div.articles");
const sectionLength = chapterTitleList.length;
let chapterNumber = 0;
for (let i = 0; i < sectionLength; i++) {
const s = articlesList[i];
const sectionNumber = i + 1;
const sectionName = chapterTitleList[i];
let sectionChapterNumber = 0;
const cs = s.querySelectorAll("span.chapter_item");
for (const c of Array.from(cs)) {
chapterNumber++;
sectionChapterNumber++;
const a = c.querySelector("a");
if (a) {
const chapterName = a.innerText.trim();
const chapterUrl = a.href;
const isVIP = () => {
return c.childElementCount === 2;
};
const isPaid = () => {
return isVIP() && c.querySelector("i")?.className === "unlock";
};
const isLogin = () => {
return (document.querySelector("#header > div.container > div.right.pull-right")?.childElementCount === 3);
};
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_6__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP: isVIP(),
isPaid: isPaid(),
sectionName,
sectionNumber,
sectionChapterNumber,
chapterParse: this.chapterParse,
charset: this.charset,
options: {},
});
if (isVIP() && !(isLogin() && isPaid())) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_7__/* .Status */ .qb.aborted;
}
chapters.push(chapter);
}
}
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_8__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const rootPath = "https://www.duread8.com/";
const [parentWidth, setFontSize] = [939.2, "18"];
return getChapter({
chapterUrl,
chapterName,
isVIP,
isPaid,
charset,
options,
rootPath,
parentWidth,
setFontSize,
});
}
}
function getChapter({ chapterUrl, chapterName, isVIP, isPaid, charset, options, rootPath, parentWidth, setFontSize, }) {
function decrypt(item) {
let message = item.content;
const keys = item.keys;
const len = item.keys.length;
const accessKey = item.accessKey;
const accessKeyList = accessKey.split("");
const charsNotLatinNum = accessKeyList.length;
const output = [];
output.push(keys[accessKeyList[charsNotLatinNum - 1].charCodeAt(0) % len]);
output.push(keys[accessKeyList[0].charCodeAt(0) % len]);
for (let i = 0; i < output.length; i++) {
message = atob(message);
const data = output[i];
const iv = btoa(message.substr(0, 16));
const keys255 = btoa(message.substr(16));
const pass = crypto_js__WEBPACK_IMPORTED_MODULE_0__.format.OpenSSL.parse(keys255);
message = crypto_js__WEBPACK_IMPORTED_MODULE_0__.AES.decrypt(pass, crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Base64.parse(data), {
iv: crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Base64.parse(iv),
format: crypto_js__WEBPACK_IMPORTED_MODULE_0__.format.OpenSSL,
});
if (i < output.length - 1) {
message = message.toString(crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Base64);
message = atob(message);
}
}
return message.toString(crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8);
}
async function getChapterAuthorSay() {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_9__/* .getHtmlDOM */ .dL)(chapterUrl, undefined);
const chapterAuthorSays = doc.querySelectorAll("#J_BookCnt .chapter.author_say");
let divChapterAuthorSay;
if (chapterAuthorSays.length !== 0) {
const hr = document.createElement("hr");
divChapterAuthorSay = document.createElement("div");
divChapterAuthorSay.appendChild(hr);
for (const chapterAuthorSay of Array.from(chapterAuthorSays)) {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__.rm)("i", true, chapterAuthorSay);
divChapterAuthorSay.appendChild(chapterAuthorSay);
}
}
return divChapterAuthorSay;
}
const chapterId = chapterUrl.split("/").slice(-1)[0];
async function publicChapter() {
async function chapterDecrypt(chapterIdt, refererUrl) {
const accessKeyUrl = rootPath + "chapter/ajax_get_session_code";
const chapterContentUrl = rootPath + "chapter/get_book_chapter_detail_info";
_log__WEBPACK_IMPORTED_MODULE_5___default().debug(`[Chapter]请求 ${accessKeyUrl} Referer ${refererUrl}`);
const accessKeyObj = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_9__/* .gfetch */ .GF)(accessKeyUrl, {
method: "POST",
headers: {
Accept: "application/json, text/javascript, */*; q=0.01",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
Referer: refererUrl,
Origin: document.location.origin,
"X-Requested-With": "XMLHttpRequest",
},
data: `chapter_id=${chapterIdt}`,
responseType: "json",
})
.then((response) => response.response)
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
const chapter_access_key = accessKeyObj
.chapter_access_key;
_log__WEBPACK_IMPORTED_MODULE_5___default().debug(`[Chapter]请求 ${chapterContentUrl} Referer ${refererUrl}`);
const chapterContentObj = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_9__/* .gfetch */ .GF)(chapterContentUrl, {
method: "POST",
headers: {
Accept: "application/json, text/javascript, */*; q=0.01",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
Referer: refererUrl,
Origin: document.location.origin,
"X-Requested-With": "XMLHttpRequest",
},
data: `chapter_id=${chapterIdt}&chapter_access_key=${chapter_access_key}`,
responseType: "json",
})
.then((response) => response.response)
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
if (chapterContentObj.code !== 100000) {
_log__WEBPACK_IMPORTED_MODULE_5___default().error(chapterContentObj);
throw new Error(`下载 ${refererUrl} 失败`);
}
return decrypt({
content: chapterContentObj.chapter_content,
keys: chapterContentObj.encryt_keys,
accessKey: chapter_access_key,
});
}
const divChapterAuthorSay = await getChapterAuthorSay();
const content = document.createElement("div");
const decryptDate = await chapterDecrypt(chapterId, chapterUrl);
content.innerHTML = decryptDate;
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_3__.rm)(".chapter span", true, content);
if (divChapterAuthorSay) {
content.appendChild(divChapterAuthorSay);
}
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__/* .cleanDOM */ .zM)(content, "TM");
return {
chapterName,
contentRaw: content,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
}
async function vipChapter(parentWidth, setFontSize) {
async function vipChapterDecrypt(chapterIdi, refererUrl) {
const imageSessionCodeUrl = rootPath + "chapter/ajax_get_image_session_code";
_log__WEBPACK_IMPORTED_MODULE_5___default().debug(`[Chapter]请求 ${imageSessionCodeUrl} Referer ${refererUrl}`);
const imageSessionCodeObject = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_9__/* .gfetch */ .GF)(imageSessionCodeUrl, {
method: "POST",
headers: {
Accept: "application/json, text/javascript, */*; q=0.01",
Referer: refererUrl,
Origin: document.location.origin,
"X-Requested-With": "XMLHttpRequest",
},
responseType: "json",
})
.then((response) => response.response)
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
if (imageSessionCodeObject.code !== 100000) {
_log__WEBPACK_IMPORTED_MODULE_5___default().error(imageSessionCodeObject);
throw new Error(`下载 ${refererUrl} 失败`);
}
const imageCode = decrypt({
content: imageSessionCodeObject.image_code,
keys: imageSessionCodeObject.encryt_keys,
accessKey: imageSessionCodeObject
.access_key,
});
const vipCHapterImageUrlI = rootPath +
"chapter/book_chapter_image?chapter_id=" +
chapterIdi +
"&area_width=" +
parentWidth +
"&font=undefined" +
"&font_size=" +
setFontSize +
"&image_code=" +
imageCode +
"&bg_color_name=white" +
"&text_color_name=white";
return vipCHapterImageUrlI;
}
const getIsLogin = () => {
if (document.location.host === "www.duread8.com") {
return (document.querySelector("div.dropdown-menu")?.childElementCount === 3);
}
else if (document.location.host === "www.shubl.com") {
return (document.querySelector("div.pull-right:nth-child(2)")
?.childElementCount === 3);
}
else {
return (document.querySelector(".login-info.ly-fr")?.childElementCount === 1);
}
};
const isLogin = getIsLogin();
if (isLogin && isPaid) {
const divChapterAuthorSay = await getChapterAuthorSay();
const vipCHapterImageUrl = await vipChapterDecrypt(chapterId, chapterUrl);
_log__WEBPACK_IMPORTED_MODULE_5___default().debug(`[Chapter]请求 ${vipCHapterImageUrl} Referer ${chapterUrl}`);
const vipCHapterImageBlob = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_9__/* .gfetch */ .GF)(vipCHapterImageUrl, {
method: "GET",
headers: {
Referer: chapterUrl,
Accept: "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
},
responseType: "blob",
})
.then((response) => response.response)
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
const vipCHapterName = `vipCHapter${chapterId}.png`;
const vipCHapterImage = new _main_Attachment__WEBPACK_IMPORTED_MODULE_11__/* .AttachmentClass */ .J(vipCHapterImageUrl, vipCHapterName, "TM");
if (vipCHapterImageBlob) {
vipCHapterImage.Blob = vipCHapterImageBlob;
vipCHapterImage.status = _main_main__WEBPACK_IMPORTED_MODULE_7__/* .Status */ .qb.finished;
}
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_4__/* .putAttachmentClassCache */ .dK)(vipCHapterImage);
const contentImages = [vipCHapterImage];
let ddom;
let dtext;
if (divChapterAuthorSay) {
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__/* .cleanDOM */ .zM)(divChapterAuthorSay, "TM");
[ddom, dtext] = [dom, text, images];
}
const img = document.createElement("img");
img.setAttribute("data-src-address", vipCHapterName);
img.alt = vipCHapterImageUrl;
const contentHTML = document.createElement("div");
contentHTML.appendChild(img);
if (ddom) {
contentHTML.appendChild(ddom);
}
let contentText = `VIP章节,请打开HTML文件查看。\n`;
if (dtext) {
contentText = contentText + "\n\n" + dtext;
}
return {
chapterName,
contentRaw: contentHTML,
contentText,
contentHTML,
contentImages,
additionalMetadate: null,
};
}
else {
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
}
if (isVIP) {
return vipChapter(parentWidth, setFontSize);
}
else {
return publicChapter();
}
}
/***/ }),
/***/ "./src/rules/special/original/ciyuanji.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Ciyuanji: () => (/* binding */ Ciyuanji)
/* harmony export */ });
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("crypto-js");
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/main.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/lib/dom.ts");
class Ciyuanji extends _rules__WEBPACK_IMPORTED_MODULE_1__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
this.concurrencyLimit = 1;
}
async bookParse() {
const bookUrl = document.location.href;
const bookObject = unsafeWindow.__NUXT__.data[0].book;
const bookId = bookObject.bookId;
const bookname = bookObject.bookName;
const author = bookObject.authorName;
const introDom = document.createElement("div");
introDom.innerHTML = bookObject.notes.replace("/\n/g", "
");
const [introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_2__/* .introDomHandle */ .SN)(introDom);
const additionalMetadate = {};
const coverUrl = bookObject.imgUrl;
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_3__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_4___default().error(error));
}
additionalMetadate.tags = bookObject.tagList.map((tagobj) => tagobj.tagName);
const bookChapterObject = unsafeWindow.__NUXT__
.data[0].bookChapter;
const chapterList = bookChapterObject.chapterList;
const chapters = [];
let chapterNumber = 0;
let sectionName = null;
let sectionNumber = 0;
let sectionChapterNumber = 0;
for (const chapterObj of chapterList) {
const chapterId = chapterObj.chapterId;
const chapterUrl = `${document.location.origin}/chapter/${chapterId}?bookId=${bookId}`;
const chapterName = chapterObj.chapterName;
const _sectionName = chapterObj.title;
if (sectionName !== _sectionName) {
sectionName = _sectionName;
sectionNumber++;
sectionChapterNumber = 0;
}
chapterNumber++;
sectionChapterNumber++;
const isVIP = chapterObj.isFee === "1";
const isPaid = chapterObj.isBuy === "1";
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_5__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP,
isPaid,
sectionName,
sectionNumber,
sectionChapterNumber,
chapterParse: this.chapterParse,
charset: this.charset,
options: {},
});
if (chapter.isVIP && !chapter.isPaid) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_6__/* .Status */ .qb.aborted;
}
chapters.push(chapter);
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_7__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const data = {
key: "ZUreQN0Epkpxh3pooWOgixjTfPwumCTYWzYTQ7SMgDnqFLQ1s9tqpVhkGf02we89moQwhSQ07DVzc3LWupRgbVvm29aYeY7zyFN",
type1: "PC-Token",
type2: "PC-UserInfo",
type3: "PC-Enum",
type4: "PC-IsActivityStart",
f: "NpkTYvpvhJjEog8Y051gQDHmReY54z5t3F0zSd9QEFuxWGqfC8g8Y4GPuabq0KPdxArlji4dSnnHCARHnkqYBLu7iIw55ibTo18",
};
function encrypt(input) {
if (input && "string" === typeof input) {
const key = crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8.parse(data.key);
return crypto_js__WEBPACK_IMPORTED_MODULE_0__.DES.encrypt(input, key, {
mode: crypto_js__WEBPACK_IMPORTED_MODULE_0__.mode.ECB,
padding: crypto_js__WEBPACK_IMPORTED_MODULE_0__.pad.Pkcs7,
}).toString();
}
}
function decrypt(input) {
if (input && "string" === typeof input) {
input = input.replace(/\n/g, "");
const key = crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8.parse(data.key);
return crypto_js__WEBPACK_IMPORTED_MODULE_0__.DES.decrypt(input, key, {
mode: crypto_js__WEBPACK_IMPORTED_MODULE_0__.mode.ECB,
padding: crypto_js__WEBPACK_IMPORTED_MODULE_0__.pad.Pkcs7,
}).toString(crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8);
}
}
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_8__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
const _script = Array.from(doc.querySelectorAll("script")).filter((s) => /^window\.__NUXT__/.test(s.innerHTML));
if (_script.length === 1) {
const script = _script[0];
const scriptText = script.innerHTML.replace(/^window\./, "const ");
const __NUXT__ = (0,_lib_dom__WEBPACK_IMPORTED_MODULE_9__/* .sandboxed */ .J0)(`${scriptText}; return __NUXT__`);
const chapterObj = __NUXT__.data[0].chapter;
const content = document.createElement("div");
const chapterContent = decrypt(chapterObj.chapterContentFormat);
if (chapterContent) {
content.innerHTML = chapterContent;
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__/* .cleanDOM */ .zM)(content, "TM");
return {
chapterName,
contentRaw: content,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
}
}
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
}
/***/ }),
/***/ "./src/rules/special/original/cool18.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Cool18: () => (/* binding */ Cool18)
/* harmony export */ });
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/rules.ts");
class Cool18 extends _rules__WEBPACK_IMPORTED_MODULE_0__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
this.nsfw = true;
}
async bookParse() {
const bookUrl = document.location.href;
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(bookUrl, this.charset);
const title = doc.querySelector('.show_content > center > font[size="6"] > b').innerText.trim();
const matchs = /[【《](.+)[】》](.+)?作者:([^\s-]+)/.exec(title);
let bookname = title;
let author = "";
if (matchs) {
bookname = matchs[1];
author = matchs[3];
}
const introduction = null;
const introductionHTML = null;
const additionalMetadate = {};
const _aElems = Array.from(document.querySelectorAll(".show_content > pre a, body > table:nth-child(7) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1) > ul:nth-child(2) > li > a"));
const _a = document.createElement("a");
_a.href = document.location.href;
_a.innerText = title;
_aElems.push(_a);
const aElems = _aElems
.filter((a) => {
const href = a.href;
const url = new URL(href);
return (url.searchParams.get("act") === "threadview" &&
url.searchParams.has("tid"));
})
.filter((a) => a.innerText.includes("(无内容)") === false)
.filter((item, pos, self) => {
const urls = self.map((a) => a.href);
const url = item.href;
return urls.indexOf(url) === pos;
})
.sort((a, b) => {
const _aTid = new URL(a.href).searchParams.get("tid");
const _bTid = new URL(b.href).searchParams.get("tid");
const aTid = parseInt(_aTid);
const bTid = parseInt(_bTid);
return aTid - bTid;
});
const chapters = aElems.map((a) => {
const chapterUrl = a.href;
const chapterNumber = -1;
const chapterName = a.innerText
.replace(`【${bookname}】`, "")
.replace(`《${bookname}》`, "")
.replace(`作者:${author}`, "")
.trim();
return new _main_Chapter__WEBPACK_IMPORTED_MODULE_2__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP: false,
isPaid: false,
sectionName: null,
sectionNumber: null,
sectionChapterNumber: null,
chapterParse: this.chapterParse,
charset: this.charset,
options: { bookname, author },
});
});
let i = 0;
for (const chapter of chapters) {
i++;
chapter.chapterNumber = i;
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_3__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_1__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
chapterName = doc.querySelector('.show_content > center > font[size="6"] > b').innerText
.replace(`【${options.bookname}】`, "")
.replace(`《${options.bookname}》`, "")
.replace(`作者:${options.author}`, "")
.trim();
const dom = doc.querySelector(".show_content > pre, .show_content > div");
if (dom) {
Array.from(dom.querySelectorAll('font[color*="E6E6DD"]')).forEach((f) => f.remove());
const contentRaw = document.createElement("div");
const nodes = Array.from(dom.childNodes);
if (nodes.length > 10) {
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_4__/* .childNodesCopy */ .vR)(dom, contentRaw);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_4__.rm)("a", true, contentRaw);
(0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__/* .convertFixWidth */ .FZ)(contentRaw);
}
else {
for (const node of nodes) {
if (node instanceof Text && (node.textContent?.length ?? 0) > 200) {
if ((0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__/* .isFixWidth */ .Kg)(node)) {
contentRaw.appendChild((0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__/* .convertFixWidthText */ .d1)(node));
continue;
}
else {
const div = document.createElement("div");
div.innerText = node.textContent?.trim() ?? "";
contentRaw.appendChild(div);
continue;
}
}
contentRaw.appendChild(node);
}
Array.from(contentRaw.querySelectorAll("p"))
.filter((p) => p.innerText.trim() === "" &&
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_4__/* .getPreviousSibling */ .U)(p) instanceof HTMLElement &&
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_4__/* .getNextSibling */ .d9)(p) instanceof HTMLElement)
.forEach((p) => p.remove());
}
const { dom: contentHTML, text: contentText, images: contentImages, } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_5__/* .cleanDOM */ .zM)(contentRaw, "TM");
return {
chapterName,
contentRaw,
contentText,
contentHTML,
contentImages,
additionalMetadate: null,
};
}
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
}
/***/ }),
/***/ "./src/rules/special/original/gongzicp.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Gongzicp: () => (/* binding */ Gongzicp)
/* harmony export */ });
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("crypto-js");
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_misc__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/lib/misc.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/main.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules.ts");
/* harmony import */ var _setting__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/setting.ts");
class Gongzicp extends _rules__WEBPACK_IMPORTED_MODULE_1__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
this.concurrencyLimit = 1;
}
async bookParse() {
const bookUrl = document.location.href;
const bookId = document.querySelector("span.id").innerText.replace("CP", "");
if (!bookId) {
throw new Error("获取bookID出错");
}
const novelGetInfoBaseUrl = "https://www.gongzicp.com/webapi/novel/novelGetInfo";
const novelGetInfoUrl = new URL(novelGetInfoBaseUrl);
novelGetInfoUrl.searchParams.set("id", bookId);
_log__WEBPACK_IMPORTED_MODULE_2___default().debug(`请求地址: ${novelGetInfoUrl.toString()}`);
const novelInfo = await fetch(novelGetInfoUrl.toString(), {
credentials: "include",
headers: {
Accept: "application/json, text/plain, */*",
Client: "pc",
Lang: "cn",
"Content-Type": "application/json;charset=utf-8",
},
referrer: bookUrl,
method: "GET",
mode: "cors",
})
.then((response) => response.json())
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_2___default().error(error));
if (novelInfo.code !== 200) {
throw new Error(`数据接口请求失败,URL:${novelGetInfoUrl.toString()}`);
}
const data = novelInfo.data;
const bookname = data.novelInfo.novel_name;
const author = data.novelInfo.author_nickname;
const introDom = document.createElement("div");
introDom.innerHTML = data.novelInfo.novel_info;
const [introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_3__/* .introDomHandle */ .SN)(introDom);
const additionalMetadate = {};
const coverUrl = data.novelInfo.novel_cover;
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_4__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_2___default().error(error));
}
additionalMetadate.tags = data.novelInfo.tag_list;
async function isLogin() {
const getUserInfoUrl = "https://www.gongzicp.com/webapi/user/getUserInfo";
_log__WEBPACK_IMPORTED_MODULE_2___default().debug(`正在请求: ${getUserInfoUrl}`);
const userInfo = await fetch(getUserInfoUrl, {
headers: {
accept: "application/json, text/javascript, */*; q=0.01",
"x-requested-with": "XMLHttpRequest",
},
method: "GET",
mode: "cors",
credentials: "include",
})
.then((response) => response.json())
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_2___default().error(error));
return userInfo.code === 200;
}
const logined = await isLogin();
const chapters = [];
const _chapterList = data.chapterList;
let sectionNumber = 0;
let sectionName = null;
let sectionChapterNumber = 0;
for (const chapterObj of _chapterList) {
if (chapterObj.type === "volume") {
sectionNumber = chapterObj.vid;
sectionName = chapterObj.name;
sectionChapterNumber = 0;
}
else if (chapterObj.type === "item") {
const chapterUrl = [
document.location.origin,
"v4",
`read-${chapterObj.id}.html`,
].join("/");
const chapterNumber = parseInt(chapterObj.order);
const chapterName = chapterObj.name;
const isVIP = chapterObj.pay;
const isPaid = chapterObj.is_sub;
const isLock = chapterObj.lock || chapterObj.chapter_status !== 1;
sectionChapterNumber++;
const chapterOption = {
novel_id: data.novelInfo.novel_id,
chapter_id: chapterObj.id,
};
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_5__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP,
isPaid,
sectionName,
sectionNumber,
sectionChapterNumber,
chapterParse: this.chapterParse,
charset: this.charset,
options: chapterOption,
});
if ((isVIP && !(logined && chapter.isPaid)) || isLock) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_6__/* .Status */ .qb.aborted;
}
chapters.push(chapter);
}
}
return new _main_Book__WEBPACK_IMPORTED_MODULE_7__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
function cpDecrypt(input) {
class CP {
iv;
key;
constructor(iv, key) {
iv += parseInt("165455", 14).toString(32);
this.iv = crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8.parse("$h$b3!" + iv);
key = atob(key) + parseInt("4d5a6c8", 14).toString(36);
this.key = crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8.parse(key + "A");
}
encrypt(input) {
if (typeof input === "string") {
const str = JSON.stringify(input);
const byte = crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8.parse(str);
return crypto_js__WEBPACK_IMPORTED_MODULE_0__.AES.encrypt(byte, this.key, {
mode: crypto_js__WEBPACK_IMPORTED_MODULE_0__.mode.CBC,
padding: crypto_js__WEBPACK_IMPORTED_MODULE_0__.pad.Pkcs7,
iv: this.iv,
});
}
}
decrypt(input) {
const byte = crypto_js__WEBPACK_IMPORTED_MODULE_0__.AES.decrypt(input, this.key, {
mode: crypto_js__WEBPACK_IMPORTED_MODULE_0__.mode.CBC,
padding: crypto_js__WEBPACK_IMPORTED_MODULE_0__.pad.Pkcs7,
iv: this.iv,
});
return crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Utf8.stringify(byte).toString();
}
}
const cp = new CP("iGzsYn", "dTBMUnJidSRFbg==");
const content = cp.decrypt(input);
return content;
}
function randomWalker() {
_log__WEBPACK_IMPORTED_MODULE_2___default().info("[chapter]随机翻页中……");
if (document.location.pathname.includes("novel")) {
document.querySelector(".chapter-list .chapter a").click();
}
if (document.location.pathname.includes("read")) {
const rightMenu = document.querySelector(".right-menu");
if (rightMenu?.childElementCount === 6) {
document.querySelector(".right-menu > div:nth-child(3) > a:nth-child(1)").click();
}
else if (rightMenu?.childElementCount === 7) {
if (document.querySelector("div.content.unpaid")) {
document.querySelector(".right-menu > div:nth-child(3) > a:nth-child(1)").click();
}
else if (Math.random() < 0.3) {
document.querySelector(".right-menu > div:nth-child(3) > a:nth-child(1)").click();
}
else {
document.querySelector(".right-menu > div:nth-child(4) > a:nth-child(1)").click();
}
}
}
}
async function getChapter() {
const cid = options.chapter_id;
const chapterGetInfoBaseUrl = "https://www.gongzicp.com/webapi/novel/chapterGetInfo";
const chapterGetInfoUrl = new URL(chapterGetInfoBaseUrl);
chapterGetInfoUrl.searchParams.set("cid", cid.toString());
chapterGetInfoUrl.searchParams.set("server", "0");
let retryTime = 0;
async function getChapterInfo(url) {
_log__WEBPACK_IMPORTED_MODULE_2___default().debug(`请求地址: ${url}, Referrer: ${chapterUrl},retryTime:${retryTime}`);
const resultI = await fetch(url, {
credentials: "include",
headers: {
Accept: "application/json, text/plain, */*",
Client: "pc",
"Content-Type": "application/json;charset=utf-8",
},
referrer: chapterUrl,
method: "GET",
mode: "cors",
})
.then((resp) => resp.json())
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_2___default().error(error));
if (resultI.data.chapterInfo.content.length !== 0 &&
resultI.data.chapterInfo.content.length < 30) {
retryTime++;
if (retryTime > _setting__WEBPACK_IMPORTED_MODULE_8__/* .retryLimit */ .o5) {
_log__WEBPACK_IMPORTED_MODULE_2___default().error(`请求 ${url} 失败`);
throw new Error(`请求 ${url} 失败`);
}
_log__WEBPACK_IMPORTED_MODULE_2___default().warn("[chapter]疑似被阻断,进行随机翻页……");
const ci = Math.round(Math.random() * retryTime) + 1;
for (let i = 0; i < ci; i++) {
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_9__/* .sleep */ ._v)(3000 + Math.round(Math.random() * 5000));
randomWalker();
}
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_9__/* .sleep */ ._v)(3000 + Math.round(Math.random() * 2000));
return getChapterInfo(url);
}
else {
retryTime = 0;
return resultI;
}
}
const result = await getChapterInfo(chapterGetInfoUrl.toString());
if (result.code === 200) {
const chapterInfo = result.data.chapterInfo;
if (chapterInfo.chapterPrice !== 0 &&
chapterInfo.content.length === 0) {
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
else if (chapterInfo.chapterPrice === 0 ||
(chapterInfo.chapterPrice !== 0 && chapterInfo.content.length !== 0)) {
const content = cpDecrypt(chapterInfo.content);
const contentRaw = document.createElement("pre");
contentRaw.innerHTML = content;
let contentText = content
.split("\n")
.map((p) => p.trim())
.join("\n\n");
let contentHTML;
const _contentHTML = document.createElement("div");
_contentHTML.innerHTML = content
.split("\n")
.map((p) => p.trim())
.map((p) => {
if (p.length === 0) {
return "
";
}
else {
return `
${p}
`;
}
})
.join("\n");
if (chapterInfo.postscript.length === 0) {
contentHTML = _contentHTML;
}
else {
contentHTML = document.createElement("div");
contentHTML.className = "main";
const hr = document.createElement("hr");
const authorSayDom = document.createElement("div");
authorSayDom.innerHTML = chapterInfo.postscript
.split("\n")
.map((p) => {
if (p.length === 0) {
return "
";
}
else {
return `
${p}
`;
}
})
.join("\n");
contentHTML.appendChild(_contentHTML);
contentHTML.appendChild(hr);
contentHTML.appendChild(authorSayDom);
contentRaw.innerHTML = [
contentRaw.innerHTML,
"-".repeat(20),
chapterInfo.postscript,
].join("\n\n");
contentText = [
contentText,
"-".repeat(20),
chapterInfo.postscript,
].join("\n\n");
}
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_9__/* .sleep */ ._v)(3000 + Math.round(Math.random() * 5000));
return {
chapterName,
contentRaw,
contentText,
contentHTML,
contentImages: null,
additionalMetadate: null,
};
}
}
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
async function antiAntiCrawler() {
if (Math.random() < 0.15) {
randomWalker();
}
await (0,_lib_misc__WEBPACK_IMPORTED_MODULE_9__/* .sleep */ ._v)(3000 + Math.round(Math.random() * 4000));
}
async function publicChapter() {
await antiAntiCrawler();
return getChapter();
}
async function vipChapter() {
await antiAntiCrawler();
return getChapter();
}
if (isVIP) {
return vipChapter();
}
else {
return publicChapter();
}
}
}
/***/ }),
/***/ "./src/rules/special/original/hanwujinian.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Hanwujinian: () => (/* binding */ Hanwujinian)
/* harmony export */ });
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("crypto-js");
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _lib_http__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/http.ts");
/* harmony import */ var _lib_dom__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__("./src/lib/dom.ts");
/* harmony import */ var _lib_rule__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/lib/rule.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_5__);
/* harmony import */ var _main_main__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__("./src/main/main.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules.ts");
class Hanwujinian extends _rules__WEBPACK_IMPORTED_MODULE_1__/* .BaseRuleClass */ .c {
constructor() {
super();
this.attachmentMode = "TM";
}
async bookParse() {
const bookUrl = document.location.href;
const anotherPageUrl = document.querySelector("a.titleText_3").href;
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_2__/* .getHtmlDOM */ .dL)(anotherPageUrl, this.charset);
const bookname = document.querySelector("span.titleText_1").innerText.trim();
const author = document.querySelector("span.authorText_1").innerText.trim();
const introDom = document.querySelector("#introtext");
const [introduction, introductionHTML] = await (0,_lib_rule__WEBPACK_IMPORTED_MODULE_3__/* .introDomHandle */ .SN)(introDom);
const coverUrl = document.querySelector(".wR_JSAS > img").src;
const additionalMetadate = {};
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_4__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((coverClass) => {
additionalMetadate.cover = coverClass;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_5___default().error(error));
}
additionalMetadate.tags = Array.from(document.querySelectorAll("div.labelBox_1 > span")).map((span) => span?.innerText.trim());
const chapters = [];
let chapterNumber = 0;
let sectionNumber = 0;
let sectionChapterNumber = 0;
let sectionName = null;
const signIn = document.querySelector("#userMeun") !== null;
const sections = doc.querySelectorAll('div.wR_JS > div.wR_JC[style*="margin: 30px auto;"]');
const divList = doc.querySelectorAll("div.wR_JS > div.wR_JC > div.wR_JSAC");
for (const divElem of Array.from(divList)) {
const aElem = divElem.querySelector("a");
const chapterName = aElem.innerText.trim();
const chapterUrl = aElem.href;
if (sections.length !== 0) {
const _sectionName = (0,_lib_rule__WEBPACK_IMPORTED_MODULE_3__/* .getSectionName */ .$d)(aElem, sections, (dom) => dom.innerText.trim());
if (_sectionName !== sectionName) {
sectionName = _sectionName;
sectionNumber++;
sectionChapterNumber = 0;
}
}
chapterNumber++;
sectionChapterNumber++;
const icon = divElem.querySelector("img");
const isVIP = icon !== null;
const isPaid = isVIP ? icon.src.includes("lock_2_off.png") : false;
const chapter = new _main_Chapter__WEBPACK_IMPORTED_MODULE_6__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber,
chapterName,
isVIP,
isPaid,
sectionName,
sectionNumber,
sectionChapterNumber,
chapterParse: this.chapterParse,
charset: this.charset,
options: { bookname },
});
if (chapter.isVIP) {
if (signIn) {
if (chapter.isPaid === false) {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_7__/* .Status */ .qb.aborted;
}
}
else {
chapter.status = _main_main__WEBPACK_IMPORTED_MODULE_7__/* .Status */ .qb.aborted;
}
}
chapters.push(chapter);
}
const book = new _main_Book__WEBPACK_IMPORTED_MODULE_8__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
book.ToCUrl = anotherPageUrl;
return book;
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const doc = await (0,_lib_http__WEBPACK_IMPORTED_MODULE_2__/* .getHtmlDOM */ .dL)(chapterUrl, charset);
const script = Array.from(doc.querySelectorAll("script")).filter((s) => s.innerHTML.includes("var chapterContent"))?.[0];
const getContent = (CryptoJS, chapterContent) => {
function AesDecrypt(content) {
const keys = {
key: "2018122911430000",
iv: "048fe2a99140c0e6",
};
const key = CryptoJS.enc.Latin1.parse(keys.key);
const iv = CryptoJS.enc.Latin1.parse(keys.iv);
const d = CryptoJS.AES.decrypt(content, key, {
iv,
padding: CryptoJS.pad.ZeroPadding,
});
return d.toString(CryptoJS.enc.Utf8);
}
const text = decodeURI(AesDecrypt(chapterContent));
const div = document.createElement("div");
div.innerText = text;
return div;
};
if (script) {
const chapterContentLine = script.innerHTML
.split("\n")
.filter((l) => l.includes("var chapterContent"))?.[0];
const content = new Function("CryptoJS", `${chapterContentLine};return (${getContent.toString()})(CryptoJS, chapterContent);`)(crypto_js__WEBPACK_IMPORTED_MODULE_0__);
(0,_lib_dom__WEBPACK_IMPORTED_MODULE_9__/* .rm2 */ .vS)(["更多优惠快去下载寒武纪年小说APP哦"], content);
content.innerHTML = content.innerHTML.replaceAll("%3A", ":");
content.innerHTML = content.innerHTML.replaceAll("++++【", "【");
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_10__/* .cleanDOM */ .zM)(content, "TM");
return {
chapterName,
contentRaw: content,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate: null,
};
}
return {
chapterName,
contentRaw: null,
contentText: null,
contentHTML: null,
contentImages: null,
additionalMetadate: null,
};
}
}
/***/ }),
/***/ "./src/rules/special/original/iqingguo.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ Iqingguo: () => (/* binding */ Iqingguo)
/* harmony export */ });
/* harmony import */ var _rules__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./src/rules.ts");
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("crypto-js");
/* harmony import */ var crypto_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(crypto_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _main_Book__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./src/main/Book.ts");
/* harmony import */ var _lib_cleanDOM__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__("./src/lib/cleanDOM.ts");
/* harmony import */ var _main_Chapter__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/main/Chapter.ts");
/* harmony import */ var _lib_attachments__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/lib/attachments.ts");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_log__WEBPACK_IMPORTED_MODULE_3__);
class Iqingguo extends _rules__WEBPACK_IMPORTED_MODULE_1__/* .BaseRuleClass */ .c {
constructor() {
super();
this.concurrencyLimit = 2;
this.attachmentMode = "TM";
}
async bookParse() {
const bookId = new URLSearchParams(document.location.search).get("id");
if (!bookId) {
throw new Error("无法找到 bookId!");
}
const bookPath = `/v1/books/${bookId}/cover`;
const catalogPath = `/v1/books/${bookId}/catalog`;
const bookData = (await get(bookPath))
.cover;
const catalogData = await get(catalogPath);
const bookUrl = document.location.href;
const bookname = bookData.name;
const author = bookData.user.author;
const introduction = bookData.description;
const introductionHTML = document.createElement("div");
introductionHTML.innerText = introduction;
const coverUrl = bookData.url;
const additionalMetadate = {
lastModified: bookData.latestModified,
tags: [bookData.genre, bookData.subGenre],
language: "zh",
ids: bookId,
};
if (coverUrl) {
(0,_lib_attachments__WEBPACK_IMPORTED_MODULE_2__/* .getAttachment */ .FG)(coverUrl, this.attachmentMode, "cover-")
.then((img) => {
additionalMetadate.cover = img;
})
.catch((error) => _log__WEBPACK_IMPORTED_MODULE_3___default().error(error));
}
const chapters = catalogData.map((c) => {
const chapterUrl = "https://www.iqingguo.com/book/reading?" +
new URLSearchParams({ id: bookId, cid: c.id }).toString();
return new _main_Chapter__WEBPACK_IMPORTED_MODULE_4__/* .Chapter */ .W({
bookUrl,
bookname,
chapterUrl,
chapterNumber: c.sn,
chapterName: c.name,
isVIP: false,
isPaid: false,
sectionName: null,
sectionNumber: null,
sectionChapterNumber: null,
chapterParse: this.chapterParse,
charset: this.charset,
options: {
bookId,
chapterId: c.id,
},
});
});
return new _main_Book__WEBPACK_IMPORTED_MODULE_5__/* .Book */ .f({
bookUrl,
bookname,
author,
introduction,
introductionHTML,
additionalMetadate,
chapters,
});
}
async chapterParse(chapterUrl, chapterName, isVIP, isPaid, charset, options) {
const chapterPath = `/v1/chapters/${options.chapterId}`;
const data = await get(chapterPath);
chapterName = data.name;
const contentRaw = document.createElement("div");
contentRaw.innerText = data.content;
const { dom, text, images } = await (0,_lib_cleanDOM__WEBPACK_IMPORTED_MODULE_6__/* .cleanDOM */ .zM)(contentRaw, "TM");
const additionalMetadate = {
lastModified: data.updateTime,
};
return {
chapterName,
contentRaw,
contentText: text,
contentHTML: dom,
contentImages: images,
additionalMetadate,
};
}
}
function sign(path, params) {
params = params ?? {};
Object.assign(params, {
packageName: "com.iqingoo.reader.web",
t: Math.ceil(new Date().getTime() / 1e3),
});
const orderd = Object.keys(params)
.sort()
.reduce((obj, key) => {
obj[key] = params[key];
return obj;
}, {});
const l = path + "?" + new URLSearchParams(orderd).toString();
orderd.sign = crypto_js__WEBPACK_IMPORTED_MODULE_0__.MD5(decodeURI(l)).toString(crypto_js__WEBPACK_IMPORTED_MODULE_0__.enc.Hex);
return orderd;
}
async function get(path, params) {
const origin = "https://iqg-api.qingoo.cn";
const parm = sign(path, params);
const url = origin + path + "?" + new URLSearchParams(parm).toString();
const resp = await fetch(url, {
headers: {
accept: "application/json, text/plain, */*",
},
method: "GET",
mode: "cors",
credentials: "include",
});
const _data = (await resp.json());
if (_data.code !== 200) {
throw new Error("请求出错! " + url);
}
return _data.data;
}
/***/ }),
/***/ "./src/rules/special/original/jjwxc.ts":
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
Jjwxc: () => (/* binding */ Jjwxc)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/generator/token-before.js
var token_before_namespaceObject = {};
__webpack_require__.r(token_before_namespaceObject);
__webpack_require__.d(token_before_namespaceObject, {
safe: () => (safe),
spec: () => (spec)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/lexer/units.js
var units_namespaceObject = {};
__webpack_require__.r(units_namespaceObject);
__webpack_require__.d(units_namespaceObject, {
angle: () => (angle),
decibel: () => (decibel),
flex: () => (flex),
frequency: () => (frequency),
length: () => (units_length),
resolution: () => (resolution),
semitones: () => (semitones),
time: () => (time)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/lexer/trace.js
var trace_namespaceObject = {};
__webpack_require__.r(trace_namespaceObject);
__webpack_require__.d(trace_namespaceObject, {
getTrace: () => (getTrace),
isKeyword: () => (isKeyword),
isProperty: () => (isProperty),
isType: () => (isType)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/AnPlusB.js
var AnPlusB_namespaceObject = {};
__webpack_require__.r(AnPlusB_namespaceObject);
__webpack_require__.d(AnPlusB_namespaceObject, {
generate: () => (AnPlusB_generate),
name: () => (AnPlusB_name),
parse: () => (AnPlusB_parse),
structure: () => (structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Atrule.js
var Atrule_namespaceObject = {};
__webpack_require__.r(Atrule_namespaceObject);
__webpack_require__.d(Atrule_namespaceObject, {
generate: () => (Atrule_generate),
name: () => (Atrule_name),
parse: () => (Atrule_parse),
structure: () => (Atrule_structure),
walkContext: () => (walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/AtrulePrelude.js
var AtrulePrelude_namespaceObject = {};
__webpack_require__.r(AtrulePrelude_namespaceObject);
__webpack_require__.d(AtrulePrelude_namespaceObject, {
generate: () => (AtrulePrelude_generate),
name: () => (AtrulePrelude_name),
parse: () => (AtrulePrelude_parse),
structure: () => (AtrulePrelude_structure),
walkContext: () => (AtrulePrelude_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/AttributeSelector.js
var AttributeSelector_namespaceObject = {};
__webpack_require__.r(AttributeSelector_namespaceObject);
__webpack_require__.d(AttributeSelector_namespaceObject, {
generate: () => (AttributeSelector_generate),
name: () => (AttributeSelector_name),
parse: () => (AttributeSelector_parse),
structure: () => (AttributeSelector_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Block.js
var Block_namespaceObject = {};
__webpack_require__.r(Block_namespaceObject);
__webpack_require__.d(Block_namespaceObject, {
generate: () => (Block_generate),
name: () => (Block_name),
parse: () => (Block_parse),
structure: () => (Block_structure),
walkContext: () => (Block_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Brackets.js
var Brackets_namespaceObject = {};
__webpack_require__.r(Brackets_namespaceObject);
__webpack_require__.d(Brackets_namespaceObject, {
generate: () => (Brackets_generate),
name: () => (Brackets_name),
parse: () => (Brackets_parse),
structure: () => (Brackets_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/CDC.js
var CDC_namespaceObject = {};
__webpack_require__.r(CDC_namespaceObject);
__webpack_require__.d(CDC_namespaceObject, {
generate: () => (CDC_generate),
name: () => (CDC_name),
parse: () => (CDC_parse),
structure: () => (CDC_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/CDO.js
var CDO_namespaceObject = {};
__webpack_require__.r(CDO_namespaceObject);
__webpack_require__.d(CDO_namespaceObject, {
generate: () => (CDO_generate),
name: () => (CDO_name),
parse: () => (CDO_parse),
structure: () => (CDO_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/ClassSelector.js
var ClassSelector_namespaceObject = {};
__webpack_require__.r(ClassSelector_namespaceObject);
__webpack_require__.d(ClassSelector_namespaceObject, {
generate: () => (ClassSelector_generate),
name: () => (ClassSelector_name),
parse: () => (ClassSelector_parse),
structure: () => (ClassSelector_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Combinator.js
var Combinator_namespaceObject = {};
__webpack_require__.r(Combinator_namespaceObject);
__webpack_require__.d(Combinator_namespaceObject, {
generate: () => (Combinator_generate),
name: () => (Combinator_name),
parse: () => (Combinator_parse),
structure: () => (Combinator_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Comment.js
var Comment_namespaceObject = {};
__webpack_require__.r(Comment_namespaceObject);
__webpack_require__.d(Comment_namespaceObject, {
generate: () => (Comment_generate),
name: () => (Comment_name),
parse: () => (Comment_parse),
structure: () => (Comment_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Declaration.js
var Declaration_namespaceObject = {};
__webpack_require__.r(Declaration_namespaceObject);
__webpack_require__.d(Declaration_namespaceObject, {
generate: () => (Declaration_generate),
name: () => (Declaration_name),
parse: () => (Declaration_parse),
structure: () => (Declaration_structure),
walkContext: () => (Declaration_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/DeclarationList.js
var DeclarationList_namespaceObject = {};
__webpack_require__.r(DeclarationList_namespaceObject);
__webpack_require__.d(DeclarationList_namespaceObject, {
generate: () => (DeclarationList_generate),
name: () => (DeclarationList_name),
parse: () => (DeclarationList_parse),
structure: () => (DeclarationList_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Dimension.js
var Dimension_namespaceObject = {};
__webpack_require__.r(Dimension_namespaceObject);
__webpack_require__.d(Dimension_namespaceObject, {
generate: () => (Dimension_generate),
name: () => (Dimension_name),
parse: () => (Dimension_parse),
structure: () => (Dimension_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Function.js
var Function_namespaceObject = {};
__webpack_require__.r(Function_namespaceObject);
__webpack_require__.d(Function_namespaceObject, {
generate: () => (Function_generate),
name: () => (Function_name),
parse: () => (Function_parse),
structure: () => (Function_structure),
walkContext: () => (Function_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Hash.js
var Hash_namespaceObject = {};
__webpack_require__.r(Hash_namespaceObject);
__webpack_require__.d(Hash_namespaceObject, {
generate: () => (Hash_generate),
name: () => (Hash_name),
parse: () => (Hash_parse),
structure: () => (Hash_structure),
xxx: () => (xxx)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Identifier.js
var Identifier_namespaceObject = {};
__webpack_require__.r(Identifier_namespaceObject);
__webpack_require__.d(Identifier_namespaceObject, {
generate: () => (Identifier_generate),
name: () => (Identifier_name),
parse: () => (Identifier_parse),
structure: () => (Identifier_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/IdSelector.js
var IdSelector_namespaceObject = {};
__webpack_require__.r(IdSelector_namespaceObject);
__webpack_require__.d(IdSelector_namespaceObject, {
generate: () => (IdSelector_generate),
name: () => (IdSelector_name),
parse: () => (IdSelector_parse),
structure: () => (IdSelector_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/MediaFeature.js
var MediaFeature_namespaceObject = {};
__webpack_require__.r(MediaFeature_namespaceObject);
__webpack_require__.d(MediaFeature_namespaceObject, {
generate: () => (MediaFeature_generate),
name: () => (MediaFeature_name),
parse: () => (MediaFeature_parse),
structure: () => (MediaFeature_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/MediaQuery.js
var MediaQuery_namespaceObject = {};
__webpack_require__.r(MediaQuery_namespaceObject);
__webpack_require__.d(MediaQuery_namespaceObject, {
generate: () => (MediaQuery_generate),
name: () => (MediaQuery_name),
parse: () => (MediaQuery_parse),
structure: () => (MediaQuery_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/MediaQueryList.js
var MediaQueryList_namespaceObject = {};
__webpack_require__.r(MediaQueryList_namespaceObject);
__webpack_require__.d(MediaQueryList_namespaceObject, {
generate: () => (MediaQueryList_generate),
name: () => (MediaQueryList_name),
parse: () => (MediaQueryList_parse),
structure: () => (MediaQueryList_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/NestingSelector.js
var NestingSelector_namespaceObject = {};
__webpack_require__.r(NestingSelector_namespaceObject);
__webpack_require__.d(NestingSelector_namespaceObject, {
generate: () => (NestingSelector_generate),
name: () => (NestingSelector_name),
parse: () => (NestingSelector_parse),
structure: () => (NestingSelector_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Nth.js
var Nth_namespaceObject = {};
__webpack_require__.r(Nth_namespaceObject);
__webpack_require__.d(Nth_namespaceObject, {
generate: () => (Nth_generate),
name: () => (Nth_name),
parse: () => (Nth_parse),
structure: () => (Nth_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Number.js
var Number_namespaceObject = {};
__webpack_require__.r(Number_namespaceObject);
__webpack_require__.d(Number_namespaceObject, {
generate: () => (Number_generate),
name: () => (Number_name),
parse: () => (Number_parse),
structure: () => (Number_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Operator.js
var Operator_namespaceObject = {};
__webpack_require__.r(Operator_namespaceObject);
__webpack_require__.d(Operator_namespaceObject, {
generate: () => (Operator_generate),
name: () => (Operator_name),
parse: () => (Operator_parse),
structure: () => (Operator_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Parentheses.js
var Parentheses_namespaceObject = {};
__webpack_require__.r(Parentheses_namespaceObject);
__webpack_require__.d(Parentheses_namespaceObject, {
generate: () => (Parentheses_generate),
name: () => (Parentheses_name),
parse: () => (Parentheses_parse),
structure: () => (Parentheses_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Percentage.js
var Percentage_namespaceObject = {};
__webpack_require__.r(Percentage_namespaceObject);
__webpack_require__.d(Percentage_namespaceObject, {
generate: () => (Percentage_generate),
name: () => (Percentage_name),
parse: () => (Percentage_parse),
structure: () => (Percentage_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/PseudoClassSelector.js
var PseudoClassSelector_namespaceObject = {};
__webpack_require__.r(PseudoClassSelector_namespaceObject);
__webpack_require__.d(PseudoClassSelector_namespaceObject, {
generate: () => (PseudoClassSelector_generate),
name: () => (PseudoClassSelector_name),
parse: () => (PseudoClassSelector_parse),
structure: () => (PseudoClassSelector_structure),
walkContext: () => (PseudoClassSelector_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/PseudoElementSelector.js
var PseudoElementSelector_namespaceObject = {};
__webpack_require__.r(PseudoElementSelector_namespaceObject);
__webpack_require__.d(PseudoElementSelector_namespaceObject, {
generate: () => (PseudoElementSelector_generate),
name: () => (PseudoElementSelector_name),
parse: () => (PseudoElementSelector_parse),
structure: () => (PseudoElementSelector_structure),
walkContext: () => (PseudoElementSelector_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Ratio.js
var Ratio_namespaceObject = {};
__webpack_require__.r(Ratio_namespaceObject);
__webpack_require__.d(Ratio_namespaceObject, {
generate: () => (Ratio_generate),
name: () => (Ratio_name),
parse: () => (Ratio_parse),
structure: () => (Ratio_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Raw.js
var Raw_namespaceObject = {};
__webpack_require__.r(Raw_namespaceObject);
__webpack_require__.d(Raw_namespaceObject, {
generate: () => (Raw_generate),
name: () => (Raw_name),
parse: () => (Raw_parse),
structure: () => (Raw_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Rule.js
var Rule_namespaceObject = {};
__webpack_require__.r(Rule_namespaceObject);
__webpack_require__.d(Rule_namespaceObject, {
generate: () => (Rule_generate),
name: () => (Rule_name),
parse: () => (Rule_parse),
structure: () => (Rule_structure),
walkContext: () => (Rule_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Selector.js
var Selector_namespaceObject = {};
__webpack_require__.r(Selector_namespaceObject);
__webpack_require__.d(Selector_namespaceObject, {
generate: () => (Selector_generate),
name: () => (Selector_name),
parse: () => (Selector_parse),
structure: () => (Selector_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/SelectorList.js
var SelectorList_namespaceObject = {};
__webpack_require__.r(SelectorList_namespaceObject);
__webpack_require__.d(SelectorList_namespaceObject, {
generate: () => (SelectorList_generate),
name: () => (SelectorList_name),
parse: () => (SelectorList_parse),
structure: () => (SelectorList_structure),
walkContext: () => (SelectorList_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/String.js
var String_namespaceObject = {};
__webpack_require__.r(String_namespaceObject);
__webpack_require__.d(String_namespaceObject, {
generate: () => (String_generate),
name: () => (String_name),
parse: () => (String_parse),
structure: () => (String_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/StyleSheet.js
var StyleSheet_namespaceObject = {};
__webpack_require__.r(StyleSheet_namespaceObject);
__webpack_require__.d(StyleSheet_namespaceObject, {
generate: () => (StyleSheet_generate),
name: () => (StyleSheet_name),
parse: () => (StyleSheet_parse),
structure: () => (StyleSheet_structure),
walkContext: () => (StyleSheet_walkContext)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/TypeSelector.js
var TypeSelector_namespaceObject = {};
__webpack_require__.r(TypeSelector_namespaceObject);
__webpack_require__.d(TypeSelector_namespaceObject, {
generate: () => (TypeSelector_generate),
name: () => (TypeSelector_name),
parse: () => (TypeSelector_parse),
structure: () => (TypeSelector_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/UnicodeRange.js
var UnicodeRange_namespaceObject = {};
__webpack_require__.r(UnicodeRange_namespaceObject);
__webpack_require__.d(UnicodeRange_namespaceObject, {
generate: () => (UnicodeRange_generate),
name: () => (UnicodeRange_name),
parse: () => (UnicodeRange_parse),
structure: () => (UnicodeRange_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Url.js
var Url_namespaceObject = {};
__webpack_require__.r(Url_namespaceObject);
__webpack_require__.d(Url_namespaceObject, {
generate: () => (Url_generate),
name: () => (Url_name),
parse: () => (Url_parse),
structure: () => (Url_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/Value.js
var Value_namespaceObject = {};
__webpack_require__.r(Value_namespaceObject);
__webpack_require__.d(Value_namespaceObject, {
generate: () => (Value_generate),
name: () => (Value_name),
parse: () => (Value_parse),
structure: () => (Value_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/WhiteSpace.js
var WhiteSpace_namespaceObject = {};
__webpack_require__.r(WhiteSpace_namespaceObject);
__webpack_require__.d(WhiteSpace_namespaceObject, {
generate: () => (WhiteSpace_generate),
name: () => (WhiteSpace_name),
parse: () => (WhiteSpace_parse),
structure: () => (WhiteSpace_structure)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/index.js
var node_namespaceObject = {};
__webpack_require__.r(node_namespaceObject);
__webpack_require__.d(node_namespaceObject, {
AnPlusB: () => (AnPlusB_namespaceObject),
Atrule: () => (Atrule_namespaceObject),
AtrulePrelude: () => (AtrulePrelude_namespaceObject),
AttributeSelector: () => (AttributeSelector_namespaceObject),
Block: () => (Block_namespaceObject),
Brackets: () => (Brackets_namespaceObject),
CDC: () => (CDC_namespaceObject),
CDO: () => (CDO_namespaceObject),
ClassSelector: () => (ClassSelector_namespaceObject),
Combinator: () => (Combinator_namespaceObject),
Comment: () => (Comment_namespaceObject),
Declaration: () => (Declaration_namespaceObject),
DeclarationList: () => (DeclarationList_namespaceObject),
Dimension: () => (Dimension_namespaceObject),
Function: () => (Function_namespaceObject),
Hash: () => (Hash_namespaceObject),
IdSelector: () => (IdSelector_namespaceObject),
Identifier: () => (Identifier_namespaceObject),
MediaFeature: () => (MediaFeature_namespaceObject),
MediaQuery: () => (MediaQuery_namespaceObject),
MediaQueryList: () => (MediaQueryList_namespaceObject),
NestingSelector: () => (NestingSelector_namespaceObject),
Nth: () => (Nth_namespaceObject),
Number: () => (Number_namespaceObject),
Operator: () => (Operator_namespaceObject),
Parentheses: () => (Parentheses_namespaceObject),
Percentage: () => (Percentage_namespaceObject),
PseudoClassSelector: () => (PseudoClassSelector_namespaceObject),
PseudoElementSelector: () => (PseudoElementSelector_namespaceObject),
Ratio: () => (Ratio_namespaceObject),
Raw: () => (Raw_namespaceObject),
Rule: () => (Rule_namespaceObject),
Selector: () => (Selector_namespaceObject),
SelectorList: () => (SelectorList_namespaceObject),
String: () => (String_namespaceObject),
StyleSheet: () => (StyleSheet_namespaceObject),
TypeSelector: () => (TypeSelector_namespaceObject),
UnicodeRange: () => (UnicodeRange_namespaceObject),
Url: () => (Url_namespaceObject),
Value: () => (Value_namespaceObject),
WhiteSpace: () => (WhiteSpace_namespaceObject)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/scope/index.js
var scope_namespaceObject = {};
__webpack_require__.r(scope_namespaceObject);
__webpack_require__.d(scope_namespaceObject, {
AtrulePrelude: () => (atrulePrelude),
Selector: () => (selector),
Value: () => (value)
});
// NAMESPACE OBJECT: ./node_modules/css-tree/lib/syntax/node/index-parse.js
var index_parse_namespaceObject = {};
__webpack_require__.r(index_parse_namespaceObject);
__webpack_require__.d(index_parse_namespaceObject, {
AnPlusB: () => (AnPlusB_parse),
Atrule: () => (Atrule_parse),
AtrulePrelude: () => (AtrulePrelude_parse),
AttributeSelector: () => (AttributeSelector_parse),
Block: () => (Block_parse),
Brackets: () => (Brackets_parse),
CDC: () => (CDC_parse),
CDO: () => (CDO_parse),
ClassSelector: () => (ClassSelector_parse),
Combinator: () => (Combinator_parse),
Comment: () => (Comment_parse),
Declaration: () => (Declaration_parse),
DeclarationList: () => (DeclarationList_parse),
Dimension: () => (Dimension_parse),
Function: () => (Function_parse),
Hash: () => (Hash_parse),
IdSelector: () => (IdSelector_parse),
Identifier: () => (Identifier_parse),
MediaFeature: () => (MediaFeature_parse),
MediaQuery: () => (MediaQuery_parse),
MediaQueryList: () => (MediaQueryList_parse),
NestingSelector: () => (NestingSelector_parse),
Nth: () => (Nth_parse),
Number: () => (Number_parse),
Operator: () => (Operator_parse),
Parentheses: () => (Parentheses_parse),
Percentage: () => (Percentage_parse),
PseudoClassSelector: () => (PseudoClassSelector_parse),
PseudoElementSelector: () => (PseudoElementSelector_parse),
Ratio: () => (Ratio_parse),
Raw: () => (Raw_parse),
Rule: () => (Rule_parse),
Selector: () => (Selector_parse),
SelectorList: () => (SelectorList_parse),
String: () => (String_parse),
StyleSheet: () => (StyleSheet_parse),
TypeSelector: () => (TypeSelector_parse),
UnicodeRange: () => (UnicodeRange_parse),
Url: () => (Url_parse),
Value: () => (Value_parse),
WhiteSpace: () => (WhiteSpace_parse)
});
// EXTERNAL MODULE: ./src/lib/attachments.ts
var attachments = __webpack_require__("./src/lib/attachments.ts");
// EXTERNAL MODULE: ./src/lib/cleanDOM.ts
var cleanDOM = __webpack_require__("./src/lib/cleanDOM.ts");
// EXTERNAL MODULE: ./src/lib/http.ts
var http = __webpack_require__("./src/lib/http.ts");
// EXTERNAL MODULE: ./src/lib/misc.ts
var misc = __webpack_require__("./src/lib/misc.ts");
// EXTERNAL MODULE: ./src/lib/dom.ts
var lib_dom = __webpack_require__("./src/lib/dom.ts");
// EXTERNAL MODULE: ./src/lib/rule.ts
var rule = __webpack_require__("./src/lib/rule.ts");
// EXTERNAL MODULE: ./node_modules/loglevel/lib/loglevel.js
var loglevel = __webpack_require__("./node_modules/loglevel/lib/loglevel.js");
var loglevel_default = /*#__PURE__*/__webpack_require__.n(loglevel);
// EXTERNAL MODULE: ./src/main/main.ts
var main = __webpack_require__("./src/main/main.ts");
// EXTERNAL MODULE: ./src/main/Attachment.ts
var Attachment = __webpack_require__("./src/main/Attachment.ts");
// EXTERNAL MODULE: ./src/main/Chapter.ts
var Chapter = __webpack_require__("./src/main/Chapter.ts");
// EXTERNAL MODULE: ./src/main/Book.ts + 1 modules
var Book = __webpack_require__("./src/main/Book.ts");
// EXTERNAL MODULE: ./src/rules.ts + 12 modules
var rules = __webpack_require__("./src/rules.ts");
// EXTERNAL MODULE: ./src/setting.ts
var setting = __webpack_require__("./src/setting.ts");
;// CONCATENATED MODULE: ./src/rules/lib/jjwxcFontDecode.ts
async function replaceJjwxcCharacter(fontName, inputText) {
let outputText = inputText;
const jjwxcFontTable = await getJjwxcFontTable(fontName);
if (jjwxcFontTable) {
for (const jjwxcCharacter in jjwxcFontTable) {
if (Object.prototype.hasOwnProperty.call(jjwxcFontTable, jjwxcCharacter)) {
const normalCharacter = jjwxcFontTable[jjwxcCharacter];
outputText = outputText.replaceAll(jjwxcCharacter, normalCharacter);
}
}
outputText = outputText.replace(/\u200c/g, "");
}
return outputText;
}
async function getJjwxcFontTable(fontName) {
const jjwxcFontTableLocal = false;
if (jjwxcFontTableLocal) {
return jjwxcFontTableLocal;
}
else if (setting/* enableJjwxcRemoteFont */.Z3) {
return await fetchRemoteFont(fontName);
}
else {
return undefined;
}
}
async function fetchRemoteFont(fontName) {
const url = `https://jjwxc.bgme.bid/api/${fontName}/table`;
loglevel_default().info(`[jjwxc-font]开始请求远程字体对照表 ${fontName}`);
let retry = setting/* retryLimit */.o5;
while (retry > 0) {
let resp;
try {
resp = await fetch(url);
}
catch (error) {
loglevel_default().error(error);
retry--;
if (retry > 0) {
await (0,misc/* sleep */._v)(5000);
continue;
}
else {
loglevel_default().info(`[jjwxc-font]远程字体对照表 ${fontName} 下载失败`);
return undefined;
}
}
if (resp.ok) {
loglevel_default().info(`[jjwxc-font]远程字体对照表 ${fontName} 下载成功`);
return (await resp.json());
}
else {
retry--;
if (retry > 0) {
await (0,misc/* sleep */._v)(5000);
}
else {
loglevel_default().info(`[jjwxc-font]远程字体对照表 ${fontName} 下载失败`);
return undefined;
}
}
}
}
// EXTERNAL MODULE: ./src/lib/GM.ts
var GM = __webpack_require__("./src/lib/GM.ts");
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/types.js
// CSS Syntax Module Level 3
// https://www.w3.org/TR/css-syntax-3/
const EOF = 0; //
const Ident = 1; //
const Function = 2; //
const AtKeyword = 3; //
const Hash = 4; //
const types_String = 5; //
const BadString = 6; //
const Url = 7; //
const BadUrl = 8; //
const Delim = 9; //
const types_Number = 10; //
const Percentage = 11; //
const Dimension = 12; //
const WhiteSpace = 13; //
const CDO = 14; //
const CDC = 15; //
const Colon = 16; // :
const Semicolon = 17; // ;
const Comma = 18; // ,
const LeftSquareBracket = 19; // <[-token>
const RightSquareBracket = 20; // <]-token>
const LeftParenthesis = 21; // <(-token>
const RightParenthesis = 22; // <)-token>
const LeftCurlyBracket = 23; // <{-token>
const RightCurlyBracket = 24; // <}-token>
const Comment = 25;
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/char-code-definitions.js
const char_code_definitions_EOF = 0;
// https://drafts.csswg.org/css-syntax-3/
// § 4.2. Definitions
// digit
// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
function isDigit(code) {
return code >= 0x0030 && code <= 0x0039;
}
// hex digit
// A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
// or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
function isHexDigit(code) {
return (
isDigit(code) || // 0 .. 9
(code >= 0x0041 && code <= 0x0046) || // A .. F
(code >= 0x0061 && code <= 0x0066) // a .. f
);
}
// uppercase letter
// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
function isUppercaseLetter(code) {
return code >= 0x0041 && code <= 0x005A;
}
// lowercase letter
// A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
function isLowercaseLetter(code) {
return code >= 0x0061 && code <= 0x007A;
}
// letter
// An uppercase letter or a lowercase letter.
function isLetter(code) {
return isUppercaseLetter(code) || isLowercaseLetter(code);
}
// non-ASCII code point
// A code point with a value equal to or greater than U+0080 .
function isNonAscii(code) {
return code >= 0x0080;
}
// name-start code point
// A letter, a non-ASCII code point, or U+005F LOW LINE (_).
function isNameStart(code) {
return isLetter(code) || isNonAscii(code) || code === 0x005F;
}
// name code point
// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
function char_code_definitions_isName(code) {
return isNameStart(code) || isDigit(code) || code === 0x002D;
}
// non-printable code point
// A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
// or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
function isNonPrintable(code) {
return (
(code >= 0x0000 && code <= 0x0008) ||
(code === 0x000B) ||
(code >= 0x000E && code <= 0x001F) ||
(code === 0x007F)
);
}
// newline
// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
// as they are converted to U+000A LINE FEED during preprocessing.
// TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
function isNewline(code) {
return code === 0x000A || code === 0x000D || code === 0x000C;
}
// whitespace
// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
function isWhiteSpace(code) {
return isNewline(code) || code === 0x0020 || code === 0x0009;
}
// § 4.3.8. Check if two code points are a valid escape
function char_code_definitions_isValidEscape(first, second) {
// If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
if (first !== 0x005C) {
return false;
}
// Otherwise, if the second code point is a newline or EOF, return false.
if (isNewline(second) || second === char_code_definitions_EOF) {
return false;
}
// Otherwise, return true.
return true;
}
// § 4.3.9. Check if three code points would start an identifier
function isIdentifierStart(first, second, third) {
// Look at the first code point:
// U+002D HYPHEN-MINUS
if (first === 0x002D) {
// If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
// or the second and third code points are a valid escape, return true. Otherwise, return false.
return (
isNameStart(second) ||
second === 0x002D ||
char_code_definitions_isValidEscape(second, third)
);
}
// name-start code point
if (isNameStart(first)) {
// Return true.
return true;
}
// U+005C REVERSE SOLIDUS (\)
if (first === 0x005C) {
// If the first and second code points are a valid escape, return true. Otherwise, return false.
return char_code_definitions_isValidEscape(first, second);
}
// anything else
// Return false.
return false;
}
// § 4.3.10. Check if three code points would start a number
function isNumberStart(first, second, third) {
// Look at the first code point:
// U+002B PLUS SIGN (+)
// U+002D HYPHEN-MINUS (-)
if (first === 0x002B || first === 0x002D) {
// If the second code point is a digit, return true.
if (isDigit(second)) {
return 2;
}
// Otherwise, if the second code point is a U+002E FULL STOP (.)
// and the third code point is a digit, return true.
// Otherwise, return false.
return second === 0x002E && isDigit(third) ? 3 : 0;
}
// U+002E FULL STOP (.)
if (first === 0x002E) {
// If the second code point is a digit, return true. Otherwise, return false.
return isDigit(second) ? 2 : 0;
}
// digit
if (isDigit(first)) {
// Return true.
return 1;
}
// anything else
// Return false.
return 0;
}
//
// Misc
//
// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
function isBOM(code) {
// UTF-16BE
if (code === 0xFEFF) {
return 1;
}
// UTF-16LE
if (code === 0xFFFE) {
return 1;
}
return 0;
}
// Fast code category
// Only ASCII code points has a special meaning, that's why we define a maps for 0..127 codes only
const CATEGORY = new Array(0x80);
const EofCategory = 0x80;
const WhiteSpaceCategory = 0x82;
const DigitCategory = 0x83;
const NameStartCategory = 0x84;
const NonPrintableCategory = 0x85;
for (let i = 0; i < CATEGORY.length; i++) {
CATEGORY[i] =
isWhiteSpace(i) && WhiteSpaceCategory ||
isDigit(i) && DigitCategory ||
isNameStart(i) && NameStartCategory ||
isNonPrintable(i) && NonPrintableCategory ||
i || EofCategory;
}
function charCodeCategory(code) {
return code < 0x80 ? CATEGORY[code] : NameStartCategory;
}
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/utils.js
function getCharCode(source, offset) {
return offset < source.length ? source.charCodeAt(offset) : 0;
}
function getNewlineLength(source, offset, code) {
if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
return 2;
}
return 1;
}
function cmpChar(testStr, offset, referenceCode) {
let code = testStr.charCodeAt(offset);
// code.toLowerCase() for A..Z
if (isUppercaseLetter(code)) {
code = code | 32;
}
return code === referenceCode;
}
function cmpStr(testStr, start, end, referenceStr) {
if (end - start !== referenceStr.length) {
return false;
}
if (start < 0 || end > testStr.length) {
return false;
}
for (let i = start; i < end; i++) {
const referenceCode = referenceStr.charCodeAt(i - start);
let testCode = testStr.charCodeAt(i);
// testCode.toLowerCase() for A..Z
if (isUppercaseLetter(testCode)) {
testCode = testCode | 32;
}
if (testCode !== referenceCode) {
return false;
}
}
return true;
}
function findWhiteSpaceStart(source, offset) {
for (; offset >= 0; offset--) {
if (!isWhiteSpace(source.charCodeAt(offset))) {
break;
}
}
return offset + 1;
}
function findWhiteSpaceEnd(source, offset) {
for (; offset < source.length; offset++) {
if (!isWhiteSpace(source.charCodeAt(offset))) {
break;
}
}
return offset;
}
function findDecimalNumberEnd(source, offset) {
for (; offset < source.length; offset++) {
if (!isDigit(source.charCodeAt(offset))) {
break;
}
}
return offset;
}
// § 4.3.7. Consume an escaped code point
function utils_consumeEscaped(source, offset) {
// It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
// that the next input code point has already been verified to be part of a valid escape.
offset += 2;
// hex digit
if (isHexDigit(getCharCode(source, offset - 1))) {
// Consume as many hex digits as possible, but no more than 5.
// Note that this means 1-6 hex digits have been consumed in total.
for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
if (!isHexDigit(getCharCode(source, offset))) {
break;
}
}
// If the next input code point is whitespace, consume it as well.
const code = getCharCode(source, offset);
if (isWhiteSpace(code)) {
offset += getNewlineLength(source, offset, code);
}
}
return offset;
}
// §4.3.11. Consume a name
// Note: This algorithm does not do the verification of the first few code points that are necessary
// to ensure the returned code points would constitute an . If that is the intended use,
// ensure that the stream starts with an identifier before calling this algorithm.
function consumeName(source, offset) {
// Let result initially be an empty string.
// Repeatedly consume the next input code point from the stream:
for (; offset < source.length; offset++) {
const code = source.charCodeAt(offset);
// name code point
if (char_code_definitions_isName(code)) {
// Append the code point to result.
continue;
}
// the stream starts with a valid escape
if (char_code_definitions_isValidEscape(code, getCharCode(source, offset + 1))) {
// Consume an escaped code point. Append the returned code point to result.
offset = utils_consumeEscaped(source, offset) - 1;
continue;
}
// anything else
// Reconsume the current input code point. Return result.
break;
}
return offset;
}
// §4.3.12. Consume a number
function consumeNumber(source, offset) {
let code = source.charCodeAt(offset);
// 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
// consume it and append it to repr.
if (code === 0x002B || code === 0x002D) {
code = source.charCodeAt(offset += 1);
}
// 3. While the next input code point is a digit, consume it and append it to repr.
if (isDigit(code)) {
offset = findDecimalNumberEnd(source, offset + 1);
code = source.charCodeAt(offset);
}
// 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
if (code === 0x002E && isDigit(source.charCodeAt(offset + 1))) {
// 4.1 Consume them.
// 4.2 Append them to repr.
offset += 2;
// 4.3 Set type to "number".
// TODO
// 4.4 While the next input code point is a digit, consume it and append it to repr.
offset = findDecimalNumberEnd(source, offset);
}
// 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
// or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
if (cmpChar(source, offset, 101 /* e */)) {
let sign = 0;
code = source.charCodeAt(offset + 1);
// ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
if (code === 0x002D || code === 0x002B) {
sign = 1;
code = source.charCodeAt(offset + 2);
}
// ... followed by a digit
if (isDigit(code)) {
// 5.1 Consume them.
// 5.2 Append them to repr.
// 5.3 Set type to "number".
// TODO
// 5.4 While the next input code point is a digit, consume it and append it to repr.
offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
}
}
return offset;
}
// § 4.3.14. Consume the remnants of a bad url
// ... its sole use is to consume enough of the input stream to reach a recovery point
// where normal tokenizing can resume.
function consumeBadUrlRemnants(source, offset) {
// Repeatedly consume the next input code point from the stream:
for (; offset < source.length; offset++) {
const code = source.charCodeAt(offset);
// U+0029 RIGHT PARENTHESIS ())
// EOF
if (code === 0x0029) {
// Return.
offset++;
break;
}
if (char_code_definitions_isValidEscape(code, getCharCode(source, offset + 1))) {
// Consume an escaped code point.
// Note: This allows an escaped right parenthesis ("\)") to be encountered
// without ending the . This is otherwise identical to
// the "anything else" clause.
offset = utils_consumeEscaped(source, offset);
}
}
return offset;
}
// § 4.3.7. Consume an escaped code point
// Note: This algorithm assumes that escaped is valid without leading U+005C REVERSE SOLIDUS (\)
function utils_decodeEscaped(escaped) {
// Single char escaped that's not a hex digit
if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) {
return escaped[0];
}
// Interpret the hex digits as a hexadecimal number.
let code = parseInt(escaped, 16);
if (
(code === 0) || // If this number is zero,
(code >= 0xD800 && code <= 0xDFFF) || // or is for a surrogate,
(code > 0x10FFFF) // or is greater than the maximum allowed code point
) {
// ... return U+FFFD REPLACEMENT CHARACTER
code = 0xFFFD;
}
// Otherwise, return the code point with that value.
return String.fromCodePoint(code);
}
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/names.js
/* harmony default export */ const names = ([
'EOF-token',
'ident-token',
'function-token',
'at-keyword-token',
'hash-token',
'string-token',
'bad-string-token',
'url-token',
'bad-url-token',
'delim-token',
'number-token',
'percentage-token',
'dimension-token',
'whitespace-token',
'CDO-token',
'CDC-token',
'colon-token',
'semicolon-token',
'comma-token',
'[-token',
']-token',
'(-token',
')-token',
'{-token',
'}-token'
]);
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/adopt-buffer.js
const MIN_SIZE = 16 * 1024;
function adoptBuffer(buffer = null, size) {
if (buffer === null || buffer.length < size) {
return new Uint32Array(Math.max(size + 1024, MIN_SIZE));
}
return buffer;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/OffsetToLocation.js
const N = 10;
const F = 12;
const R = 13;
function computeLinesAndColumns(host) {
const source = host.source;
const sourceLength = source.length;
const startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0;
const lines = adoptBuffer(host.lines, sourceLength);
const columns = adoptBuffer(host.columns, sourceLength);
let line = host.startLine;
let column = host.startColumn;
for (let i = startOffset; i < sourceLength; i++) {
const code = source.charCodeAt(i);
lines[i] = line;
columns[i] = column++;
if (code === N || code === R || code === F) {
if (code === R && i + 1 < sourceLength && source.charCodeAt(i + 1) === N) {
i++;
lines[i] = line;
columns[i] = column;
}
line++;
column = 1;
}
}
lines[sourceLength] = line;
columns[sourceLength] = column;
host.lines = lines;
host.columns = columns;
host.computed = true;
}
class OffsetToLocation {
constructor() {
this.lines = null;
this.columns = null;
this.computed = false;
}
setSource(source, startOffset = 0, startLine = 1, startColumn = 1) {
this.source = source;
this.startOffset = startOffset;
this.startLine = startLine;
this.startColumn = startColumn;
this.computed = false;
}
getLocation(offset, filename) {
if (!this.computed) {
computeLinesAndColumns(this);
}
return {
source: filename,
offset: this.startOffset + offset,
line: this.lines[offset],
column: this.columns[offset]
};
}
getLocationRange(start, end, filename) {
if (!this.computed) {
computeLinesAndColumns(this);
}
return {
source: filename,
start: {
offset: this.startOffset + start,
line: this.lines[start],
column: this.columns[start]
},
end: {
offset: this.startOffset + end,
line: this.lines[end],
column: this.columns[end]
}
};
}
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/TokenStream.js
const OFFSET_MASK = 0x00FFFFFF;
const TYPE_SHIFT = 24;
const balancePair = new Map([
[Function, RightParenthesis],
[LeftParenthesis, RightParenthesis],
[LeftSquareBracket, RightSquareBracket],
[LeftCurlyBracket, RightCurlyBracket]
]);
class TokenStream {
constructor(source, tokenize) {
this.setSource(source, tokenize);
}
reset() {
this.eof = false;
this.tokenIndex = -1;
this.tokenType = 0;
this.tokenStart = this.firstCharOffset;
this.tokenEnd = this.firstCharOffset;
}
setSource(source = '', tokenize = () => {}) {
source = String(source || '');
const sourceLength = source.length;
const offsetAndType = adoptBuffer(this.offsetAndType, source.length + 1); // +1 because of eof-token
const balance = adoptBuffer(this.balance, source.length + 1);
let tokenCount = 0;
let balanceCloseType = 0;
let balanceStart = 0;
let firstCharOffset = -1;
// capture buffers
this.offsetAndType = null;
this.balance = null;
tokenize(source, (type, start, end) => {
switch (type) {
default:
balance[tokenCount] = sourceLength;
break;
case balanceCloseType: {
let balancePrev = balanceStart & OFFSET_MASK;
balanceStart = balance[balancePrev];
balanceCloseType = balanceStart >> TYPE_SHIFT;
balance[tokenCount] = balancePrev;
balance[balancePrev++] = tokenCount;
for (; balancePrev < tokenCount; balancePrev++) {
if (balance[balancePrev] === sourceLength) {
balance[balancePrev] = tokenCount;
}
}
break;
}
case LeftParenthesis:
case Function:
case LeftSquareBracket:
case LeftCurlyBracket:
balance[tokenCount] = balanceStart;
balanceCloseType = balancePair.get(type);
balanceStart = (balanceCloseType << TYPE_SHIFT) | tokenCount;
break;
}
offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | end;
if (firstCharOffset === -1) {
firstCharOffset = start;
}
});
// finalize buffers
offsetAndType[tokenCount] = (EOF << TYPE_SHIFT) | sourceLength; //
balance[tokenCount] = sourceLength;
balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
while (balanceStart !== 0) {
const balancePrev = balanceStart & OFFSET_MASK;
balanceStart = balance[balancePrev];
balance[balancePrev] = sourceLength;
}
this.source = source;
this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset;
this.tokenCount = tokenCount;
this.offsetAndType = offsetAndType;
this.balance = balance;
this.reset();
this.next();
}
lookupType(offset) {
offset += this.tokenIndex;
if (offset < this.tokenCount) {
return this.offsetAndType[offset] >> TYPE_SHIFT;
}
return EOF;
}
lookupOffset(offset) {
offset += this.tokenIndex;
if (offset < this.tokenCount) {
return this.offsetAndType[offset - 1] & OFFSET_MASK;
}
return this.source.length;
}
lookupValue(offset, referenceStr) {
offset += this.tokenIndex;
if (offset < this.tokenCount) {
return cmpStr(
this.source,
this.offsetAndType[offset - 1] & OFFSET_MASK,
this.offsetAndType[offset] & OFFSET_MASK,
referenceStr
);
}
return false;
}
getTokenStart(tokenIndex) {
if (tokenIndex === this.tokenIndex) {
return this.tokenStart;
}
if (tokenIndex > 0) {
return tokenIndex < this.tokenCount
? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK
: this.offsetAndType[this.tokenCount] & OFFSET_MASK;
}
return this.firstCharOffset;
}
substrToCursor(start) {
return this.source.substring(start, this.tokenStart);
}
isBalanceEdge(pos) {
return this.balance[this.tokenIndex] < pos;
}
isDelim(code, offset) {
if (offset) {
return (
this.lookupType(offset) === Delim &&
this.source.charCodeAt(this.lookupOffset(offset)) === code
);
}
return (
this.tokenType === Delim &&
this.source.charCodeAt(this.tokenStart) === code
);
}
skip(tokenCount) {
let next = this.tokenIndex + tokenCount;
if (next < this.tokenCount) {
this.tokenIndex = next;
this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
next = this.offsetAndType[next];
this.tokenType = next >> TYPE_SHIFT;
this.tokenEnd = next & OFFSET_MASK;
} else {
this.tokenIndex = this.tokenCount;
this.next();
}
}
next() {
let next = this.tokenIndex + 1;
if (next < this.tokenCount) {
this.tokenIndex = next;
this.tokenStart = this.tokenEnd;
next = this.offsetAndType[next];
this.tokenType = next >> TYPE_SHIFT;
this.tokenEnd = next & OFFSET_MASK;
} else {
this.eof = true;
this.tokenIndex = this.tokenCount;
this.tokenType = EOF;
this.tokenStart = this.tokenEnd = this.source.length;
}
}
skipSC() {
while (this.tokenType === WhiteSpace || this.tokenType === Comment) {
this.next();
}
}
skipUntilBalanced(startToken, stopConsume) {
let cursor = startToken;
let balanceEnd;
let offset;
loop:
for (; cursor < this.tokenCount; cursor++) {
balanceEnd = this.balance[cursor];
// stop scanning on balance edge that points to offset before start token
if (balanceEnd < startToken) {
break loop;
}
offset = cursor > 0 ? this.offsetAndType[cursor - 1] & OFFSET_MASK : this.firstCharOffset;
// check stop condition
switch (stopConsume(this.source.charCodeAt(offset))) {
case 1: // just stop
break loop;
case 2: // stop & included
cursor++;
break loop;
default:
// fast forward to the end of balanced block
if (this.balance[balanceEnd] === cursor) {
cursor = balanceEnd;
}
}
}
this.skip(cursor - this.tokenIndex);
}
forEachToken(fn) {
for (let i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) {
const start = offset;
const item = this.offsetAndType[i];
const end = item & OFFSET_MASK;
const type = item >> TYPE_SHIFT;
offset = end;
fn(type, start, end, i);
}
}
dump() {
const tokens = new Array(this.tokenCount);
this.forEachToken((type, start, end, index) => {
tokens[index] = {
idx: index,
type: names[type],
chunk: this.source.substring(start, end),
balance: this.balance[index]
};
});
return tokens;
}
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/tokenizer/index.js
function tokenize(source, onToken) {
function getCharCode(offset) {
return offset < sourceLength ? source.charCodeAt(offset) : 0;
}
// § 4.3.3. Consume a numeric token
function consumeNumericToken() {
// Consume a number and let number be the result.
offset = consumeNumber(source, offset);
// If the next 3 input code points would start an identifier, then:
if (isIdentifierStart(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
// Create a with the same value and type flag as number, and a unit set initially to the empty string.
// Consume a name. Set the ’s unit to the returned value.
// Return the .
type = Dimension;
offset = consumeName(source, offset);
return;
}
// Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
if (getCharCode(offset) === 0x0025) {
// Create a with the same value as number, and return it.
type = Percentage;
offset++;
return;
}
// Otherwise, create a with the same value and type flag as number, and return it.
type = types_Number;
}
// § 4.3.4. Consume an ident-like token
function consumeIdentLikeToken() {
const nameStartOffset = offset;
// Consume a name, and let string be the result.
offset = consumeName(source, offset);
// If string’s value is an ASCII case-insensitive match for "url",
// and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
if (cmpStr(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
// While the next two input code points are whitespace, consume the next input code point.
offset = findWhiteSpaceEnd(source, offset + 1);
// If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
// or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
// then create a with its value set to string and return it.
if (getCharCode(offset) === 0x0022 ||
getCharCode(offset) === 0x0027) {
type = Function;
offset = nameStartOffset + 4;
return;
}
// Otherwise, consume a url token, and return it.
consumeUrlToken();
return;
}
// Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
// Create a with its value set to string and return it.
if (getCharCode(offset) === 0x0028) {
type = Function;
offset++;
return;
}
// Otherwise, create an with its value set to string and return it.
type = Ident;
}
// § 4.3.5. Consume a string token
function consumeStringToken(endingCodePoint) {
// This algorithm may be called with an ending code point, which denotes the code point
// that ends the string. If an ending code point is not specified,
// the current input code point is used.
if (!endingCodePoint) {
endingCodePoint = getCharCode(offset++);
}
// Initially create a with its value set to the empty string.
type = types_String;
// Repeatedly consume the next input code point from the stream:
for (; offset < source.length; offset++) {
const code = source.charCodeAt(offset);
switch (charCodeCategory(code)) {
// ending code point
case endingCodePoint:
// Return the .
offset++;
return;
// EOF
// case EofCategory:
// This is a parse error. Return the .
// return;
// newline
case WhiteSpaceCategory:
if (isNewline(code)) {
// This is a parse error. Reconsume the current input code point,
// create a , and return it.
offset += getNewlineLength(source, offset, code);
type = BadString;
return;
}
break;
// U+005C REVERSE SOLIDUS (\)
case 0x005C:
// If the next input code point is EOF, do nothing.
if (offset === source.length - 1) {
break;
}
const nextCode = getCharCode(offset + 1);
// Otherwise, if the next input code point is a newline, consume it.
if (isNewline(nextCode)) {
offset += getNewlineLength(source, offset + 1, nextCode);
} else if (char_code_definitions_isValidEscape(code, nextCode)) {
// Otherwise, (the stream starts with a valid escape) consume
// an escaped code point and append the returned code point to
// the ’s value.
offset = utils_consumeEscaped(source, offset) - 1;
}
break;
// anything else
// Append the current input code point to the ’s value.
}
}
}
// § 4.3.6. Consume a url token
// Note: This algorithm assumes that the initial "url(" has already been consumed.
// This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
// A quoted value, like url("foo"), is parsed as a . Consume an ident-like token
// automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
function consumeUrlToken() {
// Initially create a with its value set to the empty string.
type = Url;
// Consume as much whitespace as possible.
offset = findWhiteSpaceEnd(source, offset);
// Repeatedly consume the next input code point from the stream:
for (; offset < source.length; offset++) {
const code = source.charCodeAt(offset);
switch (charCodeCategory(code)) {
// U+0029 RIGHT PARENTHESIS ())
case 0x0029:
// Return the .
offset++;
return;
// EOF
// case EofCategory:
// This is a parse error. Return the .
// return;
// whitespace
case WhiteSpaceCategory:
// Consume as much whitespace as possible.
offset = findWhiteSpaceEnd(source, offset);
// If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
// consume it and return the
// (if EOF was encountered, this is a parse error);
if (getCharCode(offset) === 0x0029 || offset >= source.length) {
if (offset < source.length) {
offset++;
}
return;
}
// otherwise, consume the remnants of a bad url, create a ,
// and return it.
offset = consumeBadUrlRemnants(source, offset);
type = BadUrl;
return;
// U+0022 QUOTATION MARK (")
// U+0027 APOSTROPHE (')
// U+0028 LEFT PARENTHESIS (()
// non-printable code point
case 0x0022:
case 0x0027:
case 0x0028:
case NonPrintableCategory:
// This is a parse error. Consume the remnants of a bad url,
// create a , and return it.
offset = consumeBadUrlRemnants(source, offset);
type = BadUrl;
return;
// U+005C REVERSE SOLIDUS (\)
case 0x005C:
// If the stream starts with a valid escape, consume an escaped code point and
// append the returned code point to the ’s value.
if (char_code_definitions_isValidEscape(code, getCharCode(offset + 1))) {
offset = utils_consumeEscaped(source, offset) - 1;
break;
}
// Otherwise, this is a parse error. Consume the remnants of a bad url,
// create a , and return it.
offset = consumeBadUrlRemnants(source, offset);
type = BadUrl;
return;
// anything else
// Append the current input code point to the ’s value.
}
}
}
// ensure source is a string
source = String(source || '');
const sourceLength = source.length;
let start = isBOM(getCharCode(0));
let offset = start;
let type;
// https://drafts.csswg.org/css-syntax-3/#consume-token
// § 4.3.1. Consume a token
while (offset < sourceLength) {
const code = source.charCodeAt(offset);
switch (charCodeCategory(code)) {
// whitespace
case WhiteSpaceCategory:
// Consume as much whitespace as possible. Return a .
type = WhiteSpace;
offset = findWhiteSpaceEnd(source, offset + 1);
break;
// U+0022 QUOTATION MARK (")
case 0x0022:
// Consume a string token and return it.
consumeStringToken();
break;
// U+0023 NUMBER SIGN (#)
case 0x0023:
// If the next input code point is a name code point or the next two input code points are a valid escape, then:
if (char_code_definitions_isName(getCharCode(offset + 1)) || char_code_definitions_isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) {
// Create a .
type = Hash;
// If the next 3 input code points would start an identifier, set the ’s type flag to "id".
// if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
// // TODO: set id flag
// }
// Consume a name, and set the ’s value to the returned string.
offset = consumeName(source, offset + 1);
// Return the .
} else {
// Otherwise, return a with its value set to the current input code point.
type = Delim;
offset++;
}
break;
// U+0027 APOSTROPHE (')
case 0x0027:
// Consume a string token and return it.
consumeStringToken();
break;
// U+0028 LEFT PARENTHESIS (()
case 0x0028:
// Return a <(-token>.
type = LeftParenthesis;
offset++;
break;
// U+0029 RIGHT PARENTHESIS ())
case 0x0029:
// Return a <)-token>.
type = RightParenthesis;
offset++;
break;
// U+002B PLUS SIGN (+)
case 0x002B:
// If the input stream starts with a number, ...
if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
// ... reconsume the current input code point, consume a numeric token, and return it.
consumeNumericToken();
} else {
// Otherwise, return a with its value set to the current input code point.
type = Delim;
offset++;
}
break;
// U+002C COMMA (,)
case 0x002C:
// Return a .
type = Comma;
offset++;
break;
// U+002D HYPHEN-MINUS (-)
case 0x002D:
// If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
consumeNumericToken();
} else {
// Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a .
if (getCharCode(offset + 1) === 0x002D &&
getCharCode(offset + 2) === 0x003E) {
type = CDC;
offset = offset + 3;
} else {
// Otherwise, if the input stream starts with an identifier, ...
if (isIdentifierStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
// ... reconsume the current input code point, consume an ident-like token, and return it.
consumeIdentLikeToken();
} else {
// Otherwise, return a with its value set to the current input code point.
type = Delim;
offset++;
}
}
}
break;
// U+002E FULL STOP (.)
case 0x002E:
// If the input stream starts with a number, ...
if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
// ... reconsume the current input code point, consume a numeric token, and return it.
consumeNumericToken();
} else {
// Otherwise, return a with its value set to the current input code point.
type = Delim;
offset++;
}
break;
// U+002F SOLIDUS (/)
case 0x002F:
// If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
if (getCharCode(offset + 1) === 0x002A) {
// ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
// followed by a U+002F SOLIDUS (/), or up to an EOF code point.
type = Comment;
offset = source.indexOf('*/', offset + 2);
offset = offset === -1 ? source.length : offset + 2;
} else {
type = Delim;
offset++;
}
break;
// U+003A COLON (:)
case 0x003A:
// Return a .
type = Colon;
offset++;
break;
// U+003B SEMICOLON (;)
case 0x003B:
// Return a .
type = Semicolon;
offset++;
break;
// U+003C LESS-THAN SIGN (<)
case 0x003C:
// If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
if (getCharCode(offset + 1) === 0x0021 &&
getCharCode(offset + 2) === 0x002D &&
getCharCode(offset + 3) === 0x002D) {
// ... consume them and return a .
type = CDO;
offset = offset + 4;
} else {
// Otherwise, return a with its value set to the current input code point.
type = Delim;
offset++;
}
break;
// U+0040 COMMERCIAL AT (@)
case 0x0040:
// If the next 3 input code points would start an identifier, ...
if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
// ... consume a name, create an with its value set to the returned value, and return it.
type = AtKeyword;
offset = consumeName(source, offset + 1);
} else {
// Otherwise, return a with its value set to the current input code point.
type = Delim;
offset++;
}
break;
// U+005B LEFT SQUARE BRACKET ([)
case 0x005B:
// Return a <[-token>.
type = LeftSquareBracket;
offset++;
break;
// U+005C REVERSE SOLIDUS (\)
case 0x005C:
// If the input stream starts with a valid escape, ...
if (char_code_definitions_isValidEscape(code, getCharCode(offset + 1))) {
// ... reconsume the current input code point, consume an ident-like token, and return it.
consumeIdentLikeToken();
} else {
// Otherwise, this is a parse error. Return a with its value set to the current input code point.
type = Delim;
offset++;
}
break;
// U+005D RIGHT SQUARE BRACKET (])
case 0x005D:
// Return a <]-token>.
type = RightSquareBracket;
offset++;
break;
// U+007B LEFT CURLY BRACKET ({)
case 0x007B:
// Return a <{-token>.
type = LeftCurlyBracket;
offset++;
break;
// U+007D RIGHT CURLY BRACKET (})
case 0x007D:
// Return a <}-token>.
type = RightCurlyBracket;
offset++;
break;
// digit
case DigitCategory:
// Reconsume the current input code point, consume a numeric token, and return it.
consumeNumericToken();
break;
// name-start code point
case NameStartCategory:
// Reconsume the current input code point, consume an ident-like token, and return it.
consumeIdentLikeToken();
break;
// EOF
// case EofCategory:
// Return an .
// break;
// anything else
default:
// Return a with its value set to the current input code point.
type = Delim;
offset++;
}
// put token to stream
onToken(type, start, start = offset);
}
}
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/utils/List.js
//
// list
// ┌──────┐
// ┌──────────────┼─head │
// │ │ tail─┼──────────────┐
// │ └──────┘ │
// ▼ ▼
// item item item item
// ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
// null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
// │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
// ├──────┤ ├──────┤ ├──────┤ ├──────┤
// │ data │ │ data │ │ data │ │ data │
// └──────┘ └──────┘ └──────┘ └──────┘
//
let releasedCursors = null;
class List_List {
static createItem(data) {
return {
prev: null,
next: null,
data
};
}
constructor() {
this.head = null;
this.tail = null;
this.cursor = null;
}
createItem(data) {
return List_List.createItem(data);
}
// cursor helpers
allocateCursor(prev, next) {
let cursor;
if (releasedCursors !== null) {
cursor = releasedCursors;
releasedCursors = releasedCursors.cursor;
cursor.prev = prev;
cursor.next = next;
cursor.cursor = this.cursor;
} else {
cursor = {
prev,
next,
cursor: this.cursor
};
}
this.cursor = cursor;
return cursor;
}
releaseCursor() {
const { cursor } = this;
this.cursor = cursor.cursor;
cursor.prev = null;
cursor.next = null;
cursor.cursor = releasedCursors;
releasedCursors = cursor;
}
updateCursors(prevOld, prevNew, nextOld, nextNew) {
let { cursor } = this;
while (cursor !== null) {
if (cursor.prev === prevOld) {
cursor.prev = prevNew;
}
if (cursor.next === nextOld) {
cursor.next = nextNew;
}
cursor = cursor.cursor;
}
}
*[Symbol.iterator]() {
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
yield cursor.data;
}
}
// getters
get size() {
let size = 0;
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
size++;
}
return size;
}
get isEmpty() {
return this.head === null;
}
get first() {
return this.head && this.head.data;
}
get last() {
return this.tail && this.tail.data;
}
// convertors
fromArray(array) {
let cursor = null;
this.head = null;
for (let data of array) {
const item = List_List.createItem(data);
if (cursor !== null) {
cursor.next = item;
} else {
this.head = item;
}
item.prev = cursor;
cursor = item;
}
this.tail = cursor;
return this;
}
toArray() {
return [...this];
}
toJSON() {
return [...this];
}
// array-like methods
forEach(fn, thisArg = this) {
// push cursor
const cursor = this.allocateCursor(null, this.head);
while (cursor.next !== null) {
const item = cursor.next;
cursor.next = item.next;
fn.call(thisArg, item.data, item, this);
}
// pop cursor
this.releaseCursor();
}
forEachRight(fn, thisArg = this) {
// push cursor
const cursor = this.allocateCursor(this.tail, null);
while (cursor.prev !== null) {
const item = cursor.prev;
cursor.prev = item.prev;
fn.call(thisArg, item.data, item, this);
}
// pop cursor
this.releaseCursor();
}
reduce(fn, initialValue, thisArg = this) {
// push cursor
let cursor = this.allocateCursor(null, this.head);
let acc = initialValue;
let item;
while (cursor.next !== null) {
item = cursor.next;
cursor.next = item.next;
acc = fn.call(thisArg, acc, item.data, item, this);
}
// pop cursor
this.releaseCursor();
return acc;
}
reduceRight(fn, initialValue, thisArg = this) {
// push cursor
let cursor = this.allocateCursor(this.tail, null);
let acc = initialValue;
let item;
while (cursor.prev !== null) {
item = cursor.prev;
cursor.prev = item.prev;
acc = fn.call(thisArg, acc, item.data, item, this);
}
// pop cursor
this.releaseCursor();
return acc;
}
some(fn, thisArg = this) {
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
if (fn.call(thisArg, cursor.data, cursor, this)) {
return true;
}
}
return false;
}
map(fn, thisArg = this) {
const result = new List_List();
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
result.appendData(fn.call(thisArg, cursor.data, cursor, this));
}
return result;
}
filter(fn, thisArg = this) {
const result = new List_List();
for (let cursor = this.head; cursor !== null; cursor = cursor.next) {
if (fn.call(thisArg, cursor.data, cursor, this)) {
result.appendData(cursor.data);
}
}
return result;
}
nextUntil(start, fn, thisArg = this) {
if (start === null) {
return;
}
// push cursor
const cursor = this.allocateCursor(null, start);
while (cursor.next !== null) {
const item = cursor.next;
cursor.next = item.next;
if (fn.call(thisArg, item.data, item, this)) {
break;
}
}
// pop cursor
this.releaseCursor();
}
prevUntil(start, fn, thisArg = this) {
if (start === null) {
return;
}
// push cursor
const cursor = this.allocateCursor(start, null);
while (cursor.prev !== null) {
const item = cursor.prev;
cursor.prev = item.prev;
if (fn.call(thisArg, item.data, item, this)) {
break;
}
}
// pop cursor
this.releaseCursor();
}
// mutation
clear() {
this.head = null;
this.tail = null;
}
copy() {
const result = new List_List();
for (let data of this) {
result.appendData(data);
}
return result;
}
prepend(item) {
// head
// ^
// item
this.updateCursors(null, item, this.head, item);
// insert to the beginning of the list
if (this.head !== null) {
// new item <- first item
this.head.prev = item;
// new item -> first item
item.next = this.head;
} else {
// if list has no head, then it also has no tail
// in this case tail points to the new item
this.tail = item;
}
// head always points to new item
this.head = item;
return this;
}
prependData(data) {
return this.prepend(List_List.createItem(data));
}
append(item) {
return this.insert(item);
}
appendData(data) {
return this.insert(List_List.createItem(data));
}
insert(item, before = null) {
if (before !== null) {
// prev before
// ^
// item
this.updateCursors(before.prev, item, before, item);
if (before.prev === null) {
// insert to the beginning of list
if (this.head !== before) {
throw new Error('before doesn\'t belong to list');
}
// since head points to before therefore list doesn't empty
// no need to check tail
this.head = item;
before.prev = item;
item.next = before;
this.updateCursors(null, item);
} else {
// insert between two items
before.prev.next = item;
item.prev = before.prev;
before.prev = item;
item.next = before;
}
} else {
// tail
// ^
// item
this.updateCursors(this.tail, item, null, item);
// insert to the ending of the list
if (this.tail !== null) {
// last item -> new item
this.tail.next = item;
// last item <- new item
item.prev = this.tail;
} else {
// if list has no tail, then it also has no head
// in this case head points to new item
this.head = item;
}
// tail always points to new item
this.tail = item;
}
return this;
}
insertData(data, before) {
return this.insert(List_List.createItem(data), before);
}
remove(item) {
// item
// ^
// prev next
this.updateCursors(item, item.prev, item, item.next);
if (item.prev !== null) {
item.prev.next = item.next;
} else {
if (this.head !== item) {
throw new Error('item doesn\'t belong to list');
}
this.head = item.next;
}
if (item.next !== null) {
item.next.prev = item.prev;
} else {
if (this.tail !== item) {
throw new Error('item doesn\'t belong to list');
}
this.tail = item.prev;
}
item.prev = null;
item.next = null;
return item;
}
push(data) {
this.insert(List_List.createItem(data));
}
pop() {
return this.tail !== null ? this.remove(this.tail) : null;
}
unshift(data) {
this.prepend(List_List.createItem(data));
}
shift() {
return this.head !== null ? this.remove(this.head) : null;
}
prependList(list) {
return this.insertList(list, this.head);
}
appendList(list) {
return this.insertList(list);
}
insertList(list, before) {
// ignore empty lists
if (list.head === null) {
return this;
}
if (before !== undefined && before !== null) {
this.updateCursors(before.prev, list.tail, before, list.head);
// insert in the middle of dist list
if (before.prev !== null) {
// before.prev <-> list.head
before.prev.next = list.head;
list.head.prev = before.prev;
} else {
this.head = list.head;
}
before.prev = list.tail;
list.tail.next = before;
} else {
this.updateCursors(this.tail, list.tail, null, list.head);
// insert to end of the list
if (this.tail !== null) {
// if destination list has a tail, then it also has a head,
// but head doesn't change
// dest tail -> source head
this.tail.next = list.head;
// dest tail <- source head
list.head.prev = this.tail;
} else {
// if list has no a tail, then it also has no a head
// in this case points head to new item
this.head = list.head;
}
// tail always start point to new item
this.tail = list.tail;
}
list.head = null;
list.tail = null;
return this;
}
replace(oldItem, newItemOrList) {
if ('head' in newItemOrList) {
this.insertList(newItemOrList, oldItem);
} else {
this.insert(newItemOrList, oldItem);
}
this.remove(oldItem);
}
}
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/utils/create-custom-error.js
function createCustomError(name, message) {
// use Object.create(), because some VMs prevent setting line/column otherwise
// (iOS Safari 10 even throws an exception)
const error = Object.create(SyntaxError.prototype);
const errorStack = new Error();
return Object.assign(error, {
name,
message,
get stack() {
return (errorStack.stack || '').replace(/^(.+\n){1,3}/, `${name}: ${message}\n`);
}
});
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/parser/SyntaxError.js
const MAX_LINE_LENGTH = 100;
const OFFSET_CORRECTION = 60;
const TAB_REPLACEMENT = ' ';
function sourceFragment({ source, line, column }, extraLines) {
function processLines(start, end) {
return lines
.slice(start, end)
.map((line, idx) =>
String(start + idx + 1).padStart(maxNumLength) + ' |' + line
).join('\n');
}
const lines = source.split(/\r\n?|\n|\f/);
const startLine = Math.max(1, line - extraLines) - 1;
const endLine = Math.min(line + extraLines, lines.length + 1);
const maxNumLength = Math.max(4, String(endLine).length) + 1;
let cutLeft = 0;
// column correction according to replaced tab before column
column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
if (column > MAX_LINE_LENGTH) {
cutLeft = column - OFFSET_CORRECTION + 3;
column = OFFSET_CORRECTION - 2;
}
for (let i = startLine; i <= endLine; i++) {
if (i >= 0 && i < lines.length) {
lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
lines[i] =
(cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
(lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
}
}
return [
processLines(startLine, line),
new Array(column + maxNumLength + 2).join('-') + '^',
processLines(line, endLine)
].filter(Boolean).join('\n');
}
function SyntaxError_SyntaxError(message, source, offset, line, column) {
const error = Object.assign(createCustomError('SyntaxError', message), {
source,
offset,
line,
column,
sourceFragment(extraLines) {
return sourceFragment({ source, line, column }, isNaN(extraLines) ? 0 : extraLines);
},
get formattedMessage() {
return (
`Parse error: ${message}\n` +
sourceFragment({ source, line, column }, 2)
);
}
});
return error;
}
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/parser/sequence.js
function readSequence(recognizer) {
const children = this.createList();
let space = false;
const context = {
recognizer
};
while (!this.eof) {
switch (this.tokenType) {
case Comment:
this.next();
continue;
case WhiteSpace:
space = true;
this.next();
continue;
}
let child = recognizer.getNode.call(this, context);
if (child === undefined) {
break;
}
if (space) {
if (recognizer.onWhiteSpace) {
recognizer.onWhiteSpace.call(this, child, children, context);
}
space = false;
}
children.push(child);
}
if (space && recognizer.onWhiteSpace) {
recognizer.onWhiteSpace.call(this, null, children, context);
}
return children;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/parser/create.js
const NOOP = () => {};
const EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)
const NUMBERSIGN = 0x0023; // U+0023 NUMBER SIGN (#)
const SEMICOLON = 0x003B; // U+003B SEMICOLON (;)
const LEFTCURLYBRACKET = 0x007B; // U+007B LEFT CURLY BRACKET ({)
const NULL = 0;
function createParseContext(name) {
return function() {
return this[name]();
};
}
function fetchParseValues(dict) {
const result = Object.create(null);
for (const name in dict) {
const item = dict[name];
const fn = item.parse || item;
if (fn) {
result[name] = fn;
}
}
return result;
}
function processConfig(config) {
const parseConfig = {
context: Object.create(null),
scope: Object.assign(Object.create(null), config.scope),
atrule: fetchParseValues(config.atrule),
pseudo: fetchParseValues(config.pseudo),
node: fetchParseValues(config.node)
};
for (const name in config.parseContext) {
switch (typeof config.parseContext[name]) {
case 'function':
parseConfig.context[name] = config.parseContext[name];
break;
case 'string':
parseConfig.context[name] = createParseContext(config.parseContext[name]);
break;
}
}
return {
config: parseConfig,
...parseConfig,
...parseConfig.node
};
}
function createParser(config) {
let source = '';
let filename = '';
let needPositions = false;
let onParseError = NOOP;
let onParseErrorThrow = false;
const locationMap = new OffsetToLocation();
const parser = Object.assign(new TokenStream(), processConfig(config || {}), {
parseAtrulePrelude: true,
parseRulePrelude: true,
parseValue: true,
parseCustomProperty: false,
readSequence: readSequence,
consumeUntilBalanceEnd: () => 0,
consumeUntilLeftCurlyBracket(code) {
return code === LEFTCURLYBRACKET ? 1 : 0;
},
consumeUntilLeftCurlyBracketOrSemicolon(code) {
return code === LEFTCURLYBRACKET || code === SEMICOLON ? 1 : 0;
},
consumeUntilExclamationMarkOrSemicolon(code) {
return code === EXCLAMATIONMARK || code === SEMICOLON ? 1 : 0;
},
consumeUntilSemicolonIncluded(code) {
return code === SEMICOLON ? 2 : 0;
},
createList() {
return new List_List();
},
createSingleNodeList(node) {
return new List_List().appendData(node);
},
getFirstListNode(list) {
return list && list.first;
},
getLastListNode(list) {
return list && list.last;
},
parseWithFallback(consumer, fallback) {
const startToken = this.tokenIndex;
try {
return consumer.call(this);
} catch (e) {
if (onParseErrorThrow) {
throw e;
}
const fallbackNode = fallback.call(this, startToken);
onParseErrorThrow = true;
onParseError(e, fallbackNode);
onParseErrorThrow = false;
return fallbackNode;
}
},
lookupNonWSType(offset) {
let type;
do {
type = this.lookupType(offset++);
if (type !== WhiteSpace) {
return type;
}
} while (type !== NULL);
return NULL;
},
charCodeAt(offset) {
return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;
},
substring(offsetStart, offsetEnd) {
return source.substring(offsetStart, offsetEnd);
},
substrToCursor(start) {
return this.source.substring(start, this.tokenStart);
},
cmpChar(offset, charCode) {
return cmpChar(source, offset, charCode);
},
cmpStr(offsetStart, offsetEnd, str) {
return cmpStr(source, offsetStart, offsetEnd, str);
},
consume(tokenType) {
const start = this.tokenStart;
this.eat(tokenType);
return this.substrToCursor(start);
},
consumeFunctionName() {
const name = source.substring(this.tokenStart, this.tokenEnd - 1);
this.eat(Function);
return name;
},
consumeNumber(type) {
const number = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart));
this.eat(type);
return number;
},
eat(tokenType) {
if (this.tokenType !== tokenType) {
const tokenName = names[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase());
let message = `${/[[\](){}]/.test(tokenName) ? `"${tokenName}"` : tokenName} is expected`;
let offset = this.tokenStart;
// tweak message and offset
switch (tokenType) {
case Ident:
// when identifier is expected but there is a function or url
if (this.tokenType === Function || this.tokenType === Url) {
offset = this.tokenEnd - 1;
message = 'Identifier is expected but function found';
} else {
message = 'Identifier is expected';
}
break;
case Hash:
if (this.isDelim(NUMBERSIGN)) {
this.next();
offset++;
message = 'Name is expected';
}
break;
case Percentage:
if (this.tokenType === types_Number) {
offset = this.tokenEnd;
message = 'Percent sign is expected';
}
break;
}
this.error(message, offset);
}
this.next();
},
eatIdent(name) {
if (this.tokenType !== Ident || this.lookupValue(0, name) === false) {
this.error(`Identifier "${name}" is expected`);
}
this.next();
},
eatDelim(code) {
if (!this.isDelim(code)) {
this.error(`Delim "${String.fromCharCode(code)}" is expected`);
}
this.next();
},
getLocation(start, end) {
if (needPositions) {
return locationMap.getLocationRange(
start,
end,
filename
);
}
return null;
},
getLocationFromList(list) {
if (needPositions) {
const head = this.getFirstListNode(list);
const tail = this.getLastListNode(list);
return locationMap.getLocationRange(
head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart,
tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart,
filename
);
}
return null;
},
error(message, offset) {
const location = typeof offset !== 'undefined' && offset < source.length
? locationMap.getLocation(offset)
: this.eof
? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1))
: locationMap.getLocation(this.tokenStart);
throw new SyntaxError_SyntaxError(
message || 'Unexpected input',
source,
location.offset,
location.line,
location.column
);
}
});
const parse = function(source_, options) {
source = source_;
options = options || {};
parser.setSource(source, tokenize);
locationMap.setSource(
source,
options.offset,
options.line,
options.column
);
filename = options.filename || '';
needPositions = Boolean(options.positions);
onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP;
onParseErrorThrow = false;
parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
const { context = 'default', onComment } = options;
if (context in parser.context === false) {
throw new Error('Unknown context `' + context + '`');
}
if (typeof onComment === 'function') {
parser.forEachToken((type, start, end) => {
if (type === Comment) {
const loc = parser.getLocation(start, end);
const value = cmpStr(source, end - 2, end, '*/')
? source.slice(start + 2, end - 2)
: source.slice(start + 2, end);
onComment(value, loc);
}
});
}
const ast = parser.context[context].call(parser, options);
if (!parser.eof) {
parser.error();
}
return ast;
};
return Object.assign(parse, {
SyntaxError: SyntaxError_SyntaxError,
config: parser.config
});
};
// EXTERNAL MODULE: ./node_modules/source-map-js/lib/source-map-generator.js
var source_map_generator = __webpack_require__("./node_modules/source-map-js/lib/source-map-generator.js");
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/generator/sourceMap.js
const trackNodes = new Set(['Atrule', 'Selector', 'Declaration']);
function generateSourceMap(handlers) {
const map = new source_map_generator/* SourceMapGenerator */.h();
const generated = {
line: 1,
column: 0
};
const original = {
line: 0, // should be zero to add first mapping
column: 0
};
const activatedGenerated = {
line: 1,
column: 0
};
const activatedMapping = {
generated: activatedGenerated
};
let line = 1;
let column = 0;
let sourceMappingActive = false;
const origHandlersNode = handlers.node;
handlers.node = function(node) {
if (node.loc && node.loc.start && trackNodes.has(node.type)) {
const nodeLine = node.loc.start.line;
const nodeColumn = node.loc.start.column - 1;
if (original.line !== nodeLine ||
original.column !== nodeColumn) {
original.line = nodeLine;
original.column = nodeColumn;
generated.line = line;
generated.column = column;
if (sourceMappingActive) {
sourceMappingActive = false;
if (generated.line !== activatedGenerated.line ||
generated.column !== activatedGenerated.column) {
map.addMapping(activatedMapping);
}
}
sourceMappingActive = true;
map.addMapping({
source: node.loc.source,
original,
generated
});
}
}
origHandlersNode.call(this, node);
if (sourceMappingActive && trackNodes.has(node.type)) {
activatedGenerated.line = line;
activatedGenerated.column = column;
}
};
const origHandlersEmit = handlers.emit;
handlers.emit = function(value, type, auto) {
for (let i = 0; i < value.length; i++) {
if (value.charCodeAt(i) === 10) { // \n
line++;
column = 0;
} else {
column++;
}
}
origHandlersEmit(value, type, auto);
};
const origHandlersResult = handlers.result;
handlers.result = function() {
if (sourceMappingActive) {
map.addMapping(activatedMapping);
}
return {
css: origHandlersResult(),
map
};
};
return handlers;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/generator/token-before.js
const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
const HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
const code = (type, value) => {
if (type === Delim) {
type = value;
}
if (typeof type === 'string') {
const charCode = type.charCodeAt(0);
return charCode > 0x7F ? 0x8000 : charCode << 8;
}
return type;
};
// https://www.w3.org/TR/css-syntax-3/#serialization
// The only requirement for serialization is that it must "round-trip" with parsing,
// that is, parsing the stylesheet must produce the same data structures as parsing,
// serializing, and parsing again, except for consecutive s,
// which may be collapsed into a single token.
const specPairs = [
[Ident, Ident],
[Ident, Function],
[Ident, Url],
[Ident, BadUrl],
[Ident, '-'],
[Ident, types_Number],
[Ident, Percentage],
[Ident, Dimension],
[Ident, CDC],
[Ident, LeftParenthesis],
[AtKeyword, Ident],
[AtKeyword, Function],
[AtKeyword, Url],
[AtKeyword, BadUrl],
[AtKeyword, '-'],
[AtKeyword, types_Number],
[AtKeyword, Percentage],
[AtKeyword, Dimension],
[AtKeyword, CDC],
[Hash, Ident],
[Hash, Function],
[Hash, Url],
[Hash, BadUrl],
[Hash, '-'],
[Hash, types_Number],
[Hash, Percentage],
[Hash, Dimension],
[Hash, CDC],
[Dimension, Ident],
[Dimension, Function],
[Dimension, Url],
[Dimension, BadUrl],
[Dimension, '-'],
[Dimension, types_Number],
[Dimension, Percentage],
[Dimension, Dimension],
[Dimension, CDC],
['#', Ident],
['#', Function],
['#', Url],
['#', BadUrl],
['#', '-'],
['#', types_Number],
['#', Percentage],
['#', Dimension],
['#', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
['-', Ident],
['-', Function],
['-', Url],
['-', BadUrl],
['-', '-'],
['-', types_Number],
['-', Percentage],
['-', Dimension],
['-', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
[types_Number, Ident],
[types_Number, Function],
[types_Number, Url],
[types_Number, BadUrl],
[types_Number, types_Number],
[types_Number, Percentage],
[types_Number, Dimension],
[types_Number, '%'],
[types_Number, CDC], // https://github.com/w3c/csswg-drafts/pull/6874
['@', Ident],
['@', Function],
['@', Url],
['@', BadUrl],
['@', '-'],
['@', CDC], // https://github.com/w3c/csswg-drafts/pull/6874
['.', types_Number],
['.', Percentage],
['.', Dimension],
['+', types_Number],
['+', Percentage],
['+', Dimension],
['/', '*']
];
// validate with scripts/generate-safe
const safePairs = specPairs.concat([
[Ident, Hash],
[Dimension, Hash],
[Hash, Hash],
[AtKeyword, LeftParenthesis],
[AtKeyword, types_String],
[AtKeyword, Colon],
[Percentage, Percentage],
[Percentage, Dimension],
[Percentage, Function],
[Percentage, '-'],
[RightParenthesis, Ident],
[RightParenthesis, Function],
[RightParenthesis, Percentage],
[RightParenthesis, Dimension],
[RightParenthesis, Hash],
[RightParenthesis, '-']
]);
function createMap(pairs) {
const isWhiteSpaceRequired = new Set(
pairs.map(([prev, next]) => (code(prev) << 16 | code(next)))
);
return function(prevCode, type, value) {
const nextCode = code(type, value);
const nextCharCode = value.charCodeAt(0);
const emitWs =
(nextCharCode === HYPHENMINUS &&
type !== Ident &&
type !== Function &&
type !== CDC) ||
(nextCharCode === PLUSSIGN)
? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8)
: isWhiteSpaceRequired.has(prevCode << 16 | nextCode);
if (emitWs) {
this.emit(' ', WhiteSpace, true);
}
return nextCode;
};
}
const spec = createMap(specPairs);
const safe = createMap(safePairs);
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/generator/create.js
const REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\)
function processChildren(node, delimeter) {
if (typeof delimeter === 'function') {
let prev = null;
node.children.forEach(node => {
if (prev !== null) {
delimeter.call(this, prev);
}
this.node(node);
prev = node;
});
return;
}
node.children.forEach(this.node, this);
}
function processChunk(chunk) {
tokenize(chunk, (type, start, end) => {
this.token(type, chunk.slice(start, end));
});
}
function createGenerator(config) {
const types = new Map();
for (let name in config.node) {
const item = config.node[name];
const fn = item.generate || item;
if (typeof fn === 'function') {
types.set(name, item.generate || item);
}
}
return function(node, options) {
let buffer = '';
let prevCode = 0;
let handlers = {
node(node) {
if (types.has(node.type)) {
types.get(node.type).call(publicApi, node);
} else {
throw new Error('Unknown node type: ' + node.type);
}
},
tokenBefore: safe,
token(type, value) {
prevCode = this.tokenBefore(prevCode, type, value);
this.emit(value, type, false);
if (type === Delim && value.charCodeAt(0) === REVERSESOLIDUS) {
this.emit('\n', WhiteSpace, true);
}
},
emit(value) {
buffer += value;
},
result() {
return buffer;
}
};
if (options) {
if (typeof options.decorator === 'function') {
handlers = options.decorator(handlers);
}
if (options.sourceMap) {
handlers = generateSourceMap(handlers);
}
if (options.mode in token_before_namespaceObject) {
handlers.tokenBefore = token_before_namespaceObject[options.mode];
}
}
const publicApi = {
node: (node) => handlers.node(node),
children: processChildren,
token: (type, value) => handlers.token(type, value),
tokenize: processChunk
};
handlers.node(node);
return handlers.result();
};
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/convertor/create.js
function createConvertor(walk) {
return {
fromPlainObject(ast) {
walk(ast, {
enter(node) {
if (node.children && node.children instanceof List_List === false) {
node.children = new List_List().fromArray(node.children);
}
}
});
return ast;
},
toPlainObject(ast) {
walk(ast, {
leave(node) {
if (node.children && node.children instanceof List_List) {
node.children = node.children.toArray();
}
}
});
return ast;
}
};
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/walker/create.js
const { hasOwnProperty: create_hasOwnProperty } = Object.prototype;
const noop = function() {};
function ensureFunction(value) {
return typeof value === 'function' ? value : noop;
}
function invokeForType(fn, type) {
return function(node, item, list) {
if (node.type === type) {
fn.call(this, node, item, list);
}
};
}
function getWalkersFromStructure(name, nodeType) {
const structure = nodeType.structure;
const walkers = [];
for (const key in structure) {
if (create_hasOwnProperty.call(structure, key) === false) {
continue;
}
let fieldTypes = structure[key];
const walker = {
name: key,
type: false,
nullable: false
};
if (!Array.isArray(fieldTypes)) {
fieldTypes = [fieldTypes];
}
for (const fieldType of fieldTypes) {
if (fieldType === null) {
walker.nullable = true;
} else if (typeof fieldType === 'string') {
walker.type = 'node';
} else if (Array.isArray(fieldType)) {
walker.type = 'list';
}
}
if (walker.type) {
walkers.push(walker);
}
}
if (walkers.length) {
return {
context: nodeType.walkContext,
fields: walkers
};
}
return null;
}
function getTypesFromConfig(config) {
const types = {};
for (const name in config.node) {
if (create_hasOwnProperty.call(config.node, name)) {
const nodeType = config.node[name];
if (!nodeType.structure) {
throw new Error('Missed `structure` field in `' + name + '` node type definition');
}
types[name] = getWalkersFromStructure(name, nodeType);
}
}
return types;
}
function createTypeIterator(config, reverse) {
const fields = config.fields.slice();
const contextName = config.context;
const useContext = typeof contextName === 'string';
if (reverse) {
fields.reverse();
}
return function(node, context, walk, walkReducer) {
let prevContextValue;
if (useContext) {
prevContextValue = context[contextName];
context[contextName] = node;
}
for (const field of fields) {
const ref = node[field.name];
if (!field.nullable || ref) {
if (field.type === 'list') {
const breakWalk = reverse
? ref.reduceRight(walkReducer, false)
: ref.reduce(walkReducer, false);
if (breakWalk) {
return true;
}
} else if (walk(ref)) {
return true;
}
}
}
if (useContext) {
context[contextName] = prevContextValue;
}
};
}
function createFastTraveralMap({
StyleSheet,
Atrule,
Rule,
Block,
DeclarationList
}) {
return {
Atrule: {
StyleSheet,
Atrule,
Rule,
Block
},
Rule: {
StyleSheet,
Atrule,
Rule,
Block
},
Declaration: {
StyleSheet,
Atrule,
Rule,
Block,
DeclarationList
}
};
}
function createWalker(config) {
const types = getTypesFromConfig(config);
const iteratorsNatural = {};
const iteratorsReverse = {};
const breakWalk = Symbol('break-walk');
const skipNode = Symbol('skip-node');
for (const name in types) {
if (create_hasOwnProperty.call(types, name) && types[name] !== null) {
iteratorsNatural[name] = createTypeIterator(types[name], false);
iteratorsReverse[name] = createTypeIterator(types[name], true);
}
}
const fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
const fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
const walk = function(root, options) {
function walkNode(node, item, list) {
const enterRet = enter.call(context, node, item, list);
if (enterRet === breakWalk) {
return true;
}
if (enterRet === skipNode) {
return false;
}
if (iterators.hasOwnProperty(node.type)) {
if (iterators[node.type](node, context, walkNode, walkReducer)) {
return true;
}
}
if (leave.call(context, node, item, list) === breakWalk) {
return true;
}
return false;
}
let enter = noop;
let leave = noop;
let iterators = iteratorsNatural;
let walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);
const context = {
break: breakWalk,
skip: skipNode,
root,
stylesheet: null,
atrule: null,
atrulePrelude: null,
rule: null,
selector: null,
block: null,
declaration: null,
function: null
};
if (typeof options === 'function') {
enter = options;
} else if (options) {
enter = ensureFunction(options.enter);
leave = ensureFunction(options.leave);
if (options.reverse) {
iterators = iteratorsReverse;
}
if (options.visit) {
if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
iterators = options.reverse
? fastTraversalIteratorsReverse[options.visit]
: fastTraversalIteratorsNatural[options.visit];
} else if (!types.hasOwnProperty(options.visit)) {
throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).sort().join(', ') + ')');
}
enter = invokeForType(enter, options.visit);
leave = invokeForType(leave, options.visit);
}
}
if (enter === noop && leave === noop) {
throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
}
walkNode(root);
};
walk.break = breakWalk;
walk.skip = skipNode;
walk.find = function(ast, fn) {
let found = null;
walk(ast, function(node, item, list) {
if (fn.call(this, node, item, list)) {
found = node;
return breakWalk;
}
});
return found;
};
walk.findLast = function(ast, fn) {
let found = null;
walk(ast, {
reverse: true,
enter(node, item, list) {
if (fn.call(this, node, item, list)) {
found = node;
return breakWalk;
}
}
});
return found;
};
walk.findAll = function(ast, fn) {
const found = [];
walk(ast, function(node, item, list) {
if (fn.call(this, node, item, list)) {
found.push(node);
}
});
return found;
};
return walk;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/definition-syntax/generate.js
function generate_noop(value) {
return value;
}
function generateMultiplier(multiplier) {
const { min, max, comma } = multiplier;
if (min === 0 && max === 0) {
return comma ? '#?' : '*';
}
if (min === 0 && max === 1) {
return '?';
}
if (min === 1 && max === 0) {
return comma ? '#' : '+';
}
if (min === 1 && max === 1) {
return '';
}
return (
(comma ? '#' : '') +
(min === max
? '{' + min + '}'
: '{' + min + ',' + (max !== 0 ? max : '') + '}'
)
);
}
function generateTypeOpts(node) {
switch (node.type) {
case 'Range':
return (
' [' +
(node.min === null ? '-∞' : node.min) +
',' +
(node.max === null ? '∞' : node.max) +
']'
);
default:
throw new Error('Unknown node type `' + node.type + '`');
}
}
function generateSequence(node, decorate, forceBraces, compact) {
const combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
const result = node.terms
.map(term => internalGenerate(term, decorate, forceBraces, compact))
.join(combinator);
if (node.explicit || forceBraces) {
return (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
}
return result;
}
function internalGenerate(node, decorate, forceBraces, compact) {
let result;
switch (node.type) {
case 'Group':
result =
generateSequence(node, decorate, forceBraces, compact) +
(node.disallowEmpty ? '!' : '');
break;
case 'Multiplier':
// return since node is a composition
return (
internalGenerate(node.term, decorate, forceBraces, compact) +
decorate(generateMultiplier(node), node)
);
case 'Type':
result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
break;
case 'Property':
result = '<\'' + node.name + '\'>';
break;
case 'Keyword':
result = node.name;
break;
case 'AtKeyword':
result = '@' + node.name;
break;
case 'Function':
result = node.name + '(';
break;
case 'String':
case 'Token':
result = node.value;
break;
case 'Comma':
result = ',';
break;
default:
throw new Error('Unknown node type `' + node.type + '`');
}
return decorate(result, node);
}
function generate(node, options) {
let decorate = generate_noop;
let forceBraces = false;
let compact = false;
if (typeof options === 'function') {
decorate = options;
} else if (options) {
forceBraces = Boolean(options.forceBraces);
compact = Boolean(options.compact);
if (typeof options.decorate === 'function') {
decorate = options.decorate;
}
}
return internalGenerate(node, decorate, forceBraces, compact);
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/lexer/error.js
const defaultLoc = { offset: 0, line: 1, column: 1 };
function locateMismatch(matchResult, node) {
const tokens = matchResult.tokens;
const longestMatch = matchResult.longestMatch;
const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;
const badNode = mismatchNode !== node ? mismatchNode : null;
let mismatchOffset = 0;
let mismatchLength = 0;
let entries = 0;
let css = '';
let start;
let end;
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i].value;
if (i === longestMatch) {
mismatchLength = token.length;
mismatchOffset = css.length;
}
if (badNode !== null && tokens[i].node === badNode) {
if (i <= longestMatch) {
entries++;
} else {
entries = 0;
}
}
css += token;
}
if (longestMatch === tokens.length || entries > 1) { // last
start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);
end = buildLoc(start);
} else {
start = fromLoc(badNode, 'start') ||
buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));
end = fromLoc(badNode, 'end') ||
buildLoc(start, css.substr(mismatchOffset, mismatchLength));
}
return {
css,
mismatchOffset,
mismatchLength,
start,
end
};
}
function fromLoc(node, point) {
const value = node && node.loc && node.loc[point];
if (value) {
return 'line' in value ? buildLoc(value) : value;
}
return null;
}
function buildLoc({ offset, line, column }, extra) {
const loc = {
offset,
line,
column
};
if (extra) {
const lines = extra.split(/\n|\r\n?|\f/);
loc.offset += extra.length;
loc.line += lines.length - 1;
loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;
}
return loc;
}
const SyntaxReferenceError = function(type, referenceName) {
const error = createCustomError(
'SyntaxReferenceError',
type + (referenceName ? ' `' + referenceName + '`' : '')
);
error.reference = referenceName;
return error;
};
const SyntaxMatchError = function(message, syntax, node, matchResult) {
const error = createCustomError('SyntaxMatchError', message);
const {
css,
mismatchOffset,
mismatchLength,
start,
end
} = locateMismatch(matchResult, node);
error.rawMessage = message;
error.syntax = syntax ? generate(syntax) : '';
error.css = css;
error.mismatchOffset = mismatchOffset;
error.mismatchLength = mismatchLength;
error.message = message + '\n' +
' syntax: ' + error.syntax + '\n' +
' value: ' + (css || '') + '\n' +
' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
Object.assign(error, start);
error.loc = {
source: (node && node.loc && node.loc.source) || '',
start,
end
};
return error;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/utils/names.js
const keywords = new Map();
const properties = new Map();
const names_HYPHENMINUS = 45; // '-'.charCodeAt()
const keyword = getKeywordDescriptor;
const names_property = getPropertyDescriptor;
const vendorPrefix = (/* unused pure expression or super */ null && (getVendorPrefix));
function isCustomProperty(str, offset) {
offset = offset || 0;
return str.length - offset >= 2 &&
str.charCodeAt(offset) === names_HYPHENMINUS &&
str.charCodeAt(offset + 1) === names_HYPHENMINUS;
}
function getVendorPrefix(str, offset) {
offset = offset || 0;
// verdor prefix should be at least 3 chars length
if (str.length - offset >= 3) {
// vendor prefix starts with hyper minus following non-hyper minus
if (str.charCodeAt(offset) === names_HYPHENMINUS &&
str.charCodeAt(offset + 1) !== names_HYPHENMINUS) {
// vendor prefix should contain a hyper minus at the ending
const secondDashIndex = str.indexOf('-', offset + 2);
if (secondDashIndex !== -1) {
return str.substring(offset, secondDashIndex + 1);
}
}
}
return '';
}
function getKeywordDescriptor(keyword) {
if (keywords.has(keyword)) {
return keywords.get(keyword);
}
const name = keyword.toLowerCase();
let descriptor = keywords.get(name);
if (descriptor === undefined) {
const custom = isCustomProperty(name, 0);
const vendor = !custom ? getVendorPrefix(name, 0) : '';
descriptor = Object.freeze({
basename: name.substr(vendor.length),
name,
prefix: vendor,
vendor,
custom
});
}
keywords.set(keyword, descriptor);
return descriptor;
}
function getPropertyDescriptor(property) {
if (properties.has(property)) {
return properties.get(property);
}
let name = property;
let hack = property[0];
if (hack === '/') {
hack = property[1] === '/' ? '//' : '/';
} else if (hack !== '_' &&
hack !== '*' &&
hack !== '$' &&
hack !== '#' &&
hack !== '+' &&
hack !== '&') {
hack = '';
}
const custom = isCustomProperty(name, hack.length);
// re-use result when possible (the same as for lower case)
if (!custom) {
name = name.toLowerCase();
if (properties.has(name)) {
const descriptor = properties.get(name);
properties.set(property, descriptor);
return descriptor;
}
}
const vendor = !custom ? getVendorPrefix(name, hack.length) : '';
const prefix = name.substr(0, hack.length + vendor.length);
const descriptor = Object.freeze({
basename: name.substr(prefix.length),
name: name.substr(hack.length),
hack,
vendor,
prefix,
custom
});
properties.set(property, descriptor);
return descriptor;
}
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/lexer/generic-const.js
// https://drafts.csswg.org/css-cascade-5/
const cssWideKeywords = [
'initial',
'inherit',
'unset',
'revert',
'revert-layer'
];
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/lexer/generic-an-plus-b.js
const generic_an_plus_b_PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
const generic_an_plus_b_HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
const generic_an_plus_b_N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
const DISALLOW_SIGN = true;
const ALLOW_SIGN = false;
function isDelim(token, code) {
return token !== null && token.type === Delim && token.value.charCodeAt(0) === code;
}
function skipSC(token, offset, getNextToken) {
while (token !== null && (token.type === WhiteSpace || token.type === Comment)) {
token = getNextToken(++offset);
}
return offset;
}
function checkInteger(token, valueOffset, disallowSign, offset) {
if (!token) {
return 0;
}
const code = token.value.charCodeAt(valueOffset);
if (code === generic_an_plus_b_PLUSSIGN || code === generic_an_plus_b_HYPHENMINUS) {
if (disallowSign) {
// Number sign is not allowed
return 0;
}
valueOffset++;
}
for (; valueOffset < token.value.length; valueOffset++) {
if (!isDigit(token.value.charCodeAt(valueOffset))) {
// Integer is expected
return 0;
}
}
return offset + 1;
}
// ...
// ... ['+' | '-']
function consumeB(token, offset_, getNextToken) {
let sign = false;
let offset = skipSC(token, offset_, getNextToken);
token = getNextToken(offset);
if (token === null) {
return offset_;
}
if (token.type !== types_Number) {
if (isDelim(token, generic_an_plus_b_PLUSSIGN) || isDelim(token, generic_an_plus_b_HYPHENMINUS)) {
sign = true;
offset = skipSC(getNextToken(++offset), offset, getNextToken);
token = getNextToken(offset);
if (token === null || token.type !== types_Number) {
return 0;
}
} else {
return offset_;
}
}
if (!sign) {
const code = token.value.charCodeAt(0);
if (code !== generic_an_plus_b_PLUSSIGN && code !== generic_an_plus_b_HYPHENMINUS) {
// Number sign is expected
return 0;
}
}
return checkInteger(token, sign ? 0 : 1, sign, offset);
}
// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
function anPlusB(token, getNextToken) {
/* eslint-disable brace-style*/
let offset = 0;
if (!token) {
return 0;
}
//
if (token.type === types_Number) {
return checkInteger(token, 0, ALLOW_SIGN, offset); // b
}
// -n
// -n
// -n ['+' | '-']
// -n-
//
else if (token.type === Ident && token.value.charCodeAt(0) === generic_an_plus_b_HYPHENMINUS) {
// expect 1st char is N
if (!cmpChar(token.value, 1, generic_an_plus_b_N)) {
return 0;
}
switch (token.value.length) {
// -n
// -n
// -n ['+' | '-']
case 2:
return consumeB(getNextToken(++offset), offset, getNextToken);
// -n-
case 3:
if (token.value.charCodeAt(2) !== generic_an_plus_b_HYPHENMINUS) {
return 0;
}
offset = skipSC(getNextToken(++offset), offset, getNextToken);
token = getNextToken(offset);
return checkInteger(token, 0, DISALLOW_SIGN, offset);
//
default:
if (token.value.charCodeAt(2) !== generic_an_plus_b_HYPHENMINUS) {
return 0;
}
return checkInteger(token, 3, DISALLOW_SIGN, offset);
}
}
// '+'? n
// '+'? n
// '+'? n ['+' | '-']
// '+'? n-
// '+'?
else if (token.type === Ident || (isDelim(token, generic_an_plus_b_PLUSSIGN) && getNextToken(offset + 1).type === Ident)) {
// just ignore a plus
if (token.type !== Ident) {
token = getNextToken(++offset);
}
if (token === null || !cmpChar(token.value, 0, generic_an_plus_b_N)) {
return 0;
}
switch (token.value.length) {
// '+'? n
// '+'? n
// '+'? n ['+' | '-']
case 1:
return consumeB(getNextToken(++offset), offset, getNextToken);
// '+'? n-
case 2:
if (token.value.charCodeAt(1) !== generic_an_plus_b_HYPHENMINUS) {
return 0;
}
offset = skipSC(getNextToken(++offset), offset, getNextToken);
token = getNextToken(offset);
return checkInteger(token, 0, DISALLOW_SIGN, offset);
// '+'?
default:
if (token.value.charCodeAt(1) !== generic_an_plus_b_HYPHENMINUS) {
return 0;
}
return checkInteger(token, 2, DISALLOW_SIGN, offset);
}
}
//
//
//
//
// ['+' | '-']
else if (token.type === Dimension) {
let code = token.value.charCodeAt(0);
let sign = code === generic_an_plus_b_PLUSSIGN || code === generic_an_plus_b_HYPHENMINUS ? 1 : 0;
let i = sign;
for (; i < token.value.length; i++) {
if (!isDigit(token.value.charCodeAt(i))) {
break;
}
}
if (i === sign) {
// Integer is expected
return 0;
}
if (!cmpChar(token.value, i, generic_an_plus_b_N)) {
return 0;
}
//
//
// ['+' | '-']
if (i + 1 === token.value.length) {
return consumeB(getNextToken(++offset), offset, getNextToken);
} else {
if (token.value.charCodeAt(i + 1) !== generic_an_plus_b_HYPHENMINUS) {
return 0;
}
//
if (i + 2 === token.value.length) {
offset = skipSC(getNextToken(++offset), offset, getNextToken);
token = getNextToken(offset);
return checkInteger(token, 0, DISALLOW_SIGN, offset);
}
//
else {
return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
}
}
}
return 0;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/lexer/generic-urange.js
const generic_urange_PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
const generic_urange_HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)
const QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
const U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
function generic_urange_isDelim(token, code) {
return token !== null && token.type === Delim && token.value.charCodeAt(0) === code;
}
function startsWith(token, code) {
return token.value.charCodeAt(0) === code;
}
function hexSequence(token, offset, allowDash) {
let hexlen = 0;
for (let pos = offset; pos < token.value.length; pos++) {
const code = token.value.charCodeAt(pos);
if (code === generic_urange_HYPHENMINUS && allowDash && hexlen !== 0) {
hexSequence(token, offset + hexlen + 1, false);
return 6; // dissallow following question marks
}
if (!isHexDigit(code)) {
return 0; // not a hex digit
}
if (++hexlen > 6) {
return 0; // too many hex digits
};
}
return hexlen;
}
function withQuestionMarkSequence(consumed, length, getNextToken) {
if (!consumed) {
return 0; // nothing consumed
}
while (generic_urange_isDelim(getNextToken(length), QUESTIONMARK)) {
if (++consumed > 6) {
return 0; // too many question marks
}
length++;
}
return length;
}
// https://drafts.csswg.org/css-syntax/#urange
// Informally, the production has three forms:
// U+0001
// Defines a range consisting of a single code point, in this case the code point "1".
// U+0001-00ff
// Defines a range of codepoints between the first and the second value, in this case
// the range between "1" and "ff" (255 in decimal) inclusive.
// U+00??
// Defines a range of codepoints where the "?" characters range over all hex digits,
// in this case defining the same as the value U+0000-00ff.
// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
//
// =
// u '+' '?'* |
// u '?'* |
// u '?'* |
// u |
// u |
// u '+' '?'+
function urange(token, getNextToken) {
let length = 0;
// should start with `u` or `U`
if (token === null || token.type !== Ident || !cmpChar(token.value, 0, U)) {
return 0;
}
token = getNextToken(++length);
if (token === null) {
return 0;
}
// u '+' '?'*
// u '+' '?'+
if (generic_urange_isDelim(token, generic_urange_PLUSSIGN)) {
token = getNextToken(++length);
if (token === null) {
return 0;
}
if (token.type === Ident) {
// u '+' '?'*
return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
}
if (generic_urange_isDelim(token, QUESTIONMARK)) {
// u '+' '?'+
return withQuestionMarkSequence(1, ++length, getNextToken);
}
// Hex digit or question mark is expected
return 0;
}
// u '?'*
// u
// u
if (token.type === types_Number) {
const consumedHexLength = hexSequence(token, 1, true);
if (consumedHexLength === 0) {
return 0;
}
token = getNextToken(++length);
if (token === null) {
// u
return length;
}
if (token.type === Dimension || token.type === types_Number) {
// u
// u
if (!startsWith(token, generic_urange_HYPHENMINUS) || !hexSequence(token, 1, false)) {
return 0;
}
return length + 1;
}
// u '?'*
return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
}
// u '?'*
if (token.type === Dimension) {
return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
}
return 0;
};
;// CONCATENATED MODULE: ./node_modules/css-tree/lib/lexer/generic.js
const calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
const generic_balancePair = new Map([
[Function, RightParenthesis],
[LeftParenthesis, RightParenthesis],
[LeftSquareBracket, RightSquareBracket],
[LeftCurlyBracket, RightCurlyBracket]
]);
// safe char code getter
function charCodeAt(str, index) {
return index < str.length ? str.charCodeAt(index) : 0;
}
function eqStr(actual, expected) {
return cmpStr(actual, 0, actual.length, expected);
}
function eqStrAny(actual, expected) {
for (let i = 0; i < expected.length; i++) {
if (eqStr(actual, expected[i])) {
return true;
}
}
return false;
}
// IE postfix hack, i.e. 123\0 or 123px\9
function isPostfixIeHack(str, offset) {
if (offset !== str.length - 2) {
return false;
}
return (
charCodeAt(str, offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
isDigit(charCodeAt(str, offset + 1))
);
}
function outOfRange(opts, value, numEnd) {
if (opts && opts.type === 'Range') {
const num = Number(
numEnd !== undefined && numEnd !== value.length
? value.substr(0, numEnd)
: value
);
if (isNaN(num)) {
return true;
}
// FIXME: when opts.min is a string it's a dimension, skip a range validation
// for now since it requires a type covertation which is not implmented yet
if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') {
return true;
}
// FIXME: when opts.max is a string it's a dimension, skip a range validation
// for now since it requires a type covertation which is not implmented yet
if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') {
return true;
}
}
return false;
}
function consumeFunction(token, getNextToken) {
let balanceCloseType = 0;
let balanceStash = [];
let length = 0;
// balanced token consuming
scan:
do {
switch (token.type) {
case RightCurlyBracket:
case RightParenthesis:
case RightSquareBracket:
if (token.type !== balanceCloseType) {
break scan;
}
balanceCloseType = balanceStash.pop();
if (balanceStash.length === 0) {
length++;
break scan;
}
break;
case Function:
case LeftParenthesis:
case LeftSquareBracket:
case LeftCurlyBracket:
balanceStash.push(balanceCloseType);
balanceCloseType = generic_balancePair.get(token.type);
break;
}
length++;
} while (token = getNextToken(length));
return length;
}
// TODO: implement
// can be used wherever , , ,