Merge pull request #10 from AliasIO/master

Sync no.10
main
Daniel Zdziebko 7 years ago committed by GitHub
commit ba5955ac91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -54,7 +54,6 @@ zip -qr ../../../build/wappalyzer_webextension.zip . \
-x images/icon_50.png \ -x images/icon_50.png \
-x images/icon_150.png \ -x images/icon_150.png \
-x js/ms_\*.js \ -x js/ms_\*.js \
-x manifest.edge.json \
-x \*.log \ -x \*.log \
-x \*.lock \ -x \*.lock \
-x \*.gitignore \ -x \*.gitignore \
@ -68,46 +67,4 @@ zip -qr ../../../build/wappalyzer_webextension.zip . \
popd > /dev/null popd > /dev/null
# Edge
#echo "Building Edge application..."
#
#pushd build > /dev/null
#
#webextension_dir="../$webextension_dir"
#manifest_dir="Wappalyzer/edgeextension/manifest"
#
#mv $webextension_dir/manifest.json $webextension_dir/manifest.webextension.json
#mv $webextension_dir/manifest.edge.json $webextension_dir/manifest.json
#
#sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$version\"/" $webextension_dir/manifest.json
#
#manifoldjs -l debug -p edgeextension -f edgeextension -m $webextension_dir/manifest.json
#
## Replace symlinks with actual files
#rm $manifest_dir/Extension/images/icons
#
#cp ../src/apps.json $manifest_dir/Extension
#cp ../src/wappalyzer.js $manifest_dir/Extension/js
#cp -r ../src/icons $manifest_dir/Extension/images
#
#mv $webextension_dir/manifest.json $webextension_dir/manifest.edge.json
#mv $webextension_dir/manifest.webextension.json $webextension_dir/manifest.json
#
#sed -i 's/INSERT-YOUR-PACKAGE-IDENTITY-NAME-HERE/1591Wappalyzer.Wappalyzer/' $manifest_dir/appxmanifest.xml
#sed -i 's/INSERT-YOUR-PACKAGE-IDENTITY-PUBLISHER-HERE/D240C22F-A6C1-45DF-BF7B-4C835064DF51/' $manifest_dir/appxmanifest.xml
#sed -i 's/INSERT-YOUR-PACKAGE-PROPERTIES-PUBLISHERDISPLAYNAME-HERE/Wappalyzer/' $manifest_dir/appxmanifest.xml
#sed -i 's/Version="0.\([^"]\+\)/Version="\1.0/' $manifest_dir/appxmanifest.xml
#
#cp $webextension_dir/images/icon_44.png $manifest_dir/Assets/Square44x44Logo.png
#cp $webextension_dir/images/icon_150.png $manifest_dir/Assets/Square150x150Logo.png
#cp $webextension_dir/images/icon_50.png $manifest_dir/Assets/StoreLogo.png
#
#manifoldjs -l debug -p edgeextension package $manifest_dir
#
#mv Wappalyzer/edgeextension/package/edgeExtension.appx wappalyzer_edge.appx
#
#rm -rf Wappalyzer
#
#popd > /dev/null
echo "Done (v$version)." echo "Done (v$version)."

@ -6,7 +6,7 @@ set -eu
echo "Validating apps.json..." echo "Validating apps.json..."
jsonlint-cli -s schema.json src/apps.json jsonlint-cli -tps schema.json src/apps.json > /tmp/apps.json && mv /tmp/apps.json src/apps.json
echo "Validating regular expressions..." echo "Validating regular expressions..."

@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"file-type": "3.8.*", "file-type": "7.4.*",
"is-svg": "2.0.*", "is-svg": "2.1.*",
"read-chunk": "2.0.*" "read-chunk": "2.1.*"
} }
} }

@ -3,6 +3,9 @@
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"$schema": {
"type": "string"
},
"categories": { "categories": {
"type": "object", "type": "object",
"required": true, "required": true,
@ -13,7 +16,7 @@
"required": true, "required": true,
"properties": { "properties": {
"priority": { "priority": {
"type": "string" "type": "number"
}, },
"name": { "name": {
"type": "string" "type": "string"
@ -31,13 +34,13 @@
"cats": { "cats": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "number"
}, },
"required": true "required": true
}, },
"env": { "js": {
"type": [ "string", "array" ], "type": "object",
"items": { "additionalProperties": {
"type": "string" "type": "string"
} }
}, },
@ -48,19 +51,28 @@
} }
}, },
"html": { "html": {
"type": [ "string", "array" ], "type": [
"string",
"array"
],
"items": { "items": {
"type": "string" "type": "string"
} }
}, },
"excludes": { "excludes": {
"type": [ "string", "array" ], "type": [
"string",
"array"
],
"items": { "items": {
"type": "string" "type": "string"
} }
}, },
"implies": { "implies": {
"type": [ "string", "array" ], "type": [
"string",
"array"
],
"items": { "items": {
"type": "string" "type": "string"
} }
@ -72,7 +84,10 @@
} }
}, },
"script": { "script": {
"type": [ "string", "array" ], "type": [
"string",
"array"
],
"items": { "items": {
"type": "string" "type": "string"
} }

File diff suppressed because it is too large Load Diff

@ -6,9 +6,10 @@
/** global: XMLHttpRequest */ /** global: XMLHttpRequest */
(function() { (function() {
wappalyzer.driver.document = document;
const container = document.getElementById('wappalyzer-container'); const container = document.getElementById('wappalyzer-container');
const domain = top.location.host; const url = wappalyzer.parseUrl(top.location.href);
const url = top.location.href.replace(/#.*$/, '');
const hasOwn = Object.prototype.hasOwnProperty; const hasOwn = Object.prototype.hasOwnProperty;
/** /**
@ -19,7 +20,7 @@
}; };
function getPageContent() { function getPageContent() {
wappalyzer.log('func: getPageContent'); wappalyzer.log('func: getPageContent', 'driver');
var env = []; var env = [];
@ -32,7 +33,7 @@
.filter(s => s.src) .filter(s => s.src)
.map(s => s.src); .map(s => s.src);
wappalyzer.analyze(domain, url, { wappalyzer.analyze(url, {
html: document.documentElement.innerHTML, html: document.documentElement.innerHTML,
env: env, env: env,
scripts: scripts scripts: scripts
@ -40,7 +41,7 @@
} }
function getResponseHeaders() { function getResponseHeaders() {
wappalyzer.log('func: getResponseHeaders'); wappalyzer.log('func: getResponseHeaders', 'driver');
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
@ -51,7 +52,7 @@
var headers = xhr.getAllResponseHeaders().split("\n"); var headers = xhr.getAllResponseHeaders().split("\n");
if ( headers.length > 0 && headers[0] != '' ) { if ( headers.length > 0 && headers[0] != '' ) {
wappalyzer.log('responseHeaders: ' + xhr.getAllResponseHeaders()); wappalyzer.log('responseHeaders: ' + xhr.getAllResponseHeaders(), 'driver');
var responseHeaders = {}; var responseHeaders = {};
@ -69,7 +70,7 @@
} }
}); });
wappalyzer.analyze(domain, url, { wappalyzer.analyze(url, {
headers: responseHeaders headers: responseHeaders
}); });
} }
@ -83,7 +84,7 @@
* Display apps * Display apps
*/ */
wappalyzer.driver.displayApps = detected => { wappalyzer.driver.displayApps = detected => {
wappalyzer.log('func: diplayApps'); wappalyzer.log('func: diplayApps', 'driver');
var first = true; var first = true;
var app; var app;
@ -104,14 +105,14 @@
var version = detected[app].version, var version = detected[app].version,
confidence = detected[app].confidence; confidence = detected[app].confidence;
html += html +=
'<div class="wappalyzer-app' + ( first ? ' wappalyzer-first' : '' ) + '">' + '<div class="wappalyzer-app' + ( first ? ' wappalyzer-first' : '' ) + '">' +
'<a target="_blank" class="wappalyzer-application" href="' + wappalyzer.config.websiteURL + 'applications/' + app.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9-]/g, '') + '">' + '<a target="_blank" class="wappalyzer-application" href="' + wappalyzer.config.websiteURL + 'applications/' + app.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9-]/g, '') + '">' +
'<strong>' + '<strong>' +
'<img src="' + wappalyzer.config.websiteURL + 'images/icons/' + (wappalyzer.apps[app].icon || 'default.svg') + '" width="16" height="16"/> ' + app + '<img src="' + wappalyzer.config.websiteURL + 'images/icons/' + (wappalyzer.apps[app].icon || 'default.svg') + '" width="16" height="16"/> ' + app +
'</strong>' + '</strong>' +
( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) +
'</a>'; '</a>';
for ( let i in wappalyzer.apps[app].cats ) { for ( let i in wappalyzer.apps[app].cats ) {

@ -27,14 +27,14 @@ node index.js [url] [options]
### Options ### Options
``` ```
--debug=0|1 Output debug messages. --chunk-size=num Process links in chunks.
--delay=ms Wait for ms milliseconds between requests. --debug=0|1 Output debug messages.
--max-depth=num Don't analyze pages more than num levels deep. --delay=ms Wait for ms milliseconds between requests.
--max-urls=num Exit when num URLs have been analyzed. --max-depth=num Don't analyse pages more than num levels deep.
--max-wait=ms Wait no more than ms milliseconds for page resources to load. --max-urls=num Exit when num URLs have been analysed.
--recursive=0|1 Follow links on pages (crawler). --max-wait=ms Wait no more than ms milliseconds for page resources to load.
--request-timeout=ms Wait no more than ms millisecond for the page to load. --recursive=0|1 Follow links on pages (crawler).
--user-agent=str Set the user agent string. --user-agent=str Set the user agent string.
``` ```
@ -46,9 +46,8 @@ const options = {
delay: 500, delay: 500,
maxDepth: 3, maxDepth: 3,
maxUrls: 10, maxUrls: 10,
maxWait: 1000, maxWait: 5000,
recursive: true, recursive: true,
requestTimeout: 3000,
userAgent: 'Wappalyzer', userAgent: 'Wappalyzer',
}; };

@ -8,37 +8,42 @@ const Browser = require('zombie');
const json = JSON.parse(fs.readFileSync(__dirname + '/apps.json')); const json = JSON.parse(fs.readFileSync(__dirname + '/apps.json'));
const extensions = /^([^.]+$|\.(asp|aspx|cgi|htm|html|jsp|php)$)/;
class Driver { class Driver {
constructor(pageUrl, options) { constructor(pageUrl, options) {
this.options = Object.assign({}, { this.options = Object.assign({}, {
chunkSize: 5,
debug: false, debug: false,
delay: 500, delay: 500,
maxDepth: 3, maxDepth: 3,
maxUrls: 10, maxUrls: 10,
maxWait: 1000, maxWait: 5000,
recursive: false, recursive: false,
requestTimeout: 3000,
userAgent: 'Mozilla/5.0 (compatible; Wappalyzer)', userAgent: 'Mozilla/5.0 (compatible; Wappalyzer)',
}, options || {}); }, options || {});
this.options.debug = Boolean(this.options.debug); this.options.debug = Boolean(this.options.debug);
this.options.recursive = Boolean(this.options.recursive);
this.options.delay = this.options.recursive ? parseInt(this.options.delay, 10) : 0; this.options.delay = this.options.recursive ? parseInt(this.options.delay, 10) : 0;
this.options.maxDepth = parseInt(this.options.maxDepth, 10); this.options.maxDepth = parseInt(this.options.maxDepth, 10);
this.options.maxUrls = parseInt(this.options.maxUrls, 10); this.options.maxUrls = parseInt(this.options.maxUrls, 10);
this.options.maxWait = parseInt(this.options.maxWait, 10); this.options.maxWait = parseInt(this.options.maxWait, 10);
this.options.recursive = Boolean(this.options.recursive);
this.origPageUrl = url.parse(pageUrl); this.origPageUrl = url.parse(pageUrl);
this.analyzedPageUrls = []; this.analyzedPageUrls = [];
this.apps = []; this.apps = [];
this.meta = {};
this.wappalyzer = new Wappalyzer(); this.wappalyzer = new Wappalyzer();
this.wappalyzer.apps = json.apps; this.wappalyzer.apps = json.apps;
this.wappalyzer.categories = json.categories; this.wappalyzer.categories = json.categories;
this.wappalyzer.parseJsPatterns();
this.wappalyzer.driver.log = (message, source, type) => this.log(message, source, type); this.wappalyzer.driver.log = (message, source, type) => this.log(message, source, type);
this.wappalyzer.driver.displayApps = detected => this.displayApps(detected); this.wappalyzer.driver.displayApps = (detected, meta, context) => this.displayApps(detected, meta, context);
} }
analyze() { analyze() {
@ -54,8 +59,8 @@ class Driver {
this.options.debug && console.log('[wappalyzer ' + type + ']', '[' + source + ']', message); this.options.debug && console.log('[wappalyzer ' + type + ']', '[' + source + ']', message);
} }
displayApps(detected) { displayApps(detected, meta) {
this.timer('displayApps'); this.meta = meta;
Object.keys(detected).forEach(appName => { Object.keys(detected).forEach(appName => {
const app = detected[appName]; const app = detected[appName];
@ -84,118 +89,224 @@ class Driver {
} }
fetch(pageUrl, index, depth) { fetch(pageUrl, index, depth) {
this.timer('fetch'); // Return when the URL is a duplicate or maxUrls has been reached
if ( this.analyzedPageUrls.indexOf(pageUrl.href) !== -1 || this.analyzedPageUrls.length >= this.options.maxUrls ) {
return Promise.resolve();
}
return new Promise(resolve => { this.analyzedPageUrls.push(pageUrl.href);
// Return when the URL is a duplicate or maxUrls has been reached
if ( this.analyzedPageUrls.indexOf(pageUrl.href) !== -1 || this.analyzedPageUrls.length >= this.options.maxUrls ) { const timerScope = {
last: new Date().getTime()
};
this.timer('fetch; url: ' + pageUrl.href + '; depth: ' + depth + '; delay: ' + ( this.options.delay * index ) + 'ms', timerScope);
return new Promise(resolve => this.sleep(this.options.delay * index).then(() => this.visit(pageUrl, timerScope, resolve)));
}
visit(pageUrl, timerScope, resolve) {
const browser = new Browser({
silent: true,
userAgent: this.options.userAgent,
waitDuration: this.options.maxWait,
});
this.timer('browser.visit start; url: ' + pageUrl.href, timerScope);
browser.visit(pageUrl.href, () => {
this.timer('browser.visit end; url: ' + pageUrl.href, timerScope);
if ( !this.responseOk(browser, pageUrl) ) {
return resolve(); return resolve();
} }
this.analyzedPageUrls.push(pageUrl.href); const headers = this.getHeaders(browser);
const html = this.getHtml(browser);
const scripts = this.getScripts(browser);
const js = this.getJs(browser);
this.wappalyzer.analyze(pageUrl, {
headers,
html,
scripts,
js
});
const links = Array.from(browser.document.getElementsByTagName('a'))
.filter(link => link.protocol === 'http:' || link.protocol === 'https:')
.filter(link => link.hostname === this.origPageUrl.hostname)
.filter(link => extensions.test(link.pathname))
.map(link => { link.hash = ''; return url.parse(link.href) });
return resolve(links);
});
}
responseOk(browser, pageUrl) {
// Validate response
const resource = browser.resources.length ? browser.resources.filter(resource => resource.response).shift() : null;
if ( !resource ) {
this.wappalyzer.log('No response from server; url: ' + pageUrl.href, 'driver', 'error');
return false;
}
if ( resource.response.status !== 200 ) {
this.wappalyzer.log('Response was not OK; status: ' + resource.response.status + ' ' + resource.response.statusText + '; url: ' + pageUrl.href, 'driver', 'error');
return false;
}
const headers = this.getHeaders(browser);
// Validate content type
const contentType = headers.hasOwnProperty('content-type') ? headers['content-type'].shift() : null;
if ( !contentType || !/\btext\/html\b/.test(contentType) ) {
this.wappalyzer.log('Skipping; url: ' + pageUrl.href + '; content type: ' + contentType, 'driver');
this.analyzedPageUrls.splice(this.analyzedPageUrls.indexOf(pageUrl.href), 1);
this.wappalyzer.log('depth: ' + depth + '; delay: ' + ( this.options.delay * index ) + 'ms; url: ' + pageUrl.href, 'driver'); return false;
}
// Validate document
if ( !browser.document || !browser.document.documentElement ) {
this.wappalyzer.log('No HTML document; url: ' + pageUrl.href, 'driver', 'error');
return false;
}
return true;
}
getHeaders(browser) {
const headers = {};
const resource = browser.resources.length ? browser.resources.filter(resource => resource.response).shift() : null;
const browser = new Browser({ if ( resource ) {
silent: true, resource.response.headers._headers.forEach(header => {
userAgent: this.options.userAgent, if ( !headers[header[0]] ){
waitDuration: this.options.maxWait + 'ms', headers[header[0]] = [];
}
headers[header[0]].push(header[1]);
}); });
}
this.sleep(this.options.delay * index) return headers;
.then(() => { }
this.timer('browser.visit start');
browser.visit(pageUrl.href, this.options.requestTimeout, error => { getHtml(browser) {
this.timer('browser.visit end'); let html = '';
if ( !browser.resources['0'] || !browser.resources['0'].response ) { try {
this.wappalyzer.log('No response from server', 'browser', 'error'); html = browser.html();
return resolve(); if ( html.length > 50000 ) {
} html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
} catch ( error ) {
this.wappalyzer.log(error.message, 'browser', 'error');
}
return html;
}
browser.wait(this.options.maxWait) getScripts(browser) {
.catch(error => this.wappalyzer.log(error.message, 'browser', 'error')) if ( !browser.document || !browser.document.scripts ) {
.finally(() => { return [];
this.timer('browser.wait end'); }
const headers = {}; const scripts = Array.prototype.slice
.apply(browser.document.scripts)
.filter(script => script.src)
.map(script => script.src);
browser.resources['0'].response.headers._headers.forEach(header => { return scripts;
if ( !headers[header[0]] ){ }
headers[header[0]] = [];
}
headers[header[0]].push(header[1]); getJs(browser) {
}); const patterns = this.wappalyzer.jsPatterns;
const js = {};
let html = ''; Object.keys(patterns).forEach(appName => {
js[appName] = {};
try { Object.keys(patterns[appName]).forEach(chain => {
html = browser.html(); js[appName][chain] = {};
} catch ( e ) {
this.wappalyzer.log(error.message, 'browser', 'error');
}
const vars = Object.getOwnPropertyNames(browser.window); patterns[appName][chain].forEach((pattern, index) => {
const scripts = Array.prototype.slice const properties = chain.split('.');
.apply(browser.document.scripts)
.filter(s => s.src)
.map(s => s.src);
this.wappalyzer.analyze(pageUrl.hostname, pageUrl.href, { let value = properties.reduce((parent, property) => {
headers, return parent && parent.hasOwnProperty(property) ? parent[property] : null;
html, }, browser.window);
env: vars,
scripts
});
const links = browser.body.getElementsByTagName('a'); value = typeof value === 'string' || typeof value === 'number' ? value : !!value;
resolve(links); if ( value ) {
}); js[appName][chain][index] = value;
}); }
}); });
});
}); });
return js;
} }
crawl(pageUrl, index = 1, depth = 1) { crawl(pageUrl, index, depth = 1) {
this.timer('crawl'); pageUrl.canonical = pageUrl.protocol + '//' + pageUrl.host + pageUrl.pathname;
return new Promise(resolve => { return new Promise(resolve => {
this.fetch(pageUrl, index, depth) this.fetch(pageUrl, index, depth)
.catch(() => {})
.then(links => { .then(links => {
if ( links && Boolean(this.options.recursive) && depth < this.options.maxDepth ) { if ( links && Boolean(this.options.recursive) && depth < this.options.maxDepth ) {
links = Array.from(links) return this.chunk(links.slice(0, this.options.maxUrls), depth + 1);
.filter(link => link.hostname === this.origPageUrl.hostname)
.map(link => { link.hash = ''; return link });
return Promise.all(links.map((link, index) => this.crawl(link, index + 1, depth + 1)));
} else { } else {
return Promise.resolve(); return Promise.resolve();
} }
}) })
.then(() => { .then(() => {
this.timer('done'); resolve({
urls: this.analyzedPageUrls,
resolve(this.apps) applications: this.apps,
meta: this.meta
});
}); });
}); });
} }
chunk(links, depth, chunk = 0) {
if ( links.length === 0 ) {
return Promise.resolve();
}
const chunked = links.splice(0, this.options.chunkSize);
return new Promise(resolve => {
Promise.all(chunked.map((link, index) => this.crawl(link, index, depth)))
.then(() => this.chunk(links, depth, chunk + 1))
.then(() => resolve());
});
}
sleep(ms) { sleep(ms) {
return ms ? new Promise(resolve => setTimeout(resolve, ms)) : Promise.resolve(); return ms ? new Promise(resolve => setTimeout(resolve, ms)) : Promise.resolve();
} }
timer(step) { timer(message, scope) {
const time = new Date().getTime(); const time = new Date().getTime();
const sinceStart = ( Math.round(( time - this.time.start ) / 10) / 100) + 's'; const sinceStart = ( Math.round(( time - this.time.start ) / 10) / 100) + 's';
const sinceLast = ( Math.round(( time - this.time.last ) / 10) / 100) + 's'; const sinceLast = ( Math.round(( time - scope.last ) / 10) / 100) + 's';
this.wappalyzer.log('[' + step + '] Time lapsed: ' + sinceLast + ' / ' + sinceStart, 'driver'); this.wappalyzer.log('[timer] ' + message + '; lapsed: ' + sinceLast + ' / ' + sinceStart, 'driver');
this.time.last = time; scope.last = time;
} }
}; };

@ -28,6 +28,12 @@ while ( arg = args.shift() ) {
const wappalyzer = new Wappalyzer(url, options); const wappalyzer = new Wappalyzer(url, options);
setTimeout(() => {
console.log('force quit');
process.exit(1);
}, 10000);
wappalyzer.analyze() wappalyzer.analyze()
.then(json => { .then(json => {
process.stdout.write(JSON.stringify(json) + '\n') process.stdout.write(JSON.stringify(json) + '\n')

@ -0,0 +1,686 @@
{
"name": "wappalyzer",
"version": "5.3.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"abab": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
"integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4="
},
"acorn": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
"integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
},
"acorn-globals": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
"integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
"requires": {
"acorn": "2.7.0"
}
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"requires": {
"co": "4.6.0",
"fast-deep-equal": "1.0.0",
"fast-json-stable-stringify": "2.0.0",
"json-schema-traverse": "0.3.1"
}
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
},
"babel-runtime": {
"version": "5.8.29",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.29.tgz",
"integrity": "sha1-SiBSy8/1MXiNOp1rA81/RIKF+CU=",
"requires": {
"core-js": "1.2.7"
}
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"optional": true,
"requires": {
"tweetnacl": "0.14.5"
}
},
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"boom": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
"integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
"requires": {
"hoek": "4.2.0"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"combined-stream": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
"requires": {
"delayed-stream": "1.0.0"
}
},
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cryptiles": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
"integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
"requires": {
"boom": "5.2.0"
},
"dependencies": {
"boom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
"integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
"requires": {
"hoek": "4.2.0"
}
}
}
},
"cssom": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
"integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs="
},
"cssstyle": {
"version": "0.2.37",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
"requires": {
"cssom": "0.3.2"
}
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "1.0.0"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"escodegen": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
"integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
"requires": {
"esprima": "3.1.3",
"estraverse": "4.2.0",
"esutils": "2.0.2",
"optionator": "0.8.2",
"source-map": "0.5.7"
}
},
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
},
"eventsource": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
"integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
"requires": {
"original": "1.0.0"
}
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
"integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
"integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
"mime-types": "2.1.17"
}
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"requires": {
"ajv": "5.5.2",
"har-schema": "2.0.0"
}
},
"hawk": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
"integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
"requires": {
"boom": "4.3.1",
"cryptiles": "3.1.2",
"hoek": "4.2.0",
"sntp": "2.1.0"
}
},
"hoek": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
"integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "1.0.0",
"jsprim": "1.4.1",
"sshpk": "1.13.1"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
"jsdom": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz",
"integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=",
"requires": {
"abab": "1.0.4",
"acorn": "2.7.0",
"acorn-globals": "1.0.9",
"cssom": "0.3.2",
"cssstyle": "0.2.37",
"escodegen": "1.9.0",
"nwmatcher": "1.4.3",
"parse5": "1.5.1",
"request": "2.83.0",
"sax": "1.2.4",
"symbol-tree": "3.2.2",
"tough-cookie": "2.3.3",
"webidl-conversions": "2.0.1",
"whatwg-url-compat": "0.6.5",
"xml-name-validator": "2.0.1"
}
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "1.1.2",
"type-check": "0.3.2"
}
},
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.30.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
},
"mime-types": {
"version": "2.1.17",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
"requires": {
"mime-db": "1.30.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"nwmatcher": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz",
"integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw=="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"requires": {
"deep-is": "0.1.3",
"fast-levenshtein": "2.0.6",
"levn": "0.3.0",
"prelude-ls": "1.1.2",
"type-check": "0.3.2",
"wordwrap": "1.0.0"
}
},
"options": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
},
"original": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
"integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=",
"requires": {
"url-parse": "1.0.5"
}
},
"parse5": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
"integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
},
"querystringify": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz",
"integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw="
},
"request": {
"version": "2.83.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
"integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
"requires": {
"aws-sign2": "0.7.0",
"aws4": "1.6.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.3.1",
"har-validator": "5.0.3",
"hawk": "6.0.2",
"http-signature": "1.2.0",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.17",
"oauth-sign": "0.8.2",
"performance-now": "2.1.0",
"qs": "6.5.1",
"safe-buffer": "5.1.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.3",
"tunnel-agent": "0.6.0",
"uuid": "3.1.0"
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"sntp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
"integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
"requires": {
"hoek": "4.2.0"
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"optional": true
},
"sshpk": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
"bcrypt-pbkdf": "1.0.1",
"dashdash": "1.14.1",
"ecc-jsbn": "0.1.1",
"getpass": "0.1.7",
"jsbn": "0.1.1",
"tweetnacl": "0.14.5"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
},
"symbol-tree": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
"integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY="
},
"tough-cookie": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
"integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
"requires": {
"punycode": "1.4.1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "5.1.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "1.1.2"
}
},
"url-parse": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz",
"integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=",
"requires": {
"querystringify": "0.0.4",
"requires-port": "1.0.0"
}
},
"uuid": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "1.3.0"
}
},
"webidl-conversions": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz",
"integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY="
},
"whatwg-url-compat": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz",
"integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=",
"requires": {
"tr46": "0.0.3"
}
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU="
},
"zombie": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/zombie/-/zombie-5.0.7.tgz",
"integrity": "sha512-zrYFTD5iWxI3EJohmZ8F2sNafo44F/132wLj5WHLSHmytds60s+JiXLomflQ8sbNuWCZJAuszvf6+eUiVsUqPQ==",
"requires": {
"babel-runtime": "5.8.29",
"bluebird": "3.5.1",
"debug": "2.6.9",
"eventsource": "0.1.6",
"iconv-lite": "0.4.19",
"jsdom": "7.2.2",
"lodash": "3.10.1",
"mime": "1.6.0",
"ms": "0.7.3",
"request": "2.83.0",
"tough-cookie": "2.3.3",
"ws": "1.1.5"
},
"dependencies": {
"ms": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
"integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8="
},
"ultron": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
},
"ws": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
"integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
"requires": {
"options": "0.0.6",
"ultron": "1.0.2"
}
}
}
}
}
}

@ -2,7 +2,7 @@
"name": "wappalyzer", "name": "wappalyzer",
"description": "Uncovers the technologies used on websites", "description": "Uncovers the technologies used on websites",
"homepage": "https://github.com/AliasIO/Wappalyzer", "homepage": "https://github.com/AliasIO/Wappalyzer",
"version": "5.2.0", "version": "5.4.5",
"author": "Elbert Alias", "author": "Elbert Alias",
"license": "GPL-3.0", "license": "GPL-3.0",
"repository": { "repository": {
@ -17,7 +17,7 @@
"wappalyzer.js" "wappalyzer.js"
], ],
"dependencies": { "dependencies": {
"request": "^2.81.0", "request": "^2.83.0",
"zombie": "^5.0.7" "zombie": "^5.0.7"
} }
} }

@ -10,6 +10,7 @@
"optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" }, "optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" },
"nothingToDo": { "message": "Nichts zu tun." }, "nothingToDo": { "message": "Nichts zu tun." },
"noAppsDetected": { "message": "Keine Applikation entdeckt." }, "noAppsDetected": { "message": "Keine Applikation entdeckt." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Nachrichten Board" }, "categoryName2": { "message": "Nachrichten Board" },
"categoryName3": { "message": "Datenbankverwaltung" }, "categoryName3": { "message": "Datenbankverwaltung" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" }, "optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"nothingToDo": { "message": "Καμία ενέργεια." }, "nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." }, "noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Διαδικτυακό Φόρουμ" }, "categoryName2": { "message": "Διαδικτυακό Φόρουμ" },
"categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" }, "categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" },

@ -6,10 +6,11 @@
"optionsSave": { "message": "Save options" }, "optionsSave": { "message": "Save options" },
"optionsSaved": { "message": "Saved" }, "optionsSaved": { "message": "Saved" },
"optionUpgradeMessage": { "message": "Tell me about upgrades" }, "optionUpgradeMessage": { "message": "Tell me about upgrades" },
"optionDynamicIcon": { "message": "Use application icon instead of Wappalyzer logo" }, "optionDynamicIcon": { "message": "Use technology icon instead of Wappalyzer logo" },
"optionTracking": { "message": "Anonymously send reports on detected applications to wappalyzer.com for research" }, "optionTracking": { "message": "Anonymously send identified technologies to wappalyzer.com" },
"nothingToDo": { "message": "Nothing to do here." }, "nothingToDo": { "message": "Nothing to do here." },
"noAppsDetected": { "message": "No applications detected." }, "noAppsDetected": { "message": "No technologies detected." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Message Board" }, "categoryName2": { "message": "Message Board" },
"categoryName3": { "message": "Database Manager" }, "categoryName3": { "message": "Database Manager" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Enviar informes anónimos sobre las aplicaciones detectadas a wappalyzer.com para análisis" }, "optionTracking": { "message": "Enviar informes anónimos sobre las aplicaciones detectadas a wappalyzer.com para análisis" },
"nothingToDo": { "message": "Nada que hacer aquí." }, "nothingToDo": { "message": "Nada que hacer aquí." },
"noAppsDetected": { "message": "Aplicaciones no detectadas." }, "noAppsDetected": { "message": "Aplicaciones no detectadas." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "Gestor de Contenido" }, "categoryName1": { "message": "Gestor de Contenido" },
"categoryName2": { "message": "Foro" }, "categoryName2": { "message": "Foro" },
"categoryName3": { "message": "Gestor de Bases de Datos" }, "categoryName3": { "message": "Gestor de Bases de Datos" },

@ -10,6 +10,7 @@
"optionsSaved": { "message": "Sauvegardé" }, "optionsSaved": { "message": "Sauvegardé" },
"twitter": { "message": "Suivre Wappalyzer sur Twitter" }, "twitter": { "message": "Suivre Wappalyzer sur Twitter" },
"website": { "message": "Aller sur wappalyzer.com" }, "website": { "message": "Aller sur wappalyzer.com" },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" }, "categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestionnaire de base de données" }, "categoryName3": { "message": "Gestionnaire de base de données" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" }, "optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"nothingToDo": { "message": "Καμία ενέργεια." }, "nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." }, "noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Διαδικτυακό Φόρουμ" }, "categoryName2": { "message": "Διαδικτυακό Φόρουμ" },
"categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" }, "categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Secara anonim kirimkan laporan tentang aplikasi yang terdeteksi ke wappalyzer.com untuk penelitian" }, "optionTracking": { "message": "Secara anonim kirimkan laporan tentang aplikasi yang terdeteksi ke wappalyzer.com untuk penelitian" },
"nothingToDo": { "message": "Tak ada yang dilakukan disini." }, "nothingToDo": { "message": "Tak ada yang dilakukan disini." },
"noAppsDetected": { "message": "Tidak ada aplikasi yang terdeteksi." }, "noAppsDetected": { "message": "Tidak ada aplikasi yang terdeteksi." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "Sistem Pengelola Konten" }, "categoryName1": { "message": "Sistem Pengelola Konten" },
"categoryName2": { "message": "Papan Pesan" }, "categoryName2": { "message": "Papan Pesan" },
"categoryName3": { "message": "Pengelola Basis Data" }, "categoryName3": { "message": "Pengelola Basis Data" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Inviare anonimamente un report sulle applicazioni rilevate a wappalyzer.com per l'analisi" }, "optionTracking": { "message": "Inviare anonimamente un report sulle applicazioni rilevate a wappalyzer.com per l'analisi" },
"nothingToDo": { "message": "Niente da fare qui." }, "nothingToDo": { "message": "Niente da fare qui." },
"noAppsDetected": { "message": "Nessuna applicazione rilevata." }, "noAppsDetected": { "message": "Nessuna applicazione rilevata." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" }, "categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestore di Database" }, "categoryName3": { "message": "Gestore di Database" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Przesyłaj anonimowe statystyki aplikacji wykrytych przez Wappalyzer do twórców" }, "optionTracking": { "message": "Przesyłaj anonimowe statystyki aplikacji wykrytych przez Wappalyzer do twórców" },
"nothingToDo": { "message": "Nic tu nie ma." }, "nothingToDo": { "message": "Nic tu nie ma." },
"noAppsDetected": { "message": "Nie wykryto żadnych aplikacji." }, "noAppsDetected": { "message": "Nie wykryto żadnych aplikacji." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "System zarządzania treścią" }, "categoryName1": { "message": "System zarządzania treścią" },
"categoryName2": { "message": "Forum" }, "categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Menedżer baz danych" }, "categoryName3": { "message": "Menedżer baz danych" },

@ -0,0 +1,68 @@
{
"github": { "message": "Fork Wappalyzer no GitHub!" },
"noAppsDetected": { "message": "Não foi detetada nenhuma apliação." },
"nothingToDo": { "message": "Nada a fazer aqui." },
"optionTracking": { "message": "Enviar anonimamente relatorios sobre as apliações detetadas ao wappalyzer.com para investigação" },
"optionUpgradeMessage": { "message": "Atualizações automaticas" },
"optionDynamicIcon": { "message": "Utilizar o icone da aplicação em vez do logotido do Wappalyzer" },
"options": { "message": "Definições" },
"optionsSave": { "message": "Guardar as opções" },
"optionsSaved": { "message": "Guardado" },
"twitter": { "message": "Seguir o Wappalyzer no Twitter" },
"website": { "message": "Ir para wappalyzer.com" },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "Sistema de gerenciamento de conteudo(CMS)" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestor de base de dados" },
"categoryName4": { "message": "Ferramenta de documentação" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Loja online" },
"categoryName7": { "message": "Galeria de fotografias" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Gestor de servidores" },
"categoryName10": { "message": "Ferramenta de estatisticas" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Ferramenta de seguimento de problemas" },
"categoryName14": { "message": "Leitor de videos" },
"categoryName15": { "message": "Sistemas de comentários" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de policia" },
"categoryName18": { "message": "Framework WEB" },
"categoryName19": { "message": "Diversos" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "Sistema de gestão de Aprendizagem(LMS)" },
"categoryName22": { "message": "Servidor WEB" },
"categoryName23": { "message": "Ferramenta de cache" },
"categoryName24": { "message": "Editor WYSIWYG" },
"categoryName25": { "message": "Grafismo JavaScript" },
"categoryName26": { "message": "Framework para dispositivos mobile" },
"categoryName27": { "message": "Linguagem de programação" },
"categoryName28": { "message": "Sistema Operativo" },
"categoryName29": { "message": "Motor de pesquisa" },
"categoryName30": { "message": "WebMail" },
"categoryName31": { "message": "Rede de distribuição de conteudo(CDN)" },
"categoryName32": { "message": "Sistema de vendas" },
"categoryName33": { "message": "Extensão do servidor WEB" },
"categoryName34": { "message": "Base de dados" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Rede de publicidade" },
"categoryName37": { "message": "Dispositivo de rede" },
"categoryName38": { "message": "Servidor multimédia" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Impressora" },
"categoryName41": { "message": "Serviço de pagamento" },
"categoryName42": { "message": "Gestor de Tags" },
"categoryName43": { "message": "Sistema de assinaturas paga(Paywall)" },
"categoryName44": { "message": "Sistema CI" },
"categoryName45": { "message": "Sistema SCADA" },
"categoryName46": { "message": "Acesso à distancia" },
"categoryName47": { "message": "Ferramenta de desenvolvimento" },
"categoryName48": { "message": "Rede de armazenamento" },
"categoryName49": { "message": "Leitor RSS" },
"categoryName50": { "message": "Sistema de gestão de documentos" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Chat em direto" },
"categoryName53": { "message": "Sistemas de relação com o cliente(CRM)" },
"categoryName54": { "message": "Otimização para motores de pesquisa(SEO)" }
}

@ -10,6 +10,7 @@
"optionTracking": { "message": "Trimite rapoarte anonime despre aplicațiile detectate către wappalyzer.com pentru cercetare" }, "optionTracking": { "message": "Trimite rapoarte anonime despre aplicațiile detectate către wappalyzer.com pentru cercetare" },
"nothingToDo": { "message": "Nimic de făcut pe pagina curentă." }, "nothingToDo": { "message": "Nimic de făcut pe pagina curentă." },
"noAppsDetected": { "message": "Nici o aplicație detectată." }, "noAppsDetected": { "message": "Nici o aplicație detectată." },
"categoryPin": { "message": "Afișează icon tot timpul" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum de discuții" }, "categoryName2": { "message": "Forum de discuții" },
"categoryName3": { "message": "Manager baze de date" }, "categoryName3": { "message": "Manager baze de date" },

@ -63,5 +63,6 @@
"optionsSaved" : { "message" : "Успешно сохранено!" }, "optionsSaved" : { "message" : "Успешно сохранено!" },
"twitter" : { "message" : "Следите за новостями в Твиттере" }, "twitter" : { "message" : "Следите за новостями в Твиттере" },
"website" : { "message" : "Перейти на Wappalyzer.com" }, "website" : { "message" : "Перейти на Wappalyzer.com" },
"categoryPin": { "message": "Always show icon" },
"categoryName54": { "message": "SEO" } "categoryName54": { "message": "SEO" }
} }

@ -10,6 +10,7 @@
"optionTracking": { "message": "Anonymne posielať správy o zistených aplikáciách na wappalyzer.com pre výskum" }, "optionTracking": { "message": "Anonymne posielať správy o zistených aplikáciách na wappalyzer.com pre výskum" },
"nothingToDo": { "message": "Nie je tu čo robiť." }, "nothingToDo": { "message": "Nie je tu čo robiť." },
"noAppsDetected": { "message": "Žiadne aplikácie neboli zistené." }, "noAppsDetected": { "message": "Žiadne aplikácie neboli zistené." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Message Board" }, "categoryName2": { "message": "Message Board" },
"categoryName3": { "message": "Správca databáz" }, "categoryName3": { "message": "Správca databáz" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Anonim olarak tespit edilen uygulamalar hakkında wappalyzer.com'a araştırma raporları gönderin" }, "optionTracking": { "message": "Anonim olarak tespit edilen uygulamalar hakkında wappalyzer.com'a araştırma raporları gönderin" },
"nothingToDo": { "message": "Burada yapacak birşey yok." }, "nothingToDo": { "message": "Burada yapacak birşey yok." },
"noAppsDetected": { "message": "Uygulamalar tespit edilemedi." }, "noAppsDetected": { "message": "Uygulamalar tespit edilemedi." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Mesaj Tahtası" }, "categoryName2": { "message": "Mesaj Tahtası" },
"categoryName3": { "message": "Veritabanı Yöneticisi" }, "categoryName3": { "message": "Veritabanı Yöneticisi" },
@ -29,11 +30,11 @@
"categoryName17": { "message": "Font Script" }, "categoryName17": { "message": "Font Script" },
"categoryName18": { "message": "Web Framework" }, "categoryName18": { "message": "Web Framework" },
"categoryName19": { "message": "Çeşitli" }, "categoryName19": { "message": "Çeşitli" },
"categoryName20": { "message": "Editor" }, "categoryName20": { "message": "Düzenleyici" },
"categoryName21": { "message": "LMS" }, "categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Web Server" }, "categoryName22": { "message": "Web Sunucusu" },
"categoryName23": { "message": "Öncellek Aracı" }, "categoryName23": { "message": "Ön Bellek Aracı" },
"categoryName24": { "message": "Zengin Metin Editörü" }, "categoryName24": { "message": "Zengin Metin Düzenleyici" },
"categoryName25": { "message": "JavaScript Grafikleri" }, "categoryName25": { "message": "JavaScript Grafikleri" },
"categoryName26": { "message": "Mobil Framework" }, "categoryName26": { "message": "Mobil Framework" },
"categoryName27": { "message": "Programlama Dilleri" }, "categoryName27": { "message": "Programlama Dilleri" },
@ -63,5 +64,6 @@
"categoryName51": { "message": "Açılış Sayfası Oluşturucu" }, "categoryName51": { "message": "Açılış Sayfası Oluşturucu" },
"categoryName52": { "message": "Canlı Sohbet" }, "categoryName52": { "message": "Canlı Sohbet" },
"categoryName53": { "message": "CRM" }, "categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" } "categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Muhasebe" }
} }

@ -10,6 +10,7 @@
"optionTracking": { "message": "Анонімно надсилати статистику розпізнавань на сервер для досліджень" }, "optionTracking": { "message": "Анонімно надсилати статистику розпізнавань на сервер для досліджень" },
"nothingToDo": { "message": "Тут нічого робити." }, "nothingToDo": { "message": "Тут нічого робити." },
"noAppsDetected": { "message": "Нічого не знайдено." }, "noAppsDetected": { "message": "Нічого не знайдено." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS" }, "categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Форум" }, "categoryName2": { "message": "Форум" },
"categoryName3": { "message": "Менеджер БД" }, "categoryName3": { "message": "Менеджер БД" },

@ -10,6 +10,7 @@
"optionTracking": { "message": "Wappalyzer takomillashtirish uchun hisobotlarni maxfiy ravishda serverga jo'natish" }, "optionTracking": { "message": "Wappalyzer takomillashtirish uchun hisobotlarni maxfiy ravishda serverga jo'natish" },
"nothingToDo": { "message": "Bu yerda tekshirib bolmaydi." }, "nothingToDo": { "message": "Bu yerda tekshirib bolmaydi." },
"noAppsDetected": { "message": "Hech qanday dastur aniqlanmadi." }, "noAppsDetected": { "message": "Hech qanday dastur aniqlanmadi." },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "CMS (KBT)" }, "categoryName1": { "message": "CMS (KBT)" },
"categoryName2": { "message": "Forum" }, "categoryName2": { "message": "Forum" },
"categoryName3": { "message": "MB boshqaruvi" }, "categoryName3": { "message": "MB boshqaruvi" },

@ -1,15 +1,16 @@
{ {
"github": { "message": "在GitHub上fork Wappalyzer!" }, "github": { "message": "查看 GitHub 上的 Wappalyzer" },
"twitter": { "message": "在Twitter上关注Wappalyzer" }, "twitter": { "message": "关注 Twitter 上的 Wappalyzer" },
"website": { "message": "访问wappalyzer.com" }, "website": { "message": "访问 wappalyzer.com" },
"options": { "message": "选项" }, "options": { "message": "选项" },
"optionsSave": { "message": "保存选项" }, "optionsSave": { "message": "保存选项" },
"optionsSaved": { "message": "已保存" }, "optionsSaved": { "message": "已保存" },
"optionUpgradeMessage": { "message": "通知我更新内容" }, "optionUpgradeMessage": { "message": "通知我更新详情" },
"optionDynamicIcon": { "message": "使用应用程序logo而不是Wappalyzer的" }, "optionDynamicIcon": { "message": "使用应用程序而非 Wappalyzer 的标志" },
"optionTracking": { "message": "发送有关检测到应用的匿名报告到wappalyzer.com以便研究" }, "optionTracking": { "message": "发送匿名的应用报告到 wappalyzer.com 供研究使用" },
"nothingToDo": { "message": "这儿啥也没有。" }, "nothingToDo": { "message": "这儿啥也没有。" },
"noAppsDetected": { "message": "未检测到任何应用。" }, "noAppsDetected": { "message": "未检测到任何应用。" },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "内容管理系统CMS" }, "categoryName1": { "message": "内容管理系统CMS" },
"categoryName2": { "message": "消息板" }, "categoryName2": { "message": "消息板" },
"categoryName3": { "message": "数据库管理器" }, "categoryName3": { "message": "数据库管理器" },
@ -21,28 +22,28 @@
"categoryName9": { "message": "主机面板" }, "categoryName9": { "message": "主机面板" },
"categoryName10": { "message": "分析" }, "categoryName10": { "message": "分析" },
"categoryName11": { "message": "博客" }, "categoryName11": { "message": "博客" },
"categoryName12": { "message": "JavaScript框架" }, "categoryName12": { "message": "JavaScript 框架" },
"categoryName13": { "message": "Issue跟踪器" }, "categoryName13": { "message": "问题跟踪器" },
"categoryName14": { "message": "视频播放器" }, "categoryName14": { "message": "视频播放器" },
"categoryName15": { "message": "评论系统" }, "categoryName15": { "message": "评论系统" },
"categoryName16": { "message": "验证码" }, "categoryName16": { "message": "验证码" },
"categoryName17": { "message": "字体脚本" }, "categoryName17": { "message": "字体脚本" },
"categoryName18": { "message": "Web框架" }, "categoryName18": { "message": "Web 框架" },
"categoryName19": { "message": "杂项" }, "categoryName19": { "message": "杂项" },
"categoryName20": { "message": "编辑器" }, "categoryName20": { "message": "编辑器" },
"categoryName21": { "message": "学习管理系统LMS" }, "categoryName21": { "message": "学习管理系统LMS" },
"categoryName22": { "message": "Web服务器" }, "categoryName22": { "message": "Web 服务器" },
"categoryName23": { "message": "缓存工具" }, "categoryName23": { "message": "缓存工具" },
"categoryName24": { "message": "富文本编辑器" }, "categoryName24": { "message": "富文本编辑器" },
"categoryName25": { "message": "JavaScript图形库" }, "categoryName25": { "message": "JavaScript 图形库" },
"categoryName26": { "message": "移动框架" }, "categoryName26": { "message": "移动框架" },
"categoryName27": { "message": "编程语言" }, "categoryName27": { "message": "编程语言" },
"categoryName28": { "message": "操作系统" }, "categoryName28": { "message": "操作系统" },
"categoryName29": { "message": "搜索引擎" }, "categoryName29": { "message": "搜索引擎" },
"categoryName30": { "message": "网络邮件" }, "categoryName30": { "message": "网页邮箱" },
"categoryName31": { "message": "内容分发网络" }, "categoryName31": { "message": "内容分发网络CDN" },
"categoryName32": { "message": "市场自动化" }, "categoryName32": { "message": "营销自动化" },
"categoryName33": { "message": "Web服务器扩展" }, "categoryName33": { "message": "Web 服务器扩展" },
"categoryName34": { "message": "数据库" }, "categoryName34": { "message": "数据库" },
"categoryName35": { "message": "地图" }, "categoryName35": { "message": "地图" },
"categoryName36": { "message": "广告网络" }, "categoryName36": { "message": "广告网络" },
@ -58,10 +59,11 @@
"categoryName46": { "message": "远程访问" }, "categoryName46": { "message": "远程访问" },
"categoryName47": { "message": "开发工具" }, "categoryName47": { "message": "开发工具" },
"categoryName48": { "message": "网络存储" }, "categoryName48": { "message": "网络存储" },
"categoryName49": { "message": "信息流阅读器" }, "categoryName49": { "message": "信息流Feed阅读器" },
"categoryName50": { "message": "文档管理系统" }, "categoryName50": { "message": "文档管理系统" },
"categoryName51": { "message": "着陆页构建器" }, "categoryName51": { "message": "着陆页构建器" },
"categoryName52": { "message": "在线聊天" }, "categoryName52": { "message": "在线聊天" },
"categoryName53": { "message": "客户关系管理CRM" }, "categoryName53": { "message": "客户关系管理CRM" },
"categoryName54": { "message": "SEO" } "categoryName54": { "message": "搜索引擎优化SEO" },
"categoryName55": { "message": "财务" }
} }

@ -10,6 +10,7 @@
"optionTracking": { "message": "匿名傳送應用程式偵測報告至 wappalyzer.com 作為研究用途" }, "optionTracking": { "message": "匿名傳送應用程式偵測報告至 wappalyzer.com 作為研究用途" },
"nothingToDo": { "message": "這裡什麼也沒有。" }, "nothingToDo": { "message": "這裡什麼也沒有。" },
"noAppsDetected": { "message": "未偵測到應用程式。" }, "noAppsDetected": { "message": "未偵測到應用程式。" },
"categoryPin": { "message": "Always show icon" },
"categoryName1": { "message": "內容管理系統CMS" }, "categoryName1": { "message": "內容管理系統CMS" },
"categoryName2": { "message": "留言板/討論區" }, "categoryName2": { "message": "留言板/討論區" },
"categoryName3": { "message": "資料庫管理" }, "categoryName3": { "message": "資料庫管理" },

@ -46,25 +46,52 @@ body {
padding-bottom: 1rem; padding-bottom: 1rem;
} }
.detected__category-link { .detected__category-name {
border-bottom: 1px solid #dbdbdb; border-bottom: 1px solid #dbdbdb;
display: block; display: block;
margin-bottom: .5rem; margin-bottom: .5rem;
text-decoration: none;
} }
.detected__category-name { .detected__category-link {
color: #4608ad; color: #4608ad;
display: block;
font-weight: bold; font-weight: bold;
line-height: 2rem; line-height: 2rem;
text-decoration: none;
} }
.detected__category-link:hover .detected__category-name { .detected__category-link:hover {
color: #4a4a4a; color: #4a4a4a;
} }
.detected__category-pin-wrapper {
margin-left: .2rem;
}
.detected__category-pin {
cursor: pointer;
display: none;
height: 16px;
margin-left: .2rem;
width: 16px;
vertical-align: middle;
}
.detected__category:hover .detected__category-pin--inactive {
display: inline-block;
}
.detected__category-pin-wrapper--active .detected__category-pin--inactive,
.detected__category-pin-wrapper:hover .detected__category-pin--inactive {
display: none !important;
}
.detected__category-pin-wrapper--active .detected__category-pin--active,
.detected__category-pin-wrapper:hover .detected__category-pin--active {
display: inline-block;
}
.detected__app { .detected__app {
color: #4a4a4a;
display: block; display: block;
line-height: 1.7rem; line-height: 1.7rem;
text-decoration: none; text-decoration: none;
@ -84,13 +111,28 @@ body {
} }
.detected__app-name { .detected__app-name {
color: #4a4a4a; }
.detected__app-version, .detected__app-confidence {
background: #eee;
border-radius: 3px;
font-size: .7rem;
margin-left: .3rem;
padding: .1rem .2rem;
} }
.detected__app:hover .detected__app-name { .detected__app:hover .detected__app-name {
border-bottom: 1px solid #4a4a4a; border-bottom: 1px solid #4a4a4a;
} }
.detected__app:hover .detected__app-version {
border-bottom: 1px solid white;
}
.detected__app:hover .detected__app-confidence {
border-bottom: 1px solid white;
}
.detected-app { .detected-app {
padding: 7px 0; padding: 7px 0;
} }

@ -1,44 +1,65 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<meta charset="utf-8"> <head>
<meta charset="utf-8">
<title data-i18n="options">Wappalyzer options</title>
<title data-i18n="options">Wappalyzer options</title>
<link rel="icon" href="../images/icon_32.png">
<link rel="icon" href="../images/icon_32.png">
<link rel="stylesheet" href="../css/options.css">
<link rel="stylesheet" href="../css/options.css">
<script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="../js/wappalyzer.js"></script> <script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="../js/options.js"></script> <script src="../js/wappalyzer.js"></script>
</head> <script src="../js/options.js"></script>
<body> </head>
<div class="hero">
<div class="container"> <body>
<img src="../images/logo-white.svg"> <div class="hero">
</div> <div class="container">
</div> <img src="../images/logo-white.svg">
</div>
<div class="content"> </div>
<div class="container">
<h1 data-i18n="options">Options</h1> <div class="content">
<div class="container">
<p> <h1 data-i18n="options">Options</h1>
<label for="option-upgrade-message"><input id="option-upgrade-message" type="checkbox"> <span data-i18n="optionUpgradeMessage">Tell me about upgrades</span></label>
<label for="option-dynamic-icon"><input id="option-dynamic-icon" type="checkbox"> <span data-i18n="optionDynamicIcon">Use application icon instead of Wappalyzer logo</span></label> <p>
<label for="option-tracking"><input id="option-tracking" type="checkbox"> <span data-i18n="optionTracking">Anonymously send reports on detected applications to wappalyzer.com for research</span></label> <label for="option-upgrade-message">
</p> <input id="option-upgrade-message" type="checkbox">
<span data-i18n="optionUpgradeMessage">Tell me about upgrades</span>
<div id="about"> </label>
<p> <label for="option-dynamic-icon">
<button id="github"><img src="../images/github.png" width="16" height="16" alt=""/> <span data-i18n="github" >Fork Wappalyzer on GitHub!</span></button><!-- <input id="option-dynamic-icon" type="checkbox">
--><button id="twitter"><img src="../images/twitter.png" width="16" height="16" alt=""/> <span data-i18n="twitter">Follow Wappalyzer on Twitter</span></button><!-- <span data-i18n="optionDynamicIcon">Use application icon instead of Wappalyzer logo</span>
--><button id="wappalyzer"><img src="../images/icon_16.png" width="16" height="16" alt=""/> <span data-i18n="website">Go to wappalyzer.com</span></button> </label>
</p> <label for="option-tracking">
</div> <input id="option-tracking" type="checkbox">
</div> <span data-i18n="optionTracking">Anonymously send reports on detected applications to wappalyzer.com for research</span>
</div> </label>
</body> </p>
<div id="about">
<p>
<button id="github">
<img src="../images/github.png" width="16" height="16" alt="GitHub icon" />
<span data-i18n="github">Fork Wappalyzer on GitHub!</span>
</button>
<button id="twitter">
<img src="../images/twitter.png" width="16" height="16" alt="Twitter icon" />
<span data-i18n="twitter">Follow Wappalyzer on Twitter</span>
</button>
<button id="wappalyzer">
<img src="../images/icon_16.png" width="16" height="16" alt="Wappalyzer icon" />
<span data-i18n="website">Go to wappalyzer.com</span>
</button>
</p>
</div>
</div>
</div>
</body>
</html> </html>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 193.826 193.826" style="enable-background:new 0 0 193.826 193.826;" xml:space="preserve">
<path fill="#4608ad" d="M191.495,55.511L137.449,1.465c-1.951-1.953-5.119-1.953-7.07,0l-0.229,0.229c-3.314,3.313-5.14,7.72-5.14,12.406
c0,3.019,0.767,5.916,2.192,8.485l-56.55,48.533c-4.328-3.868-9.852-5.985-15.703-5.985c-6.305,0-12.232,2.455-16.689,6.913
l-0.339,0.339c-1.953,1.952-1.953,5.118,0,7.07l32.378,32.378l-31.534,31.533c-0.631,0.649-15.557,16.03-25.37,28.27
c-9.345,11.653-11.193,13.788-11.289,13.898c-1.735,1.976-1.639,4.956,0.218,6.822c0.973,0.977,2.256,1.471,3.543,1.471
c1.173,0,2.349-0.41,3.295-1.237c0.083-0.072,2.169-1.885,13.898-11.289c12.238-9.813,27.619-24.74,28.318-25.421l31.483-31.483
l30.644,30.644c0.976,0.977,2.256,1.465,3.535,1.465s2.56-0.488,3.535-1.465l0.339-0.339c4.458-4.457,6.913-10.385,6.913-16.689
c0-5.851-2.118-11.375-5.985-15.703l48.533-56.55c2.569,1.425,5.466,2.192,8.485,2.192c4.687,0,9.093-1.825,12.406-5.14l0.229-0.229
C193.448,60.629,193.448,57.463,191.495,55.511z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 193.826 193.826" style="enable-background:new 0 0 193.826 193.826;" xml:space="preserve">
<path fill="#dbdbdb" d="M191.495,55.511L137.449,1.465c-1.951-1.953-5.119-1.953-7.07,0l-0.229,0.229c-3.314,3.313-5.14,7.72-5.14,12.406
c0,3.019,0.767,5.916,2.192,8.485l-56.55,48.533c-4.328-3.868-9.852-5.985-15.703-5.985c-6.305,0-12.232,2.455-16.689,6.913
l-0.339,0.339c-1.953,1.952-1.953,5.118,0,7.07l32.378,32.378l-31.534,31.533c-0.631,0.649-15.557,16.03-25.37,28.27
c-9.345,11.653-11.193,13.788-11.289,13.898c-1.735,1.976-1.639,4.956,0.218,6.822c0.973,0.977,2.256,1.471,3.543,1.471
c1.173,0,2.349-0.41,3.295-1.237c0.083-0.072,2.169-1.885,13.898-11.289c12.238-9.813,27.619-24.74,28.318-25.421l31.483-31.483
l30.644,30.644c0.976,0.977,2.256,1.465,3.535,1.465s2.56-0.488,3.535-1.465l0.339-0.339c4.458-4.457,6.913-10.385,6.913-16.689
c0-5.851-2.118-11.375-5.985-15.703l48.533-56.55c2.569,1.425,5.466,2.192,8.485,2.192c4.687,0,9.093-1.825,12.406-5.14l0.229-0.229
C193.448,60.629,193.448,57.463,191.495,55.511z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -1,58 +1,61 @@
/** global: browser */ /** global: browser */
/** global: XMLSerializer */
if ( typeof browser !== 'undefined' && typeof document.body !== 'undefined' ) { if ( typeof browser !== 'undefined' && typeof document.body !== 'undefined' ) {
var html = document.documentElement.outerHTML; try {
var html = new XMLSerializer().serializeToString(document);
if ( html.length > 50000 ) { if ( html.length > 500000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); html = html.substring(0, 250000) + html.substring(html.length - 250000, html.length);
} }
var scripts = Array.prototype.slice const scripts = Array.prototype.slice
.apply(document.scripts) .apply(document.scripts)
.filter(s => s.src) .filter(script => script.src)
.map(s => s.src); .map(script => script.src);
try {
browser.runtime.sendMessage({
id: 'analyze',
subject: { html },
source: 'content.js'
});
browser.runtime.sendMessage({ browser.runtime.sendMessage({
id: 'analyze', id: 'analyze',
subject: { scripts }, subject: { html, scripts },
source: 'content.js' source: 'content.js'
}); });
var container = document.createElement('wappalyzerData'); const script = document.createElement('script');
container.setAttribute('id', 'wappalyzerData'); script.onload = () => {
container.setAttribute('style', 'display: none'); addEventListener('message', event => {
if ( event.data.id !== 'js' ) {
return;
}
var script = document.createElement('script'); browser.runtime.sendMessage({
id: 'analyze',
subject: {
js: event.data.js
},
source: 'content.js'
});
}, true);
script.setAttribute('id', 'wappalyzerEnvDetection'); ( chrome || browser ).runtime.sendMessage({
script.setAttribute('src', browser.extension.getURL('js/inject.js')); id: 'init_js',
subject: {},
container.addEventListener('wappalyzerEvent', (event => {
var env = event.target.childNodes[0].nodeValue;
document.documentElement.removeChild(container);
document.documentElement.removeChild(script);
env = env.split(' ').slice(0, 500);
browser.runtime.sendMessage({
id: 'analyze',
subject: { env },
source: 'content.js' source: 'content.js'
}, response => {
if ( response ) {
postMessage({
id: 'patterns',
patterns: response.patterns
}, '*');
}
}); });
}), true); };
script.setAttribute('id', 'wappalyzer');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
document.documentElement.appendChild(container); document.body.appendChild(script);
document.documentElement.appendChild(script); } catch (e) {
} catch(e) {
log(e); log(e);
} }
} }

@ -10,6 +10,7 @@ const wappalyzer = new Wappalyzer();
var tabCache = {}; var tabCache = {};
var headersCache = {}; var headersCache = {};
var categoryOrder = []; var categoryOrder = [];
var options = {};
browser.tabs.onRemoved.addListener(tabId => { browser.tabs.onRemoved.addListener(tabId => {
tabCache[tabId] = null; tabCache[tabId] = null;
@ -21,18 +22,14 @@ browser.tabs.onRemoved.addListener(tabId => {
function getOption(name, defaultValue) { function getOption(name, defaultValue) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const callback = item => { const callback = item => {
resolve(item.hasOwnProperty(name) ? item[name] : defaultValue); options[name] = item.hasOwnProperty(name) ? item[name] : defaultValue;
resolve(options[name]);
}; };
try { browser.storage.local.get(name)
// Chrome, Firefox .then(callback)
browser.storage.local.get(name) .catch(error => wappalyzer.log(error, 'driver', 'error'));
.then(callback)
.catch(error => wappalyzer.log(error, 'driver', 'error'));
} catch ( e ) {
// Edge
browser.storage.local.get(name, callback);
}
}); });
} }
@ -45,6 +42,8 @@ function setOption(name, value) {
option[name] = value; option[name] = value;
browser.storage.local.set(option); browser.storage.local.set(option);
options[name] = value;
} }
/** /**
@ -81,7 +80,11 @@ fetch('../apps.json')
wappalyzer.apps = json.apps; wappalyzer.apps = json.apps;
wappalyzer.categories = json.categories; wappalyzer.categories = json.categories;
categoryOrder = Object.keys(wappalyzer.categories).sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority); wappalyzer.parseJsPatterns();
categoryOrder = Object.keys(wappalyzer.categories)
.map(categoryId => parseInt(categoryId, 10))
.sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority);
}) })
.catch(error => { .catch(error => {
wappalyzer.log('GET apps.json: ' + error, 'driver', 'error'); wappalyzer.log('GET apps.json: ' + error, 'driver', 'error');
@ -111,6 +114,9 @@ getOption('version')
setOption('version', version); setOption('version', version);
}); });
getOption('dynamicIcon', true);
getOption('pinnedCategory');
// Run content script // Run content script
var callback = tabs => { var callback = tabs => {
tabs.forEach(tab => { tabs.forEach(tab => {
@ -122,13 +128,9 @@ var callback = tabs => {
}) })
}; };
try { browser.tabs.query({})
browser.tabs.query({}) .then(callback)
.then(callback) .catch(error => wappalyzer.log(error, 'driver', 'error'));
.catch(error => wappalyzer.log(error, 'driver', 'error'));
} catch ( e ) {
browser.tabs.query({}, callback);
}
// Capture response headers // Capture response headers
browser.webRequest.onCompleted.addListener(request => { browser.webRequest.onCompleted.addListener(request => {
@ -164,7 +166,7 @@ browser.webRequest.onCompleted.addListener(request => {
( chrome || browser ).runtime.onMessage.addListener((message, sender, sendResponse) => { ( chrome || browser ).runtime.onMessage.addListener((message, sender, sendResponse) => {
if ( typeof message.id != 'undefined' ) { if ( typeof message.id != 'undefined' ) {
if ( message.id !== 'log' ) { if ( message.id !== 'log' ) {
wappalyzer.log('Message received from ' + message.source + ': ' + message.id, 'driver'); wappalyzer.log('Message received' + ( message.source ? ' from ' + message.source : '' ) + ': ' + message.id, 'driver');
} }
var response; var response;
@ -181,7 +183,7 @@ browser.webRequest.onCompleted.addListener(request => {
message.subject.headers = headersCache[url.canonical]; message.subject.headers = headersCache[url.canonical];
} }
wappalyzer.analyze(url.hostname, url.canonical, message.subject, { wappalyzer.analyze(url, message.subject, {
tab: sender.tab tab: sender.tab
}); });
@ -192,9 +194,20 @@ browser.webRequest.onCompleted.addListener(request => {
break; break;
case 'get_apps': case 'get_apps':
response = { response = {
tabCache: tabCache[message.tab.id], tabCache: tabCache[message.tab.id],
apps: wappalyzer.apps, apps: wappalyzer.apps,
categories: wappalyzer.categories categories: wappalyzer.categories,
pinnedCategory: options.pinnedCategory,
};
break;
case 'set_option':
setOption(message.key, message.value);
break;
case 'init_js':
response = {
patterns: wappalyzer.jsPatterns
}; };
break; break;
@ -217,7 +230,7 @@ wappalyzer.driver.log = (message, source, type) => {
/** /**
* Display apps * Display apps
*/ */
wappalyzer.driver.displayApps = (detected, context) => { wappalyzer.driver.displayApps = (detected, meta, context) => {
var tab = context.tab; var tab = context.tab;
tabCache[tab.id] = tabCache[tab.id] || { detected: [] }; tabCache[tab.id] = tabCache[tab.id] || { detected: [] };
@ -225,45 +238,46 @@ wappalyzer.driver.displayApps = (detected, context) => {
tabCache[tab.id].detected = detected; tabCache[tab.id].detected = detected;
if ( Object.keys(detected).length ) { if ( Object.keys(detected).length ) {
getOption('dynamicIcon', true) var appName, found = false;
.then(dynamicIcon => {
var appName, found = false; // Find the main application to display
[ options.pinnedCategory ].concat(categoryOrder).forEach(match => {
// Find the main application to display Object.keys(detected).forEach(appName => {
categoryOrder.forEach(match => { var app = detected[appName];
Object.keys(detected).forEach(appName => {
var app = detected[appName]; app.props.cats.forEach(category => {
if ( category === match && !found ) {
app.props.cats.forEach(category => { var icon = app.props.icon || 'default.svg';
if ( category === match && !found ) {
var icon = app.props.icon || 'default.svg'; if ( !options.dynamicIcon ) {
icon = 'default.svg';
if ( !dynamicIcon ) { }
icon = 'default.svg';
} if ( /\.svg$/i.test(icon) ) {
icon = 'converted/' + icon.replace(/\.svg$/, '.png');
if ( /\.svg$/i.test(icon) ) { }
icon = 'converted/' + icon.replace(/\.svg$/, '.png');
} try {
browser.pageAction.setIcon({
browser.pageAction.setIcon({ tabId: tab.id,
tabId: tab.id, path: '../images/icons/' + icon
path: '../images/icons/' + icon });
}); } catch(e) {
// Firefox for Android does not support setIcon see https://bugzilla.mozilla.org/show_bug.cgi?id=1331746
found = true; }
}
}); found = true;
}); }
}); });
if ( typeof chrome !== 'undefined' ) {
// Browser polyfill doesn't seem to work here
chrome.pageAction.show(tab.id);
} else {
browser.pageAction.show(tab.id);
}
}); });
});
if ( typeof chrome !== 'undefined' ) {
// Browser polyfill doesn't seem to work here
chrome.pageAction.show(tab.id);
} else {
browser.pageAction.show(tab.id);
}
} }
}; };
@ -272,38 +286,43 @@ wappalyzer.driver.displayApps = (detected, context) => {
*/ */
wappalyzer.driver.getRobotsTxt = (host, secure = false) => { wappalyzer.driver.getRobotsTxt = (host, secure = false) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getOption('robotsTxtCache') getOption('tracking', true)
.then(robotsTxtCache => { .then(tracking => {
robotsTxtCache = robotsTxtCache || {}; if ( !tracking ) {
return resolve([]);
if ( host in robotsTxtCache ) { }
resolve(robotsTxtCache[host]);
} else {
var url = 'http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt';
fetch('http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt')
.then(response => {
if ( !response.ok ) {
if ( response.status === 404 ) {
return '';
} else {
throw 'GET ' + response.url + ' was not ok';
}
}
return response.text();
})
.then(robotsTxt => {
robotsTxtCache[host] = wappalyzer.parseRobotsTxt(robotsTxt);
setOption('robotsTxtCache', robotsTxtCache);
resolve(robotsTxtCache[host]); getOption('robotsTxtCache')
.then(robotsTxtCache => {
robotsTxtCache = robotsTxtCache || {};
var hostname = host.replace(/:[0-9]+$/, '') if ( host in robotsTxtCache ) {
}) resolve(robotsTxtCache[host]);
.catch(reject); } else {
} const url = 'http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt';
fetch('http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt')
.then(response => {
if ( !response.ok ) {
if ( response.status === 404 ) {
return '';
} else {
throw 'GET ' + response.url + ' was not ok';
}
}
return response.text();
})
.then(robotsTxt => {
robotsTxtCache[host] = wappalyzer.parseRobotsTxt(robotsTxt);
setOption('robotsTxtCache', robotsTxtCache);
resolve(robotsTxtCache[host]);
})
.catch(reject);
}
});
}); });
}); });
}; };
@ -316,7 +335,7 @@ wappalyzer.driver.ping = (hostnameCache, adCache) => {
.then(tracking => { .then(tracking => {
if ( tracking ) { if ( tracking ) {
if ( Object.keys(hostnameCache).length ) { if ( Object.keys(hostnameCache).length ) {
post('http://ping.wappalyzer.com/v3/', hostnameCache); post('https://api.wappalyzer.com/ping/v1/', hostnameCache);
} }
if ( adCache.length ) { if ( adCache.length ) {

@ -181,7 +181,7 @@ var exports = {};
video_assets: opt_video_assets, video_assets: opt_video_assets,
assets: opt_assets, assets: opt_assets,
version: '3', version: '3',
mrev: 'b084b53-c', mrev: '4aeaa5a-c',
msgNum: this.msgNum, msgNum: this.msgNum,
timestamp: new Date().getTime(), timestamp: new Date().getTime(),
pageVis: document.visibilityState, pageVis: document.visibilityState,
@ -890,7 +890,7 @@ var exports = {};
var _pageTags; var _pageTags;
var INIT_MS_BW_SEARCHES = 2000; var INIT_MS_BW_SEARCHES = 2000;
var PAGE_TAG_RE = new RegExp('gpt|oascentral'); var PAGE_TAG_RE = new RegExp('gpt|oascentral');
var POST_MSG_ID = '1510070508-5767-8848-29475-8984'; var POST_MSG_ID = '1511804838-25881-9878-26947-14879';
var AD_SERVER_RE = new RegExp('^(google_ads_iframe|oas_frame|atwAdFrame)'); var AD_SERVER_RE = new RegExp('^(google_ads_iframe|oas_frame|atwAdFrame)');
function getPageTags(doc) { function getPageTags(doc) {

@ -1,16 +1,61 @@
(function() { (function() {
try { try {
var i, environmentVars = '', e = document.createEvent('Events'); addEventListener('message', (event => {
if ( event.data.id !== 'patterns' ) {
return;
}
e.initEvent('wappalyzerEvent', true, false); const patterns = event.data.patterns || {};
for ( i in window ) { const js = {};
environmentVars += i + ' ';
}
document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars)); for ( let appName in patterns ) {
document.getElementById('wappalyzerData').dispatchEvent(e); if ( patterns.hasOwnProperty(appName) ) {
} catch(e) { js[appName] = {};
// Fail quietly
} for ( let chain in patterns[appName] ) {
if ( patterns[appName].hasOwnProperty(chain) ) {
js[appName][chain] = {};
for ( let index in patterns[appName][chain] ) {
const value = detectJs(chain);
if ( value ) {
js[appName][chain][index] = value;
}
}
}
}
}
}
postMessage({ id: 'js', js }, '*');
}), false);
} catch(e) {
// Fail quietly
}
function detectJs(chain) {
try {
const properties = chain.split('.');
var value = properties.length ? window : null;
for ( let i = 0; i < properties.length; i ++ ) {
var property = properties[i];
if ( value.hasOwnProperty(property) ) {
value = value[property];
} else {
value = null;
break;
}
}
return typeof value === 'string' || typeof value === 'number' ? value : !!value;
} catch(e) {
// Fail quietly
}
}
}()); }());

@ -1,846 +0,0 @@
if (!Range.prototype["intersectsNode"]) {
Range.prototype["intersectsNode"] = function (node) {
let range = document.createRange();
range.selectNode(node);
return 0 > this.compareBoundaryPoints(Range.END_TO_START, range)
&& 0 < this.compareBoundaryPoints(Range.START_TO_END, range);
};
}
var getExtensionProtocol = function () {
if (typeof browser == "undefined") {
if (typeof chrome !== "undefined")
return "chrome-extension://";
}
else {
return "ms-browser-extension://";
}
};
class FakeEvent {
addListener(callback) { }
addRules(rules, callback) { }
getRules(ruleIdentifiers, callback) { }
hasListener(callback) { return false; }
hasListeners() { return false; }
removeRules(ruleIdentifiers, callback) { }
removeListener(callback) { }
}
class EdgeBridgeHelper {
constructor() {
this.fakeEvent = new FakeEvent();
}
toAbsolutePath(relativePath) {
if (relativePath.indexOf("ms-browser-extension://") == 0) {
return relativePath.replace(myBrowser.runtime.getURL(""), "");
}
else if (relativePath.indexOf("/") != 0) {
var absolutePath = "";
var documentPath = document.location.pathname;
absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1);
absolutePath += relativePath;
return absolutePath;
}
return relativePath;
}
}
var bridgeHelper = new EdgeBridgeHelper();
class EdgeBridgeDebugLog {
constructor() {
this.CatchOnException = true;
this.VerboseLogging = true;
this.FailedCalls = {};
this.SuccededCalls = {};
this.DeprecatedCalls = {};
this.BridgedCalls = {};
this.UnavailableApis = {};
this.EdgeIssues = {};
}
log(message) {
try {
if (this.VerboseLogging) {
console.log(message);
}
}
catch (e) {
}
}
info(message) {
try {
if (this.VerboseLogging) {
console.info(message);
}
}
catch (e) {
}
}
warn(message) {
try {
if (this.VerboseLogging) {
console.warn(message);
}
}
catch (e) {
}
}
error(message) {
try {
if (this.VerboseLogging) {
console.error(message);
}
}
catch (e) {
}
}
DoActionAndLog(action, name, deprecatedTo, bridgedTo) {
var result;
try {
result = action();
this.AddToCalledDictionary(this.SuccededCalls, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
if (typeof bridgedTo !== "undefined" && typeof bridgedTo !== "null") {
this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo);
this.AddToCalledDictionary(this.BridgedCalls, name);
}
return result;
}
catch (ex) {
this.AddToCalledDictionary(this.FailedCalls, name);
if (this.CatchOnException)
this.error("API Call Failed: " + name + " - " + ex);
else
throw ex;
}
}
LogEdgeIssue(name, message) {
this.warn(message);
this.AddToCalledDictionary(this.EdgeIssues, name);
}
LogUnavailbleApi(name, deprecatedTo) {
this.warn("API Call '" + name + "' is not supported in Edge");
this.AddToCalledDictionary(this.UnavailableApis, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
}
AddToCalledDictionary(dictionary, name) {
if (typeof dictionary[name] !== "undefined") {
dictionary[name]++;
}
else {
dictionary[name] = 1;
}
}
}
var bridgeLog = new EdgeBridgeDebugLog();
class EdgeChromeAppBridge {
getDetails() {
return bridgeLog.DoActionAndLog(() => {
return EdgeChromeRuntimeBridge.prototype.getManifest();
}, "app.getManifest", undefined, "runtime.getManifest");
}
get isInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.isInstalled is not available in Edge"; }, "app.isInstalled"); }
getIsInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.getIsInstalled is not available in the Edge"; }, "app.getIsInstalled"); }
installState() { return bridgeLog.DoActionAndLog(() => { throw "app.installState is not available in Edge"; }, "app.installState"); }
runningState() { return bridgeLog.DoActionAndLog(() => { throw "app.runningState is not available in Edge"; }, "app.runningState"); }
}
class EdgeBrowserActionBridge {
get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.browserAction.onClicked; }, "browserAction.onClicked"); }
disable(tabId) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.disable(tabId);
}, "browserAction.disable");
}
enable(tabId) {
bridgeLog.DoActionAndLog(() => {
if (typeof tabId !== "undefined" && typeof tabId !== "null") {
myBrowser.browserAction.enable(tabId);
}
else {
myBrowser.browserAction.enable();
}
}, "browserAction.Enable");
}
getBadgeBackgroundColor(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.getBadgeBackgroundColor(details, callback);
}, "browserAction.getBadgeBackgroundColor");
}
getBadgeText(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.getBadgeText(details, callback);
}, "browserAction.getBadgeText");
}
setBadgeBackgroundColor(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.setBadgeBackgroundColor(details);
}, "browserAction.setBadgeBackgroundColor");
}
setBadgeText(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.setBadgeText(details);
}, "browserAction.setBadgeText");
}
setIcon(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof details.path !== "undefined") {
if (typeof details.path === "object") {
for (var key in details.path) {
if (details.path.hasOwnProperty(key)) {
details.path[key] = bridgeHelper.toAbsolutePath(details.path[key]);
}
}
}
else {
details.path = bridgeHelper.toAbsolutePath(details.path);
}
}
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.browserAction.setIcon(details, callback);
}
else {
myBrowser.browserAction.setIcon(details);
}
}, "browserAction.setIcon", undefined, "browserAction.setIcon with absolute path");
}
setPopup(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.setPopup(details);
}, "browserAction.setPopup");
}
}
class EdgeChromeBrowserActionBridge extends EdgeBrowserActionBridge {
getPopup(details, callback) {
bridgeLog.LogUnavailbleApi("browserAction.getPopup");
}
getTitle(details, callback) {
bridgeLog.LogUnavailbleApi("browserAction.getTitle");
}
setTitle(details) {
bridgeLog.LogUnavailbleApi("browserAction.setTitle");
}
}
class EdgeContextMenusBridge {
get ACTION_MENU_TOP_LEVEL_LIMIT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT; }, "contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT"); }
get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.onClicked; }, "contextMenus.onClicked"); }
create(createProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.create(createProperties, callback);
}
else {
myBrowser.contextMenus.create(createProperties);
}
}, "contextMenus.create");
}
remove(menuItemId, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.remove(menuItemId, callback);
}
else {
myBrowser.contextMenus.remove(menuItemId);
}
}, "contextMenus.remove");
}
removeAll(callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.removeAll(callback);
}
else {
myBrowser.contextMenus.removeAll();
}
}, "contextMenus.removeAll");
}
update(id, updateProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.update(id, updateProperties, callback);
}
else {
myBrowser.contextMenus.update(id, updateProperties);
}
}, "contextMenus.update");
}
}
class EdgeCookiesBridge {
get(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.cookies.get(details, callback);
}, "cookies.get");
}
getAll(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.cookies.getAll(details, callback);
}, "cookies.getAll");
}
remove(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.cookies.remove(details, callback);
}
else {
myBrowser.cookies.remove(details);
}
}, "cookies.remove");
}
set(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.cookies.set(details, callback);
}
else {
myBrowser.cookies.set(details);
}
}, "cookies.set");
}
}
class EdgeChromeCookiesBridge extends EdgeCookiesBridge {
get onChanged() { bridgeLog.LogUnavailbleApi("cookies.onChanged"); return bridgeHelper.fakeEvent; }
}
class EdgeExtensionBridge {
getBackgroundPage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getBackgroundPage();
}, "extension.getBackgroundPage");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getURL(path);
}, "extension.getURL");
}
getViews(fetchProperties) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getViews(fetchProperties);
}, "extension.getViews");
}
}
class EdgeChromeExtensionBridge extends EdgeExtensionBridge {
get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); }
get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); }
get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); }
get inIncognitoContext() { return bridgeLog.DoActionAndLog(() => { return myBrowser.extension["inPrivateContext"]; }, "extension.inIncognitoContext", undefined, "extension.inPrivateContext"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.connect(extensionId, connectInfo);
}, "extension.connect", "runtime.connect", "runtime.connect");
}
sendMessage(message, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(message, responseCallback, undefined, undefined);
}, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage");
}
sendRequest(extensionId, message, options, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(extensionId, message, options, responseCallback);
}, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage");
}
isAllowedFileSchemeAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess");
}
isAllowedIncognitoAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedIncognitoAccess");
}
setUpdateUrlData(data) {
bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData");
}
}
class EdgeHistoryBridge {
get onVisited() { bridgeLog.LogUnavailbleApi("history.onVisited"); return bridgeHelper.fakeEvent; }
get onVisitRemoved() { bridgeLog.LogUnavailbleApi("history.onVisitRemoved"); return bridgeHelper.fakeEvent; }
addUrl(details, callback) {
bridgeLog.LogUnavailbleApi("history.addUrl");
}
deleteAll(callback) {
bridgeLog.LogUnavailbleApi("history.deleteAll");
}
deleteRange(range, callback) {
bridgeLog.LogUnavailbleApi("history.deleteRange");
}
deleteUrl(details, callback) {
bridgeLog.LogUnavailbleApi("history.deleteUrl");
}
getVisits(details, callback) {
bridgeLog.LogUnavailbleApi("history.getVisits");
}
search(query, callback) {
bridgeLog.LogUnavailbleApi("history.search");
}
}
class EdgeI18nBridge {
getAcceptLanguages(callback) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getAcceptLanguages(callback);
}, "i18n.getAcceptLanguages");
}
getMessage(messageName, substitutions) {
return bridgeLog.DoActionAndLog(() => {
if (messageName.indexOf("@@extension_id") > -1) {
return myBrowser.runtime.id;
}
if (typeof substitutions !== "undefined" && typeof substitutions !== "null") {
return myBrowser.i18n.getMessage(messageName, substitutions);
}
else {
return myBrowser.i18n.getMessage(messageName);
}
}, "i18n.getMessage");
}
getUILanguage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getUILanguage();
}, "i18n.getUILanguage");
}
}
class EdgeNotificationBridge {
get onButtonClicked() { bridgeLog.LogUnavailbleApi("notifications.onButtonClicked"); return bridgeHelper.fakeEvent; }
get onClicked() { bridgeLog.LogUnavailbleApi("notifications.onClicked"); return bridgeHelper.fakeEvent; }
get onClosed() { bridgeLog.LogUnavailbleApi("notifications.onClosed"); return bridgeHelper.fakeEvent; }
get onPermissionLevelChanged() { bridgeLog.LogUnavailbleApi("notifications.onPermissionLevelChanged"); return bridgeHelper.fakeEvent; }
get onShowSettings() { bridgeLog.LogUnavailbleApi("notifications.onShowSettings"); return bridgeHelper.fakeEvent; }
clear(notificationId, callback) {
bridgeLog.LogUnavailbleApi("notifications.clear");
}
create(notificationId, options, callback) {
bridgeLog.LogUnavailbleApi("notifications.create");
}
getAll(callback) {
bridgeLog.LogUnavailbleApi("notifications.getAll");
}
getPermissionLevel(callback) {
bridgeLog.LogUnavailbleApi("notifications.getPermissionLevel");
}
update(notificationId, options, callback) {
bridgeLog.LogUnavailbleApi("notifications.update");
}
}
class EdgePageActionBridge {
get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.pageAction.onClicked; }, "pageAction.onClicked"); }
getPopup(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.getPopup(details, callback);
}, "pageAction.getPopup");
}
getTitle(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.getTitle(details, callback);
}, "pageAction.getTitle");
}
hide(tabId) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.hide(tabId);
}, "pageAction.hide");
}
setTitle(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.setTitle(details);
}, "pageAction.setTitle");
}
setIcon(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.pageAction.setIcon(details, callback);
}
else {
myBrowser.pageAction.setIcon(details, callback);
}
}, "pageAction.setIcon");
}
setPopup(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.setPopup(details);
}, "pageAction.setPopup");
}
show(tabId) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.show(tabId);
}, "pageAction.show");
}
}
class EdgePermissionsBridge {
get onAdded() { bridgeLog.LogUnavailbleApi("permissions.onAdded"); return bridgeHelper.fakeEvent; }
get onRemoved() { bridgeLog.LogUnavailbleApi("permissions.onRemoved"); return bridgeHelper.fakeEvent; }
contains(permissions, callback) {
bridgeLog.LogUnavailbleApi("permissions.contains");
}
getAll(callback) {
bridgeLog.LogUnavailbleApi("permissions.getAll");
}
remove(permissions, callback) {
bridgeLog.LogUnavailbleApi("permissions.remove");
}
request(permissions, callback) {
bridgeLog.LogUnavailbleApi("permissions.request");
}
}
class EdgeRuntimeBridge {
get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); }
get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); }
get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); }
get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
if (typeof connectInfo !== "undefined" && typeof connectInfo !== "null") {
return myBrowser.runtime.connect(extensionId, connectInfo);
}
else {
return myBrowser.runtime.connect(extensionId);
}
}, "runtime.connect");
}
getBackgroundPage(callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.runtime.getBackgroundPage(callback);
}, "runtime.getBackgroundPage");
}
getManifest() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getManifest();
}, "runtime.getManifest");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getURL(path);
}, "runtime.getURL");
}
sendMessage(extensionId, message, options, responseCallback) {
bridgeLog.DoActionAndLog(() => {
if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options, responseCallback);
}
else if (typeof options !== "undefined" && typeof options !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options);
}
else if (typeof message !== "undefined" && typeof message !== "null") {
myBrowser.runtime.sendMessage(extensionId, message);
}
else {
myBrowser.runtime.sendMessage(undefined, extensionId);
}
}, "runtime.sendMessage");
}
}
class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge {
get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; }
get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; }
get onStartup() { bridgeLog.LogUnavailbleApi("runtime.onStartup"); return bridgeHelper.fakeEvent; }
get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; }
get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; }
get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; }
openOptionsPage(callback) {
bridgeLog.DoActionAndLog(() => {
var optionsPage = myBrowser.runtime.getManifest()["options_page"];
var optionsPageUrl = myBrowser.runtime.getURL(optionsPage);
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create({ url: optionsPageUrl }, callback);
}
else {
myBrowser.tabs.create({ url: optionsPageUrl });
}
}, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })");
}
connectNative(application) {
bridgeLog.LogUnavailbleApi("runtime.connectNative");
return null;
}
getPackageDirectoryEntry(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry");
}
getPlatformInfo(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo");
}
reload() {
bridgeLog.LogUnavailbleApi("runtime.reload");
}
requestUpdateCheck(callback) {
bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck");
}
restart() {
bridgeLog.LogUnavailbleApi("runtime.restart");
}
setUninstallURL(url, callback) {
bridgeLog.LogUnavailbleApi("runtime.setUninstallURL");
}
sendNativeMessage(application, message, responseCallback) {
bridgeLog.LogUnavailbleApi("runtime.sendNativeMessage");
}
}
class EdgeStorageBridge {
get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); }
get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); }
}
class EdgeChromeStorageBridge extends EdgeStorageBridge {
get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); }
get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.sync", undefined, "storage.local"); }
}
class EdgeTabsBridge {
get onActivated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onActivated; }, "tabs.onActivated"); }
get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onCreated; }, "tabs.onCreated"); }
get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onRemoved; }, "tabs.onRemoved"); }
get onReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onReplaced; }, "tabs.onReplaced"); }
get onUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onUpdated; }, "tabs.onUpdated"); }
create(createProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create(createProperties, callback);
}
else {
myBrowser.tabs.create(createProperties);
}
}, "tabs.create");
}
detectLanguage(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.detectLanguage(tabId, callback);
}, "tabs.detectLanguage");
}
executeScript(tabId, details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.executeScript(tabId, details, callback);
}
else {
myBrowser.tabs.executeScript(tabId, details);
}
}, "tabs.executeScript");
}
get(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.get(tabId, callback);
}, "tabs.get");
}
getCurrent(callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.getCurrent(callback);
}, "tabs.getCurrent");
}
insertCSS(tabId, details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.insertCSS(tabId, details, callback);
}
else {
myBrowser.tabs.insertCSS(tabId, details);
}
}, "tabs.insertCSS");
}
query(queryInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.query(queryInfo, callback);
}, "tabs.query");
}
remove(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.remove(tabId, callback);
}
else {
myBrowser.tabs.remove(tabId);
}
}, "tabs.remove");
}
sendMessage(tabId, message, responseCallback) {
bridgeLog.DoActionAndLog(() => {
if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") {
myBrowser.tabs.sendMessage(tabId, message, responseCallback);
}
else {
myBrowser.tabs.sendMessage(tabId, message);
}
}, "tabs.sendMessage");
}
update(tabId, updateProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.update(tabId, updateProperties, callback);
}
else {
myBrowser.tabs.update(tabId, updateProperties);
}
}, "tabs.update");
}
}
class EdgeChromeTabsBridge extends EdgeTabsBridge {
get onAttached() { bridgeLog.LogUnavailbleApi("tabs.onAttached"); return bridgeHelper.fakeEvent; }
get onDetached() { bridgeLog.LogUnavailbleApi("tabs.onDetached"); return bridgeHelper.fakeEvent; }
get onHighlighted() { bridgeLog.LogUnavailbleApi("tabs.onHighlighted"); return bridgeHelper.fakeEvent; }
get onMoved() { bridgeLog.LogUnavailbleApi("tabs.onMoved"); return bridgeHelper.fakeEvent; }
get onSelectionChanged() {
return bridgeLog.DoActionAndLog(() => {
var fakeEvent = bridgeHelper.fakeEvent;
fakeEvent.addListener = (callback) => {
myBrowser.tabs.onActivated.addListener((activeInfo) => {
callback(activeInfo.tabId, { windowId: activeInfo.windowId });
});
};
return fakeEvent;
}, "tabs.onSelectionChanged", "tabs.onActivated", "tabs.onActivated");
}
duplicate(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
this.get(tabId, function (tab) {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create({ url: tab.url }, callback);
}
else {
myBrowser.tabs.create({ url: tab.url });
}
});
}, "tabs.duplicate", undefined, "tabs.create");
}
getAllInWindow(windowId, callback) {
bridgeLog.DoActionAndLog(() => {
this.query({ windowId: windowId }, callback);
}, "tabs.getAllInWindow", "tabs.query", "tabs.query");
}
getSelected(windowId, callback) {
bridgeLog.DoActionAndLog(() => {
this.query({ active: true }, (tabs) => callback(tabs[0]));
}, "tabs.getSelected", "tabs.query", "tabs.query");
}
sendRequest(tabId, request, responseCallback) {
bridgeLog.DoActionAndLog(() => {
this.sendMessage(tabId, request, responseCallback);
}, "tabs.sendRequest", "tabs.sendMessage", "tabs.sendMessage");
}
captureVisibleTab(windowId, options, callback) {
bridgeLog.LogUnavailbleApi("tabs.captureVisibleTab");
}
connect(tabId, connectInfo) {
bridgeLog.LogUnavailbleApi("tabs.connect");
return null;
}
highlight(highlightInfo, callback) {
bridgeLog.LogUnavailbleApi("tabs.highlight");
}
move(tabId, moveProperties, callback) {
bridgeLog.LogUnavailbleApi("tabs.move");
}
reload(tabId, reloadProperties, callback) {
bridgeLog.LogUnavailbleApi("tabs.reload");
}
}
class EdgeWebNavigationBridge {
get onBeforeNavigate() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onBeforeNavigate; }, "webNavigation.onBeforeNavigate"); }
get onCommitted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCommitted; }, "webNavigation.onCommitted"); }
get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCompleted; }, "webNavigation.onCompleted"); }
get onCreatedNavigationTarget() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCreatedNavigationTarget; }, "webNavigation.onCreatedNavigationTarget"); }
get onDOMContentLoaded() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onDOMContentLoaded; }, "webNavigation.onDOMContentLoaded"); }
get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onErrorOccurred; }, "webNavigation.onErrorOccurred"); }
get onHistoryStateUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onHistoryStateUpdated; }, "webNavigation.onHistoryStateUpdated"); }
get onReferenceFragmentUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onReferenceFragmentUpdated; }, "webNavigation.onReferenceFragmentUpdated"); }
get onTabReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onTabReplaced; }, "webNavigation.onTabReplaced"); }
getAllFrames(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.webNavigation.getAllFrames(details, callback);
}, "webNavigation.getAllFrames");
}
getFrame(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.webNavigation.getFrame(details, callback);
}, "webNavigation.getFrame");
}
}
class EdgeWebRequestBridge {
get MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; }, "webNavigation.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"); }
get onAuthRequired() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onAuthRequired; }, "webNavigation.onAuthRequired"); }
get onBeforeRedirect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRedirect; }, "webNavigation.onBeforeRedirect"); }
get onBeforeRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRequest; }, "webNavigation.onBeforeRequest"); }
get onBeforeSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeSendHeaders; }, "webNavigation.onBeforeSendHeaders"); }
get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onCompleted; }, "webNavigation.onCompleted"); }
get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onErrorOccurred; }, "webNavigation.onErrorOccurred"); }
get onHeadersReceived() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onHeadersReceived; }, "webNavigation.onHeadersReceived"); }
get onResponseStarted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onResponseStarted; }, "webNavigation.onResponseStarted"); }
get onSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onSendHeaders; }, "webNavigation.onSendHeaders"); }
handlerBehaviorChanged(callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.webRequest.handlerBehaviorChanged(callback);
}
else {
myBrowser.webRequest.handlerBehaviorChanged();
}
}, "webRequest.handlerBehaviorChanged");
}
}
class EdgeWindowsBridge {
get WINDOW_ID_CURRENT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_CURRENT; }, "windows.WINDOW_ID_CURRENT"); }
get WINDOW_ID_NONE() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_NONE; }, "windows.WINDOW_ID_NONE"); }
get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onCreated; }, "windows.onCreated"); }
get onFocusChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onFocusChanged; }, "windows.onFocusChanged"); }
get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onRemoved; }, "windows.onRemoved"); }
create(createData, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.windows.create(createData, callback);
}
else {
myBrowser.windows.create(createData);
}
}, "windows.create");
}
get(windowId, getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.get(windowId, getInfo, callback);
}, "windows.get");
}
getAll(getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.getAll(getInfo, callback);
}, "windows.getAll");
}
getCurrent(getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.getCurrent(getInfo, callback);
}, "windows.getCurrent");
}
getLastFocused(getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.getLastFocused(getInfo, callback);
}, "windows.getLastFocused");
}
update(windowId, updateInfo, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.windows.update(windowId, updateInfo, callback);
}
else {
myBrowser.windows.update(windowId, updateInfo);
}
}, "windows.update");
}
}
class EdgeChromeWindowsBridge extends EdgeWindowsBridge {
remove(windowId, callback) {
bridgeLog.LogUnavailbleApi("windows.remove");
}
}
class EdgeBackgroundBridge {
constructor() {
this.app = new EdgeChromeAppBridge();
this.browserAction = typeof browser.browserAction !== "undefined" ? new EdgeChromeBrowserActionBridge() : undefined;
this.contextMenus = typeof browser.contextMenus !== "undefined" ? new EdgeContextMenusBridge() : undefined;
this.cookies = typeof browser.cookies !== "undefined" ? new EdgeChromeCookiesBridge() : undefined;
this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined;
this.history = typeof browser.history !== "undefined" ? new EdgeHistoryBridge() : undefined;
this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined;
this.notifications = typeof browser.notifications !== "undefined" ? new EdgeNotificationBridge() : undefined;
this.pageAction = typeof browser.pageAction !== "undefined" ? new EdgePageActionBridge() : undefined;
this.permissions = typeof browser.permissions !== "undefined" ? new EdgePermissionsBridge() : undefined;
this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined;
this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined;
this.tabs = typeof browser.tabs !== "undefined" ? new EdgeChromeTabsBridge() : undefined;
this.webNavigation = typeof browser.webNavigation !== "undefined" ? new EdgeWebNavigationBridge() : undefined;
this.webRequest = typeof browser.webRequest !== "undefined" ? new EdgeWebRequestBridge() : undefined;
this.windows = typeof browser.windows !== "undefined" ? new EdgeChromeWindowsBridge() : undefined;
}
}
var myBrowser = browser;
var chrome = new EdgeBackgroundBridge();

@ -1,323 +0,0 @@
if (!Range.prototype["intersectsNode"]) {
Range.prototype["intersectsNode"] = function (node) {
let range = document.createRange();
range.selectNode(node);
return 0 > this.compareBoundaryPoints(Range.END_TO_START, range)
&& 0 < this.compareBoundaryPoints(Range.START_TO_END, range);
};
}
var getExtensionProtocol = function () {
if (typeof browser == "undefined") {
if (typeof chrome !== "undefined")
return "chrome-extension://";
}
else {
return "ms-browser-extension://";
}
};
class FakeEvent {
addListener(callback) { }
addRules(rules, callback) { }
getRules(ruleIdentifiers, callback) { }
hasListener(callback) { return false; }
hasListeners() { return false; }
removeRules(ruleIdentifiers, callback) { }
removeListener(callback) { }
}
class EdgeBridgeHelper {
constructor() {
this.fakeEvent = new FakeEvent();
}
toAbsolutePath(relativePath) {
if (relativePath.indexOf("ms-browser-extension://") == 0) {
return relativePath.replace(myBrowser.runtime.getURL(""), "");
}
else if (relativePath.indexOf("/") != 0) {
var absolutePath = "";
var documentPath = document.location.pathname;
absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1);
absolutePath += relativePath;
return absolutePath;
}
return relativePath;
}
}
var bridgeHelper = new EdgeBridgeHelper();
class EdgeBridgeDebugLog {
constructor() {
this.CatchOnException = true;
this.VerboseLogging = true;
this.FailedCalls = {};
this.SuccededCalls = {};
this.DeprecatedCalls = {};
this.BridgedCalls = {};
this.UnavailableApis = {};
this.EdgeIssues = {};
}
log(message) {
try {
if (this.VerboseLogging) {
console.log(message);
}
}
catch (e) {
}
}
info(message) {
try {
if (this.VerboseLogging) {
console.info(message);
}
}
catch (e) {
}
}
warn(message) {
try {
if (this.VerboseLogging) {
console.warn(message);
}
}
catch (e) {
}
}
error(message) {
try {
if (this.VerboseLogging) {
console.error(message);
}
}
catch (e) {
}
}
DoActionAndLog(action, name, deprecatedTo, bridgedTo) {
var result;
try {
result = action();
this.AddToCalledDictionary(this.SuccededCalls, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
if (typeof bridgedTo !== "undefined" && typeof bridgedTo !== "null") {
this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo);
this.AddToCalledDictionary(this.BridgedCalls, name);
}
return result;
}
catch (ex) {
this.AddToCalledDictionary(this.FailedCalls, name);
if (this.CatchOnException)
this.error("API Call Failed: " + name + " - " + ex);
else
throw ex;
}
}
LogEdgeIssue(name, message) {
this.warn(message);
this.AddToCalledDictionary(this.EdgeIssues, name);
}
LogUnavailbleApi(name, deprecatedTo) {
this.warn("API Call '" + name + "' is not supported in Edge");
this.AddToCalledDictionary(this.UnavailableApis, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
}
AddToCalledDictionary(dictionary, name) {
if (typeof dictionary[name] !== "undefined") {
dictionary[name]++;
}
else {
dictionary[name] = 1;
}
}
}
var bridgeLog = new EdgeBridgeDebugLog();
class EdgeExtensionBridge {
getBackgroundPage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getBackgroundPage();
}, "extension.getBackgroundPage");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getURL(path);
}, "extension.getURL");
}
getViews(fetchProperties) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getViews(fetchProperties);
}, "extension.getViews");
}
}
class EdgeChromeExtensionBridge extends EdgeExtensionBridge {
get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); }
get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); }
get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); }
get inIncognitoContext() { return bridgeLog.DoActionAndLog(() => { return myBrowser.extension["inPrivateContext"]; }, "extension.inIncognitoContext", undefined, "extension.inPrivateContext"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.connect(extensionId, connectInfo);
}, "extension.connect", "runtime.connect", "runtime.connect");
}
sendMessage(message, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(message, responseCallback, undefined, undefined);
}, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage");
}
sendRequest(extensionId, message, options, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(extensionId, message, options, responseCallback);
}, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage");
}
isAllowedFileSchemeAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess");
}
isAllowedIncognitoAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedIncognitoAccess");
}
setUpdateUrlData(data) {
bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData");
}
}
class EdgeI18nBridge {
getAcceptLanguages(callback) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getAcceptLanguages(callback);
}, "i18n.getAcceptLanguages");
}
getMessage(messageName, substitutions) {
return bridgeLog.DoActionAndLog(() => {
if (messageName.indexOf("@@extension_id") > -1) {
return myBrowser.runtime.id;
}
if (typeof substitutions !== "undefined" && typeof substitutions !== "null") {
return myBrowser.i18n.getMessage(messageName, substitutions);
}
else {
return myBrowser.i18n.getMessage(messageName);
}
}, "i18n.getMessage");
}
getUILanguage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getUILanguage();
}, "i18n.getUILanguage");
}
}
class EdgeRuntimeBridge {
get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); }
get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); }
get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); }
get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
if (typeof connectInfo !== "undefined" && typeof connectInfo !== "null") {
return myBrowser.runtime.connect(extensionId, connectInfo);
}
else {
return myBrowser.runtime.connect(extensionId);
}
}, "runtime.connect");
}
getBackgroundPage(callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.runtime.getBackgroundPage(callback);
}, "runtime.getBackgroundPage");
}
getManifest() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getManifest();
}, "runtime.getManifest");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getURL(path);
}, "runtime.getURL");
}
sendMessage(extensionId, message, options, responseCallback) {
bridgeLog.DoActionAndLog(() => {
if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options, responseCallback);
}
else if (typeof options !== "undefined" && typeof options !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options);
}
else if (typeof message !== "undefined" && typeof message !== "null") {
myBrowser.runtime.sendMessage(extensionId, message);
}
else {
myBrowser.runtime.sendMessage(undefined, extensionId);
}
}, "runtime.sendMessage");
}
}
class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge {
get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; }
get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; }
get onStartup() { bridgeLog.LogUnavailbleApi("runtime.onStartup"); return bridgeHelper.fakeEvent; }
get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; }
get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; }
get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; }
openOptionsPage(callback) {
bridgeLog.DoActionAndLog(() => {
var optionsPage = myBrowser.runtime.getManifest()["options_page"];
var optionsPageUrl = myBrowser.runtime.getURL(optionsPage);
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create({ url: optionsPageUrl }, callback);
}
else {
myBrowser.tabs.create({ url: optionsPageUrl });
}
}, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })");
}
connectNative(application) {
bridgeLog.LogUnavailbleApi("runtime.connectNative");
return null;
}
getPackageDirectoryEntry(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry");
}
getPlatformInfo(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo");
}
reload() {
bridgeLog.LogUnavailbleApi("runtime.reload");
}
requestUpdateCheck(callback) {
bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck");
}
restart() {
bridgeLog.LogUnavailbleApi("runtime.restart");
}
setUninstallURL(url, callback) {
bridgeLog.LogUnavailbleApi("runtime.setUninstallURL");
}
sendNativeMessage(application, message, responseCallback) {
bridgeLog.LogUnavailbleApi("runtime.sendNativeMessage");
}
}
class EdgeStorageBridge {
get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); }
get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); }
}
class EdgeChromeStorageBridge extends EdgeStorageBridge {
get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); }
get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.sync", undefined, "storage.local"); }
}
class EdgeContentBridge {
constructor() {
this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined;
this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined;
this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined;
this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined;
}
}
var myBrowser = browser;
var chrome = new EdgeContentBridge();

@ -440,8 +440,9 @@
} }
if ( this.isYoutubeAdReq(frameUrl, requestUrl) ) { if ( this.isYoutubeAdReq(frameUrl, requestUrl) ) {
var videoId = this.parseYoutubeVideoIdFromUrl(requestUrl); var destVideoId = this.parseYoutubeVideoIdFromUrl(requestUrl);
if ( videoId ) { var srcVideoId = this.parseYoutubeVideoIdFromUrl(frameUrl);
if ( srcVideoId && destVideoId ) {
request.isYoutubeAd = true; request.isYoutubeAd = true;
request.isVideo = true; request.isVideo = true;
request.rawSrcUrl = frameUrl; request.rawSrcUrl = frameUrl;
@ -535,7 +536,7 @@
return match[1]; return match[1];
} }
re = /^https?:\/\/www\.youtube\.com\/watch\?v=(.*$)/; re = /^https?:\/\/www\.youtube\.com\/watch.*(\?|&)v=([^&]*)/;
match = re.exec(url); match = re.exec(url);
if ( match && match.length > 1 ) { if ( match && match.length > 1 ) {
return match[1]; return match[1];

@ -1,5 +1,7 @@
/** global: browser */ /** global: browser */
/** global: wappalyzer */ /** global: Wappalyzer */
const wappalyzer = new Wappalyzer();
function getOption(name, defaultValue, callback) { function getOption(name, defaultValue, callback) {
browser.storage.local.get(name) browser.storage.local.get(name)

@ -1,25 +1,23 @@
/** global: chrome */ /** global: chrome */
/** global: browser */ /** global: browser */
var pinnedCategory = null;
var func = tabs => { var func = tabs => {
( chrome || browser ).runtime.sendMessage({ ( chrome || browser ).runtime.sendMessage({
id: 'get_apps', id: 'get_apps',
tab: tabs[0], tab: tabs[0],
source: 'popup.js' source: 'popup.js'
}, response => { }, response => {
pinnedCategory = response.pinnedCategory;
replaceDomWhenReady(appsToDomTemplate(response)); replaceDomWhenReady(appsToDomTemplate(response));
}); });
}; };
try { browser.tabs.query({ active: true, currentWindow: true })
// Chrome, Firefox .then(func)
browser.tabs.query({ active: true, currentWindow: true }) .catch(console.error);
.then(func)
.catch(console.error);
} catch ( e ) {
// Edge
browser.tabs.query({ active: true, currentWindow: true }, func);
}
function replaceDomWhenReady(dom) { function replaceDomWhenReady(dom) {
if ( /complete|interactive|loaded/.test(document.readyState) ) { if ( /complete|interactive|loaded/.test(document.readyState) ) {
@ -45,6 +43,34 @@ function replaceDom(domTemplate) {
Array.prototype.forEach.call(nodes, node => { Array.prototype.forEach.call(nodes, node => {
node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n); node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n);
}); });
Array.from(document.querySelectorAll('.detected__category-pin-wrapper')).forEach(pin => {
pin.addEventListener('click', event => {
const categoryId = parseInt(pin.dataset.categoryId, 10);
if ( categoryId === pinnedCategory ) {
pin.className = 'detected__category-pin-wrapper';
pinnedCategory = null;
} else {
const active = document.querySelector('.detected__category-pin-wrapper--active');
if ( active ) {
active.className = 'detected__category-pin-wrapper';
}
pin.className = 'detected__category-pin-wrapper detected__category-pin-wrapper--active';
pinnedCategory = categoryId;
}
( chrome || browser ).runtime.sendMessage({
id: 'set_option',
key: 'pinnedCategory',
value: pinnedCategory,
});
});
});
} }
function appsToDomTemplate(response) { function appsToDomTemplate(response) {
@ -76,7 +102,7 @@ function appsToDomTemplate(response) {
'a', { 'a', {
class: 'detected__app', class: 'detected__app',
target: '_blank', target: '_blank',
href: 'https://www.wappalyzer.com/applications/' + slugify(appName) href: 'https://www.wappalyzer.com/technologies/' + slugify(appName)
}, [ }, [
'img', { 'img', {
class: 'detected__app-icon', class: 'detected__app-icon',
@ -86,8 +112,18 @@ function appsToDomTemplate(response) {
'span', { 'span', {
class: 'detected__app-name' class: 'detected__app-name'
}, },
appName + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) appName,
] ], version ? [
'span', {
class: 'detected__app-version'
},
version
] : null, confidence < 100 ? [
'span', {
class: 'detected__app-confidence'
},
confidence + '% sure'
] : null
] ]
); );
} }
@ -97,15 +133,31 @@ function appsToDomTemplate(response) {
'div', { 'div', {
class: 'detected__category' class: 'detected__category'
}, [ }, [
'a', { 'div', {
class: 'detected__category-link', class: 'detected__category-name'
target: '_blank',
href: 'https://www.wappalyzer.com/categories/' + slugify(response.categories[cat].name)
}, [ }, [
'span', { 'a', {
class: 'detected__category-name' class: 'detected__category-link',
target: '_blank',
href: 'https://www.wappalyzer.com/categories/' + slugify(response.categories[cat].name)
}, },
browser.i18n.getMessage('categoryName' + cat) browser.i18n.getMessage('categoryName' + cat),
], [
'span', {
class: 'detected__category-pin-wrapper' + ( pinnedCategory == cat ? ' detected__category-pin-wrapper--active' : '' ),
'data-category-id': cat,
'title': browser.i18n.getMessage('categoryPin'),
}, [
'img', {
class: 'detected__category-pin detected__category-pin--active',
src: '../images/pin-active.svg'
},
], [
'img', {
class: 'detected__category-pin detected__category-pin--inactive',
src: '../images/pin.svg'
}
]
] ]
], [ ], [
'div', { 'div', {

@ -1,75 +0,0 @@
{
"name": "Wappalyzer",
"short_name": "Wappalyzer",
"author": "Elbert Alias",
"homepage_url": "https://www.wappalyzer.com/",
"description": "Identify web technologies",
"version": "5.1.6",
"default_locale": "en",
"manifest_version": 2,
"icons": {
"16": "images/icon_16.png",
"19": "images/icon_19.png",
"32": "images/icon_32.png",
"38": "images/icon_38.png",
"128": "images/icon_128.png"
},
"page_action": {
"default_icon": {
"16": "images/icon_16.png",
"19": "images/icon_19.png",
"32": "images/icon_32.png",
"38": "images/icon_38.png",
"128": "images/icon_128.png"
},
"default_title": "Wappalyzer",
"default_popup": "html/popup.html"
},
"background": {
"page": "html/background.html",
"persistent": true
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"node_modules/webextension-polyfill/dist/browser-polyfill.js",
"js/content.js"
],
"run_at": "document_idle"
},
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"js/browser-polyfill.js",
"js/iframe.js"
],
"run_at": "document_start",
"all_frames": true
}
],
"web_accessible_resources": [
"js/inject.js"
],
"options_page": "html/options.html",
"permissions": [
"storage",
"tabs",
"webRequest",
"webNavigation",
"http://*/*",
"https://*/*"
],
"content_security_policy": "script-src 'self'; object-src 'self'",
"-ms-preload": {
"backgroundScript": "js/ms_background_scripts_api_bridge.js",
"contentScript": "js/ms_content_scripts_api_bridge.js"
}
}

@ -4,7 +4,7 @@
"author": "Elbert Alias", "author": "Elbert Alias",
"homepage_url": "https://www.wappalyzer.com", "homepage_url": "https://www.wappalyzer.com",
"description": "Identify web technologies", "description": "Identify web technologies",
"version": "5.2.0", "version": "5.4.5",
"default_locale": "en", "default_locale": "en",
"manifest_version": 2, "manifest_version": 2,
"icons": { "icons": {

@ -1,5 +1,5 @@
{ {
"dependencies": { "dependencies": {
"webextension-polyfill": "^0.1.1" "webextension-polyfill": "^0.2.1"
} }
} }

@ -2,6 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
webextension-polyfill@^0.1.1: webextension-polyfill@^0.2.1:
version "0.1.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.1.1.tgz#1d172e59b9ee8706d5ce2c55eebfe0cf23972d70" resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.2.1.tgz#cdfc9126033039f1713553157d35beff1d4d6f4a"

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" version="1" viewBox="0 0 64 480"><g fill="#EE295F"><path d="M-192 240v240h480V0h-480v240zm312.7-1.5c32.6 97.9 59.3 178.3 59.3 178.8 0 .4-7.5.6-16.7.5l-16.8-.3-15.5-48.3-15.5-48.2-75 .2-74.9.3-15.6 48.2-15.5 48.3h-16.3c-12.7 0-16.3-.3-16-1.3.3-.6 27.2-81.2 59.9-179L21.5 60l19.9.2 19.9.3 59.4 178z"/><path d="M40.4 89.5c-.4 1.1-15.5 47.4-33.4 103l-32.7 101 66 .3c36.3.1 66.1.1 66.3-.1.2-.2-62.9-199.6-64.9-204.8-.3-1-.7-.8-1.3.6z"/></g></svg>

After

Width:  |  Height:  |  Size: 504 B

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="62px" height="62px" viewBox="0 0 62 62" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
<title>AMP-Brand-Blue-Icon</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="amp-logo-internal-site" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="AMP-Brand-Blue-Icon" fill="#0379C4">
<path d="M41.6288667,28.1614333 L28.6243667,49.8035667 L26.2683667,49.8035667 L28.5975,35.7016667 L21.3838,35.7109667 C21.3838,35.7109667 21.3156,35.7130333 21.2835667,35.7130333 C20.6336,35.7130333 20.1076333,35.1870667 20.1076333,34.5371 C20.1076333,34.2581 20.367,33.7858667 20.367,33.7858667 L33.3291333,12.1695667 L35.7244,12.1799 L33.3363667,26.3035 L40.5872667,26.2942 C40.5872667,26.2942 40.6647667,26.2931667 40.7019667,26.2931667 C41.3519333,26.2931667 41.8779,26.8191333 41.8779,27.4691 C41.8779,27.7326 41.7745667,27.9640667 41.6278333,28.1604 L41.6288667,28.1614333 Z M31,0 C13.8787,0 0,13.8797333 0,31 C0,48.1213 13.8787,62 31,62 C48.1202667,62 62,48.1213 62,31 C62,13.8797333 48.1202667,0 31,0 L31,0 Z" id="Fill-1"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,9 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="" xml:space="preserve" width="18" height="18"><rect id="backgroundrect" width="100%" height="100%" x="0" y="0" fill="none" stroke="none"/>
<style type="text/css">
.st0{fill:#35B454;}
</style>
<path class="st0" d="M14.300000190734863,0 H0.30000001192092896 V4.5 l9.199999809265137,0 c0.6000000238418579,0 1,0.5 1,1 v7.900000095367432 h-2 c-0.6000000238418579,0 -1,-0.5 -1,-1 v-5.699999809265137 H3.5999999046325684 c-2,0 -3.5999999046325684,1.600000023841858 -3.5999999046325684,3.5999999046325684 v4 c0,2 1.600000023841858,3.5999999046325684 3.5999999046325684,3.5999999046325684 h14.300000190734863 V3.6000003814697266 C17.899999618530273,1.6000003814697266 16.299999237060547,0 14.300000190734863,0 z" id="svg_2"/>
</svg>

After

Width:  |  Height:  |  Size: 831 B

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-10 -10 120 120"><defs><filter id="a" x="-50%" y="-50%" width="200%" height="200%"><feOffset result="offOut" in="SourceAlpha"/><feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/><feComponentTransfer in="blurOut" result="opacityOut"><feFuncA type="linear" slope=".5"/></feComponentTransfer><feBlend in="SourceGraphic" in2="opacityOut"/></filter></defs><path d="M5 18.25l45-16L96 18l-7.5 59L50 98.25l-38-21z" filter="url(#a)" class="outline"/><path d="M5 18.25l45-16v96l-38-21z" fill="#de3641" class="left"/><path d="M50 2.25L96 18l-7.5 59L50 98.25z" fill="#b13138" class="right"/><path d="M50 13l29.25 62.5h-10L63 61.25H50v-8.5h9.5L50 33.1l-8 19.65h8v8.5H38.1L32.5 75.5H21.75z" fill="#fff" class="letter"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250"><path fill="#dd0031" d="M125 30L31.9 63.2l14.2 123.1L125 230l78.9-43.7 14.2-123.1z"/><path fill="#c3002f" d="M125 30v22.2-.1V230l78.9-43.7 14.2-123.1L125 30z"/><path fill="#fff" d="M125 52.1L66.8 182.6h21.7l11.7-29.2h49.4l11.7 29.2H183L125 52.1zm17 83.3h-34l17-40.9 17 40.9z"/></svg>

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 345 B

@ -1 +1,74 @@
<svg xmlns="http://www.w3.org/2000/svg" width="355.809" height="355.809"><path d="M177.367 0L9.964 58.913 36.416 278.24l141.129 77.568 141.856-78.619 26.444-219.32L177.367 0z" fill="#b3b3b3"/><path d="M329.149 70.545L176.976 18.654v318.622L304.504 266.7l24.645-196.154z" fill="#af2b2d"/><path d="M28.749 71.482l22.667 196.153 125.559 69.641V18.647L28.749 71.482z" fill="#df2e31"/><path d="M212.249 177.131l-34.995-73.08-30.808 73.08h65.803zm13.342 30.729h-92.764l-20.752 51.907-38.603.714L176.977 30.224 284.09 260.48h-35.779l-22.72-52.621z" fill="#f2f2f2"/><path d="M176.976 30.224l.276 73.827 34.96 73.136h-35.157l-.079 30.625 48.613.048 22.721 52.63 36.936.685-108.27-230.951z" fill="#b3b3b3"/></svg> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.48.4 r9939"
width="335.88126"
height="355.80875"
xml:space="preserve"
sodipodi:docname="AngularJS-Shield.svg"
inkscape:export-filename="/usr/local/google/home/stephenfluin/AngularJS-Shield.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs6" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1393"
inkscape:window-height="697"
id="namedview4"
showgrid="false"
inkscape:zoom="0.25757162"
inkscape:cx="171.15375"
inkscape:cy="177.21499"
inkscape:window-x="2290"
inkscape:window-y="312"
inkscape:window-maximized="0"
inkscape:current-layer="g10"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" /><g
id="g10"
inkscape:groupmode="layer"
inkscape:label="ink_ext_XXXXXX"
transform="matrix(1.25,0,0,-1.25,-188.84625,636.71875)"><g
id="g12"
transform="scale(0.1,0.1)"><path
d="M 2850,5093.75 1510.77,4622.45 1722.39,2867.82 2851.42,2247.28 3986.27,2876.23 4197.82,4630.79 2850,5093.75 z"
style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path14"
inkscape:connector-curvature="0" /><path
d="m 4064.25,4529.39 -1217.38,415.13 0,-2548.98 1020.22,564.62 197.16,1569.23 z"
style="fill:#af2b2d;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path16"
inkscape:connector-curvature="0" /><path
d="m 1661.05,4521.89 181.34,-1569.22 1004.47,-557.13 0,2549.03 -1185.81,-422.68 z"
style="fill:#df2e31;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path18"
inkscape:connector-curvature="0" /><path
d="m 3129.05,3676.7 -279.96,584.64 -246.46,-584.64 526.42,0 z m 106.74,-245.83 -742.11,0 -166.02,-415.26 -308.82,-5.71 828.04,1842.06 856.9,-1842.06 -286.23,0 -181.76,420.97 z"
style="fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path20"
inkscape:connector-curvature="0" /><path
d="m 2846.87,4851.96 2.21,-590.62 279.67,-585.09 -281.25,0 -0.63,-245 388.9,-0.38 181.77,-421.04 295.49,-5.48 -866.16,1847.61 z"
style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path22"
inkscape:connector-curvature="0" /></g></g></svg>

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Group 28 Copy 5</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="62.1023273%" y1="0%" x2="108.19718%" y2="37.8635764%" id="linearGradient-1">
<stop stop-color="#4285EB" offset="0%"></stop>
<stop stop-color="#2EC7FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="69.644116%" y1="0%" x2="54.0428975%" y2="108.456714%" id="linearGradient-2">
<stop stop-color="#29CDFF" offset="0%"></stop>
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
<stop stop-color="#0A60FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="69.6908165%" y1="-12.9743587%" x2="16.7228981%" y2="117.391248%" id="linearGradient-3">
<stop stop-color="#FA816E" offset="0%"></stop>
<stop stop-color="#F74A5C" offset="41.472606%"></stop>
<stop stop-color="#F51D2C" offset="100%"></stop>
</linearGradient>
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-4">
<stop stop-color="#FA8E7D" offset="0%"></stop>
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
<stop stop-color="#F51D2C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="logo" transform="translate(-20.000000, -20.000000)">
<g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)">
<g id="Group-27-Copy-3">
<g id="Group-25" fill-rule="nonzero">
<g id="2">
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-1)"></path>
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-2)"></path>
</g>
<path d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z" id="Shape" fill="url(#linearGradient-3)"></path>
</g>
<ellipse id="Combined-Shape" fill="url(#linearGradient-4)" cx="100.519339" cy="100.436681" rx="23.6001926" ry="23.580786"></ellipse>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 612">
<g sodipodi:docname="twitter_bootstrap_logo.svg" inkscape:version="0.48.1 r9760" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<path fill="#563D7C" d="M612 510c0 56.1-45.9 102-102 102H102C45.9 612 0 566.1 0 510V102C0 45.9 45.9 0 102 0h408c56.1 0 102 45.9 102 102v408z"/>
<path fill="#FFF" d="M166.3 133h173.5c32 0 57.7 7.3 77 22s29 36.8 29 66.5c0 18-4.4 33.4-13.2 46.2-8.8 12.8-21.4 22.8-37.8 29.8v1c22 4.7 38.7 15.1 50 31.2 11.3 16.2 17 36.4 17 60.8 0 14-2.5 27.1-7.5 39.2-5 12.2-12.8 22.7-23.5 31.5s-24.3 15.8-41 21-36.5 7.8-59.5 7.8h-164V133zm62.5 149.5h102c15 0 27.5-4.2 37.5-12.8s15-20.8 15-36.8c0-18-4.5-30.7-13.5-38s-22-11-39-11h-102v98.6zm0 156.5h110.5c19 0 33.8-4.9 44.2-14.8 10.5-9.8 15.8-23.8 15.8-41.8 0-17.7-5.2-31.2-15.8-40.8s-25.2-14.2-44.2-14.2H228.8V439z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg215"
version="1.1"
viewBox="0 0 11.493 11.493"
height="11.493mm"
width="11.493mm">
<defs
id="defs209" />
<metadata
id="metadata212">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0,-285.507)"
id="layer1">
<path
id="path16"
style="fill:#1b1817;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.03527778"
d="M 5.74605,285.64853 C 2.57317,285.64853 0,288.22134 0,291.39528 c 0,2.53859 1.64642,4.69265 3.92995,5.45289 0.28751,0.0526 0.39229,-0.12488 0.39229,-0.27728 0,-0.13653 -0.005,-0.49777 -0.008,-0.9772 -1.59844,0.34713 -1.93569,-0.77046 -1.93569,-0.77046 -0.26141,-0.66393 -0.63818,-0.84067 -0.63818,-0.84067 -0.52176,-0.35631 0.0395,-0.34925 0.0395,-0.34925 0.57679,0.0406 0.88018,0.59231 0.88018,0.59231 0.51259,0.87806 1.34514,0.62442 1.67252,0.47731 0.0522,-0.37112 0.20073,-0.62442 0.36477,-0.768 -1.27599,-0.14534 -2.61761,-0.63817 -2.61761,-2.84021 0,-0.62759 0.22402,-1.14018 0.59161,-1.54199 -0.0593,-0.14535 -0.25647,-0.72955 0.0565,-1.52083 0,0 0.48224,-0.15452 1.58009,0.58879 0.45826,-0.12736 0.95003,-0.19086 1.43863,-0.19333 0.48824,0.002 0.97966,0.066 1.43862,0.19333 1.09714,-0.74331 1.57868,-0.58879 1.57868,-0.58879 0.31362,0.79128 0.11642,1.37548 0.0575,1.52083 0.3683,0.40181 0.59055,0.9144 0.59055,1.54199 0,2.20768 -1.34373,2.69346 -2.62361,2.83562 0.20602,0.17745 0.38982,0.52811 0.38982,1.06434 0,0.76799 -0.007,1.38782 -0.007,1.57621 0,0.15381 0.10371,0.33267 0.39511,0.27657 2.28177,-0.76164 3.92677,-2.91394 3.92677,-5.45218 0,-3.17394 -2.57316,-5.74675 -5.7471,-5.74675" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 979 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" viewBox="0 0 51 51" overflow="scroll"> <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" viewBox="0 0 51 51" overflow="scroll">
<path fill="#CC2128" d="M5.5 1.4h40.1c2.3 0 4.1 1.9 4.1 4.1v40.1c0 2.3-1.9 4.1-4.1 4.1H5.5c-2.3 0-4.1-1.9-4.1-4.1V5.5c0-2.2 1.9-4.1 4.1-4.1z"/> <path fill="#CC2128" d="M5.5 1.4h40.1c2.3 0 4.1 1.9 4.1 4.1v40.1c0 2.3-1.9 4.1-4.1 4.1H5.5c-2.3 0-4.1-1.9-4.1-4.1V5.5c0-2.2 1.9-4.1 4.1-4.1z"/>
<g fill="#FFF"> <g fill="#FFF">
<path d="M10.5 14.7l.8 3.3h2.5c-1.2 5.6-3.4 16.1-3.4 16.1-.2 1-.6 2.1-1.5 2.8-1 .8-2.5.6-3.6.3l-.9 3.2c.2.1 2.9.8 5.2.3 1.4-.3 2.6-1.3 3.2-2.1.8-1 1.2-2.8 1.5-4 .3-1 4.2-20.2 4.2-20.2h-8v.3zm30.9 16.6c-.5.2-1.1.4-1.5.4-1.2.1-2.2-.7-1.4-3.7.8-3.4 2.3-9.9 2.3-9.9h5.1l.8-3.3h-5.1l1.1-4.6H39c-.2.7-3.6 15.8-4 17.3-.4 2.1-1.1 4.4.4 6.2.9 1.1 2.3 1.5 3.5 1.5 1.1 0 2.1-.1 2.9-.5-.4-.5-.6-1.1-.6-1.8-.2-.7-.1-1.2.2-1.6z"/> <path d="M10.5 14.7l.8 3.3h2.5c-1.2 5.6-3.4 16.1-3.4 16.1-.2 1-.6 2.1-1.5 2.8-1 .8-2.5.6-3.6.3l-.9 3.2c.2.1 2.9.8 5.2.3 1.4-.3 2.6-1.3 3.2-2.1.8-1 1.2-2.8 1.5-4 .3-1 4.2-20.2 4.2-20.2h-8v.3zm30.9 16.6c-.5.2-1.1.4-1.5.4-1.2.1-2.2-.7-1.4-3.7.8-3.4 2.3-9.9 2.3-9.9h5.1l.8-3.3h-5.1l1.1-4.6H39c-.2.7-3.6 15.8-4 17.3-.4 2.1-1.1 4.4.4 6.2.9 1.1 2.3 1.5 3.5 1.5 1.1 0 2.1-.1 2.9-.5-.4-.5-.6-1.1-.6-1.8-.2-.7-.1-1.2.2-1.6z"/>
<path d="M43.8 30.7c-.4 0-.8.1-1.2.4-.5.4-.9 1-.9 1.7 0 .5.2 1 .5 1.4.4.4.9.7 1.6.7 1.1 0 2.1-.9 2.1-2.1 0-1.1-1-2.1-2.1-2.1zm-21.5-4.2h.8c3.8 0 9.6-.6 11.2-4.8.8-2 .6-4.3-1-5.8-1.3-1.2-3.2-1.6-4.9-1.6-5.5.2-9.3 5.1-10.1 9.7-.5 2.9-.6 6.1 1.3 8.6 1.5 2 3.7 2.5 6.2 2.5 3.1 0 5.5-1 5.5-1l.8-3.7s-2.7 1.5-5.6 1.5c-2.4 0-3.8-1.4-4-3.4-.2-.8-.2-2-.2-2zm6-9c.8 0 1.4.2 1.8.5.4.3.6.8.6 1.5 0 1.2-.6 2.1-2 2.8-1.3.7-3.1 1-5.3 1h-.5c.6-4.2 3.7-5.8 5.4-5.8z"/> <path d="M43.8 30.7c-.4 0-.8.1-1.2.4-.5.4-.9 1-.9 1.7 0 .5.2 1 .5 1.4.4.4.9.7 1.6.7 1.1 0 2.1-.9 2.1-2.1 0-1.1-1-2.1-2.1-2.1zm-21.5-4.2h.8c3.8 0 9.6-.6 11.2-4.8.8-2 .6-4.3-1-5.8-1.3-1.2-3.2-1.6-4.9-1.6-5.5.2-9.3 5.1-10.1 9.7-.5 2.9-.6 6.1 1.3 8.6 1.5 2 3.7 2.5 6.2 2.5 3.1 0 5.5-1 5.5-1l.8-3.7s-2.7 1.5-5.6 1.5c-2.4 0-3.8-1.4-4-3.4-.2-.8-.2-2-.2-2zm6-9c.8 0 1.4.2 1.8.5.4.3.6.8.6 1.5 0 1.2-.6 2.1-2 2.8-1.3.7-3.1 1-5.3 1h-.5c.6-4.2 3.7-5.8 5.4-5.8z"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 247 B

@ -0,0 +1 @@
<svg width="26" height="26" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg"><title>Kajabi</title><desc>Kajabi Logo</desc><g fill="#2E91FC" fill-rule="nonzero"><path d="M0 26v-26h26zM5.2 26l10.4-10.4 10.4 10.4z"/></g></svg>

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" viewBox="0 0 51 51" overflow="scroll"> <svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" viewBox="0 0 51 51" overflow="scroll">
<path fill="#FF7800" d="M5.6 1.4h39.9c2.3 0 4.2 1.8 4.2 4.2v39.9c0 2.3-1.8 4.2-4.2 4.2H5.6c-2.3 0-4.2-1.8-4.2-4.2V5.6c0-2.3 1.9-4.2 4.2-4.2z"/> <path fill="#FF7800" d="M5.6 1.4h39.9c2.3 0 4.2 1.8 4.2 4.2v39.9c0 2.3-1.8 4.2-4.2 4.2H5.6c-2.3 0-4.2-1.8-4.2-4.2V5.6c0-2.3 1.9-4.2 4.2-4.2z"/>
<path fill="#FEFEFE" d="M40.1 17.6c-3.2 0-6.1 1.9-7.3 4.8-1-2.3-3.5-4.8-6.9-4.8h-.4c-3.5 0-6.1 1.9-7.3 4.8-1.3-2.9-4.2-4.8-7.3-4.8-4.4 0-7.9 3.5-7.9 7.9v8h4v-7.9c0-2.3 1.9-4.2 4.2-4.2s4.2 1.9 4.2 4.2v7.9h3.8v-3.2c3.2 4.4 10.7 4.4 13.6-1h-5.4c-.4.4-1 .4-1.5.4-1.5 0-3.2-1-3.8-2.9h10.7c.4 3.8 3.8 6.7 7.6 6.7 4.4 0 8.2-3.5 8.2-7.9s-4.1-8-8.5-8zM22 23.5c.6-1.5 2.3-2.4 3.8-2.3 1.5.1 2.5 1 3.2 2.3h-7zm18.1 6.1c-2.3 0-4.2-1.9-4.2-4.2s1.9-4.2 4.2-4.2c2.5 0 4.4 1.9 4.4 4.2s-1.9 4.2-4.4 4.2z"/> <path fill="#FEFEFE" d="M40.1 17.6c-3.2 0-6.1 1.9-7.3 4.8-1-2.3-3.5-4.8-6.9-4.8h-.4c-3.5 0-6.1 1.9-7.3 4.8-1.3-2.9-4.2-4.8-7.3-4.8-4.4 0-7.9 3.5-7.9 7.9v8h4v-7.9c0-2.3 1.9-4.2 4.2-4.2s4.2 1.9 4.2 4.2v7.9h3.8v-3.2c3.2 4.4 10.7 4.4 13.6-1h-5.4c-.4.4-1 .4-1.5.4-1.5 0-3.2-1-3.8-2.9h10.7c.4 3.8 3.8 6.7 7.6 6.7 4.4 0 8.2-3.5 8.2-7.9s-4.1-8-8.5-8zM22 23.5c.6-1.5 2.3-2.4 3.8-2.3 1.5.1 2.5 1 3.2 2.3h-7zm18.1 6.1c-2.3 0-4.2-1.9-4.2-4.2s1.9-4.2 4.2-4.2c2.5 0 4.4 1.9 4.4 4.2s-1.9 4.2-4.4 4.2z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 758 B

After

Width:  |  Height:  |  Size: 755 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 211.8 64.9" style="enable-background:new 0 0 211.8 64.9;" xml:space="preserve">
<style type="text/css">
.st0{fill:#126FB7;}
</style>
<g>
<path class="st0" d="M32.4,27.3c-1.4-0.9-2.8-1.6-4.1-2c-1.4-0.4-2.5-0.7-3.3-0.9c-2.6-0.7-4.8-1.2-6.4-1.6
c-1.6-0.4-2.9-0.9-3.8-1.3c-0.9-0.4-1.5-0.9-1.9-1.4c-0.3-0.5-0.5-1.2-0.5-2c0-0.9,0.2-1.6,0.6-2.2c0.4-0.6,0.9-1.1,1.5-1.5
c0.6-0.4,1.3-0.7,2-0.8c0.7-0.2,1.5-0.2,2.2-0.2c1.1,0,2.2,0.1,3.1,0.3c1,0.2,1.8,0.5,2.6,1c0.7,0.5,1.3,1.1,1.8,1.9
c0.5,0.8,0.7,1.9,0.8,3.1h8.9c0-2.4-0.5-4.5-1.4-6.2c-0.9-1.7-2.2-3.1-3.7-4.2c-1.6-1.1-3.4-1.9-5.4-2.4c-2-0.5-4.1-0.7-6.3-0.7
c-1.9,0-3.8,0.3-5.6,0.8c-1.9,0.5-3.6,1.3-5.1,2.4c-1.5,1.1-2.7,2.4-3.6,4c-0.9,1.6-1.4,3.5-1.4,5.6c0,1.9,0.4,3.6,1.1,4.9
c0.7,1.4,1.7,2.5,2.9,3.4c1.2,0.9,2.5,1.6,4,2.2c1.5,0.6,3,1,4.6,1.4c1.5,0.4,3,0.8,4.5,1.2c1.5,0.4,2.8,0.8,4,1.2
c1.2,0.5,2.1,1.1,2.9,1.8c0.7,0.7,1.1,1.6,1.1,2.8c0,1.1-0.3,1.9-0.8,2.6c-0.5,0.7-1.2,1.2-2.1,1.6c-0.8,0.4-1.7,0.7-2.6,0.8
c-0.9,0.1-1.8,0.2-2.6,0.2c-1.2,0-2.4-0.1-3.5-0.4c-1.1-0.3-2.1-0.7-3-1.4c-0.8-0.6-1.5-1.4-2-2.4c-0.5-1-0.8-2.2-0.8-3.6H2.2
c0,2.6,0.4,4.8,1.4,6.7c1,1.9,2.3,3.4,4,4.6c1.7,1.2,3.6,2.1,5.8,2.7c2.2,0.6,4.4,0.9,6.7,0.9c2.9,0,5.4-0.3,7.6-1
c2.2-0.7,4-1.6,5.5-2.8c1.5-1.2,2.6-2.6,3.3-4.3c0.7-1.6,1.1-3.4,1.1-5.3c0-2.4-0.5-4.3-1.5-5.8C35,29.4,33.8,28.2,32.4,27.3z"/>
<path class="st0" d="M66.3,21.4c-0.8-1.1-1.9-1.9-3.4-2.5c-1.4-0.6-3.3-0.9-5.5-0.9c-1.6,0-3.2,0.4-4.8,1.2c-1.6,0.8-3,2.1-4.1,3.9
h-0.2V6.2h-8.3v43h8.3V33.2c0-3.1,0.5-5.3,1.5-6.7c1-1.4,2.7-2,4.9-2c2,0,3.4,0.6,4.2,1.9c0.8,1.2,1.2,3.1,1.2,5.6v17.2h8.3V30.5
c0-1.9-0.2-3.6-0.5-5.1C67.7,23.8,67.2,22.5,66.3,21.4z"/>
<path class="st0" d="M99.8,22.3c-1.4-1.4-3-2.5-5-3.2c-1.9-0.8-4.1-1.1-6.5-1.1c-2.4,0-4.5,0.4-6.5,1.1c-1.9,0.8-3.6,1.8-4.9,3.2
c-1.4,1.4-2.4,3.1-3.2,5.1c-0.7,2-1.1,4.2-1.1,6.6c0,2.4,0.4,4.6,1.1,6.6c0.7,2,1.8,3.6,3.2,5c1.4,1.4,3,2.5,4.9,3.2
c1.9,0.7,4.1,1.1,6.5,1.1c2.4,0,4.6-0.4,6.5-1.1c1.9-0.7,3.6-1.8,5-3.2c1.4-1.4,2.4-3.1,3.2-5c0.7-2,1.1-4.2,1.1-6.6
c0-2.4-0.4-4.6-1.1-6.6C102.2,25.4,101.2,23.7,99.8,22.3z M95.4,37.6c-0.2,1.2-0.6,2.2-1.2,3.1c-0.6,0.9-1.3,1.7-2.3,2.2
c-1,0.6-2.1,0.8-3.6,0.8c-1.4,0-2.6-0.3-3.5-0.8c-0.9-0.5-1.7-1.3-2.3-2.2c-0.6-0.9-1-2-1.2-3.1C81.1,36.4,81,35.2,81,34
c0-1.2,0.1-2.4,0.4-3.6c0.2-1.2,0.6-2.2,1.2-3.1c0.6-0.9,1.3-1.6,2.3-2.2c0.9-0.6,2.1-0.9,3.5-0.9c1.4,0,2.6,0.3,3.6,0.9
c1,0.6,1.7,1.3,2.3,2.2c0.6,0.9,1,1.9,1.2,3.1c0.2,1.2,0.4,2.4,0.4,3.6C95.7,35.2,95.6,36.4,95.4,37.6z"/>
<path class="st0" d="M135.6,22.9c-1.1-1.5-2.6-2.7-4.3-3.6c-1.7-0.9-3.8-1.4-6.2-1.4c-1.9,0-3.6,0.4-5.2,1.1
c-1.6,0.7-2.9,1.9-3.9,3.6h-0.1v-3.9H108v43.1h8.3V45.4h0.1c1,1.5,2.3,2.6,3.9,3.4c1.6,0.8,3.3,1.1,5.2,1.1c2.2,0,4.2-0.4,5.9-1.3
c1.7-0.9,3.1-2,4.2-3.5c1.1-1.4,1.9-3.1,2.5-5c0.5-1.9,0.8-3.8,0.8-5.9c0-2.2-0.3-4.2-0.8-6.2C137.6,26.1,136.7,24.4,135.6,22.9z
M130.2,37.6c-0.2,1.2-0.6,2.2-1.2,3.1c-0.6,0.9-1.3,1.6-2.2,2.1c-0.9,0.6-2.1,0.8-3.4,0.8c-1.3,0-2.5-0.3-3.4-0.8
c-0.9-0.5-1.7-1.3-2.3-2.1c-0.6-0.9-1-1.9-1.2-3.1c-0.3-1.2-0.4-2.4-0.4-3.6c0-1.3,0.1-2.5,0.4-3.6c0.2-1.2,0.6-2.2,1.2-3.1
c0.6-0.9,1.3-1.6,2.2-2.2c0.9-0.6,2.1-0.9,3.4-0.9c1.3,0,2.5,0.3,3.4,0.9c0.9,0.6,1.7,1.3,2.3,2.2c0.6,0.9,1,2,1.3,3.1
c0.3,1.2,0.4,2.4,0.4,3.6C130.6,35.3,130.5,36.5,130.2,37.6z"/>
<path class="st0" d="M168,23.5c-1.2-1.7-2.8-3-4.7-4c-1.9-1-4.2-1.5-6.8-1.5c-2.3,0-4.4,0.4-6.3,1.2c-1.9,0.8-3.5,2-4.9,3.4
c-1.4,1.4-2.4,3.1-3.2,5.1c-0.7,2-1.1,4.1-1.1,6.4c0,2.4,0.4,4.5,1.1,6.5c0.7,2,1.8,3.6,3.1,5.1c1.3,1.4,3,2.5,4.9,3.3
c1.9,0.8,4.1,1.1,6.5,1.1c3.4,0,6.4-0.8,8.8-2.4c2.4-1.6,4.2-4.2,5.4-7.8h-7.4c-0.3,0.9-1,1.8-2.2,2.7c-1.2,0.8-2.7,1.3-4.4,1.3
c-2.4,0-4.2-0.6-5.4-1.8c-1.3-1.2-1.9-3.2-2.1-5.9h21.9c0.2-2.4,0-4.6-0.6-6.8C170.1,27.1,169.2,25.2,168,23.5z M149.3,30.7
c0-0.6,0.2-1.3,0.4-2c0.2-0.7,0.6-1.4,1.1-2.1c0.5-0.7,1.2-1.2,2.1-1.7c0.9-0.5,2-0.7,3.3-0.7c2,0,3.6,0.5,4.6,1.6
c1,1.1,1.7,2.7,2.1,4.8H149.3z"/>
<path class="st0" d="M189.9,18.4c-1,0.3-1.9,0.8-2.8,1.3c-0.9,0.6-1.6,1.3-2.3,2.1c-0.7,0.8-1.2,1.7-1.6,2.6h-0.1v-5.6h-7.9v30.4
h8.3V35.5c0-1.4,0.1-2.6,0.4-3.8c0.3-1.2,0.7-2.2,1.4-3.1c0.6-0.9,1.5-1.6,2.6-2.1c1.1-0.5,2.4-0.8,3.9-0.8c0.5,0,1,0,1.6,0.1
c0.5,0.1,1,0.1,1.4,0.2v-7.8c-0.7-0.2-1.3-0.3-1.8-0.3C191.9,17.9,190.9,18.1,189.9,18.4z"/>
<path class="st0" d="M202.8,1.8c-4.4,0-8,3.6-8,8c0,4.4,3.6,8,8,8c4.4,0,8-3.6,8-8C210.8,5.4,207.2,1.8,202.8,1.8z M202.8,16.3
c-3.6,0-6.5-2.9-6.5-6.5s2.9-6.5,6.5-6.5c3.6,0,6.5,2.9,6.5,6.5S206.3,16.3,202.8,16.3z"/>
<path class="st0" d="M205.7,9.5c0.3-0.4,0.4-0.8,0.4-1.4c0-0.4-0.1-0.8-0.3-1c-0.2-0.3-0.4-0.5-0.7-0.7c-0.3-0.2-0.6-0.3-0.9-0.3
c-0.3-0.1-0.7-0.1-1.2-0.1h-3.4v7.8h2v-2.8h0.9l2.1,2.8h2.4l-2.6-3.3C205.1,10.1,205.5,9.8,205.7,9.5z M204,8.8
c-0.1,0.1-0.2,0.3-0.3,0.4c-0.1,0.1-0.3,0.2-0.5,0.2c-0.2,0-0.5,0-0.8,0h-0.6V7.4h0.7c0.2,0,0.4,0,0.6,0c0.2,0,0.3,0,0.5,0.1
c0.2,0.1,0.3,0.2,0.4,0.3c0.1,0.1,0.1,0.3,0.1,0.5C204.1,8.5,204,8.7,204,8.8z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="290pt" height="290pt" viewBox="0 0 290 290" version="1.1" xmlns="http://www.w3.org/2000/svg">
<g id="#2558a3ff">
<path fill="#2558a3" opacity="1.00" d=" M 9.98 23.93 C 16.48 18.43 23.40 13.14 31.49 10.21 C 31.15 19.47 31.10 28.76 29.80 37.96 C 19.87 37.96 9.89 38.55 0.00 37.37 L 0.00 34.43 C 2.69 30.38 6.26 27.02 9.98 23.93 Z" />
</g>
<g id="#1c74bdff">
<path fill="#1c74bd" opacity="1.00" d=" M 34.07 10.88 C 41.04 11.76 48.05 12.10 55.04 12.86 C 60.47 13.22 65.96 12.74 71.36 13.58 C 77.81 14.47 84.34 13.65 90.81 14.28 C 104.03 16.05 117.41 14.21 130.67 15.37 C 136.74 16.30 142.89 16.03 149.00 16.03 C 183.67 16.01 218.33 16.05 253.00 16.01 C 255.55 16.03 258.10 16.14 260.65 16.35 C 257.33 21.20 251.60 23.08 246.62 25.69 C 242.36 27.81 237.95 30.34 233.01 30.00 C 225.65 29.59 218.42 27.64 211.00 27.94 C 198.35 28.14 185.68 27.70 173.03 28.14 C 164.01 29.64 154.83 28.32 145.81 29.69 C 113.86 31.44 81.97 34.17 50.03 36.18 C 44.08 37.00 38.06 37.12 32.06 36.96 C 31.75 28.22 31.96 19.42 34.07 10.88 Z" />
</g>
<g id="#f7921eff">
<path fill="#f7921e" opacity="1.00" d=" M 259.61 25.69 C 264.29 23.45 269.14 21.56 274.01 19.77 C 274.09 34.54 270.39 49.30 272.84 64.05 C 273.37 71.44 272.40 78.91 273.65 86.27 C 275.88 132.75 281.25 179.06 286.66 225.29 C 287.42 232.58 288.79 239.80 289.10 247.13 C 286.20 246.21 283.36 245.14 280.46 244.25 C 283.01 245.98 285.67 247.54 288.19 249.33 C 275.30 256.48 262.18 263.25 248.74 269.28 C 250.01 265.99 251.60 262.84 253.02 259.61 C 250.84 261.89 248.89 264.37 246.72 266.65 C 247.24 257.78 246.93 248.88 247.02 240.00 C 246.97 235.09 247.26 230.17 246.68 225.29 C 244.99 214.51 247.02 203.52 245.35 192.73 C 244.51 185.99 245.55 179.17 244.57 172.44 C 243.42 165.53 244.59 158.49 243.46 151.59 C 242.53 145.29 243.51 138.88 242.46 132.59 C 241.51 126.24 242.51 119.79 241.57 113.44 C 240.32 105.83 241.65 98.07 240.57 90.44 C 239.16 81.26 240.90 71.91 239.35 62.74 C 238.13 53.49 239.72 44.27 240.15 35.05 C 244.88 32.49 249.70 30.11 254.55 27.81 C 254.68 28.58 254.94 30.11 255.07 30.88 C 256.25 28.90 257.35 26.64 259.61 25.69 Z" />
</g>
<g id="#da1c5bff">
<path fill="#da1c5b" opacity="1.00" d=" M 172.02 33.90 C 183.29 32.39 194.67 33.24 206.00 33.00 C 215.40 32.73 224.83 33.78 233.96 36.06 C 234.00 49.70 233.99 63.35 233.95 77.00 C 233.68 85.36 235.23 93.61 235.17 101.97 C 236.62 110.85 235.46 119.86 236.32 128.77 C 237.19 134.31 236.75 139.94 237.54 145.48 C 238.68 154.44 237.23 163.53 238.52 172.49 C 239.13 176.93 238.82 181.43 239.24 185.88 C 241.08 198.88 238.84 212.09 240.81 225.08 C 241.25 236.38 240.82 247.70 241.01 259.01 C 241.20 264.57 240.19 270.06 239.52 275.56 C 230.49 277.50 221.24 278.01 212.03 278.16 C 203.08 279.46 194.02 278.87 185.00 278.98 C 179.11 278.91 173.20 279.27 167.33 278.64 C 155.58 276.95 143.63 279.04 131.88 277.23 C 120.72 276.41 109.49 277.61 98.33 276.63 C 91.48 275.48 84.49 276.46 77.64 275.43 C 68.96 274.29 60.16 275.65 51.48 274.54 C 46.23 273.77 40.89 274.18 35.64 273.42 C 28.62 272.45 21.50 273.50 14.49 272.54 C 10.69 272.00 6.86 271.93 3.03 271.87 C 3.01 215.91 3.03 159.96 3.02 104.00 C 2.99 97.56 3.36 91.07 2.36 84.67 C 1.15 70.85 3.28 56.84 0.89 43.10 C 13.47 42.65 26.09 43.63 38.64 42.58 C 74.41 40.20 110.18 37.59 145.95 35.06 C 154.67 35.35 163.29 33.76 172.02 33.90 M 42.77 105.29 C 43.87 109.13 47.48 111.29 49.75 114.36 C 50.80 119.13 49.93 124.08 50.37 128.93 C 51.12 137.49 50.80 146.14 52.49 154.60 C 55.11 171.01 60.27 187.36 70.13 200.92 C 80.03 215.17 96.01 225.01 113.12 227.72 C 122.24 228.26 131.76 228.78 140.43 225.37 C 153.66 220.68 164.43 210.79 172.39 199.45 C 178.12 191.22 183.08 182.26 185.33 172.41 C 189.47 154.27 189.98 135.40 187.81 116.95 C 187.87 115.36 187.23 113.40 188.46 112.10 C 190.81 109.27 194.13 107.04 195.29 103.39 C 196.92 98.11 196.26 91.81 192.31 87.69 C 188.53 83.52 183.11 79.74 177.26 80.22 C 167.55 83.53 160.01 95.00 163.92 105.15 C 166.64 111.30 174.17 111.97 179.92 113.32 C 181.38 124.18 182.83 135.23 181.39 146.17 C 180.97 152.89 180.71 159.65 179.32 166.26 C 177.00 178.43 170.86 189.57 163.22 199.21 C 157.16 206.91 149.40 213.36 140.51 217.55 C 132.41 221.54 123.08 221.88 114.27 220.71 C 98.40 217.89 83.85 208.47 74.98 194.98 C 62.88 176.43 58.20 153.97 57.69 132.08 C 57.41 126.21 55.89 119.99 58.27 114.36 C 62.24 111.72 68.38 111.44 70.29 106.40 C 72.31 98.72 71.38 89.39 65.30 83.71 C 62.86 81.59 59.61 79.64 56.26 80.21 C 46.26 83.40 39.48 95.09 42.77 105.29 Z" />
</g>
<g id="#ffffffff">
<path fill="#ffffff" opacity="1.00" d=" M 42.77 105.29 C 39.48 95.09 46.26 83.40 56.26 80.21 C 59.61 79.64 62.86 81.59 65.30 83.71 C 71.38 89.39 72.31 98.72 70.29 106.40 C 68.38 111.44 62.24 111.72 58.27 114.36 C 55.89 119.99 57.41 126.21 57.69 132.08 C 58.20 153.97 62.88 176.43 74.98 194.98 C 83.85 208.47 98.40 217.89 114.27 220.71 C 123.08 221.88 132.41 221.54 140.51 217.55 C 149.40 213.36 157.16 206.91 163.22 199.21 C 170.86 189.57 177.00 178.43 179.32 166.26 C 180.71 159.65 180.97 152.89 181.39 146.17 C 182.83 135.23 181.38 124.18 179.92 113.32 C 174.17 111.97 166.64 111.30 163.92 105.15 C 160.01 95.00 167.55 83.53 177.26 80.22 C 183.11 79.74 188.53 83.52 192.31 87.69 C 196.26 91.81 196.92 98.11 195.29 103.39 C 194.13 107.04 190.81 109.27 188.46 112.10 C 187.23 113.40 187.87 115.36 187.81 116.95 C 189.98 135.40 189.47 154.27 185.33 172.41 C 183.08 182.26 178.12 191.22 172.39 199.45 C 164.43 210.79 153.66 220.68 140.43 225.37 C 131.76 228.78 122.24 228.26 113.12 227.72 C 96.01 225.01 80.03 215.17 70.13 200.92 C 60.27 187.36 55.11 171.01 52.49 154.60 C 50.80 146.14 51.12 137.49 50.37 128.93 C 49.93 124.08 50.80 119.13 49.75 114.36 C 47.48 111.29 43.87 109.13 42.77 105.29 Z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="124px" height="124px" viewBox="0 0 124 124" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.8.1 (29687) - http://www.bohemiancoding.com/sketch -->
<title>Page 1</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard-1" transform="translate(-13.000000, -14.000000)">
<g id="Page-1" transform="translate(15.000000, 15.000000)">
<polygon id="Fill-1" fill="#000000" points="63.4941 53.9491 63.4941 97.0171 55.0341 97.0171 55.0341 50.9491"></polygon>
<g id="Group-6" transform="translate(0.000000, 0.831000)">
<path d="M31.04,49.3213 C30.704,38.0813 36.636,32.3493 44.356,32.3493 C49.057,32.3493 52.638,33.8103 60.247,37.4073 C65.843,40.1043 69.983,42.1283 74.124,42.1283 C78.153,42.1283 80.056,38.8683 80.167,32.6863 L86.77,32.6863 C87.329,45.1633 80.95,49.6593 74.013,49.6593 C69.536,49.6593 65.507,48.3113 57.786,44.7143 C52.526,42.1283 48.386,39.7683 44.356,39.7683 C40.328,39.7683 37.866,42.5783 37.754,49.3213 L31.04,49.3213 Z" id="Fill-2" fill="#000000"></path>
<path d="M119.83,60.0849 C119.83,93.1749 93.007,119.9999 59.915,119.9999 C26.825,119.9999 0,93.1749 0,60.0849 C0,26.9939 26.825,0.1689 59.915,0.1689 C93.007,0.1689 119.83,26.9939 119.83,60.0849 L119.83,60.0849 Z" id="Stroke-4" stroke="#000000" stroke-width="4"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -0,0 +1 @@
<svg viewBox="0 0 279 96" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path d="m229.76 0c27.19 0 49.24 21.49 49.24 48 0 26.51-22.04 48-49.24 48-22.903 0-42.15-15.245-47.656-35.895l4.365 2.763 2.264-3.398c5.108 17.397 21.543 30.13 41.03 30.13 23.566 0 42.671-18.625 42.671-41.6 0-22.975-19.1-41.6-42.671-41.6-2.02 0-4 .136-5.944.4l4.126-6.195-.847-.536c.882-.046 1.771-.069 2.664-.069" fill="#BF3078"/><path d="m180.53 0h49.24l-65.65 96-24.618-36-24.618 36-24.895-36.406 3.893-5.845 21 30.713 19.16-28.01 5.462-7.988 5.462 7.988 19.16 28.01 53.38-78.06h-36.969-55.11l4.263-6.4h50.845" fill="#802050"/><path d="m65.65 96l-65.65-96h131.29l-65.65 96m0-11.538l53.38-78.06h-106.76l53.38 78.06" fill="#26134D"/></g></svg>

After

Width:  |  Height:  |  Size: 740 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

@ -18,6 +18,7 @@ class Wappalyzer {
this.apps = {}; this.apps = {};
this.categories = {}; this.categories = {};
this.driver = {}; this.driver = {};
this.jsPatterns = {};
this.detected = {}; this.detected = {};
this.hostnameCache = {}; this.hostnameCache = {};
@ -37,28 +38,28 @@ class Wappalyzer {
this.driver.log(message, source || '', type || 'debug'); this.driver.log(message, source || '', type || 'debug');
} }
analyze(hostname, url, data, context) { analyze(url, data, context) {
var apps = {}; var apps = {};
// Remove hash from URL
data.url = url = url.split('#')[0];
if ( typeof data.html !== 'string' ) { if ( typeof data.html !== 'string' ) {
data.html = ''; data.html = '';
} }
if ( this.detected[url] === undefined ) { if ( this.detected[url.canonical] === undefined ) {
this.detected[url] = {}; this.detected[url.canonical] = {};
} }
// Additional information
const matches = data.html.match(/<html[^>]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i);
const language = matches && matches.length ? matches[1] : null;
Object.keys(this.apps).forEach(appName => { Object.keys(this.apps).forEach(appName => {
apps[appName] = this.detected[url] && this.detected[url][appName] ? this.detected[url][appName] : new Application(appName, this.apps[appName]); apps[appName] = this.detected[url.canonical] && this.detected[url.canonical][appName] ? this.detected[url.canonical][appName] : new Application(appName, this.apps[appName]);
var app = apps[appName]; var app = apps[appName];
if ( url ) { this.analyzeUrl(app, url);
this.analyzeUrl(app, url);
}
if ( data.html ) { if ( data.html ) {
this.analyzeHtml(app, data.html); this.analyzeHtml(app, data.html);
@ -82,6 +83,12 @@ class Wappalyzer {
} }
}) })
if ( data.js ) {
Object.keys(data.js).forEach(appName => {
this.analyzeJs(apps[appName], data.js[appName]);
});
}
Object.keys(apps).forEach(appName => { Object.keys(apps).forEach(appName => {
var app = apps[appName]; var app = apps[appName];
@ -91,16 +98,16 @@ class Wappalyzer {
}); });
this.resolveExcludes(apps); this.resolveExcludes(apps);
this.resolveImplies(apps, url); this.resolveImplies(apps, url.canonical);
this.cacheDetectedApps(apps, url); this.cacheDetectedApps(apps, url.canonical);
this.trackDetectedApps(apps, url, hostname, data.html); this.trackDetectedApps(apps, url, language);
if ( Object.keys(apps).length ) { if ( Object.keys(apps).length ) {
this.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url, 'core'); this.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url.canonical, 'core');
} }
this.driver.displayApps(this.detected[url], context); this.driver.displayApps(this.detected[url.canonical], { language }, context);
} }
/** /**
@ -117,11 +124,17 @@ class Wappalyzer {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var parsed = this.parseUrl(url); var parsed = this.parseUrl(url);
if ( parsed.protocol !== 'http:' && parsed.protocol !== 'https:' ) {
return reject();
}
this.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:') this.driver.getRobotsTxt(parsed.host, parsed.protocol === 'https:')
.then(robotsTxt => { .then(robotsTxt => {
robotsTxt.forEach(disallow => parsed.pathname.indexOf(disallow) === 0 && reject()); if (robotsTxt.some(disallowedPath => parsed.pathname.indexOf(disallowedPath) === 0)) {
return reject();
resolve(); } else {
return resolve();
}
}); });
}); });
}; };
@ -169,7 +182,7 @@ class Wappalyzer {
* *
*/ */
ping() { ping() {
if ( Object.keys(this.hostnameCache).length + this.adCache.length > 200 ) { if ( Object.keys(this.hostnameCache).length + this.adCache.length > 50 ) {
this.driver.ping(this.hostnameCache, this.adCache); this.driver.ping(this.hostnameCache, this.adCache);
this.hostnameCache = {}; this.hostnameCache = {};
@ -240,6 +253,17 @@ class Wappalyzer {
return parsed; return parsed;
} }
/**
* Parse JavaScript patterns
*/
parseJsPatterns() {
Object.keys(this.apps).forEach(appName => {
if ( this.apps[appName].js ) {
this.jsPatterns[appName] = this.parsePatterns(this.apps[appName].js);
}
});
}
resolveExcludes(apps) { resolveExcludes(apps) {
var excludes = []; var excludes = [];
@ -322,49 +346,42 @@ class Wappalyzer {
/** /**
* Track detected applications * Track detected applications
*/ */
trackDetectedApps(apps, url, hostname, html) { trackDetectedApps(apps, url, language) {
if ( !( this.driver.ping instanceof Function ) ) { if ( !( this.driver.ping instanceof Function ) ) {
return; return;
} }
Object.keys(apps).forEach(appName => { const hostname = url.protocol + '//' + url.hostname;
var app = apps[appName];
if ( this.detected[url][appName].getConfidence() >= 100 ) { Object.keys(apps).forEach(appName => {
if ( validation.hostname.test(hostname) && !validation.hostnameBlacklist.test(url) ) { const app = apps[appName];
this.robotsTxtAllows(url)
.then(() => { if ( this.detected[url.canonical][appName].getConfidence() >= 100 ) {
if ( !( hostname in this.hostnameCache ) ) { if ( validation.hostname.test(url.hostname) && !validation.hostnameBlacklist.test(url.hostname) ) {
this.hostnameCache[hostname] = { if ( !( hostname in this.hostnameCache ) ) {
applications: {}, this.hostnameCache[hostname] = {
meta: {} applications: {},
}; meta: {}
} };
}
if ( !( appName in this.hostnameCache[hostname].applications ) ) { if ( !( appName in this.hostnameCache[hostname].applications ) ) {
this.hostnameCache[hostname].applications[appName] = { this.hostnameCache[hostname].applications[appName] = {
hits: 0 hits: 0
}; };
} }
this.hostnameCache[hostname].applications[appName].hits ++; this.hostnameCache[hostname].applications[appName].hits ++;
if ( apps[appName].version ) { if ( apps[appName].version ) {
this.hostnameCache[hostname].applications[appName].version = app.version; this.hostnameCache[hostname].applications[appName].version = app.version;
} }
})
.catch(() => this.log('Disallowed in robots.txt: ' + url), 'core')
} }
} }
}); });
// Additional information
if ( hostname in this.hostnameCache ) { if ( hostname in this.hostnameCache ) {
var match = html.match(/<html[^>]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i); this.hostnameCache[hostname].meta['language'] = language;
if ( match && match.length ) {
this.hostnameCache[hostname].meta['language'] = match[1];
}
} }
this.ping(); this.ping();
@ -378,8 +395,8 @@ class Wappalyzer {
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
if ( pattern.regex.test(url) ) { if ( pattern.regex.test(url.canonical) ) {
this.addDetected(app, pattern, 'url', url); this.addDetected(app, pattern, 'url', url.canonical);
} }
}); });
} }
@ -425,13 +442,16 @@ class Wappalyzer {
analyzeMeta(app, html) { analyzeMeta(app, html) {
var regex = /<meta[^>]+>/ig; var regex = /<meta[^>]+>/ig;
var patterns = this.parsePatterns(app.props.meta); var patterns = this.parsePatterns(app.props.meta);
var content; var content = '';
var match; var matches = [];
while ( patterns && ( match = regex.exec(html) ) ) { while ( patterns && ( matches = regex.exec(html) ) ) {
for ( var meta in patterns ) { for ( var meta in patterns ) {
if ( new RegExp('(name|property)=["\']' + meta + '["\']', 'i').test(match) ) {
content = match.toString().match(/content=("|')([^"']+)("|')/i); const r = new RegExp('(?:name|property)=["\']' + meta + '["\']', 'i');
if ( new RegExp('(?:name|property)=["\']' + meta + '["\']', 'i').test(matches[0]) ) {
content = matches[0].match(/content=("|')([^"']+)("|')/i);
patterns[meta].forEach(pattern => { patterns[meta].forEach(pattern => {
if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { if ( content && content.length === 4 && pattern.regex.test(content[2]) ) {
@ -483,6 +503,22 @@ class Wappalyzer {
} }
} }
/**
* Analyze JavaScript variables
*/
analyzeJs(app, results) {
Object.keys(results).forEach(string => {
Object.keys(results[string]).forEach(index => {
const pattern = this.jsPatterns[app.name][string][index];
const value = results[string][index];
if ( pattern.regex.test(value) ) {
this.addDetected(app, pattern, 'js', value);
}
});
});
}
/** /**
* Analyze robots.txt * Analyze robots.txt
*/ */

@ -2,26 +2,31 @@
# yarn lockfile v1 # yarn lockfile v1
file-type@3.8.*: file-type@7.4.*:
version "3.8.0" version "7.4.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.8.0.tgz#bcadf6a8f624ebe4a10e5ad26727b6b93f16d78d" resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.4.0.tgz#2a7c94f62a0030150bb7d9b6c70cfa1d3e759c86"
html-comment-regex@^1.1.0: html-comment-regex@^1.1.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e"
is-svg@2.0.*: is-svg@2.1.*:
version "2.0.1" version "2.1.0"
resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.0.1.tgz#f93ab3bf1d6bbca30e9753cd3485b1300eebc013" resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9"
dependencies: dependencies:
html-comment-regex "^1.1.0" html-comment-regex "^1.1.0"
pify@^2.3.0: pify@^3.0.0:
version "2.3.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
read-chunk@2.0.*: read-chunk@2.1.*:
version "2.0.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.0.0.tgz#3246e877829116cec059674c4d5f300f7a9261f3" resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655"
dependencies: dependencies:
pify "^2.3.0" pify "^3.0.0"
safe-buffer "^5.1.1"
safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"