UNPKG

site-metadata-extractor

Version:
737 lines 95.7 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 () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __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 }); 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 getTagName(node) { const element = node.get(0); return (element === null || element === void 0 ? void 0 : element.tagName) || ""; } 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 (getTagName(currentSibling) === "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 = getTagName(currentNode); 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(getTagName(e)); 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(getTagName(e)); 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 = getTagName(el); 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 topNode ? doc(topNode) : doc([]); }, // 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) && getTagName(canonicalLinkTag) === "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) && getTagName(canonicalLinkTag) === "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 = getTagName(candidate); if (tag === "embed") { if (candidate.parent() && getTagName(candidate.parent()) === "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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V4dHJhY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUdBLDZEQUFxQztBQUNyQyx1REFBK0I7QUFFL0IsNkJBQTBCO0FBQzFCLHlEQUEyRDtBQUMzRCx1Q0FBaUQ7QUFDakQsNERBQW9DO0FBRXBDLFNBQVMsVUFBVSxDQUFDLElBQXNCO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUF3QixDQUFDO0lBQ25ELE9BQU8sQ0FBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsT0FBTyxLQUFJLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBeUNELFNBQVMsV0FBVyxDQUNsQixHQUFlLEVBQ2YsT0FBeUIsRUFDekIsSUFBWTtJQUVaLE1BQU0seUJBQXlCLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN2RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQWMsRUFBRSxPQUFnQixFQUFFLEVBQUU7UUFDN0MsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sRUFBRSxHQUFHLGtCQUFrQixDQUMzQixHQUFHLEVBQ0gsSUFBSSxFQUNKLFdBQVcsRUFDWCx5QkFBeUIsQ0FDMUIsQ0FBQztRQUVGLElBQUksRUFBRSxFQUFFLENBQUM7WUFDUCxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBNEIsRUFBRSxFQUFFO2dCQUMxQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNqQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENB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