Merge branch 'master' of github.com:AliasIO/wappalyzer

main
Elbert Alias 4 years ago
commit 0480d00e7e

@ -2,19 +2,18 @@ module.exports = {
root: true,
env: {
browser: true,
node: true
node: true,
},
parserOptions: {
parser: 'babel-eslint'
parser: 'babel-eslint',
},
extends: [
'@nuxtjs',
'prettier',
'prettier/vue',
'plugin:prettier/recommended',
'plugin:nuxt/recommended'
],
plugins: [
'prettier'
'plugin:nuxt/recommended',
'plugin:json/recommended',
],
plugins: ['prettier'],
}

@ -0,0 +1,25 @@
name: Validate
on:
push:
pull_request:
jobs:
validate:
name: Validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.3
- uses: actions/setup-node@v2.1.2
with:
node-version: '14'
- name: Restore npm cache
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm install
- name: Validate
run: npm run validate

@ -6,174 +6,167 @@ const { technologies, categories } = JSON.parse(
fs.readFileSync('./src/technologies.json')
)
try {
Object.keys(technologies).forEach((name) => {
const technology = technologies[name]
// Validate regular expressions
;['url', 'html', 'meta', 'headers', 'cookies', 'script', 'js'].forEach(
(type) => {
if (technology[type]) {
const keyed =
typeof technology[type] === 'string' ||
Array.isArray(technology[type])
? { _: technology[type] }
: technology[type]
Object.keys(keyed).forEach((key) => {
const patterns = Array.isArray(keyed[key])
? keyed[key]
: [keyed[key]]
patterns.forEach((pattern, index) => {
const id = `${name}: ${type}[${key === '_' ? `${index}` : key}]`
const [regex, ...flags] = pattern.split('\\;')
let maxGroups = 0
flags.forEach((flag) => {
const [key, value] = flag.split(':')
if (key === 'version') {
const refs = value.match(/\\(\d+)/g)
if (refs) {
maxGroups = refs.reduce((max, ref) =>
Math.max(max, parseInt(refs[1] || 0))
)
}
} else if (key === 'confidence') {
if (
!/^\d+$/.test(value) ||
parseInt(value, 10) < 0 ||
parseInt(value, 10) > 99
) {
throw new Error(
`Confidence value must a number between 0 and 99: ${value} (${id})`
)
}
} else {
throw new Error(`Invalid flag: ${key} (${id})`)
}
})
// Validate regular expression
try {
// eslint-disable-next-line no-new
new RegExp(regex)
} catch (error) {
throw new Error(`${error.message} (${id})`)
}
// Count capture groups
const groups = new RegExp(`${regex}|`).exec('').length - 1
Object.keys(technologies).forEach((name) => {
const technology = technologies[name]
if (groups > maxGroups) {
throw new Error(
`Too many non-capturing groups, expected ${maxGroups}: ${regex} (${id})`
)
}
// Validate regular expressions
;['url', 'html', 'meta', 'headers', 'cookies', 'script', 'js'].forEach(
(type) => {
if (technology[type]) {
const keyed =
typeof technology[type] === 'string' ||
Array.isArray(technology[type])
? { _: technology[type] }
: technology[type]
if (type === 'html' && !/[<>]/.test(regex)) {
throw new Error(
`HTML pattern must include < or >: ${regex} (${id})`
)
}
})
})
}
}
)
Object.keys(keyed).forEach((key) => {
const patterns = Array.isArray(keyed[key]) ? keyed[key] : [keyed[key]]
// Validate categories
technology.cats.forEach((id) => {
if (!categories[id]) {
throw new Error(`No such category: ${id} (${name})`)
}
})
patterns.forEach((pattern, index) => {
const id = `${name}: ${type}[${key === '_' ? `${index}` : key}]`
// Validate icons
if (technology.icon && !fs.existsSync(`${iconPath}/${technology.icon}`)) {
throw new Error(`No such icon: ${technology.icon} (${name})`)
}
const [regex, ...flags] = pattern.split('\\;')
// Validate website URLs
try {
// eslint-disable-next-line no-new
const { protocol } = new URL(technology.website)
let maxGroups = 0
if (protocol !== 'http:' && protocol !== 'https:') {
throw new Error('Invalid protocol')
}
} catch (error) {
throw new Error(`Invalid website URL: ${technology.website} (${name})`)
}
flags.forEach((flag) => {
const [key, value] = flag.split(':')
// Validate implies and excludes
const { implies, excludes } = technology
if (key === 'version') {
const refs = value.match(/\\(\d+)/g)
if (implies) {
;(Array.isArray(implies) ? implies : [implies]).forEach((implied) => {
const [_name, ...flags] = implied.split('\\;')
if (refs) {
maxGroups = refs.reduce((max, ref) =>
Math.max(max, parseInt(refs[1] || 0))
)
}
} else if (key === 'confidence') {
if (
!/^\d+$/.test(value) ||
parseInt(value, 10) < 0 ||
parseInt(value, 10) > 99
) {
throw new Error(
`Confidence value must a number between 0 and 99: ${value} (${id})`
)
}
} else {
throw new Error(`Invalid flag: ${key} (${id})`)
}
})
const id = `${name}: implies[${implied}]`
// Validate regular expression
try {
// eslint-disable-next-line no-new
new RegExp(regex)
} catch (error) {
throw new Error(`${error.message} (${id})`)
}
if (!technologies[_name]) {
throw new Error(`Implied technology does not exist: ${_name} (${id})`)
}
// Count capture groups
const groups = new RegExp(`${regex}|`).exec('').length - 1
flags.forEach((flag) => {
const [key, value] = flag.split(':')
if (groups > maxGroups) {
throw new Error(
`Too many non-capturing groups, expected ${maxGroups}: ${regex} (${id})`
)
}
if (key === 'confidence') {
if (
!/^\d+$/.test(value) ||
parseInt(value, 10) < 0 ||
parseInt(value, 10) > 99
) {
if (type === 'html' && !/[<>]/.test(regex)) {
throw new Error(
`Confidence value must a number between 0 and 99: ${value} (${id})`
`HTML pattern must include < or >: ${regex} (${id})`
)
}
} else {
throw new Error(`Invalid flag: ${key} (${id})`)
}
})
})
})
}
}
)
if (excludes) {
;(Array.isArray(excludes) ? excludes : [excludes]).forEach((excluded) => {
const id = `${name}: excludes[${excluded}]`
if (!technologies[excluded]) {
throw new Error(
`Excluded technology does not exist: ${excluded} (${id})`
)
}
})
// Validate categories
technology.cats.forEach((id) => {
if (!categories[id]) {
throw new Error(`No such category: ${id} (${name})`)
}
})
// Validate icons
fs.readdirSync(iconPath).forEach((file) => {
const filePath = `${iconPath}/${file}`
if (technology.icon && !fs.existsSync(`${iconPath}/${technology.icon}`)) {
throw new Error(`No such icon: ${technology.icon} (${name})`)
}
// Validate website URLs
try {
// eslint-disable-next-line no-new
const { protocol } = new URL(technology.website)
if (protocol !== 'http:' && protocol !== 'https:') {
throw new Error('Invalid protocol')
}
} catch (error) {
throw new Error(`Invalid website URL: ${technology.website} (${name})`)
}
// Validate implies and excludes
const { implies, excludes } = technology
if (implies) {
;(Array.isArray(implies) ? implies : [implies]).forEach((implied) => {
const [_name, ...flags] = implied.split('\\;')
const id = `${name}: implies[${implied}]`
if (fs.statSync(filePath).isFile() && !file.startsWith('.')) {
if (!/^(png|svg)$/i.test(file.split('.').pop())) {
throw new Error(`Incorrect file type, expected PNG or SVG: ${filePath}`)
if (!technologies[_name]) {
throw new Error(`Implied technology does not exist: ${_name} (${id})`)
}
if (
!Object.values(technologies).some(({ icon }) => icon === file) &&
file !== 'default.svg'
) {
throw new Error(`Extraneous file: ${filePath}}`)
flags.forEach((flag) => {
const [key, value] = flag.split(':')
if (key === 'confidence') {
if (
!/^\d+$/.test(value) ||
parseInt(value, 10) < 0 ||
parseInt(value, 10) > 99
) {
throw new Error(
`Confidence value must a number between 0 and 99: ${value} (${id})`
)
}
} else {
throw new Error(`Invalid flag: ${key} (${id})`)
}
})
})
}
if (excludes) {
;(Array.isArray(excludes) ? excludes : [excludes]).forEach((excluded) => {
const id = `${name}: excludes[${excluded}]`
if (!technologies[excluded]) {
throw new Error(
`Excluded technology does not exist: ${excluded} (${id})`
)
}
})
}
})
// Validate icons
fs.readdirSync(iconPath).forEach((file) => {
const filePath = `${iconPath}/${file}`
if (fs.statSync(filePath).isFile() && !file.startsWith('.')) {
if (!/^(png|svg)$/i.test(file.split('.').pop())) {
throw new Error(`Incorrect file type, expected PNG or SVG: ${filePath}`)
}
})
} catch (error) {
// eslint-disable-next-line no-console
console.error(error.message)
}
if (
!Object.values(technologies).some(({ icon }) => icon === file) &&
file !== 'default.svg'
) {
throw new Error(`Extraneous file: ${filePath}}`)
}
}
})

@ -8,15 +8,17 @@
"@nuxtjs/eslint-config": "^3.1.0",
"@nuxtjs/eslint-module": "^2.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0",
"eslint": "^7.13.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-json": "^2.1.2",
"eslint-plugin-nuxt": "^1.0.0",
"eslint-plugin-prettier": "^3.1.4",
"prettier": "^2.1.0"
"prettier": "^2.1.2"
},
"scripts": {
"link": "node ./bin/link.js",
"lint": "eslint --fix src/**/*.js",
"lint": "eslint src/**/*.{js,json}",
"lint:fix": "eslint --fix src/**/*.{js,json}",
"validate": "yarn run lint && jsonlint -qV ./schema.json ./src/technologies.json && node ./bin/validate.js",
"convert": "cd ./src/drivers/webextension/images/icons ; cp *.svg converted ; cd converted ; convert-svg-to-png *.svg --width 32 --height 32 ; rm *.svg",
"prettify": "jsonlint -si --trim-trailing-commas --enforce-double-quotes ./src/technologies.json",

@ -93,6 +93,6 @@
"categoryName71": { "message": "Affiliate program" },
"categoryName72": { "message": "Appointment scheduling" },
"categoryName73": { "message": "Surveys" },
"categoryName75": { "message": "A/B testing" },
"categoryName74": { "message": "A/B testing" },
"categoryName75": { "message": "Email" }
}

@ -0,0 +1,9 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="32" height="32" fill="url(#pattern0)"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0" transform="scale(0.00444444)"/>
</pattern>
<image id="image0" width="225" height="225" xlink:href="data:image/png;base64,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"/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -0,0 +1,9 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="32" height="32" fill="url(#pattern0)"/>
<defs>
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0" transform="scale(0.00769231)"/>
</pattern>
<image id="image0" width="130" height="130" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAACCCAMAAAC93eDPAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAnFBMVEUFEDlTW3djaoTw8fM0PV7h4uf///8VH0WytcKCiJzR09tzeZBETGskDjJEDCtzCSCCCByyBRLBBA5TCyc0DS4kLlLwAQP/AADRAwuSBxljCiQVDzWiprWiBhXhAgeeZnbw4eP2YWLBxM6Sl6nhwsfjoqfhgofogoX/QEDFFB3o0tXjsrf/UFD/MDD28fLlwsbucXT/EBD/YGD/ICDtoYUNAAAAAWJLR0QGYWa4fQAAAAd0SU1FB+QLDgsuJ3RW5rAAAAABb3JOVAHPoneaAAADh0lEQVR42u2ba5eaMBCGWS3T1SoEtFRh3e661tL77f//t+IFrzHMvAlwesrz2VPePplkJpR6XkdHR0fHf8Nd2wG8Xv9V2xF88l+3LIGI7tuWUDBoW0JBmyXp7yK0WJJ7CUTD1krSLyO0VpIHCQVv2pZQMHL+x4+DUEXxHqUmU7OEoiTfunx8oOLk3RWzeZrdluCwJLM00jz+ECMc35BQ8ODm778wPH9HnOolFPTsA6SzqudvSVSmk1Bge0Klj6wAZQhfE6FvVQ5BzA6wDfGedAzxANlcFKDgSRsBL8mAvwZ7nukGYEmKFdyUADbNjLcPeBIImeOm4kUwSShYihNUnkUyCQUvsgQpksAogYRz3AQJUCFBVpLQKlRKkDRNMEGVBOLPcRmyFzgSiH21kHUFiQRiznEKS8CSwJvjpmACngRWSYKFwJRAjKaJLgNXAlVeLcZgAr6EypKM6pdQMccFTUgwz3HgkSCTYCzJhiSQYY5bNCSBbl4tGtkOe27McQ2cCUf0c1ztB+MZujmu7u7AKEng2mAhQTvHAfcGGwmakswalkDXcxw2NVtIoKs5DiwFCwl0ebXA+oOVhMuSrOnuUMHpHIdVo6UEOmuaWJe0lUCncxwUwV4CncxxUI9yIOHkaoFEcCLhOMchEZxIoENJAhEcSaCyaQIRXEmg/Rwnj+BOAvXvsQj2EobLh8FgNIJ3BCzBXy4Hg7vR9cAijiCU0F8uXwa9kek+KT0dmRJWqw/rj3n+yWMgjWCU8Hn1Zb3+mn87/HrOiSDslDoJ31c/1uvnPNf8XHEiCOeFp3PXP/P8l+nnASuCaGr6vXVdLPIf3u/HrAjodY5DwkqATtAsIl4E9B7BIeRFQG9THKbMCPUVwyMzAXyzroZ1MG1B3y9Uwl0HzwtrSsBeh/r2BHc/bEDfuJlJMkGEegpyIUiAv301wusPJfDrV2cS6qgGUSVsGGNvGQwoYQL3p7TgTDjguFnxxqVz3G5Mfnc4xeUxPYMS4P8+dU0iOxKOIF+Q6JmACdztzBROAH89cIH0WHSfwS6Biwy2CewzYAfCRQarfWFTiUcy/HxIkGNZC9qyYml/Ni0GNNYrdwE2iyEXEfMvDUzGwq8+3dThBYJPT3cf4LYY4rG2ANvlmFeeVBHeFrlMTF9jR2GdAk6YhpFml8Zq0tDzS4JUlf81YK7CAJ2LOjo6Ojo6/iH+AuEpSS6Y40ErAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIwLTExLTE0VDExOjQ1OjE5KzAwOjAwotWfUAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMC0xMS0xNFQxMTo0NToxOSswMDowMNOIJ+wAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC"/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

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

Before

Width:  |  Height:  |  Size: 755 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="27" viewBox="0 0 28 27"><path fill="#20323c" d="M13.015 13.806H7.578a.712.712 0 01-.713-.713V7.66c0-.394.319-.713.713-.713h5.44v.002c.393 0 .712.319.712.711v5.434a.712.712 0 01-.712.712zm7.57-6.875l-5.854-5.854-.006.003a3.436 3.436 0 00-.994-.692v.008A3.397 3.397 0 0012.3.08H8.287a3.42 3.42 0 00-2.398.979h-.002L.955 5.988l.002.008A3.418 3.418 0 000 8.371V19.25a3.42 3.42 0 001.053 2.47l-.003.007 4.349 4.348.003-.002a.856.856 0 001.449-.467l.014-.001v-4.216h.001c0-.393.32-.712.713-.712H12.3c.95 0 1.81-.387 2.43-1.01l.008.002 4.796-4.796.001-.011c.05-.048.097-.101.144-.152l.907-.91z"/><path fill="#48a894" d="M20.59 13.805h6.85L20.59 6.94z"/><path fill="#20323c" d="M27.439 24.49l-.001-.02V13.8h-6.85v10.67a1.716 1.716 0 001.71 1.857h3.431c.907 0 1.648-.704 1.71-1.595z"/></svg>

After

Width:  |  Height:  |  Size: 841 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 118 KiB

@ -1,33 +0,0 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 230.39 230.39">
<defs>
<linearGradient id="circle" x1="173.17" y1="86.95" x2="141.86" y2="141.17" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#cc9300"/>
<stop offset="0.47" stop-color="#ea433a"/>
<stop offset="1" stop-color="#b327bf"/>
</linearGradient>
<linearGradient id="Square_2" data-name="Square 2" x1="92.49" y1="41" x2="67.07" y2="110.85" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#cc9300"/>
<stop offset="0.26" stop-color="#ea433a"/>
<stop offset="0.47" stop-color="#b327bf"/>
<stop offset="0.76" stop-color="#66f"/>
<stop offset="1" stop-color="#00bf9a"/>
</linearGradient>
<linearGradient id="triangle" x1="75.13" y1="190.31" x2="120.2" y2="143.64" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b327bf"/>
<stop offset="0.47" stop-color="#66f"/>
<stop offset="1" stop-color="#00c09a"/>
</linearGradient>
</defs>
<path d="M154.49,220.39l-44.16,7c-30.12,4.77-41.53,3.36-53.48-.78a62.25,62.25,0,0,1-29.59-21.5C19.63,195,14.77,184.61,10,154.49L3,110.33C-1.77,80.21-.36,68.8,3.78,56.85a62.25,62.25,0,0,1,21.5-29.59C35.36,19.63,45.78,14.77,75.9,10l44.16-7c30.12-4.77,41.53-3.36,53.48.78a62.18,62.18,0,0,1,29.58,21.5c7.64,10.08,12.5,20.5,17.27,50.62l7,44.16c4.77,30.12,3.36,41.53-.78,53.48a62.18,62.18,0,0,1-21.5,29.58C195,210.76,184.61,215.62,154.49,220.39Z" style="fill-rule: evenodd"/>
<g id="Group-2-Copy-4">
<g id="Group-Copy-5">
<g id="Group-4-Copy-10">
<g id="Group-21">
<path id="Oval-Copy-84" d="M162.43,145.1a31.43,31.43,0,1,0-35.65-26.17A31.28,31.28,0,0,0,162.43,145.1Zm-1.57-9.94a21.37,21.37,0,1,1,17.45-24.39A21.2,21.2,0,0,1,160.86,135.16Z" style="fill: url(#circle)"/>
<path id="Rectangle-Copy-64" d="M61,107.94l46.64-7.38a5,5,0,0,0,4.18-5.76l-7.4-46.71a5,5,0,0,0-5.76-4.19L52,51.29a5,5,0,0,0-4.18,5.76l7.4,46.71A5,5,0,0,0,61,107.94Zm3.39-10.72L58.52,60.45l36.7-5.81L101,91.41Z" style="fill: url(#Square_2)"/>
<path id="Triangle-Copy-15" d="M90.56,124.91,70.33,181.56a5,5,0,0,0,5.53,6.67l56.94-9a5,5,0,0,0,3.2-8.05L99.29,123.53A5,5,0,0,0,90.56,124.91ZM96.94,137l25.91,33.62L82.66,177Z" style="fill: url(#triangle)"/>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

@ -54,7 +54,7 @@ const Driver = {
),
tabs: {},
robots: await getOption('robots', {}),
ads: {},
ads: [],
}
chrome.browserAction.setBadgeBackgroundColor({ color: '#6B39BD' }, () => {})

@ -806,7 +806,8 @@
18
],
"cookies": {
"cookie_name": "adonis-session"
"adonis-session": "",
"adonis-session-values": ""
},
"icon": "AdonisJS.png",
"implies": "Node.js",
@ -2547,7 +2548,10 @@
"_bsap": "",
"_bsap_serving_callback": ""
},
"scripts": "^https?://s\\d\\.buysellads\\.com/",
"scripts": [
"^https?://s\\d\\.buysellads\\.com/",
"servedby-buysellads\\.com/monetization(?:\\.[\\w\\d]+)?\\.js"
],
"website": "http://buysellads.com"
},
"CCV Shop": {
@ -6683,6 +6687,15 @@
},
"website": "https://www.hubspot.com"
},
"HubSpot Analytics": {
"cats": [
10
],
"description": "HubSpot is a marketing and sales software that helps companies attract visitors, convert leads, and close customers.",
"icon": "HubSpot.png",
"scripts": "js\\.hs-analytics\\.net/analytics",
"website": "https://www.hubspot.com/products/marketing/analytics"
},
"Hugo": {
"cats": [
57
@ -9961,6 +9974,18 @@
},
"website": "https://en.oxid-esales.com/en/home.html"
},
"Ochanoko": {
"cats": [
6
],
"description": "Ochanoko is a ecommerce online shopping cart solutions, ecommerce web site hosting.",
"icon": "Ochanoko.svg",
"js": {
"ocnkProducts": ""
},
"scripts": "ocnk-min\\.js",
"website": "https://www.ocnk.com"
},
"October CMS": {
"cats": [
1
@ -10454,6 +10479,17 @@
"url": "/owa/auth/log(?:on|off)\\.aspx",
"website": "http://help.outlook.com"
},
"Oxatis": {
"cats": [
6
],
"description": "Oxatis is a cloud-based ecommerce solution which enables users to create and manage their own online store websites.",
"icon": "Oxatis.svg",
"meta": {
"generator": "^Oxatis\\s\\(www\\.oxatis\\.com\\)$"
},
"website": "https://www.oxatis.com/"
},
"Oxygen": {
"cats": [
51
@ -11258,6 +11294,16 @@
"scripts": "prism\\.js",
"website": "http://prismjs.com"
},
"Profitwell": {
"cats": [
10
],
"icon": "Profitwell.svg",
"scripts": [
"public\\.profitwell\\.com/js/profitwell\\.js"
],
"website": "https://www.profitwell.com/"
},
"Project Wonderful": {
"cats": [
36
@ -13373,7 +13419,7 @@
"SMARTSTORE.VISITOR": ""
},
"html": "<!--Powered by SmartStore\\.NET - https://www\\.smartstore\\.com-->",
"icon": "smartstore.png",
"icon": "Smartstore.png",
"implies": "Microsoft ASP.NET",
"meta": {
"generator": "^SmartStore.NET (.+)$\\;version:\\1"
@ -14522,6 +14568,18 @@
"implies": "PHP",
"website": "http://www.thinkphp.cn"
},
"ThriveCart": {
"cats": [
6
],
"description": "ThriveCart is a sales cart solution that lets you create checkout pages for your online products and services.",
"icon": "ThriveCart.svg",
"js": {
"ThriveCart": ""
},
"scripts": "thrivecart\\.js",
"website": "https://thrivecart.com"
},
"Ticimax": {
"cats": [
6
@ -15347,6 +15405,21 @@
"scripts": "secure\\.checkout\\.visa\\.com",
"website": "https://checkout.visa.com"
},
"Visualsoft": {
"cats": [
6
],
"description": "Visualsoft is an ecommerce agency that delivers web design, development and marketing services to online retailers.",
"icon": "Visualsoft.svg",
"cookies": {
"vscommerce": ""
},
"meta": {
"vs_status_checker_version": "\\d+",
"vsvatprices": ""
},
"website": "https://www.visualsoft.co.uk/"
},
"Visual Website Optimizer": {
"cats": [
10

Loading…
Cancel
Save