UNPKG

site-metadata-extractor

Version:
724 lines 93.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable @typescript-eslint/no-explicit-any */ const isEqual_1 = __importDefault(require("lodash/isEqual")); const uniq_1 = __importDefault(require("lodash/uniq")); const url_1 = require("url"); const formatter_1 = __importStar(require("./formatter")); const cleaner_1 = require("./cleaner"); const stopwords_1 = __importDefault(require("./stopwords")); function addSiblings(doc, topNode, lang) { const baselineScoreSiblingsPara = getSiblingsScore(doc, topNode, lang); const sibs = topNode.prevAll(); sibs.each((_index, element) => { const currentNode = doc(element); const ps = getSiblingsContent(doc, lang, currentNode, baselineScoreSiblingsPara); if (ps) { ps.forEach((p) => { topNode.prepend(`<p>${p}</p>`); }); } }); return topNode; } function biggestTitleChunk(title, splitter) { let largeTextIndex = 0; let largeTextLength = 0; const titlePieces = title.split(splitter); titlePieces.forEach((piece, index) => { if (piece.length > largeTextLength) { largeTextLength = piece.length; largeTextIndex = index; } }); return titlePieces[largeTextIndex]; } function cleanNull(text) { if (text) { return text.replace(/^null$/g, ""); } return ""; } function cleanText(text) { if (text) { return text .replace(/[\r\n\t]/g, " ") .replace(/\s\s+/g, " ") .replace(/<!--.+?-->/g, "") .replace(/�/g, "") .trim(); } return text; } function cleanTitle(title, delimiters) { let titleText = title || ""; let usedDelimiter = false; delimiters.forEach((char) => { if (titleText.indexOf(char) >= 0 && !usedDelimiter) { titleText = biggestTitleChunk(titleText, char); usedDelimiter = true; } }); return cleanText(titleText); } function doesNodeListContainNode(list, node) { let contains = false; for (let i = 0; i < list.length; i++) { const nodeToCompare = list[i]; if ((0, isEqual_1.default)(node, nodeToCompare)) { contains = true; } } return contains; } function getObjectTag(doc, node) { const srcNode = node.find("param[name=movie]"); if (srcNode.length > 0) { const src = srcNode.attr("value"); const video = getVideoAttrs(doc, node); video.src = src; return video; } return {}; } function getSiblingsContent(doc, lang, currentSibling, baselineScoreSiblingsPara) { if (currentSibling.get(0).tagName === "p" && currentSibling.text().length > 0) { return [currentSibling]; } else { const potentialParagraphs = currentSibling.find("p"); if (potentialParagraphs === null) { return null; } else { const ps = []; potentialParagraphs.each((_index, element) => { const firstParagraph = doc(element); const text = firstParagraph.text(); if (text.length > 0) { const wordStats = (0, stopwords_1.default)(text, lang); const paragraphScore = wordStats.stopWordCount; const siblingBaselineScore = 0.3; const highLinkDensity = isHighLinkDensity(doc, firstParagraph); const score = baselineScoreSiblingsPara * siblingBaselineScore; if (score < paragraphScore && !highLinkDensity) { ps.push(text); } } }); return ps; } } } function getSiblingsScore(doc, topNode, lang) { const nodesToCheck = topNode.find("p"); let base = 100000; let paragraphsNumber = 0; let paragraphScore = 0; nodesToCheck.each((_index, element) => { const node = doc(element); const textNode = node.text(); const wordStats = (0, stopwords_1.default)(textNode, lang); const highLinkDensity = isHighLinkDensity(doc, node); if (wordStats.stopWordCount > 2 && !highLinkDensity) { paragraphsNumber++; paragraphScore += wordStats.stopWordCount; } }); if (paragraphsNumber > 0) { base = paragraphScore / paragraphsNumber; } return base; } function getScore(node) { const gravityScoreString = node.attr("gravityScore"); if (!gravityScoreString) { return 0; } else { return parseInt(gravityScoreString, 10); } } function getVideoAttrs(doc, node) { const el = doc(node); return { height: el.attr("height"), src: el.attr("src"), width: el.attr("width"), }; } function isAbsoluteUrl(url) { if (typeof url !== "string") { throw new TypeError(`Expected a \`string\`, got \`${typeof url}\``); } // Don't match Windows paths `c:\` if (/^[a-zA-Z]:\\/.test(url)) { return false; } // Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 // Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 return /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(url); } function isBoostable(doc, node, lang) { const minimumStopWordCount = 5; const maxStepsAwayFromNode = 3; let stepsAway = 0; const nodes = node.prevAll(); let boostable = false; nodes.each((_index, element) => { const currentNode = doc(element); const currentNodeTag = currentNode.get(0).tagName; if (currentNodeTag === "p") { if (stepsAway >= maxStepsAwayFromNode) { boostable = false; return false; } const paraText = currentNode.text(); const wordStats = (0, stopwords_1.default)(paraText, lang); if (wordStats.stopWordCount > minimumStopWordCount) { boostable = true; return false; } stepsAway++; } }); return boostable; } function isHighLinkDensity(doc, node) { const links = node.find("a"); if (links.length > 0) { const text = node.text(); const words = text.split(" "); const numberOfWords = words.length; const sb = []; links.each((_index, element) => { sb.push(doc(element).text()); }); const linkText = sb.join(" "); const linkWords = linkText.split(" "); const numberOfLinkWords = linkWords.length; const numberofLinks = links.length; const percentLinkWords = numberOfLinkWords / numberOfWords; const score = percentLinkWords * numberofLinks; if (score >= 1.0) { return true; } } return false; } function isNodeScoreThresholdMet(_doc, node, e) { const topNodeScore = getScore(node); const currentNodeScore = getScore(e); const thresholdScore = topNodeScore * 0.08; const elIsTdUlOlOrBlockQ = ["td", "ul", "ol", "blockquote"].includes(e.get(0).tagName); if (currentNodeScore < thresholdScore && !elIsTdUlOlOrBlockQ) { return false; } return true; } function isTableAndNoParaExist(doc, e) { const subParagraphs = e.find("p"); subParagraphs.each((_index, element) => { const p = doc(element); const text = p.text(); if (text.length < 25) { doc(p).remove(); } }); const subParagraphsTwo = e.find("p"); const elIsTdUlOrOl = ["td", "ul", "ol"].includes(e.get(0).tagName); if (subParagraphsTwo.length === 0 && !elIsTdUlOrOl) { return true; } return false; } function isValidDate(d) { const parsedDate = Date.parse(d); return new Date(d).toString() !== "Invalid Date" && !isNaN(parsedDate); } function postCleanup(doc, targetNode, lang) { const node = addSiblings(doc, targetNode, lang); node.children().each((_index, element) => { const el = doc(element); const elTag = el.get(0).tagName; if (!["p", "a"].includes(elTag)) { if (isHighLinkDensity(doc, el) || isTableAndNoParaExist(doc, el) || !isNodeScoreThresholdMet(doc, node, el)) { doc(el).remove(); } } }); return node; } function rawTitle(doc) { let gotTitle = false; let titleText = ""; [ doc('meta[property="og:title"]').first().attr("content"), doc('h1[class*="title"]').first().text(), doc("title").first().text(), doc("h1").first().text(), doc("h2").first().text(), ].forEach((candidate) => { if (candidate && candidate.trim() && !gotTitle) { titleText = candidate.trim(); gotTitle = true; } }); return titleText; } function updateNodeCount(node, addToCount) { const countString = node.attr("gravityNodes"); let currentScore = 0; if (countString) { currentScore = parseInt(countString, 10); } const newScore = currentScore + addToCount; node.attr("gravityNodes", `${newScore}`); } function updateScore(node, addToScore) { const scoreString = node.attr("gravityScore"); let currentScore = 0; if (scoreString) { currentScore = parseInt(scoreString, 10); } const newScore = currentScore + addToScore; node.attr("gravityScore", `${newScore}`); } const extractor = { author: (doc) => { const authorCandidates = doc("meta[property='article:author'], meta[property='og:article:author'], meta[name='author'], meta[name='dcterms.creator'], meta[name='DC.creator'], meta[name='DC.Creator'], meta[name='dc.creator'], meta[name='creator']"); const authorList = []; authorCandidates.each((_index, element) => { const author = cleanNull(doc(element).attr("content")); if (author) { authorList.push(author.trim()); } }); // fallback to a named author div if (authorList.length === 0) { const fallbackAuthor = doc("span[class*='author']").first().text() || doc("p[class*='author']").first().text() || doc("div[class*='author']").first().text() || doc("span[class*='byline']").first().text() || doc("p[class*='byline']").first().text() || doc("div[class*='byline']").first().text(); if (fallbackAuthor) { authorList.push(cleanText(fallbackAuthor)); } } return authorList; }, calculateBestNode: (doc, lang) => { let topNode = null; const nodesToCheck = doc("p, pre, td"); const parentNodes = []; const nodesWithText = []; let startingBoost = 1.0; let cnt = 0; let i = 0; nodesToCheck.each((_index, element) => { const node = doc(element); const textNode = node.text(); const wordStats = (0, stopwords_1.default)(textNode, lang); const highLinkDensity = isHighLinkDensity(doc, node); if (wordStats.stopWordCount > 2 && !highLinkDensity) { nodesWithText.push(node); } }); const nodesNumber = nodesWithText.length; const bottomNegativeScoreNodes = nodesNumber * 0.25; const negativeScoring = 0; nodesWithText.forEach((node) => { let boostScore = 0.0; if (isBoostable(doc, node, lang) === true) { if (cnt >= 0) { boostScore = (1.0 / startingBoost) * 50; startingBoost += 1; } } if (nodesNumber > 15) { if (nodesNumber - i <= bottomNegativeScoreNodes) { const booster = bottomNegativeScoreNodes - (nodesNumber - i); boostScore = -1.0 * Math.pow(booster, 2); const negScore = Math.abs(boostScore) + negativeScoring; if (negScore > 40) { boostScore = 5.0; } } } const textNode = node.text(); const wordStats = (0, stopwords_1.default)(textNode, lang); const upScore = Math.floor(wordStats.stopWordCount + boostScore); const parentNode = node.parent(); updateScore(parentNode, upScore); updateNodeCount(parentNode, 1); if (!doesNodeListContainNode(parentNodes, parentNode)) { parentNodes.push(parentNode); } if (parentNodes.indexOf(parentNode) === -1) { parentNodes.push(parentNode); } const parentParentNode = parentNode.parent(); if (parentParentNode) { updateScore(parentParentNode, upScore / 2); updateNodeCount(parentParentNode, 1); if (!doesNodeListContainNode(parentNodes, parentParentNode)) { parentNodes.push(parentParentNode); } if (parentNodes.indexOf(parentParentNode[0]) === -1) { parentNodes.push(parentParentNode[0]); } } cnt += 1; i += 1; }); let topNodeScore = 0; parentNodes.forEach((el) => { const score = getScore(doc(el)); if (score > topNodeScore) { topNode = el; topNodeScore = score; } if (topNode === null) { topNode = el; } }); return doc(topNode); }, // if it gets to the end without one of these links or meta tags, return the original url as canonical canonicalLink: (doc, resourceUrl) => { const canonicalLinkTag = doc("link[rel='canonical'], meta[property='og:url']"); if (canonicalLinkTag) { const resourceUrlObj = new url_1.URL(resourceUrl); // check if it is link or meta if (canonicalLinkTag.get(0) && canonicalLinkTag.get(0).tagName === "link") { const cleanedCanonicalLink = cleanNull(canonicalLinkTag.first().attr("href")); // check if link is a relative url, if so, append origin if (!isAbsoluteUrl(cleanedCanonicalLink)) { return `${resourceUrlObj.origin}${cleanedCanonicalLink}`; } return cleanedCanonicalLink; } else if (canonicalLinkTag.get(0) && canonicalLinkTag.get(0).tagName === "meta") { let cleanedCanonicalMeta = cleanNull(canonicalLinkTag.attr("content")); // check if resourceUrl protocol is https? if so, use that const urlProtocol = resourceUrlObj.protocol; if (urlProtocol === "https:") { cleanedCanonicalMeta = cleanedCanonicalMeta.replace(/^http:\/\//i, "https://"); return cleanedCanonicalMeta; } return cleanedCanonicalMeta; } } // return original url return resourceUrl; }, copyright: (doc) => { var _a; const copyrightCandidates = doc("p[class*='copyright'], div[class*='copyright'], span[class*='copyright'], li[class*='copyright'], p[id*='copyright'], div[id*='copyright'], span[id*='copyright'], li[id*='copyright']"); let text = (_a = copyrightCandidates === null || copyrightCandidates === void 0 ? void 0 : copyrightCandidates.first()) === null || _a === void 0 ? void 0 : _a.text(); if (!text) { // try to find copyright in text text = doc("body") .text() .replace(/\s*[\r\n]+\s*/g, ". "); } if (text.indexOf("©") > -1) { const copyright = text .replace(/.*?©(\s*copyright)?([^,;:.|\r\n]+).*/gi, "$2") .trim(); return cleanText(copyright); } return ""; }, date: (doc) => { const dateCandidates = doc("meta[property='article:published_time'], \ meta[itemprop*='datePublished'], meta[name='dcterms.modified'], \ meta[name='dcterms.date'], \ meta[name='DC.date.issued'], meta[name='dc.date.issued'], \ meta[name='dc.date.modified'], meta[name='dc.date.created'], \ meta[name='DC.date'], \ meta[name='DC.Date'], \ meta[name='dc.date'], \ meta[name='date'], \ time[itemprop*='pubDate'], \ time[itemprop*='pubdate'], \ span[itemprop*='datePublished'], \ span[property*='datePublished'], \ p[itemprop*='datePublished'], \ p[property*='datePublished'], \ div[itemprop*='datePublished'], \ div[property*='datePublished'], \ li[itemprop*='datePublished'], \ li[property*='datePublished'], \ time, \ span[class*='date'], \ p[class*='date'], \ div[class*='date']"); let dateToReturn = ""; if (dateCandidates) { const dateContentCandidate = cleanNull(dateCandidates.first().attr("content")); const dateTimeCandidate = cleanNull(dateCandidates.first().attr("datetime")); const dateTextCandidate = cleanText(dateCandidates.first().text()); if (dateContentCandidate) { dateToReturn = dateContentCandidate.trim(); } else if (dateTimeCandidate) { dateToReturn = dateTimeCandidate.trim(); } else if (dateTextCandidate) { dateToReturn = dateTextCandidate.trim(); } } if (isValidDate(dateToReturn)) { return dateToReturn; } // finally try jsonld date const jsonldBlob = extractor.jsonld(doc); if (jsonldBlob && jsonldBlob.datePublished) { dateToReturn = jsonldBlob.datePublished; } return dateToReturn; }, description: (doc) => { const descriptionTag = doc("meta[name=description], meta[property='og:description']"); if (descriptionTag) { const cleanedDescription = cleanNull(descriptionTag.first().attr("content")); if (cleanedDescription) { return (0, formatter_1.replaceCharacters)(cleanedDescription.trim(), false, true); } } return ""; }, favicon: (doc, resourceUrlObj) => { const tag = doc("link").filter((_index, el) => { var _a, _b; return ((_a = doc(el).attr("rel")) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "shortcut icon" || ((_b = doc(el).attr("rel")) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === "icon"; }); const faviconLink = tag.attr("href") || ""; // ensure the url returned from favicon is absolute url if (faviconLink && !isAbsoluteUrl(faviconLink)) { // add the origin to the faviconLink return `${resourceUrlObj.origin}${faviconLink}`; } return faviconLink; }, image: (doc) => { const images = doc("meta[property='og:image'], meta[property='og:image:url'], meta[itemprop=image], meta[name='twitter:image:src'], meta[name='twitter:image'], meta[name='twitter:image0']"); if (images.length > 0 && cleanNull(images.first().attr("content"))) { const cleanedImages = cleanNull(images.first().attr("content")) || ""; return cleanedImages.trim(); } return ""; }, jsonld: (doc) => { const jsonldTag = doc('script[type="application/ld+json"]'); if (jsonldTag) { let jsonldObj = jsonldTag.html() || "{}"; // Sanitize the jsonldObj string to remove extraneous HTML/XML tags jsonldObj = (0, cleaner_1.sanitizeJsonLdString)(jsonldObj); try { const parsedJSON = JSON.parse(jsonldObj); return parsedJSON; } catch (e) { console.warn(`Error in jsonld parse - ${e}`); } } return null; }, keywords: (doc) => { const keywordsTag = doc('meta[name="keywords"]'); if (keywordsTag) { const cleansedKeywords = cleanNull(keywordsTag.attr("content")); if (cleansedKeywords) { return cleansedKeywords.trim(); } } return ""; }, lang: (doc) => { let language = doc("html").attr("lang"); if (!language) { const tag = doc("meta[name=lang]") || doc("meta[http-equiv=content-language]"); language = tag.attr("content"); } if (language) { const value = language[0] + language[1]; const regex = /^[A-Za-z]{2}$/; if (regex.test(value)) { return value.toLowerCase(); } } return ""; }, links: (doc, topNode, lang) => { const links = []; const gatherLinks = () => { const nodes = topNode.find("a"); nodes.each((_index, element) => { const href = doc(element).attr("href"); const text = doc(element).html(); if (href && text) { links.push({ href, text, }); } }); }; if (topNode) { topNode = postCleanup(doc, topNode, lang); gatherLinks(); } return links; }, locale: (doc) => { const localeTag = doc("meta[property='og:locale']"); if (localeTag) { const cleanedLocale = cleanNull(localeTag.first().attr("content")); if (cleanedLocale) { return cleanedLocale.trim(); } } return ""; }, publisher: (doc) => { const publisherCandidates = doc("meta[property='og:site_name'], meta[itemprop=name], meta[name='dc.publisher'], meta[name='DC.publisher'], meta[name='DC.Publisher']"); if (publisherCandidates) { const cleanedPublisher = cleanNull(publisherCandidates.first().attr("content")); if (cleanedPublisher) { return cleanedPublisher.trim(); } } return ""; }, siteName: (doc) => { const siteNameTag = doc("meta[property='og:site_name'], meta[itemprop=name]"); if (siteNameTag) { const cleanedSiteName = cleanNull(siteNameTag.first().attr("content")); if (cleanedSiteName) { return cleanedSiteName.trim(); } } return ""; }, // Grab the title with soft truncation softTitle: (doc) => { const titleText = rawTitle(doc); return cleanTitle(titleText, ["|", " - ", "»"]); }, tags: (doc) => { let elements = doc("a[rel='tag']"); if (elements.length === 0) { elements = doc("a[href*='/tag/'], a[href*='/tags/'], a[href*='/topic/'], a[href*='?keyword=']"); if (elements.length === 0) { return []; } } const tags = []; elements.each((_index, element) => { const tag = doc(element); const tagText = tag.text().trim(); tagText.replace(/[\s\t\n]+/g, ""); if (tagText && tagText.length > 0) { tags.push(tagText); } }); return (0, uniq_1.default)(tags); }, text: (doc, topNode, lang) => { if (topNode) { topNode = postCleanup(doc, topNode, lang); return (0, formatter_1.default)(doc, topNode, lang); } else { return ""; } }, // Grab the title of an html doc (excluding junk) // Hard-truncates titles containing colon or spaced dash title: (doc) => { const titleText = rawTitle(doc); const cleanedTitle = cleanTitle(titleText, ["|", " - ", "»", ":"]); return (0, formatter_1.replaceCharacters)(cleanedTitle, false, true); }, type: (doc) => { const typeTag = doc("meta[property='og:type']"); if (typeTag) { const cleanedType = cleanNull(typeTag.first().attr("content")); if (cleanedType) { return cleanedType.trim(); } } return ""; }, videos: (doc, topNode) => { const videolist = []; const videoCandidates = doc(topNode).find("iframe, embed, object, video"); videoCandidates.each((_index, element) => { const candidate = doc(element); const tag = candidate.get(0).tagName; if (tag === "embed") { if (candidate.parent() && candidate.parent().get(0).tagName === "object") { videolist.push(getObjectTag(doc, candidate)); } else { videolist.push(getVideoAttrs(doc, candidate)); } } else if (tag === "object") { videolist.push(getObjectTag(doc, candidate)); } else if (tag === "iframe" || tag === "video") { videolist.push(getVideoAttrs(doc, candidate)); } }); const urls = []; const results = []; videolist.forEach((vid) => { if (vid.src) { if (vid && vid.height && vid.width && urls.indexOf(vid.src) === -1) { results.push(vid); urls.push(vid.src); } } }); return results; }, }; exports.default = extractor; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V4dHJhY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdURBQXVEO0FBQ3ZELDZEQUFxQztBQUNyQyx1REFBK0I7QUFFL0IsNkJBQTBCO0FBQzFCLHlEQUEyRDtBQUMzRCx1Q0FBaUQ7QUFDakQsNERBQW9DO0FBeUNwQyxTQUFTLFdBQVcsQ0FDbEIsR0FBaUIsRUFDakIsT0FBd0IsRUFDeEIsSUFBWTtJQUVaLE1BQU0seUJBQXlCLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN2RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQWMsRUFBRSxPQUF3QixFQUFFLEVBQUU7UUFDckQsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sRUFBRSxHQUFHLGtCQUFrQixDQUMzQixHQUFHLEVBQ0gsSUFBSSxFQUNKLFdBQVcsRUFDWCx5QkFBeUIsQ0FDMUIsQ0FBQztRQUVGLElBQUksRUFBRSxFQUFFO1lBQ04sRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQTJCLEVBQUUsRUFBRTtnQkFDekMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakMsQ0FBQyxDQUFDLENBQUM7U0FDSjtJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVELFNBQVMsaUJBQWlCLENBQUMsS0FBYSxFQUFFLFFBQWdCO0lBQ3hELElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQztJQUN2QixJQUFJLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFFeEIsTUFBTSxXQUFXLEdBQUcsS0FBSyxD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