Merge branch 'master' into tech/add-commerce.js

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

@ -9,6 +9,7 @@ const {
setTechnologies,
setCategories,
analyze,
analyzeOneToMany,
analyzeManyToMany,
resolve,
} = Wappalyzer
@ -67,6 +68,35 @@ function analyzeJs(js) {
)
}
function analyzeDom(dom) {
return Array.prototype.concat.apply(
[],
dom.map(({ name, selector, text, property, attribute, value }) => {
const technology = Wappalyzer.technologies.find(
({ name: _name }) => name === _name
)
if (text) {
return analyzeManyToMany(technology, 'dom.text', { [selector]: [text] })
}
if (property) {
return analyzeManyToMany(technology, `dom.properties.${property}`, {
[selector]: [value],
})
}
if (attribute) {
return analyzeManyToMany(technology, `dom.attributes.${attribute}`, {
[selector]: [value],
})
}
return []
})
)
}
function get(url) {
if (['http:', 'https:'].includes(url.protocol)) {
const { get } = url.protocol === 'http:' ? http : https
@ -173,7 +203,11 @@ class Driver {
class Site {
constructor(url, headers = {}, driver) {
;({ options: this.options, browser: this.browser } = driver)
;({
options: this.options,
browser: this.browser,
init: this.initDriver,
} = driver)
this.options.headers = {
...this.options.headers,
@ -225,12 +259,26 @@ class Site {
}
}
timeout() {
return new Promise((resolve, reject) =>
setTimeout(() => {
reject(new Error('The website took too long to respond'))
}, this.options.maxWait)
)
promiseTimeout(
promise,
errorMessage = 'The website took too long to respond'
) {
let timeout = null
return Promise.race([
new Promise((resolve, reject) => {
timeout = setTimeout(() => {
clearTimeout(timeout)
reject(new Error(errorMessage))
}, this.options.maxWait)
}),
promise.then((value) => {
clearTimeout(timeout)
return value
}),
])
}
async goto(url) {
@ -249,7 +297,11 @@ class Site {
}
if (!this.browser) {
throw new Error('Browser closed')
await this.initDriver()
if (!this.browser) {
throw new Error('Browser closed')
}
}
const page = await this.browser.newPage()
@ -337,99 +389,101 @@ class Site {
)
try {
await Promise.race([
this.timeout(),
page.goto(url.href, { waitUntil: 'domcontentloaded' }),
])
await this.promiseTimeout(
page.goto(url.href, { waitUntil: 'domcontentloaded' })
)
await sleep(1000)
// Links
const links = await (
await Promise.race([
this.timeout(),
page.evaluateHandle(() =>
Array.from(document.getElementsByTagName('a')).map(
({ hash, hostname, href, pathname, protocol, rel }) => ({
hash,
hostname,
href,
pathname,
protocol,
rel,
})
const links = await this.promiseTimeout(
(
await this.promiseTimeout(
page.evaluateHandle(() =>
Array.from(document.getElementsByTagName('a')).map(
({ hash, hostname, href, pathname, protocol, rel }) => ({
hash,
hostname,
href,
pathname,
protocol,
rel,
})
)
)
),
])
).jsonValue()
)
).jsonValue()
)
// CSS
const css = await (
await Promise.race([
this.timeout(),
page.evaluateHandle((maxRows) => {
const css = []
try {
if (!document.styleSheets.length) {
return ''
}
const css = await this.promiseTimeout(
(
await this.promiseTimeout(
page.evaluateHandle((maxRows) => {
const css = []
try {
if (!document.styleSheets.length) {
return ''
}
for (const sheet of Array.from(document.styleSheets)) {
for (const rules of Array.from(sheet.cssRules)) {
css.push(rules.cssText)
for (const sheet of Array.from(document.styleSheets)) {
for (const rules of Array.from(sheet.cssRules)) {
css.push(rules.cssText)
if (css.length >= maxRows) {
break
if (css.length >= maxRows) {
break
}
}
}
} catch (error) {
return ''
}
} catch (error) {
return ''
}
return css.join('\n')
}, this.options.htmlMaxRows),
])
).jsonValue()
return css.join('\n')
}, this.options.htmlMaxRows)
)
).jsonValue()
)
// Script tags
const scripts = await (
await Promise.race([
this.timeout(),
page.evaluateHandle(() =>
Array.from(document.getElementsByTagName('script'))
.map(({ src }) => src)
.filter((src) => src)
),
])
).jsonValue()
const scripts = await this.promiseTimeout(
(
await this.promiseTimeout(
page.evaluateHandle(() =>
Array.from(document.getElementsByTagName('script'))
.map(({ src }) => src)
.filter((src) => src)
)
)
).jsonValue()
)
// Meta tags
const meta = await (
await Promise.race([
this.timeout(),
page.evaluateHandle(() =>
Array.from(document.querySelectorAll('meta')).reduce(
(metas, meta) => {
const key =
meta.getAttribute('name') || meta.getAttribute('property')
if (key) {
metas[key.toLowerCase()] = [meta.getAttribute('content')]
}
const meta = await this.promiseTimeout(
(
await this.promiseTimeout(
page.evaluateHandle(() =>
Array.from(document.querySelectorAll('meta')).reduce(
(metas, meta) => {
const key =
meta.getAttribute('name') || meta.getAttribute('property')
if (key) {
metas[key.toLowerCase()] = [meta.getAttribute('content')]
}
return metas
},
{}
return metas
},
{}
)
)
),
])
).jsonValue()
)
).jsonValue()
)
// JavaScript
const js = await Promise.race([
this.timeout(),
const js = await this.promiseTimeout(
page.evaluate(
(technologies) => {
return technologies.reduce((technologies, { name, chains }) => {
@ -461,8 +515,81 @@ class Site {
Wappalyzer.technologies
.filter(({ js }) => Object.keys(js).length)
.map(({ name, js }) => ({ name, chains: Object.keys(js) }))
),
])
)
)
// DOM
const dom = await this.promiseTimeout(
page.evaluate(
(technologies) => {
return technologies.reduce((technologies, { name, dom }) => {
const toScalar = (value) =>
typeof value === 'string' || typeof value === 'number'
? value
: !!value
Object.keys(dom).forEach((selector) => {
const el = document.querySelector(selector)
if (!el) {
return
}
dom[selector].forEach(({ text, properties, attributes }) => {
if (text) {
const value = el.textContent.trim()
if (value) {
technologies.push({
name,
selector,
text: value,
})
}
}
if (properties) {
Object.keys(properties).forEach((property) => {
if (Object.prototype.hasOwnProperty.call(el, property)) {
const value = el[property]
if (typeof value !== 'undefined') {
technologies.push({
name,
selector,
property,
value: toScalar(value),
})
}
}
})
}
if (attributes) {
Object.keys(attributes).forEach((attribute) => {
if (el.hasAttribute(attribute)) {
const value = el.getAttribute(attribute)
technologies.push({
name,
selector,
attribute,
value: toScalar(value),
})
}
})
}
})
})
return technologies
}, [])
},
Wappalyzer.technologies
.filter(({ dom }) => dom)
.map(({ name, dom }) => ({ name, dom }))
)
)
// Cookies
const cookies = (await page.cookies()).reduce(
@ -506,6 +633,7 @@ class Site {
throw new Error('No response from server')
}
this.onDetect(analyzeDom(dom))
this.onDetect(analyzeJs(js))
this.onDetect(
@ -559,7 +687,11 @@ class Site {
return reducedLinks
} catch (error) {
this.error(error)
if (error.constructor.name === 'TimeoutError') {
throw new Error('The website took too long to respond')
}
throw new Error(error.message)
}
}

@ -13,7 +13,7 @@
"software"
],
"homepage": "https://www.wappalyzer.com/",
"version": "6.3.2",
"version": "6.3.8",
"author": "Wappalyzer",
"license": "MIT",
"repository": {
@ -40,6 +40,6 @@
"wappalyzer": "./cli.js"
},
"dependencies": {
"puppeteer": "^5.2.1"
"puppeteer": "^5.3.0"
}
}

@ -76,10 +76,10 @@ debug@4, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "^2.1.1"
devtools-protocol@0.0.781568:
version "0.0.781568"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.781568.tgz#4cdca90a952d2c77831096ff6cd32695d8715a04"
integrity sha512-9Uqnzy6m6zEStluH9iyJ3iHyaQziFnMnLeC8vK0eN6smiJmIx7+yB64d67C2lH/LZra+5cGscJAJsNXO+MdPMg==
devtools-protocol@0.0.799653:
version "0.0.799653"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.799653.tgz#86fc95ce5bf4fdf4b77a58047ba9d2301078f119"
integrity sha512-t1CcaZbvm8pOlikqrsIM9GOa7Ipp07+4h/q9u0JXBWjPCjHdBl9KkddX87Vv9vBHoBGtwV79sYQNGnQM6iS5gg==
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
@ -264,13 +264,13 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
puppeteer@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.2.1.tgz#7f0564f0a5384f352a38c8cc42af875cd87f4ea6"
integrity sha512-PZoZG7u+T6N1GFWBQmGVG162Ak5MAy8nYSVpeeQrwJK2oYUlDWpHEJPcd/zopyuEMTv7DiztS1blgny1txR2qw==
puppeteer@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-5.3.0.tgz#0abf83d0f2d1273baf2b56885a813f8052903e33"
integrity sha512-GjqMk5GRro3TO0sw3QMsF1H7n+/jaK2OW45qMvqjYUyJ7y4oA//9auy969HHhTG3HZXaMxY/NWXF/NXlAFIvtw==
dependencies:
debug "^4.1.0"
devtools-protocol "0.0.781568"
devtools-protocol "0.0.799653"
extract-zip "^2.0.0"
https-proxy-agent "^4.0.0"
mime "^2.0.3"

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility"},
"categoryName69": { "message": "Social login"},
"categoryName70": { "message": "SSL/TLS certificate authority"}
"categoryName70": { "message": "SSL/TLS certificate authority"},
"categoryName71": { "message": "Affiliate program"}
}

@ -8,35 +8,35 @@
"optionUpgradeMessage": { "message": "Benachrichtige mich bei Upgrades" },
"optionDynamicIcon": { "message": "Applikations Icon anstatt des Wappalyzer Icons verwenden" },
"optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" },
"optionThemeMode": { "message": "Aktivieren dunklen Modus Kompatibilität." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"optionThemeMode": { "message": "Dunkel-Modus aktivieren" },
"optionBadge": { "message": "Anzahl der identifizierten Optionen am Icon anzeigen" },
"disableOnDomain": { "message": "Auf dieser Website deaktivieren" },
"clearCache": { "message": "Cache leeren" },
"nothingToDo": { "message": "Nichts zu tun." },
"noAppsDetected": { "message": "Keine Applikation entdeckt." },
"categoryPin": { "message": "Immer Icon anzeigen" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"privacyPolicy": { "message": "Privacy policy" },
"createAlert": { "message": "Create an alert for this website" },
"noAppsDetected": { "message": "Keine Applikationen gefunden" },
"categoryPin": { "message": "Icon immer anzeigen" },
"termsAccept": { "message": "Akzeptieren" },
"termsContent": { "message": "Diese Erweiterung sendet anonyme Informationen über Websites, die Sie besuchen, einschließlich der Domain und der identifizierten Technologien, an <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. Dies kann in den Einstellungen deaktiviert werden." },
"privacyPolicy": { "message": "Datenschutzerklärung" },
"createAlert": { "message": "Alarm für diese Website erstellen" },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Nachrichten Board" },
"categoryName3": { "message": "Datenbankverwaltung" },
"categoryName4": { "message": "Dokumentations Tool" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Ecommerce" },
"categoryName6": { "message": "E-Commerce" },
"categoryName7": { "message": "Fotogalerien" },
"categoryName8": { "message": "Wikis" },
"categoryName9": { "message": "Hosting-Panels" },
"categoryName10": { "message": "Statistiken" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "JavaScript Framework" },
"categoryName13": { "message": "Fehlertracker" },
"categoryName14": { "message": "Videospieler" },
"categoryName12": { "message": "JavaScript Frameworks" },
"categoryName13": { "message": "Ticketsysteme" },
"categoryName14": { "message": "Videoplayer" },
"categoryName15": { "message": "Kommentarsystem" },
"categoryName16": { "message": "Security" },
"categoryName17": { "message": "Schrift Script" },
"categoryName18": { "message": "Web Framework" },
"categoryName18": { "message": "Web Frameworks" },
"categoryName19": { "message": "Sonstiges" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
@ -46,47 +46,48 @@
"categoryName25": { "message": "JavaScript Graphics" },
"categoryName26": { "message": "Mobile Framework" },
"categoryName27": { "message": "Programmiersprache" },
"categoryName28": { "message": "Betriebssystem" },
"categoryName29": { "message": "Suchmaschine" },
"categoryName28": { "message": "Betriebssysteme" },
"categoryName29": { "message": "Suchmaschinen" },
"categoryName30": { "message": "Webmail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Marketing Automation" },
"categoryName33": { "message": "Web Server Erweiterung" },
"categoryName34": { "message": "Datenbank" },
"categoryName35": { "message": "Map" },
"categoryName36": { "message": "Werbenetzwerk" },
"categoryName37": { "message": "Netzwerkdienst" },
"categoryName33": { "message": "Web Server Erweiterungen" },
"categoryName34": { "message": "Datenbanken" },
"categoryName35": { "message": "Karten" },
"categoryName36": { "message": "Werbenetzwerke" },
"categoryName37": { "message": "Netzwerkdienste" },
"categoryName38": { "message": "Medienserver" },
"categoryName39": { "message": "Webcam" },
"categoryName39": { "message": "Web-Kameras" },
"categoryName40": { "message": "Drucker" },
"categoryName41": { "message": "Zahlungsverarbeiter" },
"categoryName42": { "message": "Schlagwort Manager" },
"categoryName42": { "message": "Tag Manager" },
"categoryName43": { "message": "Bezahlblockade" },
"categoryName44": { "message": "Build/CI-System" },
"categoryName44": { "message": "CI-Systeme" },
"categoryName45": { "message": "SCADA System" },
"categoryName46": { "message": "Fernzugriff" },
"categoryName47": { "message": "Entwicklungswerkzeug" },
"categoryName47": { "message": "Entwicklungswerkzeuge" },
"categoryName48": { "message": "Netzwerkspeicher" },
"categoryName49": { "message": "Feedleser" },
"categoryName50": { "message": "Dokumentmanagementsysteme" },
"categoryName51": { "message": "Startseitenersteller" },
"categoryName51": { "message": "Website Baukästen" },
"categoryName52": { "message": "Live-Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Buchhaltung" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Statischer Seitengenerator" },
"categoryName58": { "message": "Benutzer-Einbindung" },
"categoryName58": { "message": "Benutzer-Onboarding" },
"categoryName59": { "message": "JavaScript Bibliotheken" },
"categoryName60": { "message": "Containers" },
"categoryName60": { "message": "Container" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" },
"categoryName64": { "message": "Reverse Proxy" },
"categoryName64": { "message": "Reverse Proxies" },
"categoryName65": { "message": "Load Balancer" },
"categoryName66": { "message": "UI Frameworks" },
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility"},
"categoryName69": { "message": "Social login"},
"categoryName70": { "message": "SSL/TLS certificate authority"}
"categoryName67": { "message": "Cookie Compliance" },
"categoryName68": { "message": "Barrierefreiheit"},
"categoryName69": { "message": "Social Login"},
"categoryName70": { "message": "SSL/TLS certificate authority"},
"categoryName71": { "message": "Partnerprogram"}
}

@ -84,5 +84,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -86,5 +86,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -55,7 +55,7 @@
"categoryName34": { "message": "Base de Datos" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Red de Publicidad" },
"categoryName37": { "message": "Network Sevice" },
"categoryName37": { "message": "Network Service" },
"categoryName38": { "message": "Media Server" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Printer" },
@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -10,15 +10,15 @@
"optionTracking": { "message": "ارسال فن آوری های شناسایی شده به صورت ناشناس به wappalyzer.com" },
"optionThemeMode": { "message": "فعال کردن حالت سازگاری تاریک." },
"nothingToDo": { "message": "هیچ چیز برای انجام اینجا نیست." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"optionBadge": { "message": "نمایش تعداد فناوری های شناسایی شده روی آیکون" },
"disableOnDomain": { "message": "غیرفعال کردن در این وبسایت" },
"clearCache": { "message": "پاکسازی شناسایی های کش شده" },
"noAppsDetected": { "message": "هیچ فن‌آوری شناسایی نشده است." },
"categoryPin": { "message": "همیشه نماد را نشان بده" },
"termsAccept": { "message": "قبول" },
"termsContent": { "message": "این افزونه اطلاعات وب‌سایت‌های بازدید شده توسط شما را به صورت ناشناس ارسال می‌کند، مانند آدرس سایت و تکنولوژی‌های استفاده شده در آن سایت را ارسال می‌کند. اطلاعات بیشتر در <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. شما می‌توانید این افزونه را غیرفعال کنید." },
"privacyPolicy": { "message": "Privacy policy" },
"createAlert": { "message": "Create an alert for this website" },
"privacyPolicy": { "message": "سیاست حفظ حریم خصوصی" },
"createAlert": { "message": "ساخت یک هشدار برای این وبسایت" },
"categoryName1": { "message": "سیستم مدیریت محتوا" },
"categoryName2": { "message": "انجمن پیام" },
"categoryName3": { "message": "مدیریت پایگاه داده" },
@ -34,7 +34,7 @@
"categoryName13": { "message": "ردیاب مشکل" },
"categoryName14": { "message": "پخش کننده ویدیویی" },
"categoryName15": { "message": "سیستم نظرسنجی" },
"categoryName16": { "message": "Security" },
"categoryName16": { "message": "امنیت" },
"categoryName17": { "message": "اسکریپ فونت" },
"categoryName18": { "message": "چارچوب وب" },
"categoryName19": { "message": "متفرقه" },
@ -83,10 +83,11 @@
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" },
"categoryName64": { "message": "پروکسی معکوس" },
"categoryName65": { "message": "Load Balancer" },
"categoryName66": { "message": "UI Frameworks" },
"categoryName65": { "message": "لودبالانسر" },
"categoryName66": { "message": "فریم‌ورکهای رابط کاربری" },
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName68": { "message": "دسترسی" },
"categoryName69": { "message": "ورود به شبکه های اجتماعی" },
"categoryName70": { "message": "صادر کننده SSL/TLS" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -84,5 +84,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -86,5 +86,6 @@
"categoryName67": { "message": "쿠키 동의" },
"categoryName68": { "message": "접근성" },
"categoryName69": { "message": "소셜 로그인" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -84,5 +84,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -86,5 +86,6 @@
"categoryName67": { "message": "Соответствие cookie" },
"categoryName68": { "message": "Доступность" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Відповідність файлам cookie" },
"categoryName68": { "message": "Доступність" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility"},
"categoryName69": { "message": "Social login"},
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -86,5 +86,6 @@
"categoryName67": { "message": "Cookie 合规" },
"categoryName68": { "message": "辅助功能"},
"categoryName69": { "message": "社交登录"},
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -88,5 +88,6 @@
"categoryName67": { "message": "Cookie compliance" },
"categoryName68": { "message": "Accessibility" },
"categoryName69": { "message": "Social login" },
"categoryName70": { "message": "SSL/TLS certificate authority" }
"categoryName70": { "message": "SSL/TLS certificate authority" },
"categoryName71": { "message": "Affiliate program"}
}

@ -186,6 +186,19 @@ a:hover {
margin-bottom: .2rem;
}
.technology__open-in-new {
color: var(--color-primary);
visibility: hidden;
height: 1.1rem;
margin-left: .1rem;
vertical-align: middle;
width: 1.1rem;
}
.technology__heading:hover .technology__open-in-new {
visibility: visible;
}
.technology__icon {
height: 16px;
margin-right: .5rem;
@ -195,6 +208,17 @@ a:hover {
.technology__link {
color: var(--color-text);
display: block;
width: 100%;
}
.technology__link:hover {
text-decoration: none;
}
.technology__link:hover .technology__name {
border-bottom: 1px solid var(--color-primary);
color: var(--color-primary);
}
.technology__confidence {
@ -208,7 +232,7 @@ a:hover {
border-radius: 3px;
font-size: .7rem;
padding: .1rem .3rem;
margin-left: .4rem;
margin-left: .2rem;
vertical-align: middle;
}

@ -51,15 +51,21 @@
<div data-template="technology" class="technology">
<div class="technology__heading">
<a class="technology__link" href="#">
<img class="technology__icon" alt="" src="../images/icons/default.svg" />
<a class="technology__link" href="#"></a>
<span class="technology__name">&nbsp;</span>
<span>
<span class="technology__version">&nbsp;</span>
</span>
<span>
<span class="technology__version">&nbsp;</span>
</span>
<span class="technology__confidence">&nbsp;</span>
<span class="technology__confidence">&nbsp;</span>
<svg class="technology__open-in-new" viewBox="0 0 24 24">
<path fill="currentColor" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z" />
</svg>
</a>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

@ -0,0 +1,4 @@
<svg width="37" height="38" viewBox="0 0 37 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.2 27.7C30.1 24.9 29.1 22.4 26.9 20.5C25.6 19.3 23.5 19 21.9 19.7C21.1 20 20.2 20.4 19.5 20.9C18.7 21.4 17.9 21.9 16.9 22C16.3 22.1 15.8 22 15.2 22.2C14 22.6 12.7 23.1 11.9 24.1C10.3 26 11 29.3 11.9 31.4C12.5 32.9 13.4 34.3 14.6 35.3C15.6 36.2 16.7 36.8 17.9 37.2C19.2 37.7 20.7 38 22.1 37.8C25.4 37.5 28.6 34.9 29.7 31.8C30.2 30.6 30.3 29.1 30.2 27.7" fill="#D12028"/>
<path d="M17.3 21.5C17.2 20.9 16.9 20.4 16.7 19.8C16 18 15.2 16.2 14.6 14.4C13.6 11.6 13.4 8.7 14.4 5.8C15.1 3.7 16.5 2.2 18.4 1.1C18.6 0.999998 18.8 0.899998 19 1.1C19.2 1.3 19.4 1.2 19.7 1.2C20.3 1.1 21 1.1 21.5 1.5C22.1 2 22 2.7 21.4 3.1C20.8 3.4 20.2 3.4 19.7 3C19.5 2.9 19.4 2.8 19.2 2.7C18.6 2.3 18.6 2.3 18 2.8C17.6 3.1 17.2 3.3 16.9 3.7C15.5 5 14.9 6.7 14.7 8.6C14.5 10.6 14.8 12.6 15.5 14.5C16.2 16.3 16.8 18.1 17.7 19.8C18 20.3 18.2 20.8 18.7 21.2C18.8 21.6 19.1 21.8 19.3 22C19.5 22.2 19.7 22.5 19.5 22.7C19.3 23.1 18.8 23.2 18.4 23.2C18 23.2 17.9 23 17.7 22.7C17.6 22.3 17.6 21.8 17.3 21.5Z" fill="#461910"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

@ -0,0 +1,3 @@
<svg width="453" height="451" viewBox="0 0 453 451" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M177.038 332.349L25.1908 349.106L1.38352 89.9005L427.655 42.859L451.462 302.064L303.942 318.344L248.347 408.063L177.038 332.349Z" fill="#1972F5"/>
</svg>

After

Width:  |  Height:  |  Size: 303 B

@ -0,0 +1,3 @@
<svg width="109" height="110" viewBox="0 0 109 110" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M90.36 1C90.7823 1.00232 91.2037 1.03911 91.62 1.11C93.19 1.47 93.88 2.91 93.07 4.11C92.8949 4.35192 92.7045 4.5824 92.5 4.8L65.61 35.39C65.3622 35.6506 65.1285 35.9244 64.91 36.21C63.91 37.58 64.91 39.21 66.81 39.36C67.11 39.36 67.7 39.36 67.7 39.36H76.91C76.91 39.36 77.51 39.36 77.8 39.36C79.6 39.55 80.53 41.2 79.58 42.54C79.36 42.85 78.82 43.42 78.82 43.42L59 65.83C58.7584 66.0941 58.5314 66.3712 58.32 66.66C57.46 68 58.46 69.58 60.24 69.66C60.73 69.66 61.24 69.66 61.71 69.66C62.1796 69.6424 62.6446 69.7591 63.0502 69.9964C63.4558 70.2338 63.7853 70.5819 64 71C64.1825 71.3842 64.2254 71.82 64.1213 72.2325C64.0173 72.6449 63.7729 73.0083 63.43 73.26C63.25 73.43 62.88 73.74 62.88 73.74L22.7 108.34C22.4287 108.588 22.145 108.821 21.85 109.04C21.6327 109.181 21.3791 109.256 21.12 109.256C20.8609 109.256 20.6073 109.181 20.39 109.04C20.2229 108.931 20.0951 108.771 20.025 108.584C19.9548 108.397 19.9461 108.192 20 108C20.118 107.706 20.2515 107.419 20.4 107.14L33 81C33 81 33.25 80.5 33.37 80.24C33.586 79.9064 33.7072 79.5203 33.7206 79.123C33.7339 78.7258 33.6388 78.3324 33.4457 77.9851C33.2525 77.6377 32.9684 77.3495 32.6239 77.1513C32.2793 76.9531 31.8874 76.8524 31.49 76.86C31.26 76.86 30.76 76.86 30.76 76.86H21.94C21.94 76.86 21.21 76.86 20.86 76.8C19.3 76.54 18.48 75.24 19.07 73.97C19.2 73.68 19.54 73.13 19.54 73.13L35.23 46.83C35.23 46.83 35.42 46.53 35.5 46.37C36.35 44.82 35.32 43.37 33.34 43.28C32.52 43.28 30.89 43.28 30.89 43.28H23C22.4426 43.334 21.8845 43.1845 21.4287 42.8592C20.9729 42.5339 20.6502 42.0547 20.52 41.51C20.4934 40.9653 20.6638 40.4293 21 40C22.6 37.2 24.1933 34.3933 25.78 31.58L41.48 3.86L41.87 3.17999C42.2615 2.47676 42.8463 1.90048 43.5553 1.51942C44.2642 1.13837 45.0675 0.968526 45.87 1.03H90.39L90.36 1Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve">
<rect fill="#203232" width="200" height="200"/>
<path fill="#FFFFFF" d="M110.8,29.8c-15.6,0-24.7,7-29,11.9c-0.5-4.2-3.3-9.6-14-9.6H44.3v24.4h9.6c1.6,0,2.1,0.5,2.1,2.1v111.6 h27.8v-41.9c0-1.1,0-2.2-0.1-3.1c4.3,4,12.6,9.5,25.6,9.5c27.2,0,46.2-21.6,46.2-52.4C155.7,50.9,137.6,29.8,110.8,29.8 M105.1,110.4c-15,0-21.8-14.3-21.8-27.6c0-20.9,11.4-28.4,22.2-28.4c13.1,0,22,11.3,22,28.2C127.4,101.9,116.2,110.4,105.1,110.4"/>
</svg>

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@ -0,0 +1,5 @@
<svg width="95" height="92" viewBox="0 0 95 92" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M47.523 91.666C53.8919 91.6754 60.2015 90.442 66.098 88.035C66.235 87.966 66.349 87.921 66.486 87.875C66.509 87.875 66.532 87.875 66.532 87.852C67.3511 87.5491 68.2176 87.3943 69.091 87.395C70.073 87.395 71.01 87.578 71.855 87.944C84.275 91.522 91.672 92.208 94.047 90C96.422 87.792 93.739 82.73 85.998 74.812C85.998 73.602 86.341 72.46 86.889 71.478C87.0611 71.1845 87.2519 70.9022 87.46 70.633C92.235 63.486 95 54.99 95 45.88C95.046 20.53 73.775 0 47.523 0C21.27 0 0 20.53 0 45.833C0 71.159 21.271 91.666 47.523 91.666Z" fill="#1884FF"/>
<path d="M48 73C62.9117 73 75 60.9117 75 46C75 31.0883 62.9117 19 48 19C33.0883 19 21 31.0883 21 46C21 60.9117 33.0883 73 48 73Z" stroke="white" stroke-width="10"/>
<path d="M48 55C52.9706 55 57 50.9706 57 46C57 41.0294 52.9706 37 48 37C43.0294 37 39 41.0294 39 46C39 50.9706 43.0294 55 48 55Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 962 B

@ -0,0 +1,6 @@
<svg width="304" height="304" viewBox="0 0 304 304" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M303.77 271.07V57.73C303.23 44.12 302.84 23.42 272.42 35.8C221.67 54.37 170.62 72.25 120.33 92.02C82.23 106.99 40.49 123.41 19 203.61C13.37 224.61 5.64 250.06 0 271.08H49.36C53.91 254.08 59.6 232.67 64.15 215.68C79.53 158.25 109.75 146.37 137.33 135.53C176.92 119.96 217 105.75 257 91.13V271.07H303.77Z" fill="#3A4757"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M119 156.54C113.96 159.296 109.241 162.603 104.93 166.4C90.03 179.67 81.93 198.6 76.93 217.51L62.83 269.41H119V156.54Z" fill="#F7941D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M180.11 131.67C167.443 136.403 154.777 141.237 142.11 146.17C138.74 147.5 135.41 148.81 132.11 150.17V269.37H180.03L180.11 131.67Z" fill="#BFD730"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M243.8 269.37V108.37C227 114.48 210.1 120.54 193.29 126.78V269.37H243.8Z" fill="#00BAD9"/>
</svg>

After

Width:  |  Height:  |  Size: 961 B

@ -0,0 +1,4 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36.73 8.73609L22.6 0.576091C21.9463 0.198687 21.2048 0 20.45 0C19.6952 0 18.9537 0.198687 18.3 0.576091L4.17001 8.73609C3.37941 9.19689 2.75598 9.89737 2.39001 10.7361V10.7961C2.39001 10.9061 2.30001 11.0061 2.27001 11.1161V11.2461C2.27001 11.3361 2.22001 11.4161 2.20001 11.5061V11.6861C2.20001 11.7561 2.20001 11.8361 2.20001 11.9061C2.20001 11.9761 2.20001 12.0461 2.20001 12.1061C2.20001 12.1661 2.20001 12.2461 2.20001 12.3161C2.20001 12.3861 2.20001 12.4561 2.20001 12.5261C2.20001 12.5961 2.20001 12.6561 2.20001 12.7261C2.20001 12.7961 2.20001 12.8761 2.20001 12.9461C2.20001 13.0161 2.20001 13.0761 2.20001 13.1361C2.20001 13.1961 2.20001 13.2961 2.20001 13.3761V13.5361C2.20001 13.6261 2.20001 13.7161 2.28001 13.8161V13.9261C2.28001 14.0361 2.36001 14.1561 2.41001 14.2661C2.77598 15.1048 3.39941 15.8053 4.19001 16.2661L32.4 32.5461C33.4012 33.1203 34.5895 33.2732 35.7035 32.9713C36.255 32.8218 36.7718 32.5651 37.2241 32.2159C37.6765 31.8667 38.0557 31.4318 38.34 30.9361C38.6243 30.4404 38.8082 29.8935 38.8812 29.3267C38.9541 28.7599 38.9147 28.1842 38.7652 27.6326C38.6157 27.0811 38.359 26.5643 38.0098 26.112C37.6606 25.6596 37.2258 25.2804 36.73 24.9961L15 12.4861L20.45 9.33609L30.23 14.9961V18.9061L38.9 23.9061V12.4861C38.8985 11.7257 38.6973 10.9791 38.3164 10.3209C37.9356 9.6628 37.3885 9.11628 36.73 8.73609Z" fill="#ABDCD5"/>
<path d="M20.41 31.9061L10.67 26.2861V22.3861L2 17.3761V28.7061C1.99969 29.4901 2.20557 30.2603 2.59698 30.9396C2.9884 31.6189 3.55157 32.1832 4.23 32.5761L18.34 40.7161C18.989 41.0967 19.7277 41.2974 20.48 41.2974C21.2323 41.2974 21.9711 41.0967 22.62 40.7161L32.32 34.9061L23.73 29.9061L20.41 31.9061Z" fill="#ABDCD5"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,3 @@
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.451 2.218L18.007 1.022L20.549 2.218L18.007 9.745L15.451 2.218ZM17.994 11.214L19.24 15.227C20.6196 19.7172 23.5361 23.5783 27.478 26.133L19.864 31.528L18.007 28.699L16.15 31.528L8.536 26.133C12.4681 23.5712 15.3783 19.7127 16.761 15.228L17.994 11.214ZM21.308 32.325L31.526 25.073L36 26.519L34.294 33.248L27.153 35.689L28.462 32.325H21.308ZM4.461 25.073L0 26.519L1.707 33.248L8.847 35.69L7.538 32.326H14.692L4.461 25.073Z" fill="#007FFD"/>
</svg>

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,4 @@
<svg width="43" height="43" viewBox="0 0 43 43" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.3 11.9C42.2 12.3 42.6 12.9 42.6 13.7V26.8C42.6 27.6 42.2 28.2 41.4 28.5C41.2 28.6 41 28.6 40.8 28.6H35.9C35.5 29.2 35.1 29.8 34.8 30.5C34.3 31.4 33.8 32.2 33.3 33.1C33.1 33.4 32.9 33.6 32.7 33.8C32.5 34 32.2 34 31.9 33.8C31.7 33.6 31.6 33.4 31.4 33.2C30.7 31.9 29.9 30.6 29.2 29.2C29 28.8 28.8 28.7 28.3 28.7H2C1.7 28.7 1.4 28.7 1.2 28.6C0.800001 28.5 0.400001 28.2 0.200001 27.7C0.200001 27.6 0.1 27.5 0 27.4V13C0.1 13 0.100001 12.9 0.200001 12.9C0.400001 12.4 0.800001 12.1 1.2 12L1.3 11.9H41.3ZM33.1 23.2C33.3 23.3 33.5 23.5 33.6 23.6C34.1 24.1 34.7 24.4 35.3 24.4C37.2 24.6 38.5 23.5 39 21.8C39.3 20.8 39.3 19.9 39.1 18.9C38.9 17.9 38.4 17.1 37.6 16.5C36.4 15.7 35 15.7 33.8 16.6C33.5 16.8 33.3 17 33.1 17.3V17.1V16.9C33.1 16.3 32.5 16 32.1 16C31.6 16 31.2 16.4 31.2 16.9V26.8C31.2 27.1 31.4 27.4 31.7 27.5C32.3 27.8 33 27.5 33.1 26.7V25.9V23.2V23.2ZM27.4 23.4C27.6 23.7 27.8 23.9 27.9 24.1C28.2 24.5 28.6 24.6 29 24.4C29.6 24.1 29.8 23.8 29.6 23.1C29.4 22.5 29.3 21.8 29.3 21.2V19C29.3 18.6 29.3 18.2 29.2 17.8C29.1 17.3 28.8 16.8 28.3 16.5C27.8 16.2 27.3 16 26.7 16H24.8C24 16.1 23.3 16.3 22.7 16.9C22.4 17.2 22.2 17.6 22.1 18.1C22 18.5 22.2 18.9 22.6 19C23 19.2 23.3 19.1 23.6 18.7C23.7 18.6 23.8 18.5 23.8 18.4C24.3 17.5 25.2 17.3 26.1 17.4C27 17.5 27.1 17.8 27.2 18.6C27.2 18.9 27.2 19 26.9 19.1C26.2 19.2 25.6 19.4 24.9 19.6C24.4 19.7 23.9 19.8 23.4 20C22.4 20.3 21.7 21.3 21.7 22.4C21.8 23.4 22.7 24.3 23.6 24.5C24.6 24.7 25.4 24.6 26.3 24.2C26.6 23.9 26.9 23.6 27.4 23.4V23.4ZM14.5 17.1C14.4 16.8 14.3 16.4 14 16.1C13.5 15.7 12.8 15.9 12.6 16.5C12.5 16.7 12.5 16.9 12.5 17.1V23.2C12.5 23.4 12.5 23.6 12.6 23.8C12.7 24.2 13.1 24.4 13.5 24.5C13.9 24.5 14.3 24.3 14.4 23.9C14.5 23.6 14.6 23.3 14.6 23V19.5C14.6 18.5 15.3 17.5 16.7 17.6C17.2 17.7 17.5 17.9 17.6 18.3C17.7 18.8 17.8 19.2 17.8 19.7V23.6C17.9 24.4 18.7 24.7 19.3 24.4C19.6 24.2 19.8 23.9 19.8 23.5V18.5C19.8 17.5 19.1 16.5 18.1 16.2C17.3 15.9 16.4 15.9 15.6 16.4C15.3 16.5 14.9 16.8 14.5 17.1V17.1ZM7 16H6.5C5.6 16 4.8 16.4 4.2 17.1C3.5 17.9 3.6 19.5 4.6 20C5.2 20.4 5.8 20.6 6.4 20.8C7 21 7.7 21.1 8.3 21.4C8.6 21.6 8.7 21.8 8.7 22.1C8.7 22.4 8.6 22.7 8.3 22.8C7.5 23.2 6.1 23.2 5.5 22.1C5.4 21.9 5.3 21.8 5.2 21.6C5 21.3 4.6 21.2 4.2 21.4C3.9 21.5 3.7 21.8 3.7 22.1C3.7 22.7 3.9 23.2 4.4 23.6C5.1 24.2 6 24.4 6.9 24.5C7.5 24.5 8 24.5 8.6 24.4C9.4 24.2 10.1 23.9 10.6 23.2C11 22.6 11.1 21.9 10.9 21.2C10.7 20.5 10.1 20.1 9.5 19.8C8.9 19.5 8.2 19.4 7.6 19.2C7.1 19.1 6.6 19 6.2 18.7C5.7 18.4 5.7 17.9 6.1 17.6C6.5 17.3 7 17.2 7.4 17.3C7.9 17.4 8.2 17.7 8.5 18C8.7 18.2 8.9 18.5 9.2 18.6C9.7 18.9 10.3 18.6 10.4 18.1C10.5 17.7 10.4 17.4 10.1 17.1C9.9 16.9 9.6 16.6 9.3 16.5C8.6 16.1 7.8 15.9 7 16Z" fill="#FF9900"/>
<path d="M37.2 20.3C37.2 20.8 37.1 21.3 36.9 21.8C36.3 23.1 34.5 23.2 33.7 22C33.5 21.6 33.3 21.2 33.3 20.8C33.2 20.1 33.3 19.3 33.6 18.6C33.9 18 34.5 17.6 35.2 17.6C36 17.6 36.5 18 36.8 18.6C37.2 19.1 37.2 19.7 37.2 20.3ZM27.2 20.3C27.3 20.8 27.2 21.4 27 21.9C26.7 22.7 26.1 23 25.3 23.1C24.8 23.2 24.3 23.1 23.9 22.6C23.6 22.3 23.6 21.7 23.9 21.3C24.1 21.1 24.3 20.9 24.7 20.9C25.5 20.7 26.4 20.5 27.2 20.3V20.3Z" fill="#FF9900"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@ -0,0 +1,5 @@
<svg width="270" height="180" viewBox="0 0 270 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<ellipse rx="89.7096" ry="89.9998" transform="matrix(-1 0 0 1 180.29 89.9998)" fill="#B8D2FF"/>
<path d="M180.29 180C130.745 180 90.5808 140.097 90.5808 90.8738H270C270 140.097 229.836 180 180.29 180Z" fill="#005DFF"/>
<path d="M90.5805 89.9998C90.5805 139.705 50.0262 180 7.86803e-06 180L0 0C50.0262 -2.18672e-06 90.5805 40.2943 90.5805 89.9998Z" fill="#FF6A00"/>
</svg>

After

Width:  |  Height:  |  Size: 472 B

@ -96,7 +96,7 @@ const Popup = {
'.alerts__link'
).href = `https://www.wappalyzer.com/alerts/?url=${encodeURIComponent(
`${url}`
)}`
)}&utm_source=popup&utm_medium=extension&utm_campaign=wappalyzer`
const { hostname } = new URL(url)
@ -210,7 +210,7 @@ const Popup = {
const link = categoryNode.querySelector('.category__link')
link.href = `https://www.wappalyzer.com/technologies/${categorySlug}/`
link.href = `https://www.wappalyzer.com/technologies/${categorySlug}/?utm_source=popup&utm_medium=extension&utm_campaign=wappalyzer`
link.dataset.i18n = `categoryName${id}`
const pins = categoryNode.querySelectorAll('.category__pin')
@ -247,9 +247,10 @@ const Popup = {
image.src = `../images/icons/${icon}`
const link = technologyNode.querySelector('.technology__link')
const linkText = technologyNode.querySelector('.technology__name')
link.href = `https://www.wappalyzer.com/technologies/${categorySlug}/${slug}/`
link.textContent = name
link.href = `https://www.wappalyzer.com/technologies/${categorySlug}/${slug}/?utm_source=popup&utm_medium=extension&utm_campaign=wappalyzer`
linkText.textContent = name
const confidenceNode = technologyNode.querySelector(
'.technology__confidence'

@ -4,7 +4,7 @@
"author": "Wappalyzer",
"homepage_url": "https://www.wappalyzer.com/",
"description": "Identify web technologies",
"version": "6.3.1",
"version": "6.3.5",
"default_locale": "en",
"manifest_version": 2,
"icons": {
@ -69,4 +69,4 @@
"https://*/*"
],
"content_security_policy": "script-src 'self'; object-src 'self'"
}
}

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

File diff suppressed because it is too large Load Diff

@ -231,6 +231,7 @@ const Wappalyzer = {
const {
cats,
url,
dom,
html,
css,
robots,
@ -254,6 +255,7 @@ const Wappalyzer = {
url: transform(url),
headers: transform(headers),
cookies: transform(cookies),
dom: transform(dom, true),
html: transform(html),
css: transform(css),
certIssuer: transform(certIssuer),
@ -298,7 +300,7 @@ const Wappalyzer = {
},
/**
* Extract information from regex pattern.
* Transform patterns for internal use.
* @param {string|array} patterns
*/
transformPatterns(patterns, caseSensitive = false) {
@ -315,34 +317,7 @@ const Wappalyzer = {
const parsed = Object.keys(patterns).reduce((parsed, key) => {
parsed[caseSensitive ? key : key.toLowerCase()] = toArray(
patterns[key]
).map((pattern) => {
const { value, regex, confidence, version } = pattern
.split('\\;')
.reduce((attrs, attr, i) => {
if (i) {
// Key value pairs
attr = attr.split(':')
if (attr.length > 1) {
attrs[attr.shift()] = attr.join(':')
}
} else {
attrs.value = attr
// Escape slashes in regular expression
attrs.regex = new RegExp(attr.replace(/\//g, '\\/'), 'i')
}
return attrs
}, {})
return {
value,
regex,
confidence: parseInt(confidence || 100, 10),
version: version || '',
}
})
).map((pattern) => Wappalyzer.parsePattern(pattern))
return parsed
}, {})
@ -350,6 +325,49 @@ const Wappalyzer = {
return 'main' in parsed ? parsed.main : parsed
},
/**
* Extract information from regex pattern.
* @param {string|object} pattern
*/
parsePattern(pattern) {
if (typeof pattern === 'object') {
return Object.keys(pattern).reduce(
(parsed, key) => ({
...parsed,
[key]: Wappalyzer.parsePattern(pattern[key]),
}),
{}
)
} else {
const { value, regex, confidence, version } = pattern
.split('\\;')
.reduce((attrs, attr, i) => {
if (i) {
// Key value pairs
attr = attr.split(':')
if (attr.length > 1) {
attrs[attr.shift()] = attr.join(':')
}
} else {
attrs.value = attr
// Escape slashes in regular expression
attrs.regex = new RegExp(attr.replace(/\//g, '\\/'), 'i')
}
return attrs
}, {})
return {
value,
regex,
confidence: parseInt(confidence || 100, 10),
version: version || '',
}
}
},
/**
* @todo describe
* @param {Object} technology
@ -400,12 +418,19 @@ const Wappalyzer = {
* @param {String} type
* @param {Array} items
*/
analyzeManyToMany(technology, type, items = {}) {
analyzeManyToMany(technology, types, items = {}) {
const [type, ...subtypes] = types.split('.')
return Object.keys(technology[type]).reduce((technologies, key) => {
const patterns = technology[type][key] || []
const values = items[key] || []
patterns.forEach((pattern) => {
patterns.forEach((_pattern) => {
const pattern = (subtypes || []).reduce(
(pattern, subtype) => pattern[subtype],
_pattern
)
values.forEach((value) => {
if (pattern.regex.test(value)) {
technologies.push({