diff --git a/bin/node_modules/.yarn-integrity b/bin/node_modules/.yarn-integrity deleted file mode 100644 index eb85016ba..000000000 --- a/bin/node_modules/.yarn-integrity +++ /dev/null @@ -1,8 +0,0 @@ -{ - "flags": [], - "linkedModules": [], - "topLevelPatters": [], - "lockfileEntries": {}, - "files": [], - "artifacts": {} -} \ No newline at end of file diff --git a/bin/run b/bin/run index 4fcaccd0c..f7a29c820 100755 --- a/bin/run +++ b/bin/run @@ -3,20 +3,6 @@ cd "$(dirname $0)" if [[ -f "$1" ]]; then - yarn install - - pushd ../src/drivers/webextension - - yarn install - - popd - - pushd ../src/drivers/npm - - yarn install - - popd - ./$1 $@ else ./help diff --git a/bin/yarn.lock b/bin/yarn.lock deleted file mode 100644 index fb57ccd13..000000000 --- a/bin/yarn.lock +++ /dev/null @@ -1,4 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - diff --git a/content.js b/content.js deleted file mode 100644 index 530856a61..000000000 --- a/content.js +++ /dev/null @@ -1,147 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -/** global: browser */ - -(function () { - var c = { - init: function () { - var html = document.documentElement.outerHTML; - - c.log('Function call: init()'); - - if (html.length > 50000) { - html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); - } - - browser.runtime.sendMessage({ - id: 'analyze', - subject: { html: html }, - source: 'content.js' - }); - - c.getEnvironmentVars(); - }, - - log: function (message) { - browser.runtime.sendMessage({ - id: 'log', - message: message, - source: 'content.js' - }); - }, - - getEnvironmentVars: function () { - var container, script; - - c.log('Function call: getEnvironmentVars()'); - - if (typeof document.body === 'undefined') { - return; - } - - try { - container = document.createElement('wappalyzerData'); - - container.setAttribute('id', 'wappalyzerData'); - container.setAttribute('style', 'display: none'); - - script = document.createElement('script'); - - script.setAttribute('id', 'wappalyzerEnvDetection'); - script.setAttribute('src', browser.extension.getURL('js/inject.js')); - - container.addEventListener('wappalyzerEvent', function (event) { - var environmentVars = event.target.childNodes[0].nodeValue; - - document.documentElement.removeChild(container); - document.documentElement.removeChild(script); - - environmentVars = environmentVars.split(' ').slice(0, 500); - - browser.runtime.sendMessage({ - id: 'analyze', - subject: { env: environmentVars }, - source: 'content.js' - }); - }, true); - - document.documentElement.appendChild(container); - document.documentElement.appendChild(script); - } catch (e) { - c.log('Error: ' + e); - } - } - }; - - c.init(); -})(); - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/driver.js b/driver.js deleted file mode 100644 index 5e0d60808..000000000 --- a/driver.js +++ /dev/null @@ -1,1853 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 3); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1,eval)("this"); -} catch(e) { - // This works if the window reference is available - if(typeof window === "object") - g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/*global window, global*/ -var util = __webpack_require__(2) -var assert = __webpack_require__(7) -var now = __webpack_require__(8) - -var slice = Array.prototype.slice -var console -var times = {} - -if (typeof global !== "undefined" && global.console) { - console = global.console -} else if (typeof window !== "undefined" && window.console) { - console = window.console -} else { - console = {} -} - -var functions = [ - [log, "log"], - [info, "info"], - [warn, "warn"], - [error, "error"], - [time, "time"], - [timeEnd, "timeEnd"], - [trace, "trace"], - [dir, "dir"], - [consoleAssert, "assert"] -] - -for (var i = 0; i < functions.length; i++) { - var tuple = functions[i] - var f = tuple[0] - var name = tuple[1] - - if (!console[name]) { - console[name] = f - } -} - -module.exports = console - -function log() {} - -function info() { - console.log.apply(console, arguments) -} - -function warn() { - console.log.apply(console, arguments) -} - -function error() { - console.warn.apply(console, arguments) -} - -function time(label) { - times[label] = now() -} - -function timeEnd(label) { - var time = times[label] - if (!time) { - throw new Error("No such label: " + label) - } - - var duration = now() - time - console.log(label + ": " + duration + "ms") -} - -function trace() { - var err = new Error() - err.name = "Trace" - err.message = util.format.apply(null, arguments) - console.error(err.stack) -} - -function dir(object) { - console.log(util.inspect(object) + "\n") -} - -function consoleAssert(expression) { - if (!expression) { - var arr = slice.call(arguments, 1) - assert.ok(false, util.format.apply(null, arr)) - } -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global, process, console) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = __webpack_require__(5); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = __webpack_require__(6); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0), __webpack_require__(4), __webpack_require__(1))) - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(console) {/** - * WebExtension driver - */ - -/** global: browser */ -/** global: chrome */ -/** global: wappalyzer */ -/** global: XMLHttpRequest */ - -(function () { - if (wappalyzer == null) { - return; - } - - var w = wappalyzer, - firstRun = false, - upgraded = false, - tab, - tabCache = {}, - headersCache = {}; - - w.driver = { - timeout: 1000, - - /** - * Log messages to console - */ - log: function (args) { - console.log('[wappalyzer ' + args.type + ']', '[' + args.source + ']', JSON.parse(args.message)); - }, - - /** - * Get a value from localStorage - */ - getOption: function (name, defaultValue, callback) { - var func = function (item) { - callback(item.hasOwnProperty(name) ? item[name] : defaultValue); - }; - - try { - // Chrome, Firefox - browser.storage.local.get(name).then(func); - } catch (e) { - // Edge - browser.storage.local.get(name, func); - } - }, - - /** - * Set a value in localStorage - */ - setOption: function (name, value) { - var option = {}; - - option[name] = value; - - browser.storage.local.set(option); - }, - - /** - * Initialize - */ - init: function () { - w.log('Function call: w.driver.init()', 'driver'); - - // Load apps.json - var xhr = new XMLHttpRequest(); - - xhr.open('GET', 'apps.json', true); - - xhr.overrideMimeType('application/json'); - - xhr.onload = function () { - var json = JSON.parse(xhr.responseText); - - w.categories = json.categories; - w.apps = json.apps; - - w.driver.categoryOrder = Object.keys(w.categories).sort(function (a, b) { - return w.categories[a].priority - w.categories[b].priority; - }); - }; - - xhr.send(null); - - // Version check - try { - var version = browser.runtime.getManifest().version; - - w.driver.getOption('version', null, function (previousVersion) { - if (previousVersion === null) { - w.driver.goToURL({ - url: w.config.websiteURL + 'installed' - }); - } else if (version !== previousVersion) { - w.driver.getOption('upgradeMessage', true, function (upgradeMessage) { - if (upgradeMessage) { - w.driver.goToURL({ - url: w.config.websiteURL + 'upgraded', - background: true - }); - } - }); - } - - w.driver.setOption('version', version); - }); - } catch (e) { - // Do nothing - } - - (chrome || browser).runtime.onMessage.addListener(w.driver.onMessage); - - var callback = function (tabs) { - tabs.forEach(function (tab) { - if (tab.url.match(/^https?:\/\//)) { - browser.tabs.executeScript(tab.id, { file: 'js/content.js' }); - } - }); - }; - - try { - browser.tabs.query({}).then(callback); - } catch (e) { - browser.tabs.query({}, callback); - } - - browser.tabs.onRemoved.addListener(function (tabId) { - tabCache[tabId] = null; - }); - - // Live intercept headers using webRequest API - browser.webRequest.onCompleted.addListener(function (details) { - var responseHeaders = {}; - - if (details.responseHeaders) { - var uri = details.url.replace(/#.*$/, ''); // Remove hash - - details.responseHeaders.forEach(function (header) { - responseHeaders[header.name.toLowerCase()] = header.value || '' + header.binaryValue; - }); - - if (headersCache.length > 50) { - headersCache = {}; - } - - if (/text\/html/.test(responseHeaders['content-type'])) { - if (headersCache[uri] === undefined) { - headersCache[uri] = {}; - } - - for (var header in responseHeaders) { - if (responseHeaders.hasOwnProperty(header)) { - headersCache[uri][header] = responseHeaders[header]; - } - } - } - } - }, { urls: ['http://*/*', 'https://*/*'], types: ['main_frame'] }, ['responseHeaders']); - - if (firstRun) { - w.driver.goToURL({ url: w.config.websiteURL + 'installed', medium: 'install' }); - - firstRun = false; - } - - if (upgraded) { - w.driver.goToURL({ url: w.config.websiteURL + 'upgraded', medium: 'upgrade', background: true }); - - upgraded = false; - } - }, - - onMessage: function (message, sender, sendResponse) { - var hostname, - response, - a = document.createElement('a'); - - if (typeof message.id != 'undefined') { - if (message.id !== 'log') { - w.log('Message received from ' + message.source + ': ' + message.id, 'driver'); - } - - switch (message.id) { - case 'log': - w.log(message.message, message.source); - - break; - case 'analyze': - tab = sender.tab; - - a.href = tab.url.replace(/#.*$/, ''); - - hostname = a.hostname; - - if (headersCache[a.href] !== undefined) { - message.subject.headers = headersCache[a.href]; - } - - w.analyze(hostname, a.href, message.subject); - - break; - case 'ad_log': - w.adCache.push(message.subject); - w.checkAdCache(); - break; - case 'get_apps': - response = { - tabCache: tabCache[message.tab.id], - apps: w.apps, - categories: w.categories - }; - - break; - default: - } - - sendResponse(response); - } - }, - - /** - * Open a tab - */ - goToURL: function (args) { - browser.tabs.create({ - url: args.url, - active: args.background === undefined || !args.background - }); - }, - - /** - * Display apps - */ - displayApps: function () { - var url = tab.url.replace(/#.*$/, ''), - count = w.detected[url] ? Object.keys(w.detected[url]).length.toString() : '0'; - - if (tabCache[tab.id] == null) { - tabCache[tab.id] = { - count: 0, - appsDetected: [] - }; - } - - tabCache[tab.id].count = count; - tabCache[tab.id].appsDetected = w.detected[url]; - - if (count > 0) { - w.driver.getOption('dynamicIcon', true, function (dynamicIcon) { - var appName, - found = false; - - // Find the main application to display - w.driver.categoryOrder.forEach(function (match) { - for (appName in w.detected[url]) { - w.apps[appName].cats.forEach(function (cat) { - var icon = w.apps[appName].icon || 'default.svg'; - - if (!dynamicIcon) { - icon = 'default.svg'; - } - - if (cat === match && !found) { - if (/\.svg$/i.test(icon)) { - icon = 'converted/' + icon.replace(/\.svg$/, '.png'); - } - - browser.pageAction.setIcon({ - tabId: tab.id, - path: 'images/icons/' + icon - }); - - 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); - } - }); - }; - }, - - /** - * Anonymously track detected applications for research purposes - */ - ping: function () { - w.driver.getOption('tracking', true, function (tracking) { - if (Object.keys(w.ping.hostnames).length && tracking) { - w.driver.post('http://ping.wappalyzer.com/v2/', w.ping); - - w.ping = { hostnames: {} }; - - w.driver.post('https://ad.wappalyzer.com/log/wp/', w.adCache); - - w.adCache = []; - } - }); - }, - - /** - * Make POST request - */ - post: function (url, data) { - var xhr = new XMLHttpRequest(); - - xhr.open('POST', url, true); - - xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - w.log({ 'POST request': { url: url, status: xhr.status, data: data } }, 'driver'); - } - }; - - xhr.send('json=' + encodeURIComponent(JSON.stringify(data))); - } - }; - - w.init(); -})(); -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) - -/***/ }), -/* 4 */ -/***/ (function(module, exports) { - -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global) { - -// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js -// original notice: - -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -function compare(a, b) { - if (a === b) { - return 0; - } - - var x = a.length; - var y = b.length; - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i]; - y = b[i]; - break; - } - } - - if (x < y) { - return -1; - } - if (y < x) { - return 1; - } - return 0; -} -function isBuffer(b) { - if (global.Buffer && typeof global.Buffer.isBuffer === 'function') { - return global.Buffer.isBuffer(b); - } - return !!(b != null && b._isBuffer); -} - -// based on node assert, original notice: - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -var util = __webpack_require__(2); -var hasOwn = Object.prototype.hasOwnProperty; -var pSlice = Array.prototype.slice; -var functionsHaveNames = (function () { - return function foo() {}.name === 'foo'; -}()); -function pToString (obj) { - return Object.prototype.toString.call(obj); -} -function isView(arrbuf) { - if (isBuffer(arrbuf)) { - return false; - } - if (typeof global.ArrayBuffer !== 'function') { - return false; - } - if (typeof ArrayBuffer.isView === 'function') { - return ArrayBuffer.isView(arrbuf); - } - if (!arrbuf) { - return false; - } - if (arrbuf instanceof DataView) { - return true; - } - if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) { - return true; - } - return false; -} -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -var regex = /\s*function\s+([^\(\s]*)\s*/; -// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js -function getName(func) { - if (!util.isFunction(func)) { - return; - } - if (functionsHaveNames) { - return func.name; - } - var str = func.toString(); - var match = str.match(regex); - return match && match[1]; -} -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = getName(stackStartFunction); - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function truncate(s, n) { - if (typeof s === 'string') { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} -function inspect(something) { - if (functionsHaveNames || !util.isFunction(something)) { - return util.inspect(something); - } - var rawname = getName(something); - var name = rawname ? ': ' + rawname : ''; - return '[Function' + name + ']'; -} -function getMessage(self) { - return truncate(inspect(self.actual), 128) + ' ' + - self.operator + ' ' + - truncate(inspect(self.expected), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); - } -}; - -function _deepEqual(actual, expected, strict, memos) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - } else if (isBuffer(actual) && isBuffer(expected)) { - return compare(actual, expected) === 0; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if ((actual === null || typeof actual !== 'object') && - (expected === null || typeof expected !== 'object')) { - return strict ? actual === expected : actual == expected; - - // If both values are instances of typed arrays, wrap their underlying - // ArrayBuffers in a Buffer each to increase performance - // This optimization requires the arrays to have the same type as checked by - // Object.prototype.toString (aka pToString). Never perform binary - // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their - // bit patterns are not identical. - } else if (isView(actual) && isView(expected) && - pToString(actual) === pToString(expected) && - !(actual instanceof Float32Array || - actual instanceof Float64Array)) { - return compare(new Uint8Array(actual.buffer), - new Uint8Array(expected.buffer)) === 0; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else if (isBuffer(actual) !== isBuffer(expected)) { - return false; - } else { - memos = memos || {actual: [], expected: []}; - - var actualIndex = memos.actual.indexOf(actual); - if (actualIndex !== -1) { - if (actualIndex === memos.expected.indexOf(expected)) { - return true; - } - } - - memos.actual.push(actual); - memos.expected.push(expected); - - return objEquiv(actual, expected, strict, memos); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b, strict, actualVisitedObjects) { - if (a === null || a === undefined || b === null || b === undefined) - return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) - return a === b; - if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) - return false; - var aIsArgs = isArguments(a); - var bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b, strict); - } - var ka = objectKeys(a); - var kb = objectKeys(b); - var key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length !== kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] !== kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) - return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -assert.notDeepStrictEqual = notDeepStrictEqual; -function notDeepStrictEqual(actual, expected, message) { - if (_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); - } -} - - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } - - try { - if (actual instanceof expected) { - return true; - } - } catch (e) { - // Ignore. The instanceof check doesn't work for arrow functions. - } - - if (Error.isPrototypeOf(expected)) { - return false; - } - - return expected.call({}, actual) === true; -} - -function _tryBlock(block) { - var error; - try { - block(); - } catch (e) { - error = e; - } - return error; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (typeof block !== 'function') { - throw new TypeError('"block" argument must be a function'); - } - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - actual = _tryBlock(block); - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - var userProvidedMessage = typeof message === 'string'; - var isUnwantedException = !shouldThrow && util.isError(actual); - var isUnexpectedException = !shouldThrow && actual && !expected; - - if ((isUnwantedException && - userProvidedMessage && - expectedException(actual, expected)) || - isUnexpectedException) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws(true, block, error, message); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws(false, block, error, message); -}; - -assert.ifError = function(err) { if (err) throw err; }; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) - -/***/ }), -/* 8 */ -/***/ (function(module, exports) { - -module.exports = now - -function now() { - return new Date().getTime() -} - - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/options.js b/options.js deleted file mode 100644 index 6bfdc3d20..000000000 --- a/options.js +++ /dev/null @@ -1,144 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -/** global: browser */ -/** global: wappalyzer */ - -document.addEventListener('DOMContentLoaded', function () { - var d = document; - - var options = { - init: function () { - options.load(); - - d.querySelector('#github').addEventListener('click', function () { - open(wappalyzer.config.githubURL); - }); - - d.querySelector('#twitter').addEventListener('click', function () { - open(wappalyzer.config.twitterURL); - }); - - d.querySelector('#wappalyzer').addEventListener('click', function () { - open(wappalyzer.config.websiteURL); - }); - }, - - get: function (name, defaultValue, callback) { - browser.storage.local.get(name).then(function (item) { - callback(item.hasOwnProperty(name) ? item[name] : defaultValue); - }); - }, - - set: function (name, value) { - var option = {}; - - option[name] = value; - - browser.storage.local.set(option); - }, - - load: function () { - options.get('upgradeMessage', true, function (value) { - var el = d.querySelector('#option-upgrade-message'); - - el.checked = value; - - el.addEventListener('change', function () { - options.set('upgradeMessage', el.checked); - }); - }); - - options.get('dynamicIcon', true, function (value) { - var el = d.querySelector('#option-dynamic-icon'); - - el.checked = value; - - el.addEventListener('change', function () { - options.set('dynamicIcon', el.checked); - }); - }); - - options.get('tracking', true, function (value) { - var el = d.querySelector('#option-tracking'); - - el.checked = value; - - el.addEventListener('change', function () { - options.set('tracking', el.checked); - }); - }); - } - }; - - options.init(); -}); - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/package.json b/package.json deleted file mode 100644 index b0fbe1ae9..000000000 --- a/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "devDependencies": { - "file-type": "3.8.*", - "is-svg": "2.0.*", - "read-chunk": "2.0.*", - "svg2png-many": "*", - "webpack": "^3.0.0" - }, - "scripts": { - "dev": "webpack --progress --colors --watch" - }, - "dependencies": { - "babel-preset-es2015": "^6.24.1", - "glob": "^7.1.2" - } -} diff --git a/popup.js b/popup.js deleted file mode 100644 index 0dbd18034..000000000 --- a/popup.js +++ /dev/null @@ -1,168 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { - -/** global: chrome */ -/** global: browser */ - -(function () { - var popup = { - init: function () { - popup.update(['p', {}, ' '], document, {}); - - var func = function (tabs) { - (chrome || browser).runtime.sendMessage({ id: 'get_apps', tab: tabs[0], source: 'popup.js' }, function (response) { - popup.update(popup.appsToDomTemplate(response)); - }); - }; - - try { - // Chrome, Firefox - browser.tabs.query({ active: true, currentWindow: true }).then(func); - } catch (e) { - // Edge - browser.tabs.query({ active: true, currentWindow: true }, func); - } - }, - - update: function (dom) { - if (/complete|interactive|loaded/.test(document.readyState)) { - popup.replaceDom(dom); - } else { - document.addEventListener('DOMContentLoaded', function () { - popup.replaceDom(dom); - }); - } - }, - - replaceDom: function (domTemplate) { - var body = document.body; - - while (body.firstChild) { - body.removeChild(body.firstChild); - } - - body.appendChild(jsonToDOM(domTemplate, document, {})); - }, - - appsToDomTemplate: function (response) { - var appName, - confidence, - version, - categories = [], - template = []; - - if (response.tabCache && response.tabCache.count > 0) { - for (appName in response.tabCache.appsDetected) { - confidence = response.tabCache.appsDetected[appName].confidenceTotal; - version = response.tabCache.appsDetected[appName].version; - categories = []; - - response.apps[appName].cats.forEach(function (cat) { - categories.push(['a', { - target: '_blank', - href: 'https://wappalyzer.com/categories/' + popup.slugify(response.categories[cat].name) - }, ['span', { - class: 'category' - }, ['span', { - class: 'name' - }, browser.i18n.getMessage('categoryName' + cat)]]]); - }); - - template.push(['div', { - class: 'detected-app' - }, ['a', { - target: '_blank', - href: 'https://wappalyzer.com/applications/' + popup.slugify(appName) - }, ['img', { - src: 'images/icons/' + (response.apps[appName].icon || 'default.svg') - }], ['span', { - class: 'label' - }, ['span', { - class: 'name' - }, appName], (version ? ' ' + version : '') + (confidence < 100 ? ' (' + confidence + '% sure)' : '')]], categories]); - } - } else { - template = ['div', { - class: 'empty' - }, browser.i18n.getMessage('noAppsDetected')]; - } - - return template; - }, - - slugify: function (string) { - return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, ''); - } - }; - - popup.init(); -})(); - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/run b/run index 6401121d8..23d0318be 100755 --- a/run +++ b/run @@ -8,4 +8,7 @@ if [[ -z "$(which docker)" ]]; then exit 1 fi -docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev ./bin/run $@ +cmd="docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev ./bin/run" + +$cmd links +$cmd $@ diff --git a/src/drivers/webextension/apps.json b/src/drivers/webextension/apps.json new file mode 120000 index 000000000..46333a9a3 --- /dev/null +++ b/src/drivers/webextension/apps.json @@ -0,0 +1 @@ +../../apps.json \ No newline at end of file diff --git a/src/drivers/webextension/background.html b/src/drivers/webextension/background.html deleted file mode 100644 index 2c539f038..000000000 --- a/src/drivers/webextension/background.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/drivers/webextension/html/background.html b/src/drivers/webextension/html/background.html new file mode 100644 index 000000000..1c31887fc --- /dev/null +++ b/src/drivers/webextension/html/background.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/drivers/webextension/options.html b/src/drivers/webextension/html/options.html similarity index 54% rename from src/drivers/webextension/options.html rename to src/drivers/webextension/html/options.html index 1eda50366..a856bf1f5 100644 --- a/src/drivers/webextension/options.html +++ b/src/drivers/webextension/html/options.html @@ -6,17 +6,18 @@ Wappalyzer options - + - + - - + + +
- +
@@ -32,9 +33,9 @@

- +

diff --git a/src/drivers/webextension/html/popup.html b/src/drivers/webextension/html/popup.html new file mode 100644 index 000000000..2f4e90ad2 --- /dev/null +++ b/src/drivers/webextension/html/popup.html @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/drivers/webextension/js/.gitkeep b/src/drivers/webextension/js/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/drivers/webextension/js/content.js b/src/drivers/webextension/js/content.js index c2c84e822..2255119e1 100644 --- a/src/drivers/webextension/js/content.js +++ b/src/drivers/webextension/js/content.js @@ -1,2490 +1,55 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_webextension_polyfill__ = __webpack_require__(4); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_webextension_polyfill___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_webextension_polyfill__); /** global: browser */ +if ( document.body !== undefined ) { + var html = document.documentElement.outerHTML; - -(function () { - var c = { - init: function () { - var html = document.documentElement.outerHTML; - - c.log('Function call: init()'); - - if (html.length > 50000) { - html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); - } - - __WEBPACK_IMPORTED_MODULE_0_webextension_polyfill___default.a.runtime.sendMessage({ - id: 'analyze', - subject: { html: html }, - source: 'content.js' - }); - - c.getEnvironmentVars(); - }, - - log: function (message) { - __WEBPACK_IMPORTED_MODULE_0_webextension_polyfill___default.a.runtime.sendMessage({ - id: 'log', - message: message, - source: 'content.js' - }); - }, - - getEnvironmentVars: function () { - var container, script; - - c.log('Function call: getEnvironmentVars()'); - - if (typeof document.body === 'undefined') { - return; - } - - try { - container = document.createElement('wappalyzerData'); - - container.setAttribute('id', 'wappalyzerData'); - container.setAttribute('style', 'display: none'); - - script = document.createElement('script'); - - script.setAttribute('id', 'wappalyzerEnvDetection'); - script.setAttribute('src', __WEBPACK_IMPORTED_MODULE_0_webextension_polyfill___default.a.extension.getURL('js/inject.js')); - - container.addEventListener('wappalyzerEvent', function (event) { - var environmentVars = event.target.childNodes[0].nodeValue; - - document.documentElement.removeChild(container); - document.documentElement.removeChild(script); - - environmentVars = environmentVars.split(' ').slice(0, 500); - - __WEBPACK_IMPORTED_MODULE_0_webextension_polyfill___default.a.runtime.sendMessage({ - id: 'analyze', - subject: { env: environmentVars }, - source: 'content.js' - }); - }, true); - - document.documentElement.appendChild(container); - document.documentElement.appendChild(script); - } catch (e) { - c.log('Error: ' + e); - } - } - }; - - c.init(); -})(); - -/***/ }), -/* 1 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1,eval)("this"); -} catch(e) { - // This works if the window reference is available - if(typeof window === "object") - g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/*global window, global*/ -var util = __webpack_require__(3) -var assert = __webpack_require__(8) -var now = __webpack_require__(9) - -var slice = Array.prototype.slice -var console -var times = {} - -if (typeof global !== "undefined" && global.console) { - console = global.console -} else if (typeof window !== "undefined" && window.console) { - console = window.console -} else { - console = {} -} - -var functions = [ - [log, "log"], - [info, "info"], - [warn, "warn"], - [error, "error"], - [time, "time"], - [timeEnd, "timeEnd"], - [trace, "trace"], - [dir, "dir"], - [consoleAssert, "assert"] -] - -for (var i = 0; i < functions.length; i++) { - var tuple = functions[i] - var f = tuple[0] - var name = tuple[1] - - if (!console[name]) { - console[name] = f - } -} - -module.exports = console - -function log() {} - -function info() { - console.log.apply(console, arguments) -} - -function warn() { - console.log.apply(console, arguments) -} - -function error() { - console.warn.apply(console, arguments) -} - -function time(label) { - times[label] = now() -} - -function timeEnd(label) { - var time = times[label] - if (!time) { - throw new Error("No such label: " + label) - } - - var duration = now() - time - console.log(label + ": " + duration + "ms") -} - -function trace() { - var err = new Error() - err.name = "Trace" - err.message = util.format.apply(null, arguments) - console.error(err.stack) -} - -function dir(object) { - console.log(util.inspect(object) + "\n") -} - -function consoleAssert(expression) { - if (!expression) { - var arr = slice.call(arguments, 1) - assert.ok(false, util.format.apply(null, arr)) - } -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global, process, console) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); + if ( html.length > 50000 ) { + html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length); } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; + browser.runtime.sendMessage({ + id: 'analyze', + subject: { html }, + source: 'content.js' }); - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = __webpack_require__(6); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = __webpack_require__(7); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(5), __webpack_require__(2))) - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(console) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) { - if (true) { - !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); - } else if (typeof exports !== "undefined") { - factory(module); - } else { - var mod = { - exports: {} - }; - factory(mod); - global.browser = mod.exports; - } -})(this, function (module) { - /* webextension-polyfill - v0.1.1 - Thu Apr 13 2017 13:15:15 */ - /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ - /* vim: set sts=2 sw=2 et tw=80: */ - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - "use strict"; - - if (typeof browser === "undefined") { - // Wrapping the bulk of this polyfill in a one-time-use function is a minor - // optimization for Firefox. Since Spidermonkey does not fully parse the - // contents of a function until the first time it's called, and since it will - // never actually need to be called, this allows the polyfill to be included - // in Firefox nearly for free. - const wrapAPIs = () => { - // NOTE: apiMetadata is associated to the content of the api-metadata.json file - // at build time by replacing the following "include" with the content of the - // JSON file. - const apiMetadata = { - "alarms": { - "clear": { - "minArgs": 0, - "maxArgs": 1 - }, - "clearAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "bookmarks": { - "create": { - "minArgs": 1, - "maxArgs": 1 - }, - "export": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getChildren": { - "minArgs": 1, - "maxArgs": 1 - }, - "getRecent": { - "minArgs": 1, - "maxArgs": 1 - }, - "getTree": { - "minArgs": 0, - "maxArgs": 0 - }, - "getSubTree": { - "minArgs": 1, - "maxArgs": 1 - }, - "import": { - "minArgs": 0, - "maxArgs": 0 - }, - "move": { - "minArgs": 2, - "maxArgs": 2 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeTree": { - "minArgs": 1, - "maxArgs": 1 - }, - "search": { - "minArgs": 1, - "maxArgs": 1 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - }, - "browserAction": { - "getBadgeBackgroundColor": { - "minArgs": 1, - "maxArgs": 1 - }, - "getBadgeText": { - "minArgs": 1, - "maxArgs": 1 - }, - "getPopup": { - "minArgs": 1, - "maxArgs": 1 - }, - "getTitle": { - "minArgs": 1, - "maxArgs": 1 - }, - "setIcon": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "commands": { - "getAll": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "contextMenus": { - "update": { - "minArgs": 2, - "maxArgs": 2 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeAll": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "cookies": { - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAllCookieStores": { - "minArgs": 0, - "maxArgs": 0 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "set": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "downloads": { - "download": { - "minArgs": 1, - "maxArgs": 1 - }, - "cancel": { - "minArgs": 1, - "maxArgs": 1 - }, - "erase": { - "minArgs": 1, - "maxArgs": 1 - }, - "getFileIcon": { - "minArgs": 1, - "maxArgs": 2 - }, - "open": { - "minArgs": 1, - "maxArgs": 1 - }, - "pause": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeFile": { - "minArgs": 1, - "maxArgs": 1 - }, - "resume": { - "minArgs": 1, - "maxArgs": 1 - }, - "search": { - "minArgs": 1, - "maxArgs": 1 - }, - "show": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "extension": { - "isAllowedFileSchemeAccess": { - "minArgs": 0, - "maxArgs": 0 - }, - "isAllowedIncognitoAccess": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "history": { - "addUrl": { - "minArgs": 1, - "maxArgs": 1 - }, - "getVisits": { - "minArgs": 1, - "maxArgs": 1 - }, - "deleteAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "deleteRange": { - "minArgs": 1, - "maxArgs": 1 - }, - "deleteUrl": { - "minArgs": 1, - "maxArgs": 1 - }, - "search": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "i18n": { - "detectLanguage": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAcceptLanguages": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "idle": { - "queryState": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "management": { - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "getSelf": { - "minArgs": 0, - "maxArgs": 0 - }, - "uninstallSelf": { - "minArgs": 0, - "maxArgs": 1 - } - }, - "notifications": { - "clear": { - "minArgs": 1, - "maxArgs": 1 - }, - "create": { - "minArgs": 1, - "maxArgs": 2 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 0 - }, - "getPermissionLevel": { - "minArgs": 0, - "maxArgs": 0 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - }, - "pageAction": { - "getPopup": { - "minArgs": 1, - "maxArgs": 1 - }, - "getTitle": { - "minArgs": 1, - "maxArgs": 1 - }, - "hide": { - "minArgs": 0, - "maxArgs": 0 - }, - "setIcon": { - "minArgs": 1, - "maxArgs": 1 - }, - "show": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "runtime": { - "getBackgroundPage": { - "minArgs": 0, - "maxArgs": 0 - }, - "getBrowserInfo": { - "minArgs": 0, - "maxArgs": 0 - }, - "getPlatformInfo": { - "minArgs": 0, - "maxArgs": 0 - }, - "openOptionsPage": { - "minArgs": 0, - "maxArgs": 0 - }, - "requestUpdateCheck": { - "minArgs": 0, - "maxArgs": 0 - }, - "sendMessage": { - "minArgs": 1, - "maxArgs": 3 - }, - "sendNativeMessage": { - "minArgs": 2, - "maxArgs": 2 - }, - "setUninstallURL": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "storage": { - "local": { - "clear": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getBytesInUse": { - "minArgs": 0, - "maxArgs": 1 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "set": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "managed": { - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getBytesInUse": { - "minArgs": 0, - "maxArgs": 1 - } - }, - "sync": { - "clear": { - "minArgs": 0, - "maxArgs": 0 - }, - "get": { - "minArgs": 0, - "maxArgs": 1 - }, - "getBytesInUse": { - "minArgs": 0, - "maxArgs": 1 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "set": { - "minArgs": 1, - "maxArgs": 1 - } - } - }, - "tabs": { - "create": { - "minArgs": 1, - "maxArgs": 1 - }, - "captureVisibleTab": { - "minArgs": 0, - "maxArgs": 2 - }, - "detectLanguage": { - "minArgs": 0, - "maxArgs": 1 - }, - "duplicate": { - "minArgs": 1, - "maxArgs": 1 - }, - "executeScript": { - "minArgs": 1, - "maxArgs": 2 - }, - "get": { - "minArgs": 1, - "maxArgs": 1 - }, - "getCurrent": { - "minArgs": 0, - "maxArgs": 0 - }, - "getZoom": { - "minArgs": 0, - "maxArgs": 1 - }, - "getZoomSettings": { - "minArgs": 0, - "maxArgs": 1 - }, - "highlight": { - "minArgs": 1, - "maxArgs": 1 - }, - "insertCSS": { - "minArgs": 1, - "maxArgs": 2 - }, - "move": { - "minArgs": 2, - "maxArgs": 2 - }, - "reload": { - "minArgs": 0, - "maxArgs": 2 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "query": { - "minArgs": 1, - "maxArgs": 1 - }, - "removeCSS": { - "minArgs": 1, - "maxArgs": 2 - }, - "sendMessage": { - "minArgs": 2, - "maxArgs": 3 - }, - "setZoom": { - "minArgs": 1, - "maxArgs": 2 - }, - "setZoomSettings": { - "minArgs": 1, - "maxArgs": 2 - }, - "update": { - "minArgs": 1, - "maxArgs": 2 - } - }, - "webNavigation": { - "getAllFrames": { - "minArgs": 1, - "maxArgs": 1 - }, - "getFrame": { - "minArgs": 1, - "maxArgs": 1 - } - }, - "webRequest": { - "handlerBehaviorChanged": { - "minArgs": 0, - "maxArgs": 0 - } - }, - "windows": { - "create": { - "minArgs": 0, - "maxArgs": 1 - }, - "get": { - "minArgs": 1, - "maxArgs": 2 - }, - "getAll": { - "minArgs": 0, - "maxArgs": 1 - }, - "getCurrent": { - "minArgs": 0, - "maxArgs": 1 - }, - "getLastFocused": { - "minArgs": 0, - "maxArgs": 1 - }, - "remove": { - "minArgs": 1, - "maxArgs": 1 - }, - "update": { - "minArgs": 2, - "maxArgs": 2 - } - } - }; - - if (Object.keys(apiMetadata).length === 0) { - throw new Error("api-metadata.json has not been included in browser-polyfill"); - } - - /** - * A WeakMap subclass which creates and stores a value for any key which does - * not exist when accessed, but behaves exactly as an ordinary WeakMap - * otherwise. - * - * @param {function} createItem - * A function which will be called in order to create the value for any - * key which does not exist, the first time it is accessed. The - * function receives, as its only argument, the key being created. - */ - class DefaultWeakMap extends WeakMap { - constructor(createItem, items = undefined) { - super(items); - this.createItem = createItem; - } - - get(key) { - if (!this.has(key)) { - this.set(key, this.createItem(key)); - } - - return super.get(key); - } - } - - /** - * Returns true if the given object is an object with a `then` method, and can - * therefore be assumed to behave as a Promise. - * - * @param {*} value The value to test. - * @returns {boolean} True if the value is thenable. - */ - const isThenable = value => { - return value && typeof value === "object" && typeof value.then === "function"; - }; - - /** - * Creates and returns a function which, when called, will resolve or reject - * the given promise based on how it is called: - * - * - If, when called, `chrome.runtime.lastError` contains a non-null object, - * the promise is rejected with that value. - * - If the function is called with exactly one argument, the promise is - * resolved to that value. - * - Otherwise, the promise is resolved to an array containing all of the - * function's arguments. - * - * @param {object} promise - * An object containing the resolution and rejection functions of a - * promise. - * @param {function} promise.resolve - * The promise's resolution function. - * @param {function} promise.rejection - * The promise's rejection function. - * - * @returns {function} - * The generated callback function. - */ - const makeCallback = promise => { - return (...callbackArgs) => { - if (chrome.runtime.lastError) { - promise.reject(chrome.runtime.lastError); - } else if (callbackArgs.length === 1) { - promise.resolve(callbackArgs[0]); - } else { - promise.resolve(callbackArgs); - } - }; - }; - - /** - * Creates a wrapper function for a method with the given name and metadata. - * - * @param {string} name - * The name of the method which is being wrapped. - * @param {object} metadata - * Metadata about the method being wrapped. - * @param {integer} metadata.minArgs - * The minimum number of arguments which must be passed to the - * function. If called with fewer than this number of arguments, the - * wrapper will raise an exception. - * @param {integer} metadata.maxArgs - * The maximum number of arguments which may be passed to the - * function. If called with more than this number of arguments, the - * wrapper will raise an exception. - * - * @returns {function(object, ...*)} - * The generated wrapper function. - */ - const wrapAsyncFunction = (name, metadata) => { - const pluralizeArguments = numArgs => numArgs == 1 ? "argument" : "arguments"; - - return function asyncFunctionWrapper(target, ...args) { - if (args.length < metadata.minArgs) { - throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`); - } - - if (args.length > metadata.maxArgs) { - throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`); - } - - return new Promise((resolve, reject) => { - target[name](...args, makeCallback({ resolve, reject })); - }); - }; - }; - - /** - * Wraps an existing method of the target object, so that calls to it are - * intercepted by the given wrapper function. The wrapper function receives, - * as its first argument, the original `target` object, followed by each of - * the arguments passed to the orginal method. - * - * @param {object} target - * The original target object that the wrapped method belongs to. - * @param {function} method - * The method being wrapped. This is used as the target of the Proxy - * object which is created to wrap the method. - * @param {function} wrapper - * The wrapper function which is called in place of a direct invocation - * of the wrapped method. - * - * @returns {Proxy} - * A Proxy object for the given method, which invokes the given wrapper - * method in its place. - */ - const wrapMethod = (target, method, wrapper) => { - return new Proxy(method, { - apply(targetMethod, thisObj, args) { - return wrapper.call(thisObj, target, ...args); - } - }); - }; - - let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty); - - /** - * Wraps an object in a Proxy which intercepts and wraps certain methods - * based on the given `wrappers` and `metadata` objects. - * - * @param {object} target - * The target object to wrap. - * - * @param {object} [wrappers = {}] - * An object tree containing wrapper functions for special cases. Any - * function present in this object tree is called in place of the - * method in the same location in the `target` object tree. These - * wrapper methods are invoked as described in {@see wrapMethod}. - * - * @param {object} [metadata = {}] - * An object tree containing metadata used to automatically generate - * Promise-based wrapper functions for asynchronous. Any function in - * the `target` object tree which has a corresponding metadata object - * in the same location in the `metadata` tree is replaced with an - * automatically-generated wrapper function, as described in - * {@see wrapAsyncFunction} - * - * @returns {Proxy} - */ - const wrapObject = (target, wrappers = {}, metadata = {}) => { - let cache = Object.create(null); - - let handlers = { - has(target, prop) { - return prop in target || prop in cache; - }, - - get(target, prop, receiver) { - if (prop in cache) { - return cache[prop]; - } - - if (!(prop in target)) { - return undefined; - } - - let value = target[prop]; - - if (typeof value === "function") { - // This is a method on the underlying object. Check if we need to do - // any wrapping. - - if (typeof wrappers[prop] === "function") { - // We have a special-case wrapper for this method. - value = wrapMethod(target, target[prop], wrappers[prop]); - } else if (hasOwnProperty(metadata, prop)) { - // This is an async method that we have metadata for. Create a - // Promise wrapper for it. - let wrapper = wrapAsyncFunction(prop, metadata[prop]); - value = wrapMethod(target, target[prop], wrapper); - } else { - // This is a method that we don't know or care about. Return the - // original method, bound to the underlying object. - value = value.bind(target); - } - } else if (typeof value === "object" && value !== null && (hasOwnProperty(wrappers, prop) || hasOwnProperty(metadata, prop))) { - // This is an object that we need to do some wrapping for the children - // of. Create a sub-object wrapper for it with the appropriate child - // metadata. - value = wrapObject(value, wrappers[prop], metadata[prop]); - } else { - // We don't need to do any wrapping for this property, - // so just forward all access to the underlying object. - Object.defineProperty(cache, prop, { - configurable: true, - enumerable: true, - get() { - return target[prop]; - }, - set(value) { - target[prop] = value; - } - }); - - return value; - } - - cache[prop] = value; - return value; - }, - - set(target, prop, value, receiver) { - if (prop in cache) { - cache[prop] = value; - } else { - target[prop] = value; - } - return true; - }, - - defineProperty(target, prop, desc) { - return Reflect.defineProperty(cache, prop, desc); - }, - - deleteProperty(target, prop) { - return Reflect.deleteProperty(cache, prop); - } - }; + try { + var container = document.createElement('wappalyzerData'); - return new Proxy(target, handlers); - }; + container.setAttribute('id', 'wappalyzerData'); + container.setAttribute('style', 'display: none'); - /** - * Creates a set of wrapper functions for an event object, which handles - * wrapping of listener functions that those messages are passed. - * - * A single wrapper is created for each listener function, and stored in a - * map. Subsequent calls to `addListener`, `hasListener`, or `removeListener` - * retrieve the original wrapper, so that attempts to remove a - * previously-added listener work as expected. - * - * @param {DefaultWeakMap} wrapperMap - * A DefaultWeakMap object which will create the appropriate wrapper - * for a given listener function when one does not exist, and retrieve - * an existing one when it does. - * - * @returns {object} - */ - const wrapEvent = wrapperMap => ({ - addListener(target, listener, ...args) { - target.addListener(wrapperMap.get(listener), ...args); - }, + var script = document.createElement('script'); - hasListener(target, listener) { - return target.hasListener(wrapperMap.get(listener)); - }, + script.setAttribute('id', 'wappalyzerEnvDetection'); + script.setAttribute('src', browser.extension.getURL('js/inject.js')); - removeListener(target, listener) { - target.removeListener(wrapperMap.get(listener)); - } - }); + container.addEventListener('wappalyzerEvent', (event => { + var env = event.target.childNodes[0].nodeValue; - const onMessageWrappers = new DefaultWeakMap(listener => { - if (typeof listener !== "function") { - return listener; - } + document.documentElement.removeChild(container); + document.documentElement.removeChild(script); - /** - * Wraps a message listener function so that it may send responses based on - * its return value, rather than by returning a sentinel value and calling a - * callback. If the listener function returns a Promise, the response is - * sent when the promise either resolves or rejects. - * - * @param {*} message - * The message sent by the other end of the channel. - * @param {object} sender - * Details about the sender of the message. - * @param {function(*)} sendResponse - * A callback which, when called with an arbitrary argument, sends - * that value as a response. - * @returns {boolean} - * True if the wrapped listener returned a Promise, which will later - * yield a response. False otherwise. - */ - return function onMessage(message, sender, sendResponse) { - let result = listener(message, sender); + env = env.split(' ').slice(0, 500); - if (isThenable(result)) { - result.then(sendResponse, error => { - console.error(error); - sendResponse(error); - }); - - return true; - } else if (result !== undefined) { - sendResponse(result); - } - }; + browser.runtime.sendMessage({ + id: 'analyze', + subject: { env }, + source: 'content.js' }); + }), true); - const staticWrappers = { - runtime: { - onMessage: wrapEvent(onMessageWrappers) - } - }; - - return wrapObject(chrome, staticWrappers, apiMetadata); - }; - - // The build process adds a UMD wrapper around this file, which makes the - // `module` variable available. - module.exports = wrapAPIs(); // eslint-disable-line no-undef - } else { - module.exports = browser; // eslint-disable-line no-undef - } -}); -//# sourceMappingURL=browser-polyfill.js.map - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2))) - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} - -/***/ }), -/* 7 */ -/***/ (function(module, exports) { - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global) { - -// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js -// original notice: - -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -function compare(a, b) { - if (a === b) { - return 0; - } - - var x = a.length; - var y = b.length; - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i]; - y = b[i]; - break; - } - } - - if (x < y) { - return -1; - } - if (y < x) { - return 1; - } - return 0; -} -function isBuffer(b) { - if (global.Buffer && typeof global.Buffer.isBuffer === 'function') { - return global.Buffer.isBuffer(b); - } - return !!(b != null && b._isBuffer); -} - -// based on node assert, original notice: - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -var util = __webpack_require__(3); -var hasOwn = Object.prototype.hasOwnProperty; -var pSlice = Array.prototype.slice; -var functionsHaveNames = (function () { - return function foo() {}.name === 'foo'; -}()); -function pToString (obj) { - return Object.prototype.toString.call(obj); -} -function isView(arrbuf) { - if (isBuffer(arrbuf)) { - return false; - } - if (typeof global.ArrayBuffer !== 'function') { - return false; - } - if (typeof ArrayBuffer.isView === 'function') { - return ArrayBuffer.isView(arrbuf); - } - if (!arrbuf) { - return false; - } - if (arrbuf instanceof DataView) { - return true; - } - if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) { - return true; - } - return false; -} -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -var regex = /\s*function\s+([^\(\s]*)\s*/; -// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js -function getName(func) { - if (!util.isFunction(func)) { - return; - } - if (functionsHaveNames) { - return func.name; - } - var str = func.toString(); - var match = str.match(regex); - return match && match[1]; -} -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = getName(stackStartFunction); - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function truncate(s, n) { - if (typeof s === 'string') { - return s.length < n ? s : s.slice(0, n); - } else { - return s; + document.documentElement.appendChild(container); + document.documentElement.appendChild(script); + } catch(e) { + log('Error: ' + e); } } -function inspect(something) { - if (functionsHaveNames || !util.isFunction(something)) { - return util.inspect(something); - } - var rawname = getName(something); - var name = rawname ? ': ' + rawname : ''; - return '[Function' + name + ']'; -} -function getMessage(self) { - return truncate(inspect(self.actual), 128) + ' ' + - self.operator + ' ' + - truncate(inspect(self.expected), 128); -} -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction +function log(message) { + browser.runtime.sendMessage({ + id: 'log', + message, + source: 'content.js' }); } - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); - } -}; - -function _deepEqual(actual, expected, strict, memos) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - } else if (isBuffer(actual) && isBuffer(expected)) { - return compare(actual, expected) === 0; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if ((actual === null || typeof actual !== 'object') && - (expected === null || typeof expected !== 'object')) { - return strict ? actual === expected : actual == expected; - - // If both values are instances of typed arrays, wrap their underlying - // ArrayBuffers in a Buffer each to increase performance - // This optimization requires the arrays to have the same type as checked by - // Object.prototype.toString (aka pToString). Never perform binary - // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their - // bit patterns are not identical. - } else if (isView(actual) && isView(expected) && - pToString(actual) === pToString(expected) && - !(actual instanceof Float32Array || - actual instanceof Float64Array)) { - return compare(new Uint8Array(actual.buffer), - new Uint8Array(expected.buffer)) === 0; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else if (isBuffer(actual) !== isBuffer(expected)) { - return false; - } else { - memos = memos || {actual: [], expected: []}; - - var actualIndex = memos.actual.indexOf(actual); - if (actualIndex !== -1) { - if (actualIndex === memos.expected.indexOf(expected)) { - return true; - } - } - - memos.actual.push(actual); - memos.expected.push(expected); - - return objEquiv(actual, expected, strict, memos); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b, strict, actualVisitedObjects) { - if (a === null || a === undefined || b === null || b === undefined) - return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) - return a === b; - if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) - return false; - var aIsArgs = isArguments(a); - var bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b, strict); - } - var ka = objectKeys(a); - var kb = objectKeys(b); - var key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length !== kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] !== kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) - return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -assert.notDeepStrictEqual = notDeepStrictEqual; -function notDeepStrictEqual(actual, expected, message) { - if (_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); - } -} - - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } - - try { - if (actual instanceof expected) { - return true; - } - } catch (e) { - // Ignore. The instanceof check doesn't work for arrow functions. - } - - if (Error.isPrototypeOf(expected)) { - return false; - } - - return expected.call({}, actual) === true; -} - -function _tryBlock(block) { - var error; - try { - block(); - } catch (e) { - error = e; - } - return error; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (typeof block !== 'function') { - throw new TypeError('"block" argument must be a function'); - } - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - actual = _tryBlock(block); - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - var userProvidedMessage = typeof message === 'string'; - var isUnwantedException = !shouldThrow && util.isError(actual); - var isUnexpectedException = !shouldThrow && actual && !expected; - - if ((isUnwantedException && - userProvidedMessage && - expectedException(actual, expected)) || - isUnexpectedException) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws(true, block, error, message); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws(false, block, error, message); -}; - -assert.ifError = function(err) { if (err) throw err; }; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) - -/***/ }), -/* 9 */ -/***/ (function(module, exports) { - -module.exports = now - -function now() { - return new Date().getTime() -} - - -/***/ }) -/******/ ]); \ No newline at end of file diff --git a/src/drivers/webextension/js/driver.js b/src/drivers/webextension/js/driver.js index aee87b2cc..6bbe373fe 100644 --- a/src/drivers/webextension/js/driver.js +++ b/src/drivers/webextension/js/driver.js @@ -1,84969 +1,271 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 3); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global) {/*global window, global*/ -var util = __webpack_require__(2) -var assert = __webpack_require__(7) -var now = __webpack_require__(8) - -var slice = Array.prototype.slice -var console -var times = {} +/** + * WebExtension driver + */ -if (typeof global !== "undefined" && global.console) { - console = global.console -} else if (typeof window !== "undefined" && window.console) { - console = window.console -} else { - console = {} -} +var tabCache = {}; +var headersCache = {}; +var categoryOrder = []; -var functions = [ - [log, "log"], - [info, "info"], - [warn, "warn"], - [error, "error"], - [time, "time"], - [timeEnd, "timeEnd"], - [trace, "trace"], - [dir, "dir"], - [consoleAssert, "assert"] -] +browser.tabs.onRemoved.addListener(tabId => { + tabCache[tabId] = null; +}); -for (var i = 0; i < functions.length; i++) { - var tuple = functions[i] - var f = tuple[0] - var name = tuple[1] +/** + * Get a value from localStorage + */ +function getOption(name, defaultValue) { + return new Promise((resolve, reject) => { + const callback = item => { + resolve(item.hasOwnProperty(name) ? item[name] : defaultValue); + }; - if (!console[name]) { - console[name] = f + try { + // Chrome, Firefox + browser.storage.local.get(name) + .then(callback) + .catch(console.error); + } catch ( e ) { + // Edge + browser.storage.local.get(name, callback); } + }); } -module.exports = console - -function log() {} - -function info() { - console.log.apply(console, arguments) -} - -function warn() { - console.log.apply(console, arguments) -} - -function error() { - console.warn.apply(console, arguments) -} - -function time(label) { - times[label] = now() -} - -function timeEnd(label) { - var time = times[label] - if (!time) { - throw new Error("No such label: " + label) - } - - var duration = now() - time - console.log(label + ": " + duration + "ms") -} +/** + * Set a value in localStorage + */ +function setOption(name, value) { + var option = {}; -function trace() { - var err = new Error() - err.name = "Trace" - err.message = util.format.apply(null, arguments) - console.error(err.stack) -} + option[name] = value; -function dir(object) { - console.log(util.inspect(object) + "\n") + browser.storage.local.set(option); } -function consoleAssert(expression) { - if (!expression) { - var arr = slice.call(arguments, 1) - assert.ok(false, util.format.apply(null, arr)) - } +/** + * Open a tab + */ +function openTab(args) { + browser.tabs.create({ + url: args.url, + active: args.background === undefined || !args.background + }); } -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) - -/***/ }), -/* 1 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1,eval)("this"); -} catch(e) { - // This works if the window reference is available - if(typeof window === "object") - g = window; +/** + * Make a POST request + */ +function post(url, body) { + fetch(url, { + method: 'POST', + body + }) + .then(response => { + wappalyzer.log('POST ' + url + ': ', 'driver'); + }) + .catch(error => { + wappalyzer.log('POST ' + url + ': ' + error, 'driver', 'error'); + }); } -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -/* WEBPACK VAR INJECTION */(function(global, process, console) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } +fetch('../apps.json') + .then(response => { + return response.json(); + }) + .then(json => { + wappalyzer.apps = json.apps; + wappalyzer.categories = json.categories; - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } + categoryOrder = Object.keys(wappalyzer.categories).sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority); + }) + .catch(error => { + wappalyzer.log('GET apps.json: ' + error, 'driver', 'error'); }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } +// Version check +var version = browser.runtime.getManifest().version; - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; +getOption('version') + .then(previousVersion => { + if ( previousVersion === null ) { + openTab({ + url: wappalyzer.config.websiteURL + 'installed' + }); + } else if ( version !== previousVersion ) { + getOption('upgradeMessage', true) + .then(upgradeMessage => { + if ( upgradeMessage ) { + openTab({ + url: wappalyzer.config.websiteURL + 'upgraded', + background: true + }); + } + }); } - return fn.apply(this, arguments); - } - - return deprecated; -}; + setOption('version', version); + }); -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; +// Run content script +var callback = tabs => { + tabs.forEach(tab => { + if ( tab.url.match(/^https?:\/\//) ) { + browser.tabs.executeScript(tab.id, { + file: 'js/content.js' + }); } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' + }) }; - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; +try { + browser.tabs.query({}) + .then(callback) + .catch(console.error); +} catch ( e ) { + browser.tabs.query({}, callback); } +// Capture response headers +browser.webRequest.onCompleted.addListener(request => { + var responseHeaders = {}; -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} + if ( request.responseHeaders ) { + var uri = request.url.replace(/#.*$/, ''); // Remove hash + request.responseHeaders.forEach(header => { + responseHeaders[header.name.toLowerCase()] = header.value || '' + header.binaryValue; + }); -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); + if ( headersCache.length > 50 ) { + headersCache = {}; } - return ret; - } - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } + if ( /text\/html/.test(responseHeaders['content-type']) ) { + if ( headersCache[uri] === undefined ) { + headersCache[uri] = {}; + } - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); + Object.keys(responseHeaders).forEach(header => { + headersCache[uri][header] = responseHeaders[header]; + }); } } +}, { urls: [ 'http://*/*', 'https://*/*' ], types: [ 'main_frame' ] }, [ 'responseHeaders' ]); - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); +// Listen for messages +( chrome || browser ).runtime.onMessage.addListener((message, sender, sendResponse) => { + if ( typeof message.id != 'undefined' ) { + if ( message.id !== 'log' ) { + wappalyzer.log('Message received from ' + message.source + ': ' + message.id, 'driver'); } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - return reduceToSingleString(output, base, braces); -} + var response; + switch ( message.id ) { + case 'log': + wappalyzer.log(message.message, message.source); -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} + break; + case 'analyze': + var a = document.createElement('a'); + a.href = sender.tab.url.replace(/#.*$/, ''); -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} + if ( headersCache[a.href] !== undefined ) { + message.subject.headers = headersCache[a.href]; + } + wappalyzer.analyze(a.hostname, a.href, message.subject, { tab: sender.tab }); -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} + break; + case 'ad_log': + wappalyzer.cacheDetectedAds(message.subject); + break; + case 'get_apps': + response = { + tabCache: tabCache[message.tab.id], + apps: wappalyzer.apps, + categories: wappalyzer.categories + }; -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); + break; + default: } - } - - return name + ': ' + str; -} - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; + sendResponse(response); } +}); - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; +/** + * Log messages to console + */ +wappalyzer.driver.log = (message, source, type) => { + console.log('[wappalyzer ' + type + ']', '[' + source + ']', message); } -exports.isObject = isObject; -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; +/** + * Display apps + */ +wappalyzer.driver.displayApps = (detected, context) => { + var tab = context.tab; -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; + tabCache[tab.id] = tabCache[tab.id] || { detected: [] }; -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; + tabCache[tab.id].detected = detected; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; + if ( Object.keys(detected).length ) { + getOption('dynamicIcon', true) + .then(dynamicIcon => { + var appName, found = false; -exports.isBuffer = __webpack_require__(5); + // Find the main application to display + categoryOrder.forEach(match => { + Object.keys(detected).forEach(appName => { + var app = detected[appName]; -function objectToString(o) { - return Object.prototype.toString.call(o); -} + app.props.cats.forEach(category => { + var icon = app.icon || 'default.svg'; + if ( !dynamicIcon ) { + icon = 'default.svg'; + } -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} + if ( category === match && !found ) { + if ( /\.svg$/i.test(icon) ) { + icon = 'converted/' + icon.replace(/\.svg$/, '.png'); + } + browser.pageAction.setIcon({ + tabId: tab.id, + path: '../images/icons/' + icon + }); -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; + found = true; + } + }); + }); + }); -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); + if ( typeof chrome !== 'undefined' ) { + // Browser polyfill doesn't seem to work here + chrome.pageAction.show(tab.id); + } else { + browser.pageAction.show(tab.id); + } + }); + } } - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); -}; - - /** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. + * Anonymously track detected applications for research purposes */ -exports.inherits = __webpack_require__(6); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); +wappalyzer.driver.ping = (ping, adCache) => { + getOption('tracking', true) + .then(tracking => { + if ( tracking ) { + post('http://ping.wappalyzer.com/v2/', ping); + post('https://ad.wappalyzer.com/log/wp/', adCache); + } + }); } - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(4), __webpack_require__(0))) - -/***/ }), -/* 3 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); -/* WEBPACK VAR INJECTION */(function(console) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__wappalyzer__ = __webpack_require__(9); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill__ = __webpack_require__(11); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_webextension_polyfill__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_request__ = __webpack_require__(162); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_request___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_request__); -/** - * WebExtension driver - */ - - - - - -var tabCache = {}; -var headersCache = {}; - -__WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.tabs.onRemoved.addListener(function (tabId) { - tabCache[tabId] = null; -}); - -/** - * Get a value from localStorage - */ -function getOption(name, defaultValue, callback) { - const func = item => { - callback(item.hasOwnProperty(name) ? item[name] : defaultValue); - }; - - try { - // Chrome, Firefox - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.storage.local.get(name).then(func); - } catch (e) { - // Edge - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.storage.local.get(name, func); - } -} - -/** - * Set a value in localStorage - */ -function setOption(name, value) { - var option = {}; - - option[name] = value; - - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.storage.local.set(option); -} - -/** - * Open a tab - */ -function openTab(args) { - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.tabs.create({ - url: args.url, - active: args.background === undefined || !args.background - }); -} - -/** - * Make a POST request - */ -function post(url, body) { - __WEBPACK_IMPORTED_MODULE_2_request___default.a.post({ url, body, json: true }, (error, response) => { - __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].log('Post request: ' + (error || response.statusCode), 'driver'); - }); -} - -// -var categoryOrder = Object.keys(__WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].categories).sort(function (a, b) { - return __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].categories[a].priority - __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].categories[b].priority; -}); - -// Version check -var version = __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.runtime.getManifest().version; - -getOption('version', null, function (previousVersion) { - if (previousVersion === null) { - openTab({ - url: __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].config.websiteURL + 'installed' - }); - } else if (version !== previousVersion) { - getOption('upgradeMessage', true, function (upgradeMessage) { - if (upgradeMessage) { - openTab({ - url: __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].config.websiteURL + 'upgraded', - background: true - }); - } - }); - } - - setOption('version', version); -}); - -// Run content script -var callback = function (tabs) { - tabs.forEach(function (tab) { - if (tab.url.match(/^https?:\/\//)) { - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.tabs.executeScript(tab.id, { file: 'js/content.js' }); - } - }); -}; - -try { - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.tabs.query({}).then(callback); -} catch (e) { - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.tabs.query({}, callback); -} - -// Capture response headers -__WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.webRequest.onCompleted.addListener(request => { - var responseHeaders = {}; - - if (request.responseHeaders) { - var uri = request.url.replace(/#.*$/, ''); // Remove hash - - request.responseHeaders.forEach(header => { - responseHeaders[header.name.toLowerCase()] = header.value || '' + header.binaryValue; - }); - - if (headersCache.length > 50) { - headersCache = {}; - } - - if (/text\/html/.test(responseHeaders['content-type'])) { - if (headersCache[uri] === undefined) { - headersCache[uri] = {}; - } - - Object.keys(responseHeaders).forEach(header => { - headersCache[uri][header] = responseHeaders[header]; - }); - } - } -}, { urls: ['http://*/*', 'https://*/*'], types: ['main_frame'] }, ['responseHeaders']); - -// Listen for messages -(chrome || __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a).runtime.onMessage.addListener((message, sender, sendResponse) => { - if (typeof message.id != 'undefined') { - if (message.id !== 'log') { - __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].log('Message received from ' + message.source + ': ' + message.id, 'driver'); - } - - switch (message.id) { - case 'log': - __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].log(message.message, message.source); - - break; - case 'analyze': - var a = document.createElement('a'); - - a.href = sender.tab.url.replace(/#.*$/, ''); - - if (headersCache[a.href] !== undefined) { - message.subject.headers = headersCache[a.href]; - } - - __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].analyze(a.hostname, a.href, message.subject, { tab: sender.tab }); - - break; - case 'ad_log': - __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].cacheDetectedAds(message.subject); - - break; - case 'get_apps': - var response = { - tabCache: tabCache[message.tab.id], - apps: __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].apps, - categories: __WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].categories - }; - - break; - default: - } - - sendResponse(response); - } -}); - -/** - * Log messages to console - */ -__WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].driver.log = (message, source, type) => { - console.log('[wappalyzer ' + type + ']', '[' + source + ']', message); -}; - -/** - * Display apps - */ -__WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].driver.displayApps = (detected, context) => { - var tab = context.tab; - - tabCache[tab.id] = tabCache[tab.id] || { detected: [] }; - - tabCache[tab.id].detected = detected; - - if (Object.keys(detected).length) { - getOption('dynamicIcon', true, function (dynamicIcon) { - var appName, - found = false; - - // Find the main application to display - categoryOrder.forEach(match => { - Object.keys(detected).forEach(appName => { - var app = detected[appName]; - - app.props.cats.forEach(function (category) { - var icon = app.icon || 'default.svg'; - - if (!dynamicIcon) { - icon = 'default.svg'; - } - - if (category === match && !found) { - if (/\.svg$/i.test(icon)) { - icon = 'converted/' + icon.replace(/\.svg$/, '.png'); - } - - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.pageAction.setIcon({ - tabId: tab.id, - path: 'images/icons/' + icon - }); - - found = true; - } - }); - }); - }); - - if (typeof chrome !== 'undefined') { - // Browser polyfill doesn't seem to work here - chrome.pageAction.show(tab.id); - } else { - __WEBPACK_IMPORTED_MODULE_1_webextension_polyfill___default.a.pageAction.show(tab.id); - } - }); - }; -}; - -/** - * Anonymously track detected applications for research purposes - */ -__WEBPACK_IMPORTED_MODULE_0__wappalyzer__["a" /* default */].driver.ping = (ping, adCache) => { - getOption('tracking', true, tracking => { - if (tracking) { - post('http://ping.wappalyzer.com/v2/', ping); - post('https://ad.wappalyzer.com/log/wp/', adCache); - } - }); -}; -/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0))) - -/***/ }), -/* 4 */ -/***/ (function(module, exports) { - -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global) { - -// compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js -// original notice: - -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -function compare(a, b) { - if (a === b) { - return 0; - } - - var x = a.length; - var y = b.length; - - for (var i = 0, len = Math.min(x, y); i < len; ++i) { - if (a[i] !== b[i]) { - x = a[i]; - y = b[i]; - break; - } - } - - if (x < y) { - return -1; - } - if (y < x) { - return 1; - } - return 0; -} -function isBuffer(b) { - if (global.Buffer && typeof global.Buffer.isBuffer === 'function') { - return global.Buffer.isBuffer(b); - } - return !!(b != null && b._isBuffer); -} - -// based on node assert, original notice: - -// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 -// -// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! -// -// Originally from narwhal.js (http://narwhaljs.org) -// Copyright (c) 2009 Thomas Robinson <280north.com> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the 'Software'), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -var util = __webpack_require__(2); -var hasOwn = Object.prototype.hasOwnProperty; -var pSlice = Array.prototype.slice; -var functionsHaveNames = (function () { - return function foo() {}.name === 'foo'; -}()); -function pToString (obj) { - return Object.prototype.toString.call(obj); -} -function isView(arrbuf) { - if (isBuffer(arrbuf)) { - return false; - } - if (typeof global.ArrayBuffer !== 'function') { - return false; - } - if (typeof ArrayBuffer.isView === 'function') { - return ArrayBuffer.isView(arrbuf); - } - if (!arrbuf) { - return false; - } - if (arrbuf instanceof DataView) { - return true; - } - if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) { - return true; - } - return false; -} -// 1. The assert module provides functions that throw -// AssertionError's when particular conditions are not met. The -// assert module must conform to the following interface. - -var assert = module.exports = ok; - -// 2. The AssertionError is defined in assert. -// new assert.AssertionError({ message: message, -// actual: actual, -// expected: expected }) - -var regex = /\s*function\s+([^\(\s]*)\s*/; -// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js -function getName(func) { - if (!util.isFunction(func)) { - return; - } - if (functionsHaveNames) { - return func.name; - } - var str = func.toString(); - var match = str.match(regex); - return match && match[1]; -} -assert.AssertionError = function AssertionError(options) { - this.name = 'AssertionError'; - this.actual = options.actual; - this.expected = options.expected; - this.operator = options.operator; - if (options.message) { - this.message = options.message; - this.generatedMessage = false; - } else { - this.message = getMessage(this); - this.generatedMessage = true; - } - var stackStartFunction = options.stackStartFunction || fail; - if (Error.captureStackTrace) { - Error.captureStackTrace(this, stackStartFunction); - } else { - // non v8 browsers so we can have a stacktrace - var err = new Error(); - if (err.stack) { - var out = err.stack; - - // try to strip useless frames - var fn_name = getName(stackStartFunction); - var idx = out.indexOf('\n' + fn_name); - if (idx >= 0) { - // once we have located the function frame - // we need to strip out everything before it (and its line) - var next_line = out.indexOf('\n', idx + 1); - out = out.substring(next_line + 1); - } - - this.stack = out; - } - } -}; - -// assert.AssertionError instanceof Error -util.inherits(assert.AssertionError, Error); - -function truncate(s, n) { - if (typeof s === 'string') { - return s.length < n ? s : s.slice(0, n); - } else { - return s; - } -} -function inspect(something) { - if (functionsHaveNames || !util.isFunction(something)) { - return util.inspect(something); - } - var rawname = getName(something); - var name = rawname ? ': ' + rawname : ''; - return '[Function' + name + ']'; -} -function getMessage(self) { - return truncate(inspect(self.actual), 128) + ' ' + - self.operator + ' ' + - truncate(inspect(self.expected), 128); -} - -// At present only the three keys mentioned above are used and -// understood by the spec. Implementations or sub modules can pass -// other keys to the AssertionError's constructor - they will be -// ignored. - -// 3. All of the following functions must throw an AssertionError -// when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide -// both the actual and expected values to the assertion error for -// display purposes. - -function fail(actual, expected, message, operator, stackStartFunction) { - throw new assert.AssertionError({ - message: message, - actual: actual, - expected: expected, - operator: operator, - stackStartFunction: stackStartFunction - }); -} - -// EXTENSION! allows for well behaved errors defined elsewhere. -assert.fail = fail; - -// 4. Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - -function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); -} -assert.ok = ok; - -// 5. The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); - -assert.equal = function equal(actual, expected, message) { - if (actual != expected) fail(actual, expected, message, '==', assert.equal); -}; - -// 6. The non-equality assertion tests for whether two objects are not equal -// with != assert.notEqual(actual, expected, message_opt); - -assert.notEqual = function notEqual(actual, expected, message) { - if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); - } -}; - -// 7. The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - -assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); - } -}; - -assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); - } -}; - -function _deepEqual(actual, expected, strict, memos) { - // 7.1. All identical values are equivalent, as determined by ===. - if (actual === expected) { - return true; - } else if (isBuffer(actual) && isBuffer(expected)) { - return compare(actual, expected) === 0; - - // 7.2. If the expected value is a Date object, the actual value is - // equivalent if it is also a Date object that refers to the same time. - } else if (util.isDate(actual) && util.isDate(expected)) { - return actual.getTime() === expected.getTime(); - - // 7.3 If the expected value is a RegExp object, the actual value is - // equivalent if it is also a RegExp object with the same source and - // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). - } else if (util.isRegExp(actual) && util.isRegExp(expected)) { - return actual.source === expected.source && - actual.global === expected.global && - actual.multiline === expected.multiline && - actual.lastIndex === expected.lastIndex && - actual.ignoreCase === expected.ignoreCase; - - // 7.4. Other pairs that do not both pass typeof value == 'object', - // equivalence is determined by ==. - } else if ((actual === null || typeof actual !== 'object') && - (expected === null || typeof expected !== 'object')) { - return strict ? actual === expected : actual == expected; - - // If both values are instances of typed arrays, wrap their underlying - // ArrayBuffers in a Buffer each to increase performance - // This optimization requires the arrays to have the same type as checked by - // Object.prototype.toString (aka pToString). Never perform binary - // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their - // bit patterns are not identical. - } else if (isView(actual) && isView(expected) && - pToString(actual) === pToString(expected) && - !(actual instanceof Float32Array || - actual instanceof Float64Array)) { - return compare(new Uint8Array(actual.buffer), - new Uint8Array(expected.buffer)) === 0; - - // 7.5 For all other Object pairs, including Array objects, equivalence is - // determined by having the same number of owned properties (as verified - // with Object.prototype.hasOwnProperty.call), the same set of keys - // (although not necessarily the same order), equivalent values for every - // corresponding key, and an identical 'prototype' property. Note: this - // accounts for both named and indexed properties on Arrays. - } else if (isBuffer(actual) !== isBuffer(expected)) { - return false; - } else { - memos = memos || {actual: [], expected: []}; - - var actualIndex = memos.actual.indexOf(actual); - if (actualIndex !== -1) { - if (actualIndex === memos.expected.indexOf(expected)) { - return true; - } - } - - memos.actual.push(actual); - memos.expected.push(expected); - - return objEquiv(actual, expected, strict, memos); - } -} - -function isArguments(object) { - return Object.prototype.toString.call(object) == '[object Arguments]'; -} - -function objEquiv(a, b, strict, actualVisitedObjects) { - if (a === null || a === undefined || b === null || b === undefined) - return false; - // if one is a primitive, the other must be same - if (util.isPrimitive(a) || util.isPrimitive(b)) - return a === b; - if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) - return false; - var aIsArgs = isArguments(a); - var bIsArgs = isArguments(b); - if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) - return false; - if (aIsArgs) { - a = pSlice.call(a); - b = pSlice.call(b); - return _deepEqual(a, b, strict); - } - var ka = objectKeys(a); - var kb = objectKeys(b); - var key, i; - // having the same number of owned properties (keys incorporates - // hasOwnProperty) - if (ka.length !== kb.length) - return false; - //the same set of keys (although not necessarily the same order), - ka.sort(); - kb.sort(); - //~~~cheap key test - for (i = ka.length - 1; i >= 0; i--) { - if (ka[i] !== kb[i]) - return false; - } - //equivalent values for every corresponding key, and - //~~~possibly expensive deep test - for (i = ka.length - 1; i >= 0; i--) { - key = ka[i]; - if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) - return false; - } - return true; -} - -// 8. The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - -assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); - } -}; - -assert.notDeepStrictEqual = notDeepStrictEqual; -function notDeepStrictEqual(actual, expected, message) { - if (_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); - } -} - - -// 9. The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - -assert.strictEqual = function strictEqual(actual, expected, message) { - if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); - } -}; - -// 10. The strict non-equality assertion tests for strict inequality, as -// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - -assert.notStrictEqual = function notStrictEqual(actual, expected, message) { - if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); - } -}; - -function expectedException(actual, expected) { - if (!actual || !expected) { - return false; - } - - if (Object.prototype.toString.call(expected) == '[object RegExp]') { - return expected.test(actual); - } - - try { - if (actual instanceof expected) { - return true; - } - } catch (e) { - // Ignore. The instanceof check doesn't work for arrow functions. - } - - if (Error.isPrototypeOf(expected)) { - return false; - } - - return expected.call({}, actual) === true; -} - -function _tryBlock(block) { - var error; - try { - block(); - } catch (e) { - error = e; - } - return error; -} - -function _throws(shouldThrow, block, expected, message) { - var actual; - - if (typeof block !== 'function') { - throw new TypeError('"block" argument must be a function'); - } - - if (typeof expected === 'string') { - message = expected; - expected = null; - } - - actual = _tryBlock(block); - - message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + - (message ? ' ' + message : '.'); - - if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); - } - - var userProvidedMessage = typeof message === 'string'; - var isUnwantedException = !shouldThrow && util.isError(actual); - var isUnexpectedException = !shouldThrow && actual && !expected; - - if ((isUnwantedException && - userProvidedMessage && - expectedException(actual, expected)) || - isUnexpectedException) { - fail(actual, expected, 'Got unwanted exception' + message); - } - - if ((shouldThrow && actual && expected && - !expectedException(actual, expected)) || (!shouldThrow && actual)) { - throw actual; - } -} - -// 11. Expected to throw an error: -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws(true, block, error, message); -}; - -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws(false, block, error, message); -}; - -assert.ifError = function(err) { if (err) throw err; }; - -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - if (hasOwn.call(obj, key)) keys.push(key); - } - return keys; -}; - -/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) - -/***/ }), -/* 8 */ -/***/ (function(module, exports) { - -module.exports = now - -function now() { - return new Date().getTime() -} - - -/***/ }), -/* 9 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__apps_json__ = __webpack_require__(10); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__apps_json___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__apps_json__); -/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__modules_application_js__ = __webpack_require__(359); -/** - * Wappalyzer v5 - * - * Created by Elbert Alias - * - * License: GPLv3 http://www.gnu.org/licenses/gpl-3.0.txt - */ - - - - - - -const validation = { - hostname: /(www.)?((.+?)\.(([a-z]{2,3}\.)?[a-z]{2,6}))$/, - hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/ -}; - -var wappalyzer = { - apps: __WEBPACK_IMPORTED_MODULE_0__apps_json___default.a.apps, - categories: __WEBPACK_IMPORTED_MODULE_0__apps_json___default.a.categories, - driver: {} -}; - -var detected = {}; -var hostnameCache = {}; -var adCache = []; - -wappalyzer.config = { - websiteURL: 'https://wappalyzer.com/', - twitterURL: 'https://twitter.com/Wappalyzer', - githubURL: 'https://github.com/AliasIO/Wappalyzer' -}; - -/** - * Log messages to console - */ -wappalyzer.log = (message, source, type) => { - wappalyzer.driver.log(message, source || '', type || 'debug'); -}; - -wappalyzer.analyze = (hostname, url, data, context) => { - wappalyzer.log('Function call: analyze()', 'core'); - - var apps = {}; - - // Remove hash from URL - data.url = url = url.split('#')[0]; - - if (typeof data.html !== 'string') { - data.html = ''; - } - - if (detected[url] === undefined) { - detected[url] = {}; - } - - Object.keys(wappalyzer.apps).forEach(appName => { - apps[appName] = detected[url] && detected[url][appName] ? detected[url][appName] : new __WEBPACK_IMPORTED_MODULE_1__modules_application_js__["a" /* default */](appName, wappalyzer.apps[appName]); - - var app = apps[appName]; - - if (url) { - analyzeUrl(app, url); - } - - if (data.html) { - analyzeHtml(app, data.html); - analyzeScript(app, data.html); - analyzeMeta(app, data.html); - } - - if (data.headers) { - analyzeHeaders(app, data.headers); - } - - if (data.env) { - analyzeEnv(app, data.env); - } - }); - - Object.keys(apps).forEach(app => { - if (!app.detected) { - delete apps[app.name]; - } - }); - - resolveExcludes(apps); - resolveImplies(apps, url); - - cacheDetectedApps(apps, url); - trackDetectedApps(apps, url, hostname, data.html); - - if (Object.keys(apps).length) { - wappalyzer.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url, 'core'); - } - - wappalyzer.driver.displayApps(detected[url], context); -}; - -/** - * Enclose string in array - */ -function asArray(value) { - return typeof value === 'string' ? [value] : value; -} - -/** - * Parse apps.json patterns - */ -function parsePatterns(patterns) { - var parsed = {}; - - // Convert string to object containing array containing string - if (typeof patterns === 'string' || patterns instanceof Array) { - patterns = { - main: asArray(patterns) - }; - } - - for (var key in patterns) { - parsed[key] = []; - - asArray(patterns[key]).forEach(pattern => { - var attrs = {}; - - pattern.split('\\;').forEach((attr, i) => { - if (i) { - // Key value pairs - attr = attr.split(':'); - - if (attr.length > 1) { - attrs[attr.shift()] = attr.join(':'); - } - } else { - attrs.string = attr; - - try { - attrs.regex = new RegExp(attr.replace('/', '\/'), 'i'); // Escape slashes in regular expression - } catch (e) { - attrs.regex = new RegExp(); - - wappalyzer.log(e + ': ' + attr, 'error', 'core'); - } - } - }); - - parsed[key].push(attrs); - }); - } - - // Convert back to array if the original pattern list was an array (or string) - if (parsed.hasOwnProperty('main')) { - parsed = parsed.main; - } - - return parsed; -} - -function resolveExcludes(apps) { - var excludes = []; - - // Exclude app in detected apps only - Object.keys(apps).forEach(appName => { - var app = apps[appName]; - - if (app.props.excludes) { - asArray(app.props.excludes).forEach(excluded => { - excludes.push(excluded); - }); - } - }); - - // Remove excluded applications - Object.keys(apps).forEach(appName => { - if (excludes.indexOf(appName) !== -1) { - delete apps[appName]; - } - }); -} - -function resolveImplies(apps, url) { - var checkImplies = true; - - // Implied applications - // Run several passes as implied apps may imply other apps - while (checkImplies) { - checkImplies = false; - - Object.keys(apps).forEach(appName => { - var app = apps[appName]; - - if (app && app.implies) { - asArray(app.props.implies).forEach(implied => { - implied = parsePatterns(implied)[0]; - - if (!wappalyzer.apps[implied.string]) { - wappalyzer.log('Implied application ' + implied.string + ' does not exist', 'core', 'warn'); - - return; - } - - if (!apps.hasOwnProperty(implied.string)) { - apps[implied.string] = detected[url] && detected[url][implied.string] ? detected[url][implied.string] : new __WEBPACK_IMPORTED_MODULE_1__modules_application_js__["a" /* default */](implied.string, true); - - checkImplies = true; - } - - // Apply app confidence to implied app - Object.keys(app.confidence).forEach(id => { - apps[implied.string].confidence[id + ' implied by ' + appName] = app.confidence[id] * (implied.confidence ? implied.confidence / 100 : 1); - }); - }); - } - }); - } -} - -/** - * Cache detected applications - */ -function cacheDetectedApps(apps, url) { - wappalyzer.log('Function call: cacheDetectedApps()', 'core'); - - Object.keys(apps).forEach(appName => { - var app = apps[appName]; - - // Per URL - detected[url][appName] = app; - - Object.keys(app.confidence).forEach(id => { - detected[url][appName].confidence[id] = app.confidence[id]; - }); - }); -} - -/** - * Cache detected ads - */ -function cacheDetectedAds(ad) { - adCache.push(ad); -} - -/** - * Track detected applications - */ -function trackDetectedApps(apps, url, hostname, html) { - wappalyzer.log('Function call: trackDetectedApps()', 'core'); - - Object.keys(apps).forEach(appName => { - var app = apps[appName]; - - if (detected[url][appName].getConfidence() >= 100 && validation.hostname.test(hostname) && !validation.hostnameBlacklist.test(url)) { - if (!hostnameCache.hasOwnProperty(hostname)) { - hostnameCache[hostname] = { - applications: {}, - meta: {} - }; - } - - if (!hostnameCache[hostname].applications.hasOwnProperty(appName)) { - hostnameCache[hostname].applications[appName] = { - hits: 0 - }; - } - - hostnameCache[hostname].applications[appName].hits++; - - if (apps[appName].version) { - hostnameCache[hostname].applications[appName].version = app.version; - } - } - }); - - // Additional information - if (hostnameCache.hasOwnProperty(hostname)) { - var match = html.match(/]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i); - - if (match && match.length) { - hostnameCache[hostname].meta['language'] = match[1]; - } - } - - if (Object.keys(hostnameCache).length >= 50 || adCache.length >= 50) { - wappalyzer.driver.ping(hostnameCache, adCache); - - hostnameCache = {}; - adCache = []; - } -} - -/** - * Analyze URL - */ -function analyzeUrl(app, url) { - var patterns = parsePatterns(app.props.url); - - if (patterns.length) { - patterns.forEach(pattern => { - if (pattern.regex.test(url)) { - app.setDetected(pattern, 'url', url); - } - }); - } -} - -/** - * Analyze HTML - */ -function analyzeHtml(app, html) { - var patterns = parsePatterns(app.props.html); - - if (patterns.length) { - patterns.forEach(pattern => { - if (pattern.regex.test(html)) { - app.setDetected(pattern, 'html', html); - } - }); - } -} - -/** - * Analyze script tag - */ -function analyzeScript(app, html) { - var regex = new RegExp(']+src=("|\')([^"\']+)', 'ig'); - var patterns = parsePatterns(app.props.script); - - if (patterns.length) { - patterns.forEach(pattern => { - var match; - - while (match = regex.exec(html)) { - if (pattern.regex.test(match[2])) { - app.setDetected(pattern, 'script', match[2]); - } - } - }); - } -} - -/** - * Analyze meta tag - */ -function analyzeMeta(app, html) { - var regex = /]+>/ig; - var patterns = parsePatterns(app.props.meta); - var content; - var match; - - while (patterns && (match = regex.exec(html))) { - for (var meta in patterns) { - if (new RegExp('(name|property)=["\']' + meta + '["\']', 'i').test(match)) { - content = match.toString().match(/content=("|')([^"']+)("|')/i); - - patterns[meta].forEach(pattern => { - if (content && content.length === 4 && pattern.regex.test(content[2])) { - app.setDetected(pattern, 'meta', content[2], meta); - } - }); - } - } - } -} - -/** - * analyze response headers - */ -function analyzeHeaders(app, headers) { - var patterns = parsePatterns(app.props.headers); - - if (headers) { - Object.keys(patterns).forEach(header => { - patterns[header].forEach(pattern => { - header = header.toLowerCase(); - - if (headers.hasOwnProperty(header) && pattern.regex.test(headers[header])) { - app.setDetected(pattern, 'headers', headers[header], header); - } - }); - }); - } -} - -/** - * Analyze environment variables - */ -function analyzeEnv(app, envs) { - var patterns = parsePatterns(app.props.env); - - if (patterns.length) { - patterns.forEach(pattern => { - Object.keys(envs).forEach(env => { - if (pattern.regex.test(envs[env])) { - app.setDetected(pattern, 'env', envs[env]); - } - }); - }); - } -} - -/* harmony default export */ __webpack_exports__["a"] = (wappalyzer); - -/***/ }), -/* 10 */ -/***/ (function(module, exports) { - -module.exports = { - "apps": { - "1&1": { - "cats": [ - "6" - ], - "icon": "1and1.svg", - "implies": "PHP", - "url": "/shop/catalog/browse\\?sessid=", - "website": "http://1and1.com" - }, - "1C-Bitrix": { - "cats": [ - "1" - ], - "headers": { - "Set-Cookie": "BITRIX_", - "X-Powered-CMS": "Bitrix Site Manager" - }, - "html": "(?:]+components/bitrix|(?:src|href)=\"/bitrix/(?:js|templates))", - "icon": "1C-Bitrix.png", - "implies": "PHP", - "script": "1c-bitrix", - "website": "http://www.1c-bitrix.ru" - }, - "2z Project": { - "cats": [ - "1" - ], - "icon": "2z Project.png", - "meta": { - "generator": "2z project ([\\d.]+)\\;version:\\1" - }, - "website": "http://2zproject-cms.ru" - }, - "3DM": { - "cats": [ - "19" - ], - "html": "3ware 3DM([\\d\\.]+)?\\;version:\\1", - "icon": "3DM.png", - "implies": "3ware", - "website": "http://www.3ware.com" - }, - "3dCart": { - "cats": [ - "1", - "6" - ], - "headers": { - "Set-Cookie": "3dvisit", - "X-Powered-By": "3DCART" - }, - "icon": "3dCart.png", - "script": "(?:twlh(?:track)?\\.asp|3d_upsell\\.js)", - "website": "http://www.3dcart.com" - }, - "3ware": { - "cats": [ - "22" - ], - "headers": { - "Server": "3ware\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "3ware.png", - "website": "http://www.3ware.com" - }, - "AD EBiS": { - "cats": [ - "10" - ], - "html": [ - "<!-- EBiS contents tag", - "<!--EBiS tag", - "<!-- Tag EBiS", - "<!-- EBiS common tag" - ], - "icon": "ebis.png", - "website": "http://www.ebis.ne.jp" - }, - "AMPcms": { - "cats": [ - "1" - ], - "env": "^amp_js_init$", - "headers": { - "Set-Cookie": "^AMP=", - "X-AMP-Version": "([\\d.]+)\\;version:\\1" - }, - "icon": "AMPcms.png", - "implies": "PHP", - "website": "http://www.ampcms.org" - }, - "AOLserver": { - "cats": [ - "22" - ], - "headers": { - "Server": "AOLserver/?([\\d.]+)?\\;version:\\1" - }, - "icon": "AOLserver.png", - "website": "http://aolserver.com" - }, - "AT Internet Analyzer": { - "cats": [ - "10" - ], - "env": [ - "^xtsite$", - "^ATInternet$" - ], - "icon": "AT Internet.png", - "website": "http://atinternet.com/en" - }, - "AT Internet XiTi": { - "cats": [ - "10" - ], - "env": "^Xt_", - "icon": "AT Internet.png", - "script": "xiti\\.com/hit\\.xiti", - "website": "http://atinternet.com/en" - }, - "ATEN": { - "cats": [ - "22" - ], - "headers": { - "Server": "ATEN HTTP Server(?:\\(?V?([\\d\\.]+)\\)?)?\\;version:\\1" - }, - "icon": "ATEN.png", - "website": "http://www.aten.com" - }, - "AWStats": { - "cats": [ - "10" - ], - "icon": "AWStats.png", - "implies": "Perl", - "meta": { - "generator": "AWStats ([\\d.]+(?: \\(build [\\d.]+\\))?)\\;version:\\1" - }, - "website": "http://awstats.sourceforge.net" - }, - "Accessible Portal": { - "cats": [ - "1" - ], - "icon": "Accessible Portal.png", - "implies": "PHP", - "meta": { - "generator": "Accessible Portal" - }, - "website": "http://www.accessibleportal.com" - }, - "Act-On": { - "cats": [ - "32" - ], - "env": "^ActOn$", - "icon": "ActOn.png", - "website": "http://act-on.com" - }, - "Prebid": { - "cats": [ - "36" - ], - "icon": "Prebid.png", - "env": [ - "pbjs", - "PREBID_TIMEOUT" - ], - "script": [ - "/prebid\\.js", - "adnxs\\.com/[^\"]*(?:prebid|/pb\\.js)" - ], - "website": "http://prebid.org" - }, - "AdInfinity": { - "cats": [ - "36" - ], - "icon": "AdInfinity.png", - "script": "adinfinity\\.com\\.au", - "website": "http://adinfinity.com.au" - }, - "AdRiver": { - "cats": [ - "36" - ], - "env": "^adriver$", - "html": "(?:<embed[^>]+(?:src=\"https?://mh\\d?\\.adriver\\.ru/|flashvars=\"[^\"]*(?:http:%3A//(?:ad|mh\\d?)\\.adriver\\.ru/|adriver_banner))|<(?:(?:iframe|img)[^>]+src|a[^>]+href)=\"https?://ad\\.adriver\\.ru/)", - "icon": "AdRiver.png", - "script": "(?:adriver\\.core\\.\\d\\.js|https?://(?:content|ad|masterh\\d)\\.adriver\\.ru/)", - "website": "http://adriver.ru" - }, - "AdRoll": { - "cats": [ - "36" - ], - "env": "^adroll_", - "icon": "AdRoll.svg", - "script": "(?:a|s)\\.adroll\\.com", - "website": "http://adroll.com" - }, - "Adcash": { - "cats": [ - "36" - ], - "env": "^(?:ac_bgclick_URL|ct_(?:siteunder|tag|n(?:SuUrl(?:Opp)?)|Su(?:Loaded|Url)))$", - "icon": "Adcash.svg", - "script": "^[^\\/]*//(?:[^\\/]+\\.)?adcash\\.com/(?:script|ad)/", - "url": "^https?://(?:[^\\/]+\\.)?adcash\\.com/script/pop_", - "website": "http://adcash.com" - }, - "AddShoppers": { - "cats": [ - "5" - ], - "icon": "AddShoppers.png", - "script": "cdn\\.shop\\.pe/widget/", - "website": "http://www.addshoppers.com" - }, - "AddThis": { - "cats": [ - "5" - ], - "env": "^addthis", - "icon": "AddThis.svg", - "script": "addthis\\.com/js/", - "website": "http://www.addthis.com" - }, - "AddToAny": { - "cats": [ - "5" - ], - "env": "^a2apage_init$", - "icon": "AddToAny.png", - "script": "addtoany\\.com/menu/page\\.js", - "website": "http://www.addtoany.com" - }, - "Adminer": { - "cats": [ - "3" - ], - "html": [ - "Adminer</a> <span class=\"version\">([\\d.]+)</span>\\;version:\\1", - "onclick=\"bodyClick\\(event\\);\" onload=\"verifyVersion\\('([\\d.]+)'\\);\">\\;version:\\1" - ], - "icon": "adminer.png", - "implies": "PHP", - "website": "http://www.adminer.org" - }, - "Adnegah": { - "cats": [ - "36" - ], - "headers": { - "X-Advertising-By": "adnegah.net" - }, - "html": "<iframe [^>]*src=\"[^\"]+adnegah\\.net", - "icon": "adnegah.png", - "script": "[^a-z]adnegah.*\\.js$", - "website": "https://Adnegah.net" - }, - "Adobe ColdFusion": { - "cats": [ - "18" - ], - "env": "^_cfEmails$", - "headers": { - "Cookie": "CFTOKEN=" - }, - "html": "<!-- START headerTags\\.cfm", - "icon": "Adobe ColdFusion.svg", - "implies": "CFML", - "script": "/cfajax/", - "url": "\\.cfm(?:$|\\?)", - "website": "http://adobe.com/products/coldfusion-family.html" - }, - "Adobe Experience Manager": { - "cats": [ - "1" - ], - "html": [ - "<div class=\"[^\"]*parbase", - "<div[^>]+data-component-path=\"[^\"+]jcr:" - ], - "icon": "Adobe Experience Manager.svg", - "implies": "Java", - "script": "/etc/designs/", - "website": "http://www.adobe.com/au/marketing-cloud/enterprise-content-management.html" - }, - "Adobe GoLive": { - "cats": [ - "20" - ], - "icon": "Adobe GoLive.png", - "meta": { - "generator": "Adobe GoLive(?:\\s([\\d.]+))?\\;version:\\1" - }, - "website": "http://www.adobe.com/products/golive" - }, - "Adobe Muse": { - "cats": [ - "20" - ], - "icon": "Adobe Muse.svg", - "meta": { - "generator": "^Muse(?:$| ?/?(\\d[\\d.]+))\\;version:\\1" - }, - "website": "http://muse.adobe.com" - }, - "Adobe RoboHelp": { - "cats": [ - "4" - ], - "env": "^gbWh(?:Ver|Lang|Msg|Util|Proxy)$", - "icon": "Adobe RoboHelp.svg", - "meta": { - "generator": "^Adobe RoboHelp(?: ([\\d]+))?\\;version:\\1" - }, - "script": "(?:wh(?:utils|ver|proxy|lang|topic|msg)|ehlpdhtm)\\.js", - "website": "http://adobe.com/products/robohelp.html" - }, - "Advanced Web Stats": { - "cats": [ - "10" - ], - "html": "aws\\.src = [^<]+caphyon-analytics", - "icon": "Advanced Web Stats.png", - "implies": "Java", - "website": "http://www.advancedwebstats.com" - }, - "Advert Stream": { - "cats": [ - "36" - ], - "env": "^advst_is_above_the_fold$", - "icon": "Advert Stream.png", - "script": "(?:ad\\.advertstream\\.com|adxcore\\.com)", - "website": "http://www.advertstream.com" - }, - "Adzerk": { - "cats": [ - "36" - ], - "env": "^ados(?:Results)?$", - "html": "<iframe [^>]*src=\"[^\"]+adzerk\\.net", - "icon": "Adzerk.png", - "script": "adzerk\\.net/ados\\.js", - "website": "http://adzerk.com" - }, - "Aegea": { - "cats": [ - "11" - ], - "headers": { - "X-Powered-By": "^E2 Aegea v(\\d+)$\\;version:\\1" - }, - "icon": "Aegea.png", - "implies": [ - "PHP", - "jQuery" - ], - "website": "http://blogengine.ru" - }, - "AfterBuy": { - "cats": [ - "6" - ], - "html": [ - "<dd>This OnlineStore is brought to you by ViA-Online GmbH Afterbuy. Information and contribution at https://www.afterbuy.de</dd>" - ], - "icon": "after-buy.png", - "script": "shop-static\\.afterbuy\\.de", - "website": "http://www.afterbuy.de" - }, - "Aircall": { - "cats": [ - "52" - ], - "icon": "aircall.png", - "script": "^https?://cdn\\.aircall\\.io/", - "website": "http://aircall.io" - }, - "Airee": { - "cats": [ - "31" - ], - "headers": { - "Server": "Airee" - }, - "icon": "Airee.png", - "website": "http://xn--80aqc2a.xn--p1ai" - }, - "Akamai": { - "cats": [ - "31" - ], - "headers": { - "X-Akamai-Transformed": "" - }, - "icon": "Akamai.png", - "website": "http://akamai.com" - }, - "Akka HTTP": { - "cats": [ - "18", - "22" - ], - "headers": { - "Server": "akka-http(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "akka-http.png", - "website": "http://akka.io" - }, - "Algolia Realtime Search": { - "cats": [ - "29" - ], - "env": "^AlgoliaSearch$", - "icon": "Algolia Realtime Search.svg", - "website": "http://www.algolia.com" - }, - "Allegro RomPager": { - "cats": [ - "22" - ], - "headers": { - "Server": "Allegro-Software-RomPager(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "Allegro RomPager.png", - "website": "http://allegrosoft.com/embedded-web-server-s2" - }, - "AlloyUI": { - "cats": [ - "12" - ], - "env": "^AUI$", - "icon": "AlloyUI.png", - "implies": [ - "Twitter Bootstrap", - "YUI" - ], - "script": "^https?://cdn\\.alloyui\\.com/", - "website": "http://www.alloyui.com" - }, - "Amaya": { - "cats": [ - "20" - ], - "icon": "Amaya.png", - "meta": { - "generator": "Amaya(?: V?([\\d.]+[a-z]))?\\;version:\\1" - }, - "website": "http://www.w3.org/Amaya" - }, - "Amazon Cloudfront": { - "cats": [ - "31" - ], - "headers": { - "X-Amz-Cf-Id": "" - }, - "icon": "Amazon-Cloudfront.svg", - "website": "http://aws.amazon.com/cloudfront/" - }, - "Amazon EC2": { - "cats": [ - "22" - ], - "headers": { - "Server": "\\(Amazon\\)" - }, - "icon": "aws-ec2.svg", - "website": "http://aws.amazon.com/ec2/" - }, - "Amazon S3": { - "cats": [ - "19" - ], - "headers": { - "Server": "AmazonS3" - }, - "icon": "aws-s3.svg", - "website": "http://aws.amazon.com/s3/" - }, - "Ametys": { - "cats": [ - "1" - ], - "icon": "Ametys.png", - "implies": "Java", - "meta": { - "generator": "(?:Ametys|Anyware Technologies)" - }, - "script": "ametys\\.js", - "website": "http://ametys.org" - }, - "Amiro.CMS": { - "cats": [ - "1" - ], - "icon": "Amiro.CMS.png", - "implies": "PHP", - "meta": { - "generator": "Amiro" - }, - "website": "http://amirocms.com" - }, - "Angular Material": { - "cats": [ - "18" - ], - "env": "^ngMaterial$", - "icon": "Angular.svg", - "implies": "AngularJS", - "script": [ - "/([\\d.]+(?:\\-?rc[.\\d]*)*)/angular-material(?:\\.min)?\\.js\\;version:\\1", - "angular-material.*\\.js" - ], - "website": "http://material.angularjs.org" - }, - "AngularJS": { - "cats": [ - "12" - ], - "env": "^angular$", - "icon": "AngularJS.svg", - "script": [ - "angular(?:\\-|\\.)([\\d.]*\\d)[^/]*\\.js\\;version:\\1", - "/([\\d.]+(?:\\-?rc[.\\d]*)*)/angular(?:\\.min)?\\.js\\;version:\\1", - "angular.*\\.js" - ], - "website": "http://angularjs.org" - }, - "Apache": { - "cats": [ - "22" - ], - "headers": { - "Server": "(?:Apache(?:$|/([\\d.]+)|[^/-])|(?:^|\b)HTTPD)\\;version:\\1" - }, - "icon": "Apache.svg", - "website": "http://apache.org" - }, - "Apache HBase": { - "cats": [ - "34" - ], - "html": "<style[^>]+static/hbase", - "icon": "Apache HBase.png", - "implies": "Java", - "website": "http://hbase.apache.org" - }, - "Apache Hadoop": { - "cats": [ - "34" - ], - "html": "<style[^>]+static/hadoop", - "icon": "Apache Hadoop.svg", - "website": "http://hadoop.apache.org" - }, - "Apache JSPWiki": { - "cats": [ - "8" - ], - "html": "<html[^>]* xmlns:jspwiki=", - "icon": "Apache JSPWiki.png", - "implies": "Apache Tomcat", - "script": "jspwiki", - "url": "wiki\\.jsp", - "website": "http://jspwiki.org" - }, - "Apache Tomcat": { - "cats": [ - "22" - ], - "headers": { - "Server": "Apache-Coyote(/1\\.1)?\\;version:\\1?4.1+:", - "X-Powered-By": "\bTomcat\b(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "Apache Tomcat.svg", - "implies": "Java", - "website": "http://tomcat.apache.org" - }, - "Apache Traffic Server": { - "cats": [ - "22" - ], - "headers": { - "Server": "ATS/?([\\d.]+)?\\;version:\\1" - }, - "icon": "Apache Traffic Server.png", - "website": "http://trafficserver.apache.org/" - }, - "Apache Wicket": { - "cats": [ - "18" - ], - "env": "^Wicket", - "icon": "Apache Wicket.svg", - "implies": "Java", - "website": "http://wicket.apache.org" - }, - "ApexPages": { - "cats": [ - "51" - ], - "headers": { - "X-Powered-By": "Salesforce.com ApexPages" - }, - "icon": "ApexPages.png", - "implies": "Salesforce", - "website": "https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_intro.htm" - }, - "Apostrophe CMS": { - "cats": [ - "1" - ], - "html": "<[^>]+data-apos-refreshable[^>]", - "icon": "apostrophecms.svg", - "implies": "Node.js", - "website": "http://apostrophecms.org" - }, - "AppNexus": { - "cats": [ - "36" - ], - "html": "<(?:iframe|img)[^>]+adnxs\\.(?:net|com)", - "icon": "AppNexus.svg", - "script": "adnxs\\.(?:net|com)", - "website": "http://appnexus.com" - }, - "Arastta": { - "cats": [ - "6" - ], - "excludes": "OpenCart", - "headers": { - "Arastta": "(.*)\\;version:\\1", - "X-Arastta": "" - }, - "html": "Powered by <a [^>]*href=\"https?://(?:www\\.)?arastta\\.org[^>]+>Arastta", - "icon": "Arastta.svg", - "implies": "PHP", - "script": "arastta\\.js", - "website": "http://arastta.org" - }, - "Arc Forum": { - "cats": [ - "2" - ], - "html": "ping\\.src = node\\.href;\\s+[^>]+\\s+}\\s+</script>", - "icon": "Arc Forum.png", - "website": "http://arclanguage.org" - }, - "ArcGIS API for JavaScript": { - "cats": [ - "35" - ], - "script": [ - "js.arcgis.com", - "basemaps.arcgis.com" - ], - "icon": "arcgis_icon.png", - "website": "https://developers.arcgis.com/javascript/" - }, - "Artifactory": { - "cats": [ - "47" - ], - "env": "^ArtifactoryUpdates$", - "html": [ - "<span class=\"version\">Artifactory(?: Pro)?(?: Power Pack)?(?: ([\\d.]+))?\\;version:\\1" - ], - "icon": "Artifactory.svg", - "script": [ - "wicket/resource/org\\.artifactory\\." - ], - "website": "http://jfrog.com/open-source/#os-arti" - }, - "Artifactory Web Server": { - "cats": [ - "22" - ], - "headers": { - "Server": "Artifactory(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "Artifactory.svg", - "implies": [ - "Artifactory" - ], - "website": "http://jfrog.com/open-source/#os-arti" - }, - "ArvanCloud": { - "cats": [ - "31" - ], - "env": "^ArvanCloud$", - "headers": { - "AR-PoweredBy": "Arvan Cloud \\(arvancloud.com\\)" - }, - "icon": "ArvanCloud.png", - "website": "http://www.ArvanCloud.com" - }, - "AsciiDoc": { - "cats": [ - "1", - "20", - "27" - ], - "env": "^asciidoc$", - "icon": "AsciiDoc.png", - "meta": { - "generator": "^AsciiDoc ([\\d.]+)\\;version:\\1" - }, - "website": "http://www.methods.co.nz/asciidoc" - }, - "Asymptix PHP Framework": { - "cats": [ - "18" - ], - "headers": { - "X-Powered-By": "Asymptix PHP Framework(?:.*)" - }, - "html": [ - "Powered by <a href=\"http://www.asymptix.com/\" rel=\"external\">Asymptix PHP Framework</a>" - ], - "icon": "Asymptix PHP Framework.png", - "implies": "PHP", - "website": "http://github.com/Asymptix/Framework" - }, - "Atlassian Bitbucket": { - "cats": [ - "47" - ], - "env": "^bitbucket$", - "icon": "Atlassian Bitbucket.svg", - "implies": "Python", - "meta": { - "application-name": "Bitbucket" - }, - "website": "http://www.atlassian.com/software/bitbucket/overview/" - }, - "Atlassian Confluence": { - "cats": [ - "8" - ], - "headers": { - "X-Confluence-Request-Time": "" - }, - "html": "Powered by <a href=[^>]+atlassian\\.com/software/confluence(?:[^>]+>Atlassian Confluence</a> ([\\d.]+))?\\;version:\\1", - "icon": "Atlassian Confluence.svg", - "implies": "Java", - "meta": { - "confluence-request-time": "" - }, - "website": "http://www.atlassian.com/software/confluence/overview/team-collaboration-software" - }, - "Atlassian FishEye": { - "cats": [ - "47" - ], - "headers": { - "Set-cookie": "FESESSIONID" - }, - "html": "<title>(?:Log in to )?FishEye (?:and Crucible )?([\\d.]+)?\\;version:\\1", - "icon": "Atlassian FishEye.svg", - "website": "http://www.atlassian.com/software/fisheye/overview/" - }, - "Atlassian Jira": { - "cats": [ - "13" - ], - "env": "^jira$", - "html": "Powered by\\s+]+atlassian\\.com/(?:software/jira|jira-bug-tracking/)[^>]+>Atlassian\\s+JIRA(?:[^v]*v(?:ersion: )?(\\d+\\.\\d+(?:\\.\\d+)?))?\\;version:\\1", - "icon": "Atlassian Jira.svg", - "implies": "Java", - "meta": { - "ajs-version-number": "([\\d\\.]+)\\;version:\\1", - "application-name": "JIRA" - }, - "website": "http://www.atlassian.com/software/jira/overview/" - }, - "Atlassian Jira Issue Collector": { - "cats": [ - "13", - "47" - ], - "icon": "Atlassian Jira.svg", - "script": [ - "jira-issue-collector-plugin", - "atlassian\\.jira\\.collector\\.plugin" - ], - "website": "http://www.atlassian.com/software/jira/overview/" - }, - "Aurelia": { - "cats": [ - "12" - ], - "html": [ - "<[^>]+aurelia-app=[^>]", - "<[^>]+data-main=[^>]aurelia-bootstrapper", - "<[^>]+au-target-id=[^>]\\d" - ], - "icon": "Aurelia.svg", - "script": [ - "aurelia(?:\\.min)?\\.js" - ], - "website": "http://aurelia.io" - }, - "Avangate": { - "cats": [ - "6" - ], - "env": "^(?:__)?avng8_", - "html": "]* href=\"^https?://edge\\.avangate\\.net/", - "icon": "Avangate.svg", - "script": "^https?://edge\\.avangate\\.net/", - "website": "http://avangate.com" - }, - "BEM": { - "cats": [ - "12" - ], - "html": "<[^>]+data-bem", - "icon": "BEM.png", - "website": "http://en.bem.info" - }, - "BIGACE": { - "cats": [ - "1" - ], - "html": "(?:Powered by ]+BIGACE|", - "icon": "Business Catalyst.png", - "script": "CatalystScripts", - "website": "http://businesscatalyst.com" - }, - "BuySellAds": { - "cats": [ - "36" - ], - "env": "^_bsa", - "html": "]*>[^<]+?bsa.src\\s*=\\s*['\"](?:https?:)?\\/{2}\\w\\d\\.buysellads\\.com\\/[\\w\\d\\/]+?bsa\\.js['\"]", - "icon": "BuySellAds.png", - "script": "^https?://s\\d\\.buysellads\\.com/", - "website": "http://buysellads.com" - }, - "C++": { - "cats": [ - "27" - ], - "icon": "C++.png", - "website": "http://isocpp.org" - }, - "CFML": { - "cats": [ - "27" - ], - "icon": "CFML.png", - "website": "http://adobe.com/products/coldfusion-family.html" - }, - "CKEditor": { - "cats": [ - "24" - ], - "env": "^CKEDITOR$", - "icon": "CKEditor.png", - "website": "http://ckeditor.com" - }, - "CMS Made Simple": { - "cats": [ - "1" - ], - "headers": { - "Set-Cookie": "^CMSSESSID" - }, - "icon": "CMS Made Simple.png", - "implies": "PHP", - "meta": { - "generator": "CMS Made Simple" - }, - "website": "http://cmsmadesimple.org" - }, - "CMSimple": { - "cats": [ - "1" - ], - "implies": "PHP", - "meta": { - "generator": "CMSimple( [\\d.]+)?\\;version:\\1" - }, - "website": "http://www.cmsimple.org/en" - }, - "CO2Stats": { - "cats": [ - "10" - ], - "html": "src=[^>]+co2stats\\.com/propres\\.php", - "icon": "CO2Stats.png", - "website": "http://co2stats.com" - }, - "CPG Dragonfly": { - "cats": [ - "1" - ], - "headers": { - "X-Powered-By": "Dragonfly CMS" - }, - "icon": "CPG Dragonfly.png", - "implies": "PHP", - "meta": { - "generator": "CPG Dragonfly" - }, - "website": "http://dragonflycms.org" - }, - "CS Cart": { - "cats": [ - "6" - ], - "env": "^fn_compare_strings$", - "html": [ - " Powered by (?:]+cs-cart\\.com|CS-Cart)", - ".cm-noscript[^>]+" - ], - "icon": "CS Cart.png", - "implies": "PHP", - "website": "http://www.cs-cart.com" - }, - "CacheFly": { - "cats": [ - "31" - ], - "headers": { - "Server": "^CFS ", - "X-CF1": "", - "X-CF2": "" - }, - "icon": "CacheFly.png", - "website": "http://www.cachefly.com" - }, - "Caddy": { - "cats": [ - "22" - ], - "headers": { - "Server": "^Caddy$" - }, - "icon": "caddy.svg", - "implies": "Go", - "website": "http://caddyserver.com" - }, - "CakePHP": { - "cats": [ - "18" - ], - "headers": { - "Set-Cookie": "cakephp=" - }, - "icon": "CakePHP.png", - "implies": "PHP", - "meta": { - "application-name": "CakePHP" - }, - "website": "http://cakephp.org" - }, - "Canon": { - "cats": [ - "40" - ], - "icon": "Canon.png", - "website": "http://www.canon.com" - }, - "Canon HTTP Server": { - "cats": [ - "22" - ], - "headers": { - "Server": "CANON HTTP Server(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "Canon.png", - "implies": "Canon", - "website": "http://www.canon.com" - }, - "Captch Me": { - "cats": [ - "16", - "36" - ], - "env": "^Captchme", - "icon": "Captch Me.svg", - "script": "^https?://api\\.captchme\\.net/", - "website": "http://captchme.com" - }, - "Carbon Ads": { - "cats": [ - "36" - ], - "env": "^_carbonads", - "html": "<[a-z]+ [^>]*id=\"carbonads-container\"", - "icon": "Carbon Ads.png", - "script": "[^\\/]*\\/\\/(?:engine|srv)\\.carbonads\\.com\\/", - "website": "http://carbonads.net" - }, - "Cargo": { - "cats": [ - "1" - ], - "html": "]+Cargo feed", - "icon": "Cargo.png", - "implies": "PHP", - "meta": { - "cargo_title": "" - }, - "script": "/cargo\\.", - "website": "http://cargocollective.com" - }, - "Catberry.js": { - "cats": [ - "12", - "18" - ], - "env": "^catberry$", - "headers": { - "X-Powered-By": "Catberry" - }, - "icon": "Catberry.js.png", - "implies": "Node.js", - "website": "http://catberry.org" - }, - "Catwalk": { - "cats": [ - "22" - ], - "headers": { - "Server": "Catwalk\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "Catwalk.png", - "implies": "Canon", - "website": "http://www.canon.com" - }, - "CentOS": { - "cats": [ - "28" - ], - "headers": { - "Server": "CentOS", - "X-Powered-By": "CentOS" - }, - "icon": "CentOS.png", - "website": "http://centos.org" - }, - "CenteHTTPd": { - "cats": [ - "22" - ], - "headers": { - "Server": "CenteHTTPd(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "CenteHTTPd.png", - "website": "http://cente.jp/cente/app/HTTPdc.html" - }, - "Chameleon": { - "cats": [ - "1" - ], - "icon": "Chameleon.png", - "implies": [ - "Apache", - "PHP" - ], - "meta": { - "generator": "chameleon-cms" - }, - "website": "http://chameleon-system.de" - }, - "Chamilo": { - "cats": [ - "21" - ], - "headers": { - "X-Powered-By": "Chamilo ([\\d.]+)\\;version:\\1" - }, - "html": "\">Chamilo ([\\d.]+)\\;version:\\1", - "icon": "Chamilo.png", - "implies": "PHP", - "meta": { - "generator": "Chamilo ([\\d.]+)\\;version:\\1" - }, - "website": "http://www.chamilo.org" - }, - "Chartbeat": { - "cats": [ - "10" - ], - "env": "^_sf_(?:endpt|async_config)$", - "icon": "Chartbeat.png", - "script": "chartbeat\\.js", - "website": "http://chartbeat.com" - }, - "Cherokee": { - "cats": [ - "22" - ], - "headers": { - "Server": "Cherokee/([\\d.]+)\\;version:\\1" - }, - "icon": "Cherokee.png", - "website": "http://www.cherokee-project.com" - }, - "CherryPy": { - "cats": [ - "18", - "22" - ], - "headers": { - "Server": "CherryPy\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "CherryPy.png", - "implies": "Python", - "website": "http://www.cherrypy.org" - }, - "Chitika": { - "cats": [ - "36" - ], - "env": "ch_c(?:lient|olor_site_link)", - "icon": "Chitika.png", - "script": "scripts\\.chitika\\.net/", - "website": "http://chitika.com" - }, - "Ckan": { - "cats": [ - "1" - ], - "headers": { - "Access-Control-Allow-Headers": "X-CKAN-API-KEY", - "Link": "; rel=shortlink" - }, - "icon": "Ckan.png", - "implies": [ - "Python", - "Solr", - "Java", - "PostgreSQL" - ], - "meta": { - "generator": ".*ckan.*" - }, - "website": "http://ckan.org/" - }, - "ClickHeat": { - "cats": [ - "10" - ], - "env": "^clickHeat", - "icon": "ClickHeat.png", - "implies": "PHP", - "script": "clickheat.*\\.js", - "website": "http://www.labsmedia.com/clickheat/index.html" - }, - "ClickTale": { - "cats": [ - "10" - ], - "env": "^ClickTale", - "icon": "ClickTale.png", - "website": "http://www.clicktale.com" - }, - "Clicky": { - "cats": [ - "10" - ], - "env": "^clicky$", - "icon": "Clicky.png", - "script": "static\\.getclicky\\.com", - "website": "http://getclicky.com" - }, - "Clientexec": { - "cats": [ - "6" - ], - "html": "clientexec\\.[^>]*\\s?=\\s?[^>]*;", - "icon": "Clientexec.png", - "website": "http://www.clientexec.com" - }, - "Clipboard.js": { - "cats": [ - "19" - ], - "env": "^Clipboard$", - "icon": "Clipboard.js.svg", - "script": "clipboard(?:\\.min)?\\.js", - "website": "https://clipboardjs.com/" - }, - "CloudCart": { - "cats": [ - "6" - ], - "icon": "cloudcart.svg", - "meta": { - "author": "^CloudCart LLC$" - }, - "script": "/cloudcart-(?:assets|storage)/", - "website": "http://cloudcart.com" - }, - "CloudFlare": { - "cats": [ - "31" - ], - "env": "^CloudFlare$", - "headers": { - "Server": "cloudflare" - }, - "icon": "CloudFlare.svg", - "website": "http://www.cloudflare.com" - }, - "Cloudera": { - "cats": [ - "34" - ], - "headers": { - "Server": "cloudera" - }, - "icon": "Cloudera.png", - "website": "http://www.cloudera.com" - }, - "CodeIgniter": { - "cats": [ - "18" - ], - "headers": { - "Set-Cookie": "(?:exp_last_activity|exp_tracker|ci_(?:session|(csrf_token)))\\;version:\\1?2+:" - }, - "html": "]+name=\"ci_csrf_token\"\\;version:2+", - "icon": "CodeIgniter.png", - "implies": "PHP", - "website": "http://codeigniter.com" - }, - "CodeMirror": { - "cats": [ - "19" - ], - "env": "^CodeMirror$", - "icon": "CodeMirror.png", - "website": "http://codemirror.net" - }, - "Comandia": { - "cats": [ - "6" - ], - "env": "^Comandia$", - "html": "]+=['\"]//cdn\\.mycomandia\\.com", - "icon": "Comandia.svg", - "website": "http://comandia.com" - }, - "Commerce Server": { - "cats": [ - "6" - ], - "headers": { - "COMMERCE-SERVER-SOFTWARE": "" - }, - "icon": "Commerce Server.png", - "implies": "Microsoft ASP.NET", - "website": "http://commerceserver.net" - }, - "CompaqHTTPServer": { - "cats": [ - "22" - ], - "headers": { - "Server": "CompaqHTTPServer\\/?([\\d\\.]+)?\\;version:\\1" - }, - "icon": "HP.svg", - "website": "http://www.hp.com" - }, - "Concrete5": { - "cats": [ - "1" - ], - "env": "^CCM_IMAGE_PATH$", - "icon": "Concrete5.png", - "implies": "PHP", - "meta": { - "generator": "concrete5 - ([\\d.ab]+)\\;version:\\1" - }, - "script": "concrete/js/", - "website": "http://concrete5.org" - }, - "Connect": { - "cats": [ - "18" - ], - "headers": { - "X-Powered-By": "^Connect$" - }, - "icon": "Connect.png", - "implies": "Node.js", - "website": "http://www.senchalabs.org/connect" - }, - "Contao": { - "cats": [ - "1" - ], - "html": [ - "", - "]+(?:typolight|contao)\\.css" - ], - "icon": "Contao.png", - "implies": "PHP", - "meta": { - "generator": "^Contao Open Source CMS$" - }, - "website": "http://contao.org" - }, - "Contenido": { - "cats": [ - "1" - ], - "icon": "Contenido.png", - "implies": "PHP", - "meta": { - "generator": "Contenido ([\\d.]+)\\;version:\\1" - }, - "website": "http://contenido.org/en" - }, - "Contens": { - "cats": [ - "1" - ], - "icon": "Contens.png", - "implies": [ - "Java", - "CFML" - ], - "meta": { - "generator": "Contensis CMS Version ([\\d.]+)\\;version:\\1" - }, - "website": "http://www.contens.com/en/pub/index.cfm" - }, - "ContentBox": { - "cats": [ - "1", - "11" - ], - "icon": "ContentBox.png", - "implies": "Adobe ColdFusion", - "meta": { - "generator": "ContentBox powered by ColdBox" - }, - "website": "http://www.gocontentbox.org" - }, - "ConversionLab": { - "cats": [ - "10" - ], - "icon": "ConversionLab.png", - "script": "conversionlab\\.trackset\\.com/track/tsend\\.js", - "website": "http://www.trackset.it/conversionlab" - }, - "Coppermine": { - "cats": [ - "7" - ], - "html": "|", - "icon": "InProces.png", - "script": "brein/inproces/website/websitefuncties\\.js", - "website": "http://www.brein.nl/oplossing/product/website" - }, - "Incapsula": { - "cats": [ - "31" - ], - "headers": { - "X-CDN": "Incapsula" - }, - "icon": "Incapsula.png", - "website": "http://www.incapsula.com" - }, - "Indexhibit": { - "cats": [ - "1" - ], - "html": "<(?:link|a href) [^>]+ndxz-studio", - "implies": [ - "PHP", - "Apache", - "Exhibit" - ], - "meta": { - "generator": "Indexhibit" - }, - "website": "http://www.indexhibit.org" - }, - "Indico": { - "cats": [ - "1" - ], - "headers": { - "Set-cookie": "MAKACSESSION" - }, - "html": "Powered by\\s+(?:CERN )?(?:CDS )?Indico( [\\d\\.]+)?\\;version:\\1", - "icon": "Indico.png", - "website": "http://indico-software.org" - }, - "Indy": { - "cats": [ - "22" - ], - "headers": { - "Server": "Indy(?:/([\\d.]+))?\\;version:\\1" - }, - "website": "http://indyproject.org" - }, - "InfernoJS": { - "cats": [ - "12" - ], - "env": "^Inferno$", - "icon": "InfernoJS.png", - "website": "https://infernojs.org/" - }, - "Infusionsoft": { - "cats": [ - "32" - ], - "html": [ - "]*name=\"infusionsoft_version\" [^>]*value=\"([^>]*)\" [^>]*\\/>\\;version:\\1", - "]*value=\"([^>]*)\" [^>]*name=\"infusionsoft_version\" [^>]*\\/>\\;version:\\1" - ], - "icon": "infusionsoft.svg", - "website": "http://infusionsoft.com" - }, - "InstantCMS": { - "cats": [ - "1" - ], - "headers": { - "Set-Cookie": "InstantCMS\\[logdate\\]=" - }, - "icon": "InstantCMS.png", - "implies": "PHP", - "meta": { - "generator": "InstantCMS" - }, - "website": "http://www.instantcms.ru" - }, - "Intel Active Management Technology": { - "cats": [ - "22", - "46" - ], - "headers": { - "Server": "Intel\\(R\\) Active Management Technology(?: ([\\d.]+))?\\;version:\\1" - }, - "icon": "Intel Active Management Technology.png", - "website": "http://intel.com" - }, - "IntenseDebate": { - "cats": [ - "15" - ], - "icon": "IntenseDebate.png", - "script": "intensedebate\\.com", - "website": "http://intensedebate.com" - }, - "Intercom": { - "cats": [ - "10" - ], - "env": "^Intercom$", - "icon": "Intercom.png", - "script": "(?:api\\.intercom\\.io/api|static\\.intercomcdn\\.com/intercom\\.v1)", - "website": "http://intercom.io" - }, - "Intershop": { - "cats": [ - "6" - ], - "icon": "Intershop.png", - "script": "(?:is-bin|INTERSHOP)", - "website": "http://intershop.com" - }, - "Invenio": { - "cats": [ - "50" - ], - "headers": { - "Set-cookie": "INVENIOSESSION" - }, - "html": "(?:Powered by|System)\\s+(?:CERN )?(?:CDS )?Invenio\\s*v?([\\d\\.]+)?\\;version:\\1", - "icon": "Invenio.png", - "website": "http://invenio-software.org" - }, - "Ionicons": { - "cats": [ - "17" - ], - "html": "]* href=[^>]+ionicons(?:\\.min)?\\.css", - "icon": "Ionicons.png", - "website": "http://ionicons.com" - }, - "JAlbum": { - "cats": [ - "7" - ], - "icon": "JAlbum.png", - "implies": "Java", - "meta": { - "generator": "JAlbum( [\\d.]+)?\\;version:\\1" - }, - "website": "http://jalbum.net/en" - }, - "JBoss Application Server": { - "cats": [ - "22" - ], - "headers": { - "X-Powered-By": "JBoss(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "JBoss Application Server.png", - "website": "http://jboss.org/jbossas.html" - }, - "JBoss Web": { - "cats": [ - "22" - ], - "excludes": "Apache Tomcat", - "headers": { - "X-Powered-By": "JBossWeb(?:-([\\d.]+))?\\;version:\\1" - }, - "icon": "JBoss Web.png", - "implies": "JBoss Application Server", - "website": "http://jboss.org/jbossweb" - }, - "JC-HTTPD": { - "cats": [ - "22" - ], - "excludes": "Apache", - "headers": { - "Server": "JC-HTTPD(?:/([\\d.]+))?\\;version:\\1" - }, - "icon": "JC-HTTPD.png", - "implies": "Canon", - "website": "http://canon.com" - }, - "JS Charts": { - "cats": [ - "25" - ], - "env": "^JSChart$", - "icon": "JS Charts.png", - "script": "jscharts.*\\.js", - "website": "http://www.jscharts.com" - }, - "JTL Shop": { - "cats": [ - "6" - ], - "headers": { - "Set-Cookie": "JTLSHOP=" - }, - "html": "(?:]+name=\"JTLSHOP|]+id=\"wrapper_r\"|<[^>]+(?:feed|components)/com_|]+class=\"pill)\\;confidence:50", - "icon": "Joomla.png", - "implies": "PHP", - "meta": { - "generator": "Joomla!(?: ([\\d.]+))?\\;version:\\1" - }, - "url": "option=com_", - "website": "http://joomla.org" - }, - "K2": { - "cats": [ - "19" - ], - "env": "^K2RatingURL$", - "html": "", - "icon": "Lightspeed.svg", - "script": "http://assets.webshopapp.com", - "url": "seoshop.webshopapp.com", - "website": "http://www.lightspeedhq.com/products/ecommerce/" - }, - "Lighty": { - "cats": [ - "18" - ], - "headers": { - "Set-Cookie": "lighty_version" - }, - "icon": "Lighty.png", - "implies": "PHP", - "website": "http://gitlab.com/lighty/framework" - }, - "LimeSurvey": { - "cats": [ - "19" - ], - "headers": { - "generator": "LimeSurvey" - }, - "icon": "LimeSurvey.png", - "website": "http://limesurvey.org/" - }, - "LinkSmart": { - "cats": [ - "36" - ], - "env": "^(?:_mb_site_guid$|LS_JSON|LinkSmart(?:_|$))", - "icon": "LinkSmart.png", - "script": "^https?://cdn\\.linksmart\\.com/linksmart_([\\d.]+?)(?:\\.min)?\\.js\\;version:\\1", - "website": "http://linksmart.com" - }, - "Linkedin": { - "cats": [ - "5" - ], - "icon": "Linkedin.svg", - "script": "//platform\\.linkedin\\.com/in\\.js", - "website": "http://linkedin.com" - }, - "List.js": { - "cats": [ - "12" - ], - "env": "^List$", - "icon": "List.js.png", - "script": "^list\\.(?:min\\.)?js$", - "website": "http://www.listjs.com" - }, - "LiteSpeed": { - "cats": [ - "22" - ], - "headers": { - "Server": "^LiteSpeed$" - }, - "icon": "LiteSpeed.png", - "website": "http://litespeedtech.com" - }, - "Lithium": { - "cats": [ - "1" - ], - "env": [ - "^LITHIUM$" - ], - "headers": { - "Set-Cookie": "LithiumVisitor=" - }, - "html": " ]+Powered by Lithium", - "icon": "Lithium.png", - "implies": "PHP", - "website": "http://www.lithium.com" - }, - "LiveAgent": { - "cats": [ - "52" - ], - "env": "^LiveAgent$", - "icon": "LiveAgent.png", - "website": "http://www.ladesk.com" - }, - "LiveChat": { - "cats": [ - "52" - ], - "icon": "LiveChat.png", - "script": "cdn\\.livechatinc\\.com/.*tracking\\.js", - "website": "http://livechatinc.com" - }, - "LiveJournal": { - "cats": [ - "11" - ], - "icon": "LiveJournal.png", - "url": "\\.livejournal\\.com", - "website": "http://www.livejournal.com" - }, - "LivePerson": { - "cats": [ - "52" - ], - "icon": "LivePerson.png", - "script": "^https?://lptag\\.liveperson\\.net/tag/tag\\.js", - "website": "https://www.liveperson.com/" - }, - "LiveStreet CMS": { - "cats": [ - "1" - ], - "env": "^LIVESTREET", - "headers": { - "X-Powered-By": "LiveStreet CMS" - }, - "icon": "LiveStreet CMS.png", - "implies": "PHP", - "website": "http://livestreetcms.com" - }, - "Livefyre": { - "cats": [ - "15" - ], - "env": [ - "^fyre$", - "^FyreLoader$" - ], - "html": "<[^>]+(?:id|class)=\"livefyre", - "icon": "Livefyre.png", - "script": "livefyre_init\\.js", - "website": "http://livefyre.com" - }, - "Liveinternet": { - "cats": [ - "10" - ], - "html": [ - "]*>[^]{0,128}?src\\s*=\\s*['\"]//counter\\.yadro\\.ru/hit(?:;\\S+)?\\?(?:t\\d+\\.\\d+;)?r", - "", - "", - "]*/sites/[a-z\\d]{24}/theme/stylesheets", - "icon": "Locomotive.png", - "implies": [ - "Ruby on Rails", - "MongoDB" - ], - "website": "http://www.locomotivecms.com" - }, - "Logitech Media Server": { - "cats": [ - "22", - "38" - ], - "headers": { - "Server": "Logitech Media Server(?: \\(([\\d\\.]+))?\\;version:\\1" - }, - "icon": "Logitech Media Server.png", - "website": "http://www.mysqueezebox.com" - }, - "Lotus Domino": { - "cats": [ - "22" - ], - "headers": { - "Server": "Lotus-Domino" - }, - "icon": "Lotus Domino.png", - "implies": "Java", - "website": "http://www-01.ibm.com/software/lotus/products/domino" - }, - "Lua": { - "cats": [ - "27" - ], - "headers": { - "X-Powered-By": "\bLua(?: ([\\d.]+))?\\;version:\\1" - }, - "icon": "Lua.png", - "website": "http://www.lua.org" - }, - "Lucene": { - "cats": [ - "34" - ], - "icon": "Lucene.png", - "implies": "Java", - "website": "http://lucene.apache.org/core/" - }, - "Luigi’s Box": { - "cats": [ - "10", - "29" - ], - "env": "^Luigis$", - "icon": "Luigisbox.svg", - "website": "https://www.luigisbox.com" - }, - "M.R. Inc BoxyOS": { - "cats": [ - "28" - ], - "icon": "M.R. Inc.png", - "website": "http://mrincworld.com" - }, - "M.R. Inc SiteFrame": { - "cats": [ - "18" - ], - "headers": { - "Powered-By": "M\\.R\\. Inc SiteFrame" - }, - "icon": "M.R. Inc.png", - "website": "http://mrincworld.com" - }, - "M.R. Inc Webserver": { - "cats": [ - "22" - ], - "headers": { - "Server": "M\\.R\\. Inc Webserver" - }, - "icon": "M.R. Inc.png", - "implies": [ - "M.R. Inc BoxyOS" - ], - "website": "http://mrincworld.com" - }, - "MHonArc": { - "cats": [ - "50" - ], - "html": "\\;version:\\1", - "icon": "mhonarc.png", - "website": "http://www.mhonarc.at" - }, - "MOBOTIX": { - "cats": [ - "39" - ], - "icon": "MOBOTIX.png", - "meta": { - "author": "MOBOTIX AG\\;confidence:40", - "copyright": "MOBOTIX AG\\;confidence:40", - "publisher": "MOBOTIX AG\\;confidence:40" - }, - "url": "control/userimage\\.html\\;confidence:70", - "website": "http://mobotix.com" - }, - "MODX": { - "cats": [ - "1" - ], - "env": "^MODX_MEDIA_PATH$", - "headers": { - "Set-Cookie": "SN5[a-f\\d]{12}", - "X-Powered-By": "^MODX" - }, - "html": [ - "]+>Powered by MODX", - "<(?:link|script)[^>]+assets/snippets/\\;confidence:20", - "]+id=\"ajaxSearch_form\\;confidence:20", - "]+id=\"ajaxSearch_input\\;confidence:20" - ], - "icon": "MODX.png", - "implies": "PHP", - "meta": { - "generator": "MODX[^\\d.]*([\\d.]+)?\\;version:\\1" - }, - "website": "http://modx.com" - }, - "MadAdsMedia": { - "cats": [ - "36" - ], - "env": "^setM(?:Iframe|RefURL)$", - "icon": "MadAdsMedia.png", - "script": "^https?://(?:ads-by|pixel)\\.madadsmedia.com/", - "website": "http://madadsmedia.com" - }, - "Magento": { - "cats": [ - "6" - ], - "env": [ - "^(?:Mage|VarienForm)$" - ], - "headers": { - "Set-Cookie": "frontend=\\;confidence:50" - }, - "html": [ - "