Merge branch 'master' into master

main
Elbert Alias 4 years ago committed by GitHub
commit 38e1a4bd3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,18 @@
name: Close inactive issues
on:
schedule:
- cron: "30 0 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
days-before-stale: 90
days-before-close: 14
stale-issue-label: "stale"
stale-pr-message: "This PR is stale because it has been open for 90 days with no activity."
close-pr-message: "This PR was closed because it has been inactive for 14 days since being marked as stale."
stale-issue-message: "This issue is stale because it has been open for 90 days with no activity."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."

@ -1,4 +1,4 @@
[![Travis](https://travis-ci.org/aliasio/wappalyzer.svg?branch=master)](https://travis-ci.org/aliasio/wappalyzer/) [![Validate](https://github.com/AliasIO/wappalyzer/actions/workflows/validate.yml/badge.svg)](https://github.com/AliasIO/wappalyzer/actions/workflows/validate.yml)
[![wappalyzer NPM](https://img.shields.io/badge/npm-wappalyzer-blue)](https://www.npmjs.com/package/wappalyzer) [![wappalyzer NPM](https://img.shields.io/badge/npm-wappalyzer-blue)](https://www.npmjs.com/package/wappalyzer)
[![wappalyzer-core NPM](https://img.shields.io/badge/npm-wappalyzer--core-blue)](https://www.npmjs.com/package/wappalyzer-core) [![wappalyzer-core NPM](https://img.shields.io/badge/npm-wappalyzer--core-blue)](https://www.npmjs.com/package/wappalyzer-core)
[![Github Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/AliasIO)](https://github.com/sponsors/AliasIO) [![Github Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&link=https://github.com/sponsors/AliasIO)](https://github.com/sponsors/AliasIO)

@ -19,7 +19,6 @@ const { AWS_LAMBDA_FUNCTION_NAME, CHROMIUM_BIN, CHROMIUM_DATA_DIR } =
let puppeteer let puppeteer
let chromiumArgs = [ let chromiumArgs = [
'--no-sandbox', '--no-sandbox',
'--single-process',
'--no-zygote', '--no-zygote',
'--disable-gpu', '--disable-gpu',
'--ignore-certificate-errors', '--ignore-certificate-errors',
@ -460,7 +459,8 @@ class Site {
promiseTimeout( promiseTimeout(
promise, promise,
fallback, fallback,
errorMessage = 'Operation took too long to respond' errorMessage = 'Operation took too long to respond',
maxWait = this.options.maxWait
) { ) {
let timeout = null let timeout = null
@ -478,7 +478,7 @@ class Site {
error.code = 'PROMISE_TIMEOUT_ERROR' error.code = 'PROMISE_TIMEOUT_ERROR'
fallback !== undefined ? resolve(fallback) : reject(error) fallback !== undefined ? resolve(fallback) : reject(error)
}, this.options.maxWait) }, maxWait)
}), }),
promise.then((value) => { promise.then((value) => {
clearTimeout(timeout) clearTimeout(timeout)
@ -615,11 +615,16 @@ class Site {
await page.setUserAgent(this.options.userAgent) await page.setUserAgent(this.options.userAgent)
try { try {
await this.promiseTimeout( try {
page.goto(url.href), await this.promiseTimeout(page.goto(url.href))
undefined, } catch (error) {
'Timeout (navigation)' if (
) error.constructor.name !== 'TimeoutError' &&
error.code !== 'PROMISE_TIMEOUT_ERROR'
) {
throw error
}
}
if (!this.options.noScripts) { if (!this.options.noScripts) {
await sleep(1000) await sleep(1000)
@ -779,11 +784,7 @@ class Site {
this.analyzedUrls[url.href] && this.analyzedUrls[url.href] &&
!this.analyzedUrls[url.href].status !this.analyzedUrls[url.href].status
) { ) {
await page.close() throw new Error('No response from server')
this.log(`Page closed (${url})`)
throw new Error(`No response from server`)
} }
this.cache[url.href] = { this.cache[url.href] = {
@ -843,10 +844,18 @@ class Site {
await page.close() await page.close()
this.log('Page closed') this.log(`Page closed (${url})`)
return reducedLinks return reducedLinks
} catch (error) { } catch (error) {
try {
await page.close()
this.log(`Page closed (${url})`)
} catch (error) {
this.log(error)
}
let hostname = url let hostname = url
try { try {
@ -890,17 +899,26 @@ class Site {
await sleep(this.options.delay * index) await sleep(this.options.delay * index)
} }
const links = await this.goto(url) await Promise.all([
(async () => {
if (links && this.options.recursive && depth < this.options.maxDepth) { const links = await this.goto(url)
await this.batch(links.slice(0, this.options.maxUrls), depth + 1)
}
if (this.options.probe && !this.probed) { if (
this.probed = true links &&
this.options.recursive &&
depth < this.options.maxDepth
) {
await this.batch(links.slice(0, this.options.maxUrls), depth + 1)
}
})(),
(async () => {
if (this.options.probe && !this.probed) {
this.probed = true
await this.probe(url) await this.probe(url)
} }
})(),
])
} catch (error) { } catch (error) {
this.analyzedUrls[url.href] = { this.analyzedUrls[url.href] = {
status: 0, status: 0,
@ -950,31 +968,9 @@ class Site {
magento: '/magento_version', magento: '/magento_version',
} }
for (const file of Object.keys(files)) {
const path = files[file]
try {
await sleep(this.options.delay)
const body = await get(new URL(path, url.href), {
userAgent: this.options.userAgent,
timeout: Math.min(this.options.maxWait, 3000),
})
this.log(`get ${path}: ok`)
await this.onDetect(
url,
await analyze({ [file]: body.slice(0, 100000) })
)
} catch (error) {
this.error(`get ${path}: ${error.message || error}`)
}
}
// DNS // DNS
const records = {} const records = {}
const resolve = (func, hostname) => { const resolveDns = (func, hostname) => {
return this.promiseTimeout( return this.promiseTimeout(
func(hostname).catch((error) => { func(hostname).catch((error) => {
if (error.code !== 'ENODATA') { if (error.code !== 'ENODATA') {
@ -984,39 +980,74 @@ class Site {
return [] return []
}), }),
[], [],
'Timeout (dns)' 'Timeout (dns)',
Math.min(this.options.maxWait, 15000)
) )
} }
const domain = url.hostname.replace(/^www\./, '') const domain = url.hostname.replace(/^www\./, '')
;[records.cname, records.ns, records.mx, records.txt, records.soa] = await Promise.all([
await Promise.all([ // Static files
resolve(dns.resolveCname, url.hostname), ...Object.keys(files).map(async (file, index) => {
resolve(dns.resolveNs, domain), const path = files[file]
resolve(dns.resolveMx, domain),
resolve(dns.resolveTxt, domain),
resolve(dns.resolveSoa, domain),
])
const dnsRecords = Object.keys(records).reduce((dns, type) => { try {
dns[type] = dns[type] || [] await sleep(this.options.delay * index)
Array.prototype.push.apply( const body = await get(new URL(path, url.href), {
dns[type], userAgent: this.options.userAgent,
Array.isArray(records[type]) timeout: Math.min(this.options.maxWait, 3000),
? records[type].map((value) => { })
return typeof value === 'object'
? Object.values(value).join(' ') this.log(`Probe ok (${path})`)
: value
}) await this.onDetect(
: [Object.values(records[type]).join(' ')] url,
) await analyze({ [file]: body.slice(0, 100000) })
)
} catch (error) {
this.error(`Probe failed (${path}): ${error.message || error}`)
}
}),
// DNS
// eslint-disable-next-line no-async-promise-executor
new Promise(async (resolve, reject) => {
;[records.cname, records.ns, records.mx, records.txt, records.soa] =
await Promise.all([
resolveDns(dns.resolveCname, url.hostname),
resolveDns(dns.resolveNs, domain),
resolveDns(dns.resolveMx, domain),
resolveDns(dns.resolveTxt, domain),
resolveDns(dns.resolveSoa, domain),
])
const dnsRecords = Object.keys(records).reduce((dns, type) => {
dns[type] = dns[type] || []
return dns Array.prototype.push.apply(
}, {}) dns[type],
Array.isArray(records[type])
? records[type].map((value) => {
return typeof value === 'object'
? Object.values(value).join(' ')
: value
})
: [Object.values(records[type]).join(' ')]
)
await this.onDetect(url, await analyze({ dns: dnsRecords })) return dns
}, {})
this.log(
`Probe DNS ok: (${Object.values(dnsRecords).flat().length} records)`
)
await this.onDetect(url, await analyze({ dns: dnsRecords }))
resolve()
}),
])
} }
async batch(links, depth, batch = 0) { async batch(links, depth, batch = 0) {
@ -1108,8 +1139,6 @@ class Site {
if (page) { if (page) {
try { try {
await page.close() await page.close()
this.log('Page closed')
} catch (error) { } catch (error) {
// Continue // Continue
} }

@ -13,7 +13,7 @@
"software" "software"
], ],
"homepage": "https://www.wappalyzer.com/", "homepage": "https://www.wappalyzer.com/",
"version": "6.8.5", "version": "6.8.9",
"author": "Wappalyzer", "author": "Wappalyzer",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
@ -43,4 +43,4 @@
"dependencies": { "dependencies": {
"puppeteer": "^5.3.0" "puppeteer": "^5.3.0"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M28 0H4C2 0 0 2 0 4V28C0 30.2092 1.79086 32 4 32H28C30.2092 32 32 30.2092 32 28V4C32 1.79086 30.2092 0 28 0ZM23.4334 12.5195L22.302 11.3882L20.0392 13.6509L21.1706 14.7823L23.4334 12.5195ZM19.332 9.83258C19.7225 9.44206 20.3556 9.44206 20.7462 9.83258L22.3018 11.3882L10.9881 22.702L8.72538 20.4392L19.332 9.83258ZM14.8066 5.3072C15.1971 4.91668 15.8303 4.91668 16.2208 5.3072L17.7765 6.86284L17.7764 6.86292L18.9076 7.99414L16.6449 10.2569L15.5136 9.12566L8.7255 15.9138L9.85682 17.0451L7.59408 19.3079L6.46276 18.1765L6.46274 18.1766L4.90712 16.6209C4.51658 16.2304 4.51658 15.5972 4.90712 15.2067L14.8066 5.3072ZM26.8274 15.9137L27.9588 17.0451L25.696 19.3079L24.5646 18.1765L26.8274 15.9137ZM13.2508 24.9646L13.2509 24.9644L12.1197 23.8334L14.3825 21.5706L15.5136 22.7018L23.8574 14.358C24.2478 13.9674 24.881 13.9674 25.2716 14.358L26.8272 15.9136L16.2206 26.5202C15.8301 26.9108 15.1969 26.9108 14.8064 26.5202L13.2508 24.9646Z" fill="#2B2C30"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -4,7 +4,7 @@
"author": "Wappalyzer", "author": "Wappalyzer",
"homepage_url": "https://www.wappalyzer.com/", "homepage_url": "https://www.wappalyzer.com/",
"description": "Identify web technologies", "description": "Identify web technologies",
"version": "6.8.5", "version": "6.8.9",
"default_locale": "en", "default_locale": "en",
"manifest_version": 2, "manifest_version": 2,
"icons": { "icons": {

@ -13,7 +13,7 @@
"software" "software"
], ],
"homepage": "https://www.wappalyzer.com/", "homepage": "https://www.wappalyzer.com/",
"version": "6.8.5", "version": "6.8.9",
"author": "Wappalyzer", "author": "Wappalyzer",
"license": "MIT", "license": "MIT",
"repository": { "repository": {

@ -346,8 +346,8 @@
"description": "Blackbaud Luminate Online provides online fundraising and marketing automation for nonprofits.", "description": "Blackbaud Luminate Online provides online fundraising and marketing automation for nonprofits.",
"icon": "Blackbaud-Luminate-Online.png", "icon": "Blackbaud-Luminate-Online.png",
"js": { "js": {
"don_premium_map": "", "BLACKBAUD": "",
"BLACKBAUD": "" "don_premium_map": ""
}, },
"scripts": "js/convio/modules\\.js", "scripts": "js/convio/modules\\.js",
"url": "/site/Donation2?.*df_id=", "url": "/site/Donation2?.*df_id=",
@ -415,9 +415,12 @@
], ],
"description": "Blitz provides intelligent static page caching for creating lightning-fast sites with Craft CMS.", "description": "Blitz provides intelligent static page caching for creating lightning-fast sites with Craft CMS.",
"html": "<!-- Cached by Blitz on", "html": "<!-- Cached by Blitz on",
"implies": "Craft CMS",
"pricing": ["onetime", "low"],
"icon": "Blitz.svg", "icon": "Blitz.svg",
"implies": "Craft CMS",
"pricing": [
"onetime",
"low"
],
"website": "https://putyourlightson.com/plugins/blitz" "website": "https://putyourlightson.com/plugins/blitz"
}, },
"Blogger": { "Blogger": {
@ -1261,4 +1264,4 @@
"scripts": "basket.*\\.js\\;confidence:10", "scripts": "basket.*\\.js\\;confidence:10",
"website": "https://addyosmani.github.io/basket.js/" "website": "https://addyosmani.github.io/basket.js/"
} }
} }

@ -258,7 +258,7 @@
}, },
"scripts": [ "scripts": [
"googlecommerce\\.com/trustedstores/api/js" "googlecommerce\\.com/trustedstores/api/js"
], ],
"website": "https://www.wappalyzer.com/technologies/ecommerce/cart-functionality" "website": "https://www.wappalyzer.com/technologies/ecommerce/cart-functionality"
}, },
"CartStack": { "CartStack": {
@ -619,20 +619,20 @@
21 21
], ],
"description": "Classeh is a LMS that allows user to participate in webinars and also use LMS options like messanger,finances,homework,quiz and some extra options like sending messages and more.", "description": "Classeh is a LMS that allows user to participate in webinars and also use LMS options like messanger,finances,homework,quiz and some extra options like sending messages and more.",
"dom": "a[href*='apps.classeh.ir'][target='_blank']",
"icon": "Classeh.svg", "icon": "Classeh.svg",
"implies": [ "implies": [
"PHP", "PHP",
"React", "React",
"Python" "Python"
], ],
"dom": "a[href*='apps.classeh.ir'][target='_blank']",
"meta": { "meta": {
"author": "^fanavar\\.org$" "author": "^fanavar\\.org$"
}, },
"saas": true,
"pricing": [ "pricing": [
"recurring" "recurring"
], ],
"saas": true,
"website": "https://fanavar.org" "website": "https://fanavar.org"
}, },
"Classy": { "Classy": {
@ -1524,7 +1524,7 @@
"icon": "cookieyes.svg", "icon": "cookieyes.svg",
"js": { "js": {
"cookieYes": "" "cookieYes": ""
}, },
"scripts": [ "scripts": [
"app\\.cookieyes\\.com/client_data/", "app\\.cookieyes\\.com/client_data/",
"cdn-cookieyes\\.com/client_data/" "cdn-cookieyes\\.com/client_data/"
@ -1637,9 +1637,9 @@
}, },
"scripts": [ "scripts": [
"static\\.cloud\\.coveo\\.com" "static\\.cloud\\.coveo\\.com"
], ],
"website": "https://www.coveo.com/" "website": "https://www.coveo.com/"
}, },
"CoverManager": { "CoverManager": {
"cats": [ "cats": [
5, 5,
@ -1848,6 +1848,10 @@
], ],
"description": "Customer.io is an automated messaging platform for marketers.", "description": "Customer.io is an automated messaging platform for marketers.",
"icon": "Customer.io.png", "icon": "Customer.io.png",
"pricing": [
"recurring",
"mid"
],
"saas": true, "saas": true,
"pricing": ["recurring", "mid"], "pricing": ["recurring", "mid"],
"scripts": "assets\\.customer\\.io", "scripts": "assets\\.customer\\.io",
@ -1961,4 +1965,4 @@
"oss": true, "oss": true,
"website": "https://github.com/zloirock/core-js" "website": "https://github.com/zloirock/core-js"
} }
} }

@ -535,9 +535,9 @@
"description": "Flow is an ecommerce platform that enables brands and retailers to sell their merchandise to customers internationally by creating localized shopping experiences.", "description": "Flow is an ecommerce platform that enables brands and retailers to sell their merchandise to customers internationally by creating localized shopping experiences.",
"icon": "Flow.png", "icon": "Flow.png",
"js": { "js": {
"flow.cart": "",
"flow.countryPicker": "", "flow.countryPicker": "",
"flow_cart_localize": "", "flow_cart_localize": ""
"flow.cart": ""
}, },
"pricing": [ "pricing": [
"poa" "poa"
@ -631,7 +631,6 @@
17 17
], ],
"description": "Fork Awesome is now a community effort based on Font Awesome by Dave Gandy.", "description": "Fork Awesome is now a community effort based on Font Awesome by Dave Gandy.",
"icon": "Fork Awesome.png",
"dom": { "dom": {
"link[href*='fork-awesome.min.css']": { "link[href*='fork-awesome.min.css']": {
"attributes": { "attributes": {
@ -644,6 +643,7 @@
} }
} }
}, },
"icon": "Fork Awesome.png",
"oss": true, "oss": true,
"website": "https://forkaweso.me" "website": "https://forkaweso.me"
}, },
@ -843,7 +843,7 @@
"icon": "Freshchat.svg", "icon": "Freshchat.svg",
"js": { "js": {
"Freshbots": "" "Freshbots": ""
}, },
"pricing": [ "pricing": [
"low", "low",
"recurring" "recurring"

@ -1,4 +1,18 @@
{ {
"GEOvendas": {
"cats": [
6
],
"description": "GEOvendas is an ecommerce platform with analytics, sales force, B2B and B2C products.",
"dom": "a[href*='geovendas.com.br'][target='_blank']",
"icon": "GEOvendas.svg",
"pricing": [
"mid",
"recurring"
],
"saas": true,
"website": "https://www.geovendas.com"
},
"GOV.UK Elements": { "GOV.UK Elements": {
"cats": [ "cats": [
66 66
@ -263,20 +277,6 @@
"icon": "Gentoo.png", "icon": "Gentoo.png",
"website": "http://www.gentoo.org" "website": "http://www.gentoo.org"
}, },
"GEOvendas": {
"cats": [
6
],
"description": "GEOvendas is an ecommerce platform with analytics, sales force, B2B and B2C products.",
"icon": "GEOvendas.svg",
"dom": "a[href*='geovendas.com.br'][target='_blank']",
"saas": true,
"pricing": [
"mid",
"recurring"
],
"website": "https://www.geovendas.com"
},
"Gerrit": { "Gerrit": {
"cats": [ "cats": [
47 47
@ -702,7 +702,7 @@
"implies": [ "implies": [
"Google Analytics", "Google Analytics",
"Cart Functionality" "Cart Functionality"
], ],
"js": { "js": {
"gaplugins.EC": "" "gaplugins.EC": ""
}, },
@ -1028,11 +1028,11 @@
"description": "Grafana is a multi-platform open source analytics and interactive visualisation web application.", "description": "Grafana is a multi-platform open source analytics and interactive visualisation web application.",
"icon": "Grafana.svg", "icon": "Grafana.svg",
"js": { "js": {
"grafanaBootData.settings.buildInfo['version']": "([\\d.]+)\\;version:\\1", "__grafana_public_path__": "",
"__grafana_public_path__": "" "grafanaBootData.settings.buildInfo['version']": "([\\d.]+)\\;version:\\1"
}, },
"scripts": "grafana\\..+\\.com/public/build/",
"oss": true, "oss": true,
"scripts": "grafana\\..+\\.com/public/build/",
"website": "https://grafana.com" "website": "https://grafana.com"
}, },
"Graffiti CMS": { "Graffiti CMS": {

@ -287,10 +287,10 @@
], ],
"js": { "js": {
"HeroWebPluginSettings": "" "HeroWebPluginSettings": ""
}, },
"scripts": "cdn\\.usehero\\.com", "scripts": "cdn\\.usehero\\.com",
"website": "https://www.usehero.com/" "website": "https://www.usehero.com/"
}, },
"Heroku": { "Heroku": {
"cats": [ "cats": [
62 62
@ -633,4 +633,4 @@
"scripts": "//hantana\\.org/widget", "scripts": "//hantana\\.org/widget",
"website": "https://hantana.org/" "website": "https://hantana.org/"
} }
} }

@ -384,7 +384,7 @@
"oss": true, "oss": true,
"scripts": "instant\\.page", "scripts": "instant\\.page",
"website": "https://instant.page/" "website": "https://instant.page/"
}, },
"InstantCMS": { "InstantCMS": {
"cats": [ "cats": [
1 1

@ -496,15 +496,18 @@
"icon": "Justuno.png", "icon": "Justuno.png",
"js": { "js": {
"JustunoApp": "" "JustunoApp": ""
}, },
"pricing": [
"recurring",
"low"
],
"saas": true, "saas": true,
"pricing": ["recurring", "low"],
"scripts": [ "scripts": [
"my\\.jst\\.ai", "my\\.jst\\.ai",
"cdn\\.justuno\\.com" "cdn\\.justuno\\.com"
], ],
"website": "https://www.justuno.com/" "website": "https://www.justuno.com/"
}, },
"jComponent": { "jComponent": {
"cats": [ "cats": [
12, 12,
@ -656,4 +659,4 @@
"scripts": "//cdn\\.jsdelivr\\.net/", "scripts": "//cdn\\.jsdelivr\\.net/",
"website": "https://www.jsdelivr.com/" "website": "https://www.jsdelivr.com/"
} }
} }

@ -667,4 +667,4 @@
], ],
"website": "https://www.kustomer.com/" "website": "https://www.kustomer.com/"
} }
} }

@ -803,6 +803,26 @@
"scripts": "loja2\\.com\\.br", "scripts": "loja2\\.com\\.br",
"website": "https://www.loja2.com.br" "website": "https://www.loja2.com.br"
}, },
"Loop54": {
"cats": [
29,
76
],
"description": "Loop54 is a ecommerce search and navigation SaaS product.",
"icon": "Loop54.png",
"cookies": {
"Loop54User": ""
},
"js": {
"Loop54.config.libVersion": "([\\d\\.]+)\\;version:\\1"
},
"saas": true,
"pricing": [
"mid",
"recurring"
],
"website": "https://www.loop54.com"
},
"Lootly": { "Lootly": {
"cats": [ "cats": [
84, 84,

@ -236,17 +236,17 @@
35 35
], ],
"description": "Mapplic is a plugin for creating interactive maps based on simple image (jpg, png) or vector (svg) files.", "description": "Mapplic is a plugin for creating interactive maps based on simple image (jpg, png) or vector (svg) files.",
"icon": "Mapplic.svg",
"dom": "div.mapplic-layer > div.mapplic-map-image", "dom": "div.mapplic-layer > div.mapplic-map-image",
"scripts": [ "icon": "Mapplic.svg",
"wp-content/plugins/mapplic/",
"/include/mapplic/mapplic\\.js"
],
"saas": true,
"pricing": [ "pricing": [
"low", "low",
"onetime" "onetime"
], ],
"saas": true,
"scripts": [
"wp-content/plugins/mapplic/",
"/include/mapplic/mapplic\\.js"
],
"website": "https://mapplic.com" "website": "https://mapplic.com"
}, },
"MariaDB": { "MariaDB": {
@ -735,6 +735,22 @@
], ],
"website": "https://metomic.io" "website": "https://metomic.io"
}, },
"microCMS": {
"cats": [
1
],
"description": "microCMS is a Japan-based headless CMS that enables editors and developers to build delicate sites and apps.",
"icon": "microCMS.svg",
"dom": "img[src*='.microcms-assets.io/']",
"saas": true,
"pricing": [
"freemium",
"low",
"recurring",
"payg"
],
"website": "https://microcms.io"
},
"Microsoft 365": { "Microsoft 365": {
"cats": [ "cats": [
30, 30,
@ -1007,11 +1023,11 @@
"meta": { "meta": {
"mixin_hash_id": "" "mixin_hash_id": ""
}, },
"saas": true,
"pricing": [ "pricing": [
"low", "low",
"payg" "payg"
], ],
"saas": true,
"website": "https://mixin.ir" "website": "https://mixin.ir"
}, },
"Mixpanel": { "Mixpanel": {
@ -1729,4 +1745,4 @@
], ],
"website": "https://code.google.com/p/modwsgi" "website": "https://code.google.com/p/modwsgi"
} }
} }

@ -514,19 +514,19 @@
"Periodic": { "Periodic": {
"cats": [ "cats": [
72 72
], ],
"description": "Periodic is a white-label scheduling system.", "description": "Periodic is a white-label scheduling system.",
"icon": "Periodic.svg", "icon": "Periodic.svg",
"js": { "js": {
"PeriodicSyncManager": "", "PeriodicSyncManager": "",
"PeriodicWave": "" "PeriodicWave": ""
}, },
"scripts": "/integrations/embed/periodic-embed-resize\\.js",
"saas": true,
"pricing": [ "pricing": [
"low", "low",
"recurring" "recurring"
], ],
"saas": true,
"scripts": "/integrations/embed/periodic-embed-resize\\.js",
"website": "https://periodic.is" "website": "https://periodic.is"
}, },
"Perl": { "Perl": {
@ -1346,10 +1346,10 @@
"icon": "Printful.png", "icon": "Printful.png",
"implies": [ "implies": [
"Cart Functionality" "Cart Functionality"
], ],
"scripts": "static\\.cdn\\.printful\\.com", "scripts": "static\\.cdn\\.printful\\.com",
"website": "https://www.printful.com/" "website": "https://www.printful.com/"
}, },
"Prism": { "Prism": {
"cats": [ "cats": [
19 19
@ -1367,8 +1367,8 @@
1 1
], ],
"description": "Prismic is a headless CMS for Jamstack.", "description": "Prismic is a headless CMS for Jamstack.",
"icon": "Prismic.svg",
"dom": "img[src*='images.prismic.io'", "dom": "img[src*='images.prismic.io'",
"icon": "Prismic.svg",
"pricing": [ "pricing": [
"low", "low",
"freemium", "freemium",
@ -1864,4 +1864,4 @@
}, },
"website": "http://punbb.informer.com" "website": "http://punbb.informer.com"
} }
} }

@ -369,11 +369,15 @@
], ],
"js": { "js": {
"rebuyConfig": "" "rebuyConfig": ""
}, },
"pricing": ["recurring", "payg", "low"], "pricing": [
"recurring",
"payg",
"low"
],
"scripts": "rebuyengine\\.com", "scripts": "rebuyengine\\.com",
"website": "https://rebuyengine.com/" "website": "https://rebuyengine.com/"
}, },
"Recart": { "Recart": {
"cats": [ "cats": [
32 32
@ -397,12 +401,18 @@
"Cart Functionality" "Cart Functionality"
], ],
"saas": true, "saas": true,
"pricing": ["recurring", "payg", "mid"], ],
"pricing": [
"recurring",
"payg",
"mid"
],
"saas": true,
"scripts": [ "scripts": [
"rechargeassets-bootstrapheroes-rechargeapps\\.netdna-ssl\\.com" "rechargeassets-bootstrapheroes-rechargeapps\\.netdna-ssl\\.com"
], ],
"website": "https://rechargepayments.com/" "website": "https://rechargepayments.com/"
}, },
"Recite Me": { "Recite Me": {
"cats": [ "cats": [
68 68
@ -489,11 +499,11 @@
"cats": [ "cats": [
36 36
], ],
"description": "Reddit Ads is an online advertising offering from Reddit.", "description": "Reddit Ads is an online advertising offering from Reddit.",
"icon": "Reddit.png", "icon": "Reddit.png",
"scripts": "www\\.redditstatic\\.com", "scripts": "www\\.redditstatic\\.com",
"website": "https://advertising.reddithelp.com/" "website": "https://advertising.reddithelp.com/"
}, },
"Redis": { "Redis": {
"cats": [ "cats": [
34 34
@ -1173,4 +1183,4 @@
], ],
"website": "https://www.google.com/recaptcha/" "website": "https://www.google.com/recaptcha/"
} }
} }

@ -2628,11 +2628,13 @@
"icon": "Squadded.png", "icon": "Squadded.png",
"implies": [ "implies": [
"Cart Functionality" "Cart Functionality"
], ],
"pricing": ["poa"], "pricing": [
"poa"
],
"scripts": "static\\.squadded\\.co", "scripts": "static\\.squadded\\.co",
"website": "https://www.squadded.co/" "website": "https://www.squadded.co/"
}, },
"Square": { "Square": {
"cats": [ "cats": [
41 41
@ -3532,4 +3534,4 @@
}, },
"website": "https://styled-components.com" "website": "https://styled-components.com"
} }
} }

@ -679,11 +679,11 @@
"js": { "js": {
"LS.store.url": "^.+\\.mitiendanube\\.com$" "LS.store.url": "^.+\\.mitiendanube\\.com$"
}, },
"saas": true,
"pricing": [ "pricing": [
"high", "high",
"recurring" "recurring"
], ],
"saas": true,
"website": "https://www.tiendanube.com" "website": "https://www.tiendanube.com"
}, },
"TikTok Pixel": { "TikTok Pixel": {

@ -162,29 +162,6 @@
"icon": "Varnish.svg", "icon": "Varnish.svg",
"website": "http://www.varnish-cache.org" "website": "http://www.varnish-cache.org"
}, },
"vcita": {
"cats": [
53,
72
],
"description": "vcita is an all-in-one customer service and business management software designed for service providers.",
"icon": "vcita.svg",
"dom": "iframe[src*='www.vcita.com/widgets/']",
"js": {
"Vcita": "",
"LiveSite.btCheckout": ""
},
"scripts": [
"www\\.vcita\\.com/widgets/",
"widgets\\.vcdnita\\.com/"
],
"saas": true,
"pricing": [
"low",
"recurring"
],
"website": "https://www.vcita.com"
},
"Venmo": { "Venmo": {
"cats": [ "cats": [
41 41
@ -578,6 +555,29 @@
}, },
"website": "https://www.vbulletin.com" "website": "https://www.vbulletin.com"
}, },
"vcita": {
"cats": [
53,
72
],
"description": "vcita is an all-in-one customer service and business management software designed for service providers.",
"dom": "iframe[src*='www.vcita.com/widgets/']",
"icon": "vcita.svg",
"js": {
"LiveSite.btCheckout": "",
"Vcita": ""
},
"pricing": [
"low",
"recurring"
],
"saas": true,
"scripts": [
"www\\.vcita\\.com/widgets/",
"widgets\\.vcdnita\\.com/"
],
"website": "https://www.vcita.com"
},
"vibecommerce": { "vibecommerce": {
"cats": [ "cats": [
6 6

@ -897,14 +897,14 @@
73 73
], ],
"description": "Wufoo is an online form builder that creates forms including contact forms, online payments, online surveys and event registrations.", "description": "Wufoo is an online form builder that creates forms including contact forms, online payments, online surveys and event registrations.",
"icon": "Wufoo.svg",
"dom": "a[href*='.wufoo.com/forms/'][target='_blank']", "dom": "a[href*='.wufoo.com/forms/'][target='_blank']",
"saas": true, "icon": "Wufoo.svg",
"pricing": [ "pricing": [
"freemium", "freemium",
"low", "low",
"recurring" "recurring"
], ],
"saas": true,
"website": "https://www.wufoo.com" "website": "https://www.wufoo.com"
}, },
"Wunderkind": { "Wunderkind": {
@ -994,4 +994,4 @@
"url": "^https?://[^/]+\\.wpcache\\.co", "url": "^https?://[^/]+\\.wpcache\\.co",
"website": "https://wpcache.co" "website": "https://wpcache.co"
} }
} }

@ -163,11 +163,11 @@
"zingchart": "" "zingchart": ""
}, },
"oss": true, "oss": true,
"saas": true,
"pricing": [ "pricing": [
"freemium", "freemium",
"mid" "mid"
], ],
"saas": true,
"website": "https://www.zingchart.com" "website": "https://www.zingchart.com"
}, },
"Zinnia": { "Zinnia": {
@ -349,15 +349,15 @@
"description": "Zyro is a website builder service by the Hostinger group.", "description": "Zyro is a website builder service by the Hostinger group.",
"icon": "Zyro.svg", "icon": "Zyro.svg",
"implies": "Vue.js", "implies": "Vue.js",
"meta":{ "meta": {
"generator": "^Zyro\\.com Website Builder$" "generator": "^Zyro\\.com Website Builder$"
}, },
"scripts": "userapp\\.zyrosite\\.com/",
"saas": true,
"pricing": [ "pricing": [
"low", "low",
"recurring" "recurring"
], ],
"saas": true,
"scripts": "userapp\\.zyrosite\\.com/",
"website": "https://zyro.com" "website": "https://zyro.com"
} }
} }