indexnow-submit
Version:
CLI tool to use IndexNow to notify search engines of website changes
185 lines • 21 kB
JavaScript
import * as fs from 'fs';
import got from 'got';
import Sitemapper from 'sitemapper';
// import { default as SitemapXMLParser } from 'sitemap-xml-parser';
import { parse, toSeconds } from "iso8601-duration";
import { default as FeedMe } from 'feedme';
/**
* Use Axios to post a URL list via IndexNow to the given search engine.
*
* @param key The authentication key to use for IndexNow
* @param engine The domain name for the search engine
* @param host The domain name for your website
* @param urlList The list of URLs to post to IndexNow
*/
export async function postURLlist(engine, host, key, urlList) {
const u = indexNowURL(engine);
try {
// POST /indexnow HTTP/1.1
// Content-Type: application/json; charset=utf-8
// Host: <searchengine>
// {
// "host": "www.example.com",
// "key": "aaa6c957e47d498589ee7a33281997cb",
// "keyLocation": "https://www.example.com/myIndexNowKey63638.txt",
// "urlList": [
// "https://www.example.com/url1",
// "https://www.example.com/folder/url2",
// "https://www.example.com/url3"
// ]
// }
const response = await got.post(u.toString(), {
// headers: {
// 'Content-Type': 'application/json; charset=utf-8'
// },
json: {
host: host,
key: key,
urlList: urlList
}
});
console.log(`Submitted ${urlList.length} URL's to ${engine} status ${response.statusCode}`);
}
catch (err) {
console.error(err);
}
}
/**
* Submit a single URL to an IndexNow service. If this executes with
* no error it was successful. Otherwise a suitable error is thrown.
*
* @param engine The domain name of the search engine
* @param url The URL to submit
* @param key The IndexNow key to use
*/
export async function submitSingleURL(engine, url, key) {
// https://<searchengine>/indexnow?url=url-changed&key=your-key
const u = indexNowURL(engine);
u.searchParams.append('url', url);
u.searchParams.append('key', key);
console.log(`Submitting ${u.toString()}`);
const response = await got.get(u.toString());
console.log(`Submitted to ${engine} ${url} status ${response.statusCode}`);
}
/**
* Generate a URL obect for the IndexNow service on the given
* search engine.
* @param engine The domain name for the search engine
* @returns
*/
export function indexNowURL(engine) {
const u = new URL(`https://ENGINE/indexnow`);
u.host = engine;
return u;
}
/**
* Fetches all items from a sitemap, accodomating sitemaps that have
* sub-sitemaps. The return value is an array of {SitemapEntry}.
*
* @param u The URL for the sitemap
* @param maxAge Optional, an ISO8601 descriptor a maximum age, so we
* can select recently created items. e.g. P10D means 10 days
* @returns
*/
export async function fetchURLsFromSitemap(u, maxAge) {
if (!u)
throw new Error(`No URL given ${u}`);
// console.log(`fetchURLsFromSitemap ${u} ${maxAge}`);
const sitemapXMLParser = new Sitemapper({
url: u,
timeout: 15000,
fields: {
loc: true,
lastmod: true,
changefreq: true,
priority: true,
}
});
// const sitemapXMLParser = new SitemapXMLParser(u, {
// delay: 3000,
// limit: 5
// });
// console.log(`fetching`);
const items = await sitemapXMLParser.fetch();
const ret = new Array();
for (const item of items.sites) {
if (typeof item === 'string') {
ret.push({ loc: [item] });
}
else if (typeof item === 'object') {
const anyitem = item;
if (typeof anyitem.loc === 'string') {
anyitem.loc = [anyitem.loc];
}
ret.push(anyitem);
}
}
return ret;
// return items;
// if (maxAge) {
// const now = new Date();
// const maxSecs = toSeconds(parse(maxAge));
// // console.log(`maxAge ${maxAge} maxSecs ${maxSecs}`);
// return items.sites;
// // .filter(item => {
// // const lastmod = new Date(item.lastmod);
// // const age = now.getTime() - lastmod.getTime();
// // return (age / 1000) < maxSecs;
// // });
// } else {
// return items.sites;
// }
}
/**
* Retrieve URLs from the RSS or Atom file, returning as
* an array.
*
* @param feedURL The URL for the RSS or Atom feed
* @param maxAge An ISO8601 duration string as discussed above
* @returns
*/
export async function fetchURLsFromRSSAtom(feedURL, maxAge) {
const uFeed = new URL(feedURL);
let feed;
try {
// Support reading the RSS file either from a file or
// over the Internet
let rssStream;
if (uFeed.protocol === 'file:') {
rssStream = fs.createReadStream(uFeed.pathname, 'utf-8');
}
else {
const resFeed = await got.stream(feedURL);
rssStream = resFeed;
}
feed = await new Promise((resolve, reject) => {
try {
let parser = new FeedMe(true);
parser.on('finish', () => {
resolve(parser.done());
});
rssStream.pipe(parser);
}
catch (err) {
reject(err);
}
});
}
catch (err) {
throw new Error(`Fetching feed ${feedURL} failed because ${err.message}`);
}
const urlList = [];
for (const item of feed.items) {
if (maxAge) {
const now = new Date();
const maxSecs = toSeconds(parse(maxAge));
const pubdate = new Date(item.pubdate);
const age = now.getTime() - pubdate.getTime();
if ((age / 1000) > maxSecs)
continue;
}
urlList.push(item.link);
}
return urlList;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9saWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxHQUE2QixNQUFNLEtBQUssQ0FBQztBQUNoRCxPQUFPLFVBQVUsTUFBTSxZQUFZLENBQUM7QUFDcEMsb0VBQW9FO0FBQ3BFLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDcEQsT0FBTyxFQUFFLE9BQU8sSUFBSSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFFM0M7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsV0FBVyxDQUM3QixNQUFjLEVBQUUsSUFBWSxFQUM1QixHQUFXLEVBQUcsT0FBc0I7SUFHcEMsTUFBTSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTlCLElBQUk7UUFFQSwwQkFBMEI7UUFDMUIsZ0RBQWdEO1FBQ2hELHVCQUF1QjtRQUN2QixJQUFJO1FBQ0osaUNBQWlDO1FBQ2pDLGlEQUFpRDtRQUNqRCx1RUFBdUU7UUFDdkUsbUJBQW1CO1FBQ25CLDBDQUEwQztRQUMxQyxpREFBaUQ7UUFDakQseUNBQXlDO1FBQ3pDLFFBQVE7UUFDUixJQUFJO1FBRUosTUFBTSxRQUFRLEdBQWtCLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDekQsYUFBYTtZQUNiLHdEQUF3RDtZQUN4RCxLQUFLO1lBQ0wsSUFBSSxFQUFFO2dCQUNGLElBQUksRUFBRSxJQUFJO2dCQUNWLEdBQUcsRUFBRSxHQUFHO2dCQUNSLE9BQU8sRUFBRSxPQUFPO2FBQ25CO1NBQ2UsQ0FBQyxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxPQUFPLENBQUMsTUFBTSxhQUFhLE1BQU0sV0FBVyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztLQUMvRjtJQUFDLE9BQU8sR0FBRyxFQUFFO1FBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztLQUN0QjtBQUNMLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxlQUFlLENBQ2pDLE1BQWMsRUFBRSxHQUFXLEVBQUUsR0FBVztJQUd4QywrREFBK0Q7SUFFL0QsTUFBTSxDQUFDLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRTlCLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztJQUNsQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFFbEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFMUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBRTdDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLE1BQU0sSUFBSSxHQUFHLFdBQVcsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxNQUFjO0lBRXRDLE1BQU0sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDN0MsQ0FBQyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUM7SUFDaEIsT0FBTyxDQUFDLENBQUM7QUFDYixDQUFDO0FBNEJEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDdEMsQ0FBUyxFQUFFLE1BQWU7SUFJMUIsSUFBSSxDQUFDLENBQUM7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBRTdDLHNEQUFzRDtJQUV0RCxNQUFNLGdCQUFnQixHQUFHLElBQUksVUFBVSxDQUFDO1FBQ3BDLEdBQUcsRUFBRSxDQUFDO1FBQ04sT0FBTyxFQUFFLEtBQUs7UUFDZCxNQUFNLEVBQUU7WUFDSixHQUFHLEVBQUUsSUFBSTtZQUNULE9BQU8sRUFBRSxJQUFJO1lBQ2IsVUFBVSxFQUFFLElBQUk7WUFDaEIsUUFBUSxFQUFFLElBQUk7U0FDakI7S0FDRixDQUFDLENBQUM7SUFDTCxxREFBcUQ7SUFDckQsbUJBQW1CO0lBQ25CLGVBQWU7SUFDZixNQUFNO0lBRU4sMkJBQTJCO0lBRTNCLE1BQU0sS0FBSyxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDN0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLEVBQWdCLENBQUM7SUFDdEMsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO1FBQzVCLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFO1lBQzFCLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBRSxJQUFJLENBQUUsRUFBRSxDQUFDLENBQUM7U0FDL0I7YUFBTSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRTtZQUNqQyxNQUFNLE9BQU8sR0FBYSxJQUFJLENBQUM7WUFDL0IsSUFBSSxPQUFPLE9BQU8sQ0FBQyxHQUFHLEtBQUssUUFBUSxFQUFFO2dCQUNqQyxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBRSxDQUFDO2FBQ2pDO1lBQ0QsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNyQjtLQUNKO0lBQ0QsT0FBTyxHQUFHLENBQUM7SUFDWCxnQkFBZ0I7SUFFaEIsZ0JBQWdCO0lBQ2hCLDhCQUE4QjtJQUU5QixnREFBZ0Q7SUFDaEQsNkRBQTZEO0lBRTdELDBCQUEwQjtJQUMxQiwyQkFBMkI7SUFDM0IscURBQXFEO0lBQ3JELDREQUE0RDtJQUM1RCw0Q0FBNEM7SUFDNUMsYUFBYTtJQUNiLFdBQVc7SUFDWCwwQkFBMEI7SUFDMUIsSUFBSTtBQUVSLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDdEMsT0FBZSxFQUFFLE1BQWM7SUFHL0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFL0IsSUFBSSxJQUFJLENBQUM7SUFDVCxJQUFJO1FBQ0Esc0RBQXNEO1FBQ3RELG9CQUFvQjtRQUNwQixJQUFJLFNBQVMsQ0FBQztRQUNkLElBQUksS0FBSyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7WUFDNUIsU0FBUyxHQUFHLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQzVEO2FBQU07WUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDMUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztTQUN2QjtRQUVELElBQUksR0FBRyxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3pDLElBQUk7Z0JBQ0EsSUFBSSxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzlCLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRTtvQkFDckIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUMzQixDQUFDLENBQUMsQ0FBQztnQkFDSCxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQzFCO1lBQUMsT0FBTyxHQUFHLEVBQUU7Z0JBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQUU7UUFDbEMsQ0FBQyxDQUFDLENBQUM7S0FDTjtJQUFDLE9BQU0sR0FBRyxFQUFFO1FBQ1QsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsT0FBTyxtQkFBbUIsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7S0FDN0U7SUFFRCxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7SUFDbkIsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFO1FBQzNCLElBQUksTUFBTSxFQUFFO1lBQ1IsTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDekMsTUFBTSxPQUFPLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxPQUFPO2dCQUFFLFNBQVM7U0FDeEM7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUMzQjtJQUVELE9BQU8sT0FBTyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCB7IHByb21pc2VzIGFzIGZzcCB9IGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCBnb3QsIHsgUmVzcG9uc2UsIEdvdE9wdGlvbnMgfSBmcm9tICdnb3QnO1xuaW1wb3J0IFNpdGVtYXBwZXIgZnJvbSAnc2l0ZW1hcHBlcic7XG4vLyBpbXBvcnQgeyBkZWZhdWx0IGFzIFNpdGVtYXBYTUxQYXJzZXIgfSBmcm9tICdzaXRlbWFwLXhtbC1wYXJzZXInO1xuaW1wb3J0IHsgcGFyc2UsIHRvU2Vjb25kcyB9IGZyb20gXCJpc284NjAxLWR1cmF0aW9uXCI7XG5pbXBvcnQgeyBkZWZhdWx0IGFzIEZlZWRNZSB9IGZyb20gJ2ZlZWRtZSc7XG5cbi8qKlxuICogVXNlIEF4aW9zIHRvIHBvc3QgYSBVUkwgbGlzdCB2aWEgSW5kZXhOb3cgdG8gdGhlIGdpdmVuIHNlYXJjaCBlbmdpbmUuXG4gKiBcbiAqIEBwYXJhbSBrZXkgVGhlIGF1dGhlbnRpY2F0aW9uIGtleSB0byB1c2UgZm9yIEluZGV4Tm93XG4gKiBAcGFyYW0gZW5naW5lIFRoZSBkb21haW4gbmFtZSBmb3IgdGhlIHNlYXJjaCBlbmdpbmVcbiAqIEBwYXJhbSBob3N0IFRoZSBkb21haW4gbmFtZSBmb3IgeW91ciB3ZWJzaXRlXG4gKiBAcGFyYW0gdXJsTGlzdCBUaGUgbGlzdCBvZiBVUkxzIHRvIHBvc3QgdG8gSW5kZXhOb3dcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBvc3RVUkxsaXN0KFxuICAgIGVuZ2luZTogc3RyaW5nLCBob3N0OiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsICB1cmxMaXN0OiBBcnJheTxzdHJpbmc+XG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBcbiAgICBjb25zdCB1ID0gaW5kZXhOb3dVUkwoZW5naW5lKTtcblxuICAgIHRyeSB7XG5cbiAgICAgICAgLy8gUE9TVCAvaW5kZXhub3cgSFRUUC8xLjFcbiAgICAgICAgLy8gQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XG4gICAgICAgIC8vIEhvc3Q6IDxzZWFyY2hlbmdpbmU+XG4gICAgICAgIC8vIHtcbiAgICAgICAgLy8gICAgIFwiaG9zdFwiOiBcInd3dy5leGFtcGxlLmNvbVwiLFxuICAgICAgICAvLyAgICAgXCJrZXlcIjogXCJhYWE2Yzk1N2U0N2Q0OTg1ODllZTdhMzMyODE5OTdjYlwiLFxuICAgICAgICAvLyAgICAgXCJrZXlMb2NhdGlvblwiOiBcImh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL215SW5kZXhOb3dLZXk2MzYzOC50eHRcIixcbiAgICAgICAgLy8gICAgIFwidXJsTGlzdFwiOiBbXG4gICAgICAgIC8vICAgICAgICAgXCJodHRwczovL3d3dy5leGFtcGxlLmNvbS91cmwxXCIsXG4gICAgICAgIC8vICAgICAgICAgXCJodHRwczovL3d3dy5leGFtcGxlLmNvbS9mb2xkZXIvdXJsMlwiLFxuICAgICAgICAvLyAgICAgICAgIFwiaHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vdXJsM1wiXG4gICAgICAgIC8vICAgICBdXG4gICAgICAgIC8vIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZTogUmVzcG9uc2U8YW55PiA9IGF3YWl0IGdvdC5wb3N0KHUudG9TdHJpbmcoKSwge1xuICAgICAgICAgICAgLy8gaGVhZGVyczoge1xuICAgICAgICAgICAgLy8gICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOCdcbiAgICAgICAgICAgIC8vIH0sXG4gICAgICAgICAgICBqc29uOiB7XG4gICAgICAgICAgICAgICAgaG9zdDogaG9zdCxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICB1cmxMaXN0OiB1cmxMaXN0XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gYXMgR290T3B0aW9uczxhbnk+KTtcbiAgICAgICAgY29uc29sZS5sb2coYFN1Ym1pdHRlZCAke3VybExpc3QubGVuZ3RofSBVUkwncyB0byAke2VuZ2luZX0gc3RhdHVzICR7cmVzcG9uc2Uuc3RhdHVzQ29kZX1gKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBTdWJtaXQgYSBzaW5nbGUgVVJMIHRvIGFuIEluZGV4Tm93IHNlcnZpY2UuICBJZiB0aGlzIGV4ZWN1dGVzIHdpdGhcbiAqIG5vIGVycm9yIGl0IHdhcyBzdWNjZXNzZnVsLiAgT3RoZXJ3aXNlIGEgc3VpdGFibGUgZXJyb3IgaXMgdGhyb3duLlxuICogXG4gKiBAcGFyYW0gZW5naW5lIFRoZSBkb21haW4gbmFtZSBvZiB0aGUgc2VhcmNoIGVuZ2luZVxuICogQHBhcmFtIHVybCBUaGUgVVJMIHRvIHN1Ym1pdFxuICogQHBhcmFtIGtleSBUaGUgSW5kZXhOb3cga2V5IHRvIHVzZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3VibWl0U2luZ2xlVVJMKFxuICAgIGVuZ2luZTogc3RyaW5nLCB1cmw6IHN0cmluZywga2V5OiBzdHJpbmdcbik6IFByb21pc2U8dm9pZD4ge1xuXG4gICAgLy8gaHR0cHM6Ly88c2VhcmNoZW5naW5lPi9pbmRleG5vdz91cmw9dXJsLWNoYW5nZWQma2V5PXlvdXIta2V5XG5cbiAgICBjb25zdCB1ID0gaW5kZXhOb3dVUkwoZW5naW5lKTtcblxuICAgIHUuc2VhcmNoUGFyYW1zLmFwcGVuZCgndXJsJywgdXJsKTtcbiAgICB1LnNlYXJjaFBhcmFtcy5hcHBlbmQoJ2tleScsIGtleSk7XG5cbiAgICBjb25zb2xlLmxvZyhgU3VibWl0dGluZyAke3UudG9TdHJpbmcoKX1gKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZ290LmdldCh1LnRvU3RyaW5nKCkpO1xuXG4gICAgY29uc29sZS5sb2coYFN1Ym1pdHRlZCB0byAke2VuZ2luZX0gJHt1cmx9IHN0YXR1cyAke3Jlc3BvbnNlLnN0YXR1c0NvZGV9YCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBVUkwgb2JlY3QgZm9yIHRoZSBJbmRleE5vdyBzZXJ2aWNlIG9uIHRoZSBnaXZlbiBcbiAqIHNlYXJjaCBlbmdpbmUuIFxuICogQHBhcmFtIGVuZ2luZSBUaGUgZG9tYWluIG5hbWUgZm9yIHRoZSBzZWFyY2ggZW5naW5lXG4gKiBAcmV0dXJucyBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZGV4Tm93VVJMKGVuZ2luZTogc3RyaW5nKTogVVJMIHtcblxuICAgIGNvbnN0IHUgPSBuZXcgVVJMKGBodHRwczovL0VOR0lORS9pbmRleG5vd2ApO1xuICAgIHUuaG9zdCA9IGVuZ2luZTtcbiAgICByZXR1cm4gdTtcbn1cblxuLyoqXG4gKiBEZXNjcmliZXMgU2l0ZW1hcCBlbnRyaWVzIFxuICovXG5leHBvcnQgdHlwZSBTaXRlbWFwRW50cnkgPSB7XG4gICAgLyoqXG4gICAgICogVVJMKHMpIGZvciBhbiBpdGVtIGluIHRoZSBTaXRlbWFwXG4gICAgICovXG4gICAgbG9jOiBBcnJheTxzdHJpbmc+LFxuXG4gICAgLyoqXG4gICAgICogTGFzdCBtb2RpZmljYXRpb24gZGF0ZShzKVxuICAgICAqL1xuICAgIGxhc3Rtb2Q/OiBBcnJheTxzdHJpbmc+LFxuXG4gICAgLyoqXG4gICAgICogSG93IG9mdGVuIHRvIGV4cGVjdCB0aGlzIGl0ZW0gdG8gY2hhbmdlXG4gICAgICovXG4gICAgY2hhbmdlZnJlcT86IEFycmF5PHN0cmluZz4sXG5cbiAgICAvKipcbiAgICAgKiBQcmlvcml0aXphdGlvblxuICAgICAqL1xuICAgIHByaW9yaXR5PzogQXJyYXk8c3RyaW5nPixcbiAgICBpbWFnZT86IEFycmF5PHN0cmluZz5cbn07XG5cbi8qKlxuICogRmV0Y2hlcyBhbGwgaXRlbXMgZnJvbSBhIHNpdGVtYXAsIGFjY29kb21hdGluZyBzaXRlbWFwcyB0aGF0IGhhdmVcbiAqIHN1Yi1zaXRlbWFwcy4gIFRoZSByZXR1cm4gdmFsdWUgaXMgYW4gYXJyYXkgb2Yge1NpdGVtYXBFbnRyeX0uXG4gKiBcbiAqIEBwYXJhbSB1IFRoZSBVUkwgZm9yIHRoZSBzaXRlbWFwXG4gKiBAcGFyYW0gbWF4QWdlIE9wdGlvbmFsLCBhbiBJU084NjAxIGRlc2NyaXB0b3IgYSBtYXhpbXVtIGFnZSwgc28gd2VcbiAqICAgIGNhbiBzZWxlY3QgcmVjZW50bHkgY3JlYXRlZCBpdGVtcy4gIGUuZy4gUDEwRCBtZWFucyAxMCBkYXlzXG4gKiBAcmV0dXJucyBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoVVJMc0Zyb21TaXRlbWFwKFxuICAgIHU6IHN0cmluZywgbWF4QWdlPzogc3RyaW5nXG4pIDogUHJvbWlzZTxBcnJheTxTaXRlbWFwRW50cnk+Plxue1xuXG4gICAgaWYgKCF1KSB0aHJvdyBuZXcgRXJyb3IoYE5vIFVSTCBnaXZlbiAke3V9YCk7XG5cbiAgICAvLyBjb25zb2xlLmxvZyhgZmV0Y2hVUkxzRnJvbVNpdGVtYXAgJHt1fSAke21heEFnZX1gKTtcblxuICAgIGNvbnN0IHNpdGVtYXBYTUxQYXJzZXIgPSBuZXcgU2l0ZW1hcHBlcih7XG4gICAgICAgIHVybDogdSxcbiAgICAgICAgdGltZW91dDogMTUwMDAsIC8vIDE1IHNlY29uZHNcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgICBsb2M6IHRydWUsXG4gICAgICAgICAgICBsYXN0bW9kOiB0cnVlLFxuICAgICAgICAgICAgY2hhbmdlZnJlcTogdHJ1ZSxcbiAgICAgICAgICAgIHByaW9yaXR5OiB0cnVlLFxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAvLyBjb25zdCBzaXRlbWFwWE1MUGFyc2VyID0gbmV3IFNpdGVtYXBYTUxQYXJzZXIodSwge1xuICAgIC8vICAgICBkZWxheTogMzAwMCxcbiAgICAvLyAgICAgbGltaXQ6IDVcbiAgICAvLyB9KTtcblxuICAgIC8vIGNvbnNvbGUubG9nKGBmZXRjaGluZ2ApO1xuXG4gICAgY29uc3QgaXRlbXMgPSBhd2FpdCBzaXRlbWFwWE1MUGFyc2VyLmZldGNoKCk7XG4gICAgY29uc3QgcmV0ID0gbmV3IEFycmF5PFNpdGVtYXBFbnRyeT4oKTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMuc2l0ZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0LnB1c2goeyBsb2M6IFsgaXRlbSBdIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpdGVtID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgY29uc3QgYW55aXRlbTogYW55ID0gPGFueT5pdGVtO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhbnlpdGVtLmxvYyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBhbnlpdGVtLmxvYyA9IFsgYW55aXRlbS5sb2MgXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldC5wdXNoKGFueWl0ZW0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gICAgLy8gcmV0dXJuIGl0ZW1zO1xuXG4gICAgLy8gaWYgKG1heEFnZSkge1xuICAgIC8vICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gICAgLy8gICAgIGNvbnN0IG1heFNlY3MgPSB0b1NlY29uZHMocGFyc2UobWF4QWdlKSk7XG4gICAgLy8gICAgIC8vIGNvbnNvbGUubG9nKGBtYXhBZ2UgJHttYXhBZ2V9IG1heFNlY3MgJHttYXhTZWNzfWApO1xuXG4gICAgLy8gICAgIHJldHVybiBpdGVtcy5zaXRlcztcbiAgICAvLyAgICAgLy8gLmZpbHRlcihpdGVtID0+IHtcbiAgICAvLyAgICAgLy8gICAgIGNvbnN0IGxhc3Rtb2QgPSBuZXcgRGF0ZShpdGVtLmxhc3Rtb2QpO1xuICAgIC8vICAgICAvLyAgICAgY29uc3QgYWdlID0gbm93LmdldFRpbWUoKSAtIGxhc3Rtb2QuZ2V0VGltZSgpO1xuICAgIC8vICAgICAvLyAgICAgcmV0dXJuIChhZ2UgLyAxMDAwKSA8IG1heFNlY3M7XG4gICAgLy8gICAgIC8vIH0pO1xuICAgIC8vIH0gZWxzZSB7XG4gICAgLy8gICAgIHJldHVybiBpdGVtcy5zaXRlcztcbiAgICAvLyB9XG4gICAgXG59XG5cbi8qKlxuICogUmV0cmlldmUgVVJMcyBmcm9tIHRoZSBSU1Mgb3IgQXRvbSBmaWxlLCByZXR1cm5pbmcgYXNcbiAqIGFuIGFycmF5LlxuICogXG4gKiBAcGFyYW0gZmVlZFVSTCAgVGhlIFVSTCBmb3IgdGhlIFJTUyBvciBBdG9tIGZlZWRcbiAqIEBwYXJhbSBtYXhBZ2UgQW4gSVNPODYwMSBkdXJhdGlvbiBzdHJpbmcgYXMgZGlzY3Vzc2VkIGFib3ZlXG4gKiBAcmV0dXJucyBcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoVVJMc0Zyb21SU1NBdG9tKFxuICAgIGZlZWRVUkw6IHN0cmluZywgbWF4QWdlOiBzdHJpbmdcbik6IFByb21pc2U8QXJyYXk8c3RyaW5nPj4ge1xuXG4gICAgY29uc3QgdUZlZWQgPSBuZXcgVVJMKGZlZWRVUkwpO1xuXG4gICAgbGV0IGZlZWQ7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gU3VwcG9ydCByZWFkaW5nIHRoZSBSU1MgZmlsZSBlaXRoZXIgZnJvbSBhIGZpbGUgb3IgXG4gICAgICAgIC8vIG92ZXIgdGhlIEludGVybmV0XG4gICAgICAgIGxldCByc3NTdHJlYW07XG4gICAgICAgIGlmICh1RmVlZC5wcm90b2NvbCA9PT0gJ2ZpbGU6Jykge1xuICAgICAgICAgICAgcnNzU3RyZWFtID0gZnMuY3JlYXRlUmVhZFN0cmVhbSh1RmVlZC5wYXRobmFtZSwgJ3V0Zi04Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByZXNGZWVkID0gYXdhaXQgZ290LnN0cmVhbShmZWVkVVJMKTtcbiAgICAgICAgICAgIHJzc1N0cmVhbSA9IHJlc0ZlZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBmZWVkID0gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsZXQgcGFyc2VyID0gbmV3IEZlZWRNZSh0cnVlKTtcbiAgICAgICAgICAgICAgICBwYXJzZXIub24oJ2ZpbmlzaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShwYXJzZXIuZG9uZSgpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByc3NTdHJlYW0ucGlwZShwYXJzZXIpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7IHJlamVjdChlcnIpOyB9XG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2goZXJyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRmV0Y2hpbmcgZmVlZCAke2ZlZWRVUkx9IGZhaWxlZCBiZWNhdXNlICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgfVxuXG4gICAgY29uc3QgdXJsTGlzdCA9IFtdO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBmZWVkLml0ZW1zKSB7XG4gICAgICAgIGlmIChtYXhBZ2UpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBjb25zdCBtYXhTZWNzID0gdG9TZWNvbmRzKHBhcnNlKG1heEFnZSkpO1xuICAgICAgICAgICAgY29uc3QgcHViZGF0ZSA9IG5ldyBEYXRlKGl0ZW0ucHViZGF0ZSk7XG4gICAgICAgICAgICBjb25zdCBhZ2UgPSBub3cuZ2V0VGltZSgpIC0gcHViZGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICBpZiAoKGFnZSAvIDEwMDApID4gbWF4U2VjcykgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdXJsTGlzdC5wdXNoKGl0ZW0ubGluayk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVybExpc3Q7XG59Il19