Add WebExtension driver

main
Elbert Alias 8 years ago
parent 540be244aa
commit 8b946ee3bf

@ -66,6 +66,13 @@ pushd $WAPPALYZER_ROOT/src/drivers/chrome > /dev/null
zip -qr $WAPPALYZER_ROOT/build/wappalyzer_chrome.zip .
# Google Chrome
echo "Building WebExtension driver..."
pushd $WAPPALYZER_ROOT/src/drivers/webextension > /dev/null
zip -qr $WAPPALYZER_ROOT/build/wappalyzer_webextension.zip .
popd > /dev/null
echo "Done. Builds have been created in $WAPPALYZER_ROOT/build."

@ -46,6 +46,16 @@ if [ "$(compgen -G "$path/icons/converted/*.png" | head -n1)" ]; then
ln -f $path/icons/converted/*.png $path/drivers/chrome/images/icons/converted
fi
ln -f $path/wappalyzer.js $path/drivers/webextension/js
ln -f $path/apps.json $path/drivers/webextension
ln -f $path/icons/*.png $path/drivers/webextension/images/icons
ln -f $path/icons/*.svg $path/drivers/webextension/images/icons
ln -f $path/utils/*.js $path/drivers/webextension/js
if [ "$(compgen -G "$path/icons/converted/*.png" | head -n1)" ]; then
ln -f $path/icons/converted/*.png $path/drivers/webextension/images/icons/converted
fi
echo "OK"
exit 0

@ -1,23 +1,20 @@
#!/bin/bash
path=$1
path="$1"
if [ -z $path ]
then
if [ -z $WAPPALYZER_ROOT ]
then
if [ -z "$path" ]; then
if [ -z "$WAPPALYZER_ROOT" ]; then
echo "-$(basename $0): No path specified"
exit 1
fi
path=$WAPPALYZER_ROOT
path="$WAPPALYZER_ROOT"
fi
set -eu
if [ ! -d $path/src ]
then
if [ ! -d "$path/src" ]; then
echo "-$(basename $0): Incorrect path"
exit 1
@ -27,7 +24,7 @@ path="$path/src"
echo "Validating apps.json..."
node $WAPPALYZER_NODE_PATH/node_modules/jsonlint/lib/cli.js --quiet -V $WAPPALYZER_ROOT/schema.json $path/apps.json
node "$WAPPALYZER_NODE_PATH/node_modules/jsonlint/lib/cli.js" --quiet -V "$WAPPALYZER_ROOT/schema.json" "$path/apps.json"
echo "Validating regular expressions..."

@ -0,0 +1,7 @@
apps.json
images/icons/converted/*.png
images/icons/*.png
images/icons/*.svg
js/wappalyzer.js
js/iframe.js
js/network.js

@ -0,0 +1,60 @@
{
"github": { "message": "Κάνε fork το Wappalyzer στο GitHub!" },
"twitter": { "message": "Ακολούθησε το Wappalyzer στο Twitter" },
"website": { "message": "Πήγαινε στο wappalyzer.com" },
"options": { "message": "Ρυθμίσεις Wappalyzer" },
"optionsSave": { "message": "Ρυθμίσεις αποθήκευσης" },
"optionsSaved": { "message": "Αποθηκεύτηκε" },
"optionUpgradeMessage": { "message": "Ενημερώστε με για αναβαθμίσεις" },
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Διαδικτυακό Φόρουμ" },
"categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" },
"categoryName4": { "message": "Εργαλείο Τεκμηρίωσης" },
"categoryName5": { "message": "Widget" },
"categoryName10": { "message": "Analytics" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework της JavaScript" },
"categoryName13": { "message": "Issue Tracker" },
"categoryName14": { "message": "Πρόγραμμα αναπαραγωγής Βίντεο" },
"categoryName15": { "message": "Σύστημα Σχολίων" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script Γραμματοσειράς" },
"categoryName18": { "message": "Framework Διαδικτύου" },
"categoryName19": { "message": "Διάφορα" },
"categoryName20": { "message": "Επεξεργαστής Κειμένου" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Διακομιστής Διαδικτύου" },
"categoryName23": { "message": "Εργαλείο Μνήμης Cache" },
"categoryName24": { "message": "Επεξεργαστής Εμπλουτισμένου Κειμένου" },
"categoryName25": { "message": "Γραφικά JavaScript" },
"categoryName26": { "message": "Framework για Κινητά" },
"categoryName27": { "message": "Γλώσσα Προγραμματισμού" },
"categoryName28": { "message": "Λειτουργικό Σύστημα" },
"categoryName29": { "message": "Μηχανή Αναζήτησης" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Αυτοματοποίηση Marketing" },
"categoryName33": { "message": "Επέκταση Διακομιστή Διαδικτύου" },
"categoryName34": { "message": "Βάση Δεδομένων" },
"categoryName35": { "message": "Χάρτης" },
"categoryName36": { "message": "Δίκτυο Διαφημίσεων" },
"categoryName37": { "message": "Υπηρεσία Δικτύου" },
"categoryName38": { "message": "Διακομιστής Πολυμέσων" },
"categoryName39": { "message": "Διαδικτυακή κάμερα" },
"categoryName40": { "message": "Εκτυπωτής" },
"categoryName41": { "message": "Σύστημα Επεξεργασίας Πληρωμών" },
"categoryName42": { "message": "Σύστημα Διαχείρισης Tags" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Σύστημα Build/CI" },
"categoryName45": { "message": "Σύστημα SCADA" },
"categoryName46": { "message": "Απομακρυσμένη Πρόσβαση" },
"categoryName47": { "message": "Εργαλείο Ανάπτυξης" },
"categoryName48": { "message": "Δικτυακός Αποθηκευτικός Χώρος" },
"categoryName49": { "message": "Feed Readers" },
"categoryName50": { "message": "Συστήματα Διαχειρίσης Εγγράφων" },
"categoryName51": { "message": "Σύστημα Κατασκευής Σελίδων Υποδοχής" },
"categoryName52": { "message": "Live Chat" }
}

@ -0,0 +1,60 @@
{
"github": { "message": "Fork Wappalyzer on GitHub!" },
"twitter": { "message": "Follow Wappalyzer on Twitter" },
"website": { "message": "Go to wappalyzer.com" },
"options": { "message": "Options" },
"optionsSave": { "message": "Save options" },
"optionsSaved": { "message": "Saved" },
"optionUpgradeMessage": { "message": "Tell me about upgrades" },
"optionTracking": { "message": "Anonymously send reports on detected applications to wappalyzer.com for research" },
"nothingToDo": { "message": "Nothing to do here." },
"noAppsDetected": { "message": "No applications detected." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Message Board" },
"categoryName3": { "message": "Database Manager" },
"categoryName4": { "message": "Documentation Tool" },
"categoryName5": { "message": "Widget" },
"categoryName10": { "message": "Analytics" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "JavaScript Framework" },
"categoryName13": { "message": "Issue Tracker" },
"categoryName14": { "message": "Video Player" },
"categoryName15": { "message": "Comment System" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Font Script" },
"categoryName18": { "message": "Web Framework" },
"categoryName19": { "message": "Miscellaneous" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Web Server" },
"categoryName23": { "message": "Cache Tool" },
"categoryName24": { "message": "Rich Text Editor" },
"categoryName25": { "message": "JavaScript Graphics" },
"categoryName26": { "message": "Mobile Framework" },
"categoryName27": { "message": "Programming Language" },
"categoryName28": { "message": "Operating System" },
"categoryName29": { "message": "Search Engine" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Marketing Automation" },
"categoryName33": { "message": "Web Server Extension" },
"categoryName34": { "message": "Database" },
"categoryName35": { "message": "Map" },
"categoryName36": { "message": "Advertising Network" },
"categoryName37": { "message": "Network Service" },
"categoryName38": { "message": "Media Server" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Printer" },
"categoryName41": { "message": "Payment Processor" },
"categoryName42": { "message": "Tag Manager" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Build/CI System" },
"categoryName45": { "message": "SCADA System" },
"categoryName46": { "message": "Remote Access" },
"categoryName47": { "message": "Development Tool" },
"categoryName48": { "message": "Network Storage" },
"categoryName49": { "message": "Feed Readers" },
"categoryName50": { "message": "Document Management Systems" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Live Chat" }
}

@ -0,0 +1,64 @@
{
"github": { "message": "¡Forkea Wappalyzer en GitHub!" },
"twitter": { "message": "Sigue Wappalyzer en Twitter" },
"website": { "message": "Ir a wappalyzer.com" },
"options": { "message": "Opciones" },
"optionsSave": { "message": "Guardar opciones" },
"optionsSaved": { "message": "Guardado" },
"optionUpgradeMessage": { "message": "Indicarme actualizaciones" },
"optionTracking": { "message": "Enviar informes anónimos sobre las aplicaciones detectadas a wappalyzer.com para análisis" },
"nothingToDo": { "message": "Nada que hacer aquí." },
"noAppsDetected": { "message": "Aplicaciones no detectadas." },
"categoryName1": { "message": "Gestor de Contenido" },
"categoryName2": { "message": "Foro" },
"categoryName3": { "message": "Gestor de Bases de Datos" },
"categoryName4": { "message": "Herramienta de Documentación" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Tienda Web" },
"categoryName7": { "message": "Galería fotográfica" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Panel de Hosting" },
"categoryName10": { "message": "Analítica" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Gestor de Incidencias" },
"categoryName14": { "message": "Reproductor de Vídeo" },
"categoryName15": { "message": "Sistema de Comentarios" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Tipografía" },
"categoryName18": { "message": "Framework Web" },
"categoryName19": { "message": "Miscelánea" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Servidor Web" },
"categoryName23": { "message": "Herramienta de Cache" },
"categoryName24": { "message": "Editor de Texto Enriquecido" },
"categoryName25": { "message": "Gráficos JavaScript" },
"categoryName26": { "message": "Framework Móvil" },
"categoryName27": { "message": "Lenguaje de programación" },
"categoryName28": { "message": "Sistema Operativo" },
"categoryName29": { "message": "Motor de Búsqueda" },
"categoryName30": { "message": "Correo Web" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Automatización de Marketing" },
"categoryName33": { "message": "Extensión de Servidor Web" },
"categoryName34": { "message": "Base de Datos" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Red de Publicidad" },
"categoryName37": { "message": "Network Sevice" },
"categoryName38": { "message": "Media Server" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Printer" },
"categoryName41": { "message": "Payment Processor" },
"categoryName42": { "message": "Tag Manager" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Build/CI System" },
"categoryName45": { "message": "SCADA System" },
"categoryName46": { "message": "Remote Access" },
"categoryName47": { "message": "Development Tool" },
"categoryName48": { "message": "Network Storage" },
"categoryName49": { "message": "Feed Readers" },
"categoryName50": { "message": "Document Management Systems" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Live Chat" }
}

@ -0,0 +1,64 @@
{
"github": { "message": "Forker Wappalyzer sur GitHub!" },
"noAppsDetected": { "message": "Pas d'applications détectées." },
"nothingToDo": { "message": "Rien à faire ici." },
"optionTracking": { "message": "Envoyer anonymement des rapports sur les applications détectées à wappalyzer.com pour la recherche" },
"optionUpgradeMessage": { "message": "M'afficher les mises à jour" },
"options": { "message": "Options" },
"optionsSave": { "message": "Sauver les options" },
"optionsSaved": { "message": "Sauvé" },
"twitter": { "message": "Suivre Wappalyzer sur Twitter" },
"website": { "message": "Aller à wappalyzer.com" },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestionnaire de base de données" },
"categoryName4": { "message": "Outil de documentation" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Boutique en ligne" },
"categoryName7": { "message": "Galerie photo" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Gestionnaires de serveur" },
"categoryName10": { "message": "Outil de statistiques" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Outil de suivi de problèmes" },
"categoryName14": { "message": "Lecteur de vidéos" },
"categoryName15": { "message": "Système de commentaires" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de police" },
"categoryName18": { "message": "Framework web" },
"categoryName19": { "message": "Divers" },
"categoryName20": { "message": "Editeur" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Serveur web" },
"categoryName23": { "message": "Outil de cache" },
"categoryName24": { "message": "Editeur WYSIWYG" },
"categoryName25": { "message": "Graphismes JavaScript" },
"categoryName26": { "message": "Framework pour mobiles" },
"categoryName27": { "message": "Language de programmation" },
"categoryName28": { "message": "Système d'exploitation" },
"categoryName29": { "message": "Moteur de recherche" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Logiciel de marketing" },
"categoryName33": { "message": "Extension de serveur web" },
"categoryName34": { "message": "Base de données" },
"categoryName35": { "message": "Carte" },
"categoryName36": { "message": "Réseau publicitaire" },
"categoryName37": { "message": "Périphérique réseau" },
"categoryName38": { "message": "Serveur multimédia" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Imprimante" },
"categoryName41": { "message": "Service de paiement" },
"categoryName42": { "message": "Tag Manager" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Système CI" },
"categoryName45": { "message": "Système SCADA" },
"categoryName46": { "message": "Accès à distance" },
"categoryName47": { "message": "Outil de développement" },
"categoryName48": { "message": "Stockage réseau" },
"categoryName49": { "message": "Lecteur RSS" },
"categoryName50": { "message": "Système de gestion de documents" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Chat en direct" }
}

@ -0,0 +1,60 @@
{
"github": { "message": "Κάνε fork το Wappalyzer στο GitHub!" },
"twitter": { "message": "Ακολούθησε το Wappalyzer στο Twitter" },
"website": { "message": "Πήγαινε στο wappalyzer.com" },
"options": { "message": "Ρυθμίσεις" },
"optionsSave": { "message": "Ρυθμίσεις αποθήκευσης" },
"optionsSaved": { "message": "Αποθηκεύτηκε" },
"optionUpgradeMessage": { "message": "Ενημερώστε με για αναβαθμίσεις" },
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Διαδικτυακό Φόρουμ" },
"categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" },
"categoryName4": { "message": "Εργαλείο Τεκμηρίωσης" },
"categoryName5": { "message": "Widget" },
"categoryName10": { "message": "Analytics" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework της JavaScript" },
"categoryName13": { "message": "Issue Tracker" },
"categoryName14": { "message": "Πρόγραμμα αναπαραγωγής Βίντεο" },
"categoryName15": { "message": "Σύστημα Σχολίων" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script Γραμματοσειράς" },
"categoryName18": { "message": "Framework Διαδικτύου" },
"categoryName19": { "message": "Διάφορα" },
"categoryName20": { "message": "Επεξεργαστής Κειμένου" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Διακομιστής Διαδικτύου" },
"categoryName23": { "message": "Εργαλείο Μνήμης Cache" },
"categoryName24": { "message": "Επεξεργαστής Εμπλουτισμένου Κειμένου" },
"categoryName25": { "message": "Γραφικά JavaScript" },
"categoryName26": { "message": "Framework για Κινητά" },
"categoryName27": { "message": "Γλώσσα Προγραμματισμού" },
"categoryName28": { "message": "Λειτουργικό Σύστημα" },
"categoryName29": { "message": "Μηχανή Αναζήτησης" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Αυτοματοποίηση Marketing" },
"categoryName33": { "message": "Επέκταση Διακομιστή Διαδικτύου" },
"categoryName34": { "message": "Βάση Δεδομένων" },
"categoryName35": { "message": "Χάρτης" },
"categoryName36": { "message": "Δίκτυο Διαφημίσεων" },
"categoryName37": { "message": "Υπηρεσία Δικτύου" },
"categoryName38": { "message": "Διακομιστής Πολυμέσων" },
"categoryName39": { "message": "Διαδικτυακή κάμερα" },
"categoryName40": { "message": "Εκτυπωτής" },
"categoryName41": { "message": "Σύστημα Επεξεργασίας Πληρωμών" },
"categoryName42": { "message": "Σύστημα Διαχείρισης Tags" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Σύστημα Build/CI" },
"categoryName45": { "message": "Σύστημα SCADA" },
"categoryName46": { "message": "Απομακρυσμένη Πρόσβαση" },
"categoryName47": { "message": "Εργαλείο Ανάπτυξης" },
"categoryName48": { "message": "Δικτυακός Αποθηκευτικός Χώρος" },
"categoryName49": { "message": "Feed Readers" },
"categoryName50": { "message": "Συστήματα Διαχειρίσης Εγγράφων" },
"categoryName51": { "message": "Σύστημα Κατασκευής Σελίδων Υποδοχής" },
"categoryName52": { "message": "Live Chat" }
}

@ -0,0 +1,65 @@
{
"github": { "message": "Fork Wappalyzer su GitHub!" },
"twitter": { "message": "Follow Wappalyzer su Twitter" },
"website": { "message": "Vai su wappalyzer.com" },
"options": { "message": "Opzioni" },
"optionsSave": { "message": "Salva opzioni" },
"optionsSaved": { "message": "Salvato" },
"optionUpgradeMessage": { "message": "Parlami dell'upgrade" },
"optionTracking": { "message": "Inviare anonimamente un report sulle applicazioni rilevate a wappalyzer.com per l'analisi" },
"nothingToDo": { "message": "Niente da fare qui." },
"noAppsDetected": { "message": "Nessuna applicazione rilevata." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestore di Database" },
"categoryName4": { "message": "Strumento di documentazione" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "eCommerce" },
"categoryName7": { "message": "Galleria fotografica" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Pannello Hosting" },
"categoryName10": { "message": "Analytics" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Issue Tracker" },
"categoryName14": { "message": "Player Video" },
"categoryName15": { "message": "Sistema di commenti" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Font Script" },
"categoryName18": { "message": "Framework Web" },
"categoryName19": { "message": "Miscellanea" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Web Server" },
"categoryName23": { "message": "Cache Tool" },
"categoryName24": { "message": "Editor di Testo Ricco" },
"categoryName25": { "message": "JavaScript Graphics" },
"categoryName26": { "message": "Framework Mobile" },
"categoryName27": { "message": "Linguaggio di programmazione" },
"categoryName28": { "message": "Sistema Operativo" },
"categoryName29": { "message": "Motore di Ricerca" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Marketing Automation" },
"categoryName33": { "message": "Estensione Web Server" },
"categoryName34": { "message": "Database" },
"categoryName35": { "message": "Mappa" },
"categoryName36": { "message": "Network Pubblicitario" },
"categoryName37": { "message": "Network Service" },
"categoryName38": { "message": "Media Server" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Stampante" },
"categoryName41": { "message": "Payment Processor" },
"categoryName42": { "message": "Tag Manager" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Sistema Build/CI" },
"categoryName45": { "message": "SCADA System" },
"categoryName46": { "message": "Accesso" },
"categoryName47": { "message": "Strumenti di Sviluppo" },
"categoryName48": { "message": "Network Storage" },
"categoryName49": { "message": "Lettore di Feed" },
"categoryName50": { "message": "Sistema di Gestione Documenti" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Live Chat" }
}

@ -0,0 +1,60 @@
{
"github": { "message": "Fork-uiește Wappalyzer pe GitHub!" },
"twitter": { "message": "Urmărește Wappalyzer pe Twitter" },
"website": { "message": "Mergi la wappalyzer.com" },
"options": { "message": "Opțiuni" },
"optionsSave": { "message": "Salvează opțiuni" },
"optionsSaved": { "message": "Salvat" },
"optionUpgradeMessage": { "message": "Anunță-mă dacă sunt actualizări" },
"optionTracking": { "message": "Trimite rapoarte anonime despre aplicațiile detectate către wappalyzer.com pentru cercetare" },
"nothingToDo": { "message": "Nimic de făcut pe pagina curentă." },
"noAppsDetected": { "message": "Nici o aplicație detectată." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum de discuții" },
"categoryName3": { "message": "Manager baze de date" },
"categoryName4": { "message": "Unealtă pentru documentare" },
"categoryName5": { "message": "Widget" },
"categoryName10": { "message": "Analiză trafic web" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Tracker probleme" },
"categoryName14": { "message": "Player Video" },
"categoryName15": { "message": "Sistem de comentarii" },
"categoryName16": { "message": "Verificare Captcha" },
"categoryName17": { "message": "Script pentru fonturi" },
"categoryName18": { "message": "Framework Web" },
"categoryName19": { "message": "Divers" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Server Web" },
"categoryName23": { "message": "Unealtă Cache" },
"categoryName24": { "message": "Editor Texte Rich" },
"categoryName25": { "message": "Grafică JavaScript" },
"categoryName26": { "message": "Framework Mobile" },
"categoryName27": { "message": "Limbaj de programare" },
"categoryName28": { "message": "Sistem de operare" },
"categoryName29": { "message": "Motor de căutare" },
"categoryName30": { "message": "Poștă electronică" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Automatizare marketing" },
"categoryName33": { "message": "Extensie server web" },
"categoryName34": { "message": "Bază de date" },
"categoryName35": { "message": "Hartă" },
"categoryName36": { "message": "Rețea de advertising" },
"categoryName37": { "message": "Serviciu rețea" },
"categoryName38": { "message": "Server Media" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Imprimantă" },
"categoryName41": { "message": "Sistem de plată" },
"categoryName42": { "message": "Manager cuvinte cheie" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Build/CI System" },
"categoryName45": { "message": "SCADA System" },
"categoryName46": { "message": "Remote Access" },
"categoryName47": { "message": "Development Tool" },
"categoryName48": { "message": "Network Storage" },
"categoryName49": { "message": "Feed Readers" },
"categoryName50": { "message": "Document Management Systems" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Live Chat" }
}

@ -0,0 +1,60 @@
{
"categoryName1" : { "message" : "CMS" },
"categoryName2" : { "message" : "Форум" },
"categoryName3" : { "message" : "Менеджер БД" },
"categoryName4" : { "message" : "Документация" },
"categoryName5" : { "message" : "Виджет" },
"categoryName10" : { "message" : "Аналитика" },
"categoryName11" : { "message" : "Блог" },
"categoryName12" : { "message" : "JS фреймворк" },
"categoryName13" : { "message" : "Баг трекер" },
"categoryName14" : { "message" : "Видео плеер" },
"categoryName15" : { "message" : "Система комментариев" },
"categoryName16" : { "message" : "Капча" },
"categoryName17" : { "message" : "Шрифт" },
"categoryName18" : { "message" : "Веб фреймворк" },
"categoryName19" : { "message" : "Прочее" },
"categoryName20" : { "message" : "HTML редактор" },
"categoryName21" : { "message" : "LMS" },
"categoryName22" : { "message" : "Веб сервер" },
"categoryName23" : { "message" : "Кеширование" },
"categoryName24" : { "message" : "WYSIWYG редактор" },
"categoryName25" : { "message" : "JS графика" },
"categoryName26" : { "message" : "Мобильный фреймворк" },
"categoryName27" : { "message" : "Язык программирования" },
"categoryName28" : { "message" : "Операционная система" },
"categoryName29" : { "message" : "Поисковый движок" },
"categoryName30" : { "message" : "Веб почта" },
"categoryName31" : { "message" : "CDN" },
"categoryName32" : { "message" : "Управление маркетингом" },
"categoryName33" : { "message" : "Расширение Веб сервера" },
"categoryName34" : { "message" : "База данных" },
"categoryName35" : { "message" : "Карта" },
"categoryName36" : { "message" : "Рекламная сеть" },
"categoryName37" : { "message" : "Сетевая служба" },
"categoryName38" : { "message" : "Медиа сервер" },
"categoryName39" : { "message" : "Вебкамера" },
"categoryName40" : { "message" : "Принтер" },
"categoryName41" : { "message" : "Провайдер платежей" },
"categoryName42" : { "message" : "Менеджер тэгов" },
"categoryName43" : { "message" : "Paywall" },
"categoryName44" : { "message" : "Система непрерывной интеграции" },
"categoryName45" : { "message" : "Система SCADA" },
"categoryName46" : { "message" : "Удаленное управление" },
"categoryName47" : { "message" : "Утилита для разработчиков" },
"categoryName48" : { "message" : "Сетевое хранилище" },
"categoryName49" : { "message" : "Граббер контента" },
"categoryName50" : { "message" : "Управление документами" },
"categoryName51" : { "message": "Генератор лендингов" },
"categoryName52" : { "message": "Live Chat" },
"github" : { "message" : "Форкнуть на GitHub!" },
"noAppsDetected" : { "message" : "Нет данных о сайте" },
"nothingToDo" : { "message" : "Тут нечего искать" },
"optionTracking" : { "message" : "Анонимно отправлять статистику распознанных данных на сервер (для улучшения расширения)" },
"optionUpgradeMessage" : { "message" : "Оповещать меня о новых обновлениях" },
"options" : { "message" : "Настройки" },
"optionsSave" : { "message" : "Сохранить" },
"optionsSaved" : { "message" : "Успешно сохранено!" },
"twitter" : { "message" : "Следите за новостями в Твиттере" },
"website" : { "message" : "Перейти на Wappalyzer.com" }
}

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/browser-polyfill.js"></script>
<script src="js/wappalyzer.js"></script>
<script src="js/defaults.js"></script>
<script src="js/driver.js"></script>
<script src="js/network.js"></script>
</head>
<body>
</body>
</html>

@ -0,0 +1,106 @@
body {
color: #303942;
cursor: default;
font-family: Helvetica, Arial, sans-serif;
font-size: .8rem;
line-height: 1.4rem;
margin: 0;
}
p {
margin: 0 0 1rem 0;
}
h1, h2, h3 {
font-weight: normal;
line-height: 1;
}
h1 {
border-bottom: 1px solid #dbdbdb;
font-size: 1.5rem;
margin: 0 0 1.5rem 0;
padding: 1rem 0 1.5rem 0;
}
h2 {
font-size: 1.3em;
margin-bottom: 0.4em;
}
h3 {
color: black;
font-size: 1.2em;
margin-bottom: 0.5em;
}
a {
color: rgb(17, 85, 204);
text-decoration: underline;
}
label {
display: block;
}
button {
background: #4608ad;
border: none;
border-radius: .2rem;
color: white;
font-size: inherit;
padding: 0 .6rem;
line-height: 1.8rem;
}
a:active {
color: rgb(5, 37, 119);
}
.hero {
background: linear-gradient(160deg, #32067c, #150233);
padding: 1.5rem 0 1rem 1.5rem;
}
.hero img {
height: 3rem;
}
.container {
margin: 0 auto;
max-width: 800px;
}
.content {
padding: 1.5rem;
}
#options-saved {
display: none;
margin-left: .5rem;
-webkit-animation: fadeout 2s;
}
#about {
border-top: 1px solid #dbdbdb;
margin-top: 2.5rem;
padding: 1.5rem 0 1.5rem 0;
}
#about img {
margin-right: .2rem;
vertical-align: middle;
}
#about button {
background: white;
border: 1px solid #dbdbdb;
cursor: pointer;
color: #303942;
margin: 0 1rem .5rem 0;
}
@-webkit-keyframes fadeout {
from { opacity: 1; }
to { opacity: 0; }
}

@ -0,0 +1,96 @@
body {
background: #fff;
color: #4a4a4a;
font-family: Helvetica, Arial, sans-serif;
font-size: 13px;
line-height: 16px;
margin: 0;
min-width: 200px;
padding: 15px;
}
a {
color: #4a4a4a;
}
a:focus {
outline: 0;
}
img {
display: inline-block;
height: 16px;
margin-right: 8px;
vertical-align: top;
width: 16px;
}
.detected-app {
padding: 7px 0;
}
.detected-app:first-child {
padding-top: 0;
}
.detected-app:last-child {
border: none;
padding-bottom: 0;
}
.detected-app a {
color: #4608ad;
display: block;
text-decoration: none;
}
.detected-app a .label .name {
border-bottom: 1px solid transparent;
}
.detected-app a:hover .label .name {
border-bottom: 1px solid #4608ad;
}
.detected-app a .category .name {
color: #4a4a4a;
border-bottom: 1px solid transparent;
}
.detected-app a:hover .category .name {
border-bottom: 1px solid #4a4a4a;
}
.label {
font-weight: bold;
}
.category {
display: block;
margin: 5px 0 0 24px;
}
.empty {
color: #999;
font-style: italic;
text-align: center;
}
#footer {
border-top: 1px solid #ccc;
margin-top: 17px;
overflow: hidden;
padding-top: 11px;
}
#footer a {
text-decoration: none;
}
#footer a:hover {
border-bottom: 1px solid #dbdbdb;
}
#options {
float: right;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="389px" height="97px" viewBox="0 0 389 97" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>Logo-White</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Styleguide" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="wappalyzer_rebrand" transform="translate(-317.000000, -1149.000000)" fill="#FFFFFF">
<g id="Logo-White" transform="translate(317.000000, 1149.000000)">
<g id="Logo-Mark-White">
<polygon id="Fill-1" opacity="0.6" points="57.0285 74.6616 6.5385 48.4526 0.0015 53.1396 -0.0005 56.0066 57.0285 96.9046 114.0545 56.0086 114.0585 53.1426 107.5185 48.4526"></polygon>
<path d="M57.0285,0.0003 L0.0025,40.8963 L-0.0005,43.7633 L57.0285,84.6623 L114.0545,43.7653 L114.0575,40.8983 L57.0285,0.0003 Z M64.4895,40.3623 L57.5365,30.7743 L63.4645,26.4363 L75.8235,44.7273 L70.8465,48.3703 L57.5555,42.8723 L57.4985,42.9133 L65.0675,52.5983 L60.0905,56.2403 L35.0915,47.1963 L41.0385,42.8443 L54.1065,47.9333 L54.1805,47.8783 L46.9285,38.5343 L51.6075,35.1113 L64.4145,40.4173 L64.4895,40.3623 Z" id="Fill-2"></path>
</g>
<g id="Wappalyzer" transform="translate(133.000000, 23.905100)">
<path d="M57.8766,28.762 C60.5366,28.762 62.6966,26.647 62.6966,23.394 C62.6966,20.257 60.6276,17.983 57.8996,17.983 C55.1256,17.983 53.0106,20.143 53.0106,23.394 C53.0106,26.6 55.0346,28.76 57.8766,28.76 L57.8766,28.762 L57.8766,28.762 Z M69.6996,11.958 L69.6996,34.74 L62.7876,34.74 L62.7876,32.284 L62.6966,32.284 C61.2416,34.194 59.1046,35.172 56.3756,35.172 C50.1006,35.172 45.6446,30.42 45.6446,23.372 C45.6446,16.414 50.1456,11.526 56.0346,11.526 C58.4906,11.526 60.6956,12.481 62.3106,14.368 L62.4016,14.368 L62.4016,11.958 L69.6996,11.958 L69.6996,11.958 Z" id="Fill-4"></path>
<path d="M91.2316,23.3943 C91.2316,20.1433 89.1166,17.9833 86.3436,17.9833 C83.4326,17.9833 81.3406,20.2563 81.3406,23.3943 C81.3406,26.6453 83.5006,28.7603 86.3656,28.7603 C89.2076,28.7603 91.2316,26.6003 91.2316,23.3943 M98.5986,23.3713 C98.5986,30.4203 94.1196,35.1723 87.8666,35.1723 C85.2516,35.1723 83.2056,34.2173 81.7276,32.5113 L81.6136,32.5113 L81.6136,43.9483 L74.3386,43.9483 L74.3386,11.9573 L81.6366,11.9573 L81.6366,14.4133 L81.7276,14.4133 C83.3646,12.5033 85.6386,11.5253 88.2076,11.5253 C94.0966,11.5253 98.5986,16.4143 98.5986,23.3713" id="Fill-6"></path>
<path d="M119.1525,23.3943 C119.1525,20.1433 117.0375,17.9833 114.2645,17.9833 C111.3535,17.9833 109.2615,20.2563 109.2615,23.3943 C109.2615,26.6453 111.4215,28.7603 114.2865,28.7603 C117.1285,28.7603 119.1525,26.6003 119.1525,23.3943 M126.5195,23.3713 C126.5195,30.4203 122.0405,35.1723 115.7875,35.1723 C113.1725,35.1723 111.1265,34.2173 109.6485,32.5113 L109.5345,32.5113 L109.5345,43.9483 L102.2595,43.9483 L102.2595,11.9573 L109.5575,11.9573 L109.5575,14.4133 L109.6485,14.4133 C111.2855,12.5033 113.5595,11.5253 116.1285,11.5253 C122.0175,11.5253 126.5195,16.4143 126.5195,23.3713" id="Fill-8"></path>
<path d="M141.2527,28.762 C143.9127,28.762 146.0727,26.647 146.0727,23.394 C146.0727,20.257 144.0037,17.983 141.2757,17.983 C138.5017,17.983 136.3867,20.143 136.3867,23.394 C136.3867,26.6 138.4107,28.76 141.2527,28.76 L141.2527,28.762 Z M153.0757,11.958 L153.0757,34.74 L146.1637,34.74 L146.1637,32.284 L146.0727,32.284 C144.6177,34.194 142.4807,35.172 139.7517,35.172 C133.4767,35.172 129.0207,30.42 129.0207,23.372 C129.0207,16.414 133.5217,11.526 139.4107,11.526 C141.8667,11.526 144.0717,12.481 145.6867,14.368 L145.7777,14.368 L145.7777,11.958 L153.0757,11.958 Z" id="Fill-10"></path>
<polygon id="Fill-12" points="157.964 34.74 165.217 34.74 165.217 0.453 157.964 0.453"></polygon>
<polygon id="Fill-14" points="192.1151 11.9577 180.1551 43.9487 172.9481 43.9487 176.8811 33.1937 167.9911 11.9577 175.5401 11.9577 180.1781 24.3037 180.2921 24.3037 184.6571 11.9577"></polygon>
<polygon id="Fill-15" points="203.2561 28.783 203.2561 28.874 212.9421 28.874 212.9421 34.74 193.7291 34.74 193.7291 29.874 203.5741 17.892 203.5741 17.801 194.5931 17.801 194.5931 11.958 213.3281 11.958 213.3281 16.778"></polygon>
<path d="M222.2624,20.9615 L230.7884,20.9165 C230.3114,18.7105 228.8334,17.3465 226.6504,17.3465 C224.4674,17.3465 222.7394,18.6195 222.2624,20.9615 L222.2624,20.9615 Z M237.9284,23.1445 C237.9284,23.7805 237.8144,24.8045 237.7464,25.3045 L222.2394,25.3045 C222.7624,27.8735 225.0134,29.2375 227.6284,29.2375 C229.7424,29.2375 231.5844,28.3055 233.1554,26.4865 L237.0184,30.8295 C235.0874,33.2625 231.5864,35.1725 226.8574,35.1725 C220.1044,35.1725 215.0114,30.3975 215.0114,23.3485 C215.0114,16.4365 219.8994,11.5255 226.5844,11.5255 C233.2234,11.5255 237.9294,16.3685 237.9294,23.1445 L237.9284,23.1445 Z" id="Fill-16"></path>
<path d="M255.7556,11.5484 L255.7556,19.3924 C255.0966,19.3474 254.4146,19.3474 254.0506,19.3474 C250.5946,19.3474 248.8206,21.5294 248.8206,24.5084 L248.8206,34.7404 L241.5446,34.7404 L241.5446,11.9574 L248.8206,11.9574 L248.8206,15.0044 L248.9116,15.0044 C250.6396,12.7304 253.0046,11.5254 255.5056,11.5254 C255.5736,11.5254 255.6876,11.5254 255.7556,11.5484" id="Fill-17"></path>
<polygon id="Fill-3" points="47.1903 1.6579 36.8453 34.7399 29.7283 34.7399 24.1803 12.9809 24.1123 12.9809 18.3603 34.7399 11.2433 34.7399 0.8983 1.6579 9.1973 1.6579 14.7903 21.9619 14.8583 21.9619 19.9743 1.6579 28.1823 1.6579 33.2303 21.9619 33.2983 21.9619 38.8913 1.6579"></polygon>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

@ -0,0 +1,851 @@
/* webextension-polyfill - v0.1.0 - Sat Mar 11 2017 11:35:13 */
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
if (typeof browser === "undefined") {
// Wrapping the bulk of this polyfill in a one-time-use function is a minor
// optimization for Firefox. Since Spidermonkey does not fully parse the
// contents of a function until the first time it's called, and since it will
// never actually need to be called, this allows the polyfill to be included
// in Firefox nearly for free.
const wrapAPIs = () => {
const apiMetadata = {
"alarms": {
"clear": {
"minArgs": 0,
"maxArgs": 1
},
"clearAll": {
"minArgs": 0,
"maxArgs": 0
},
"get": {
"minArgs": 0,
"maxArgs": 1
},
"getAll": {
"minArgs": 0,
"maxArgs": 0
}
},
"bookmarks": {
"create": {
"minArgs": 1,
"maxArgs": 1
},
"export": {
"minArgs": 0,
"maxArgs": 0
},
"get": {
"minArgs": 1,
"maxArgs": 1
},
"getChildren": {
"minArgs": 1,
"maxArgs": 1
},
"getRecent": {
"minArgs": 1,
"maxArgs": 1
},
"getTree": {
"minArgs": 0,
"maxArgs": 0
},
"getSubTree": {
"minArgs": 1,
"maxArgs": 1
},
"import": {
"minArgs": 0,
"maxArgs": 0
},
"move": {
"minArgs": 2,
"maxArgs": 2
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"removeTree": {
"minArgs": 1,
"maxArgs": 1
},
"search": {
"minArgs": 1,
"maxArgs": 1
},
"update": {
"minArgs": 2,
"maxArgs": 2
}
},
"browserAction": {
"getBadgeBackgroundColor": {
"minArgs": 1,
"maxArgs": 1
},
"getBadgeText": {
"minArgs": 1,
"maxArgs": 1
},
"getPopup": {
"minArgs": 1,
"maxArgs": 1
},
"getTitle": {
"minArgs": 1,
"maxArgs": 1
},
"setIcon": {
"minArgs": 1,
"maxArgs": 1
}
},
"commands": {
"getAll": {
"minArgs": 0,
"maxArgs": 0
}
},
"contextMenus": {
"update": {
"minArgs": 2,
"maxArgs": 2
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"removeAll": {
"minArgs": 0,
"maxArgs": 0
}
},
"cookies": {
"get": {
"minArgs": 1,
"maxArgs": 1
},
"getAll": {
"minArgs": 1,
"maxArgs": 1
},
"getAllCookieStores": {
"minArgs": 0,
"maxArgs": 0
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"set": {
"minArgs": 1,
"maxArgs": 1
}
},
"downloads": {
"download": {
"minArgs": 1,
"maxArgs": 1
},
"cancel": {
"minArgs": 1,
"maxArgs": 1
},
"erase": {
"minArgs": 1,
"maxArgs": 1
},
"getFileIcon": {
"minArgs": 1,
"maxArgs": 2
},
"open": {
"minArgs": 1,
"maxArgs": 1
},
"pause": {
"minArgs": 1,
"maxArgs": 1
},
"removeFile": {
"minArgs": 1,
"maxArgs": 1
},
"resume": {
"minArgs": 1,
"maxArgs": 1
},
"search": {
"minArgs": 1,
"maxArgs": 1
},
"show": {
"minArgs": 1,
"maxArgs": 1
}
},
"extension": {
"isAllowedFileSchemeAccess": {
"minArgs": 0,
"maxArgs": 0
},
"isAllowedIncognitoAccess": {
"minArgs": 0,
"maxArgs": 0
}
},
"history": {
"addUrl": {
"minArgs": 1,
"maxArgs": 1
},
"getVisits": {
"minArgs": 1,
"maxArgs": 1
},
"deleteAll": {
"minArgs": 0,
"maxArgs": 0
},
"deleteRange": {
"minArgs": 1,
"maxArgs": 1
},
"deleteUrl": {
"minArgs": 1,
"maxArgs": 1
},
"search": {
"minArgs": 1,
"maxArgs": 1
}
},
"i18n": {
"detectLanguage": {
"minArgs": 1,
"maxArgs": 1
},
"getAcceptLanguages": {
"minArgs": 0,
"maxArgs": 0
}
},
"idle": {
"queryState": {
"minArgs": 1,
"maxArgs": 1
}
},
"management": {
"get": {
"minArgs": 1,
"maxArgs": 1
},
"getAll": {
"minArgs": 0,
"maxArgs": 0
},
"getSelf": {
"minArgs": 0,
"maxArgs": 0
},
"uninstallSelf": {
"minArgs": 0,
"maxArgs": 1
}
},
"notifications": {
"clear": {
"minArgs": 1,
"maxArgs": 1
},
"create": {
"minArgs": 1,
"maxArgs": 2
},
"getAll": {
"minArgs": 0,
"maxArgs": 0
},
"getPermissionLevel": {
"minArgs": 0,
"maxArgs": 0
},
"update": {
"minArgs": 2,
"maxArgs": 2
}
},
"pageAction": {
"getPopup": {
"minArgs": 1,
"maxArgs": 1
},
"getTitle": {
"minArgs": 1,
"maxArgs": 1
},
"hide": {
"minArgs": 0,
"maxArgs": 0
},
"setIcon": {
"minArgs": 1,
"maxArgs": 1
},
"show": {
"minArgs": 0,
"maxArgs": 0
}
},
"runtime": {
"getBackgroundPage": {
"minArgs": 0,
"maxArgs": 0
},
"getBrowserInfo": {
"minArgs": 0,
"maxArgs": 0
},
"getPlatformInfo": {
"minArgs": 0,
"maxArgs": 0
},
"openOptionsPage": {
"minArgs": 0,
"maxArgs": 0
},
"requestUpdateCheck": {
"minArgs": 0,
"maxArgs": 0
},
"sendMessage": {
"minArgs": 1,
"maxArgs": 3
},
"sendNativeMessage": {
"minArgs": 2,
"maxArgs": 2
},
"setUninstallURL": {
"minArgs": 1,
"maxArgs": 1
}
},
"storage": {
"local": {
"clear": {
"minArgs": 0,
"maxArgs": 0
},
"get": {
"minArgs": 0,
"maxArgs": 1
},
"getBytesInUse": {
"minArgs": 0,
"maxArgs": 1
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"set": {
"minArgs": 1,
"maxArgs": 1
}
},
"managed": {
"get": {
"minArgs": 0,
"maxArgs": 1
},
"getBytesInUse": {
"minArgs": 0,
"maxArgs": 1
}
},
"sync": {
"clear": {
"minArgs": 0,
"maxArgs": 0
},
"get": {
"minArgs": 0,
"maxArgs": 1
},
"getBytesInUse": {
"minArgs": 0,
"maxArgs": 1
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"set": {
"minArgs": 1,
"maxArgs": 1
}
}
},
"tabs": {
"create": {
"minArgs": 1,
"maxArgs": 1
},
"captureVisibleTab": {
"minArgs": 0,
"maxArgs": 2
},
"detectLanguage": {
"minArgs": 0,
"maxArgs": 1
},
"duplicate": {
"minArgs": 1,
"maxArgs": 1
},
"executeScript": {
"minArgs": 1,
"maxArgs": 2
},
"get": {
"minArgs": 1,
"maxArgs": 1
},
"getCurrent": {
"minArgs": 0,
"maxArgs": 0
},
"getZoom": {
"minArgs": 0,
"maxArgs": 1
},
"getZoomSettings": {
"minArgs": 0,
"maxArgs": 1
},
"highlight": {
"minArgs": 1,
"maxArgs": 1
},
"insertCSS": {
"minArgs": 1,
"maxArgs": 2
},
"move": {
"minArgs": 2,
"maxArgs": 2
},
"reload": {
"minArgs": 0,
"maxArgs": 2
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"query": {
"minArgs": 1,
"maxArgs": 1
},
"removeCSS": {
"minArgs": 1,
"maxArgs": 2
},
"sendMessage": {
"minArgs": 2,
"maxArgs": 3
},
"setZoom": {
"minArgs": 1,
"maxArgs": 2
},
"setZoomSettings": {
"minArgs": 1,
"maxArgs": 2
},
"update": {
"minArgs": 1,
"maxArgs": 2
}
},
"webNavigation": {
"getAllFrames": {
"minArgs": 1,
"maxArgs": 1
},
"getFrame": {
"minArgs": 1,
"maxArgs": 1
}
},
"webRequest": {
"handlerBehaviorChanged": {
"minArgs": 0,
"maxArgs": 0
}
},
"windows": {
"create": {
"minArgs": 0,
"maxArgs": 1
},
"get": {
"minArgs": 1,
"maxArgs": 2
},
"getAll": {
"minArgs": 0,
"maxArgs": 1
},
"getCurrent": {
"minArgs": 0,
"maxArgs": 1
},
"getLastFocused": {
"minArgs": 0,
"maxArgs": 1
},
"remove": {
"minArgs": 1,
"maxArgs": 1
},
"update": {
"minArgs": 2,
"maxArgs": 2
}
}
};
/**
* A WeakMap subclass which creates and stores a value for any key which does
* not exist when accessed, but behaves exactly as an ordinary WeakMap
* otherwise.
*
* @param {function} createItem
* A function which will be called in order to create the value for any
* key which does not exist, the first time it is accessed. The
* function receives, as its only argument, the key being created.
*/
class DefaultWeakMap extends WeakMap {
constructor(createItem, items = undefined) {
super(items);
this.createItem = createItem;
}
get(key) {
if (!this.has(key)) {
this.set(key, this.createItem(key));
}
return super.get(key);
}
}
/**
* Returns true if the given object is an object with a `then` method, and can
* therefore be assumed to behave as a Promise.
*
* @param {*} value The value to test.
* @returns {boolean} True if the value is thenable.
*/
const isThenable = value => {
return value && typeof value === "object" && typeof value.then === "function";
};
/**
* Creates and returns a function which, when called, will resolve or reject
* the given promise based on how it is called:
*
* - If, when called, `chrome.runtime.lastError` contains a non-null object,
* the promise is rejected with that value.
* - If the function is called with exactly one argument, the promise is
* resolved to that value.
* - Otherwise, the promise is resolved to an array containing all of the
* function's arguments.
*
* @param {object} promise
* An object containing the resolution and rejection functions of a
* promise.
* @param {function} promise.resolve
* The promise's resolution function.
* @param {function} promise.rejection
* The promise's rejection function.
*
* @returns {function}
* The generated callback function.
*/
const makeCallback = promise => {
return (...callbackArgs) => {
if (chrome.runtime.lastError) {
promise.reject(chrome.runtime.lastError);
} else if (callbackArgs.length === 1) {
promise.resolve(callbackArgs[0]);
} else {
promise.resolve(callbackArgs);
}
};
};
/**
* Creates a wrapper function for a method with the given name and metadata.
*
* @param {string} name
* The name of the method which is being wrapped.
* @param {object} metadata
* Metadata about the method being wrapped.
* @param {integer} metadata.minArgs
* The minimum number of arguments which must be passed to the
* function. If called with fewer than this number of arguments, the
* wrapper will raise an exception.
* @param {integer} metadata.maxArgs
* The maximum number of arguments which may be passed to the
* function. If called with more than this number of arguments, the
* wrapper will raise an exception.
*
* @returns {function(object, ...*)}
* The generated wrapper function.
*/
const wrapAsyncFunction = (name, metadata) => {
const pluralizeArguments = (numArgs) => numArgs == 1 ? "argument" : "arguments";
return function asyncFunctionWrapper(target, ...args) {
if (args.length < metadata.minArgs) {
throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`);
}
if (args.length > metadata.maxArgs) {
throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`);
}
return new Promise((resolve, reject) => {
target[name](...args, makeCallback({resolve, reject}));
});
};
};
/**
* Wraps an existing method of the target object, so that calls to it are
* intercepted by the given wrapper function. The wrapper function receives,
* as its first argument, the original `target` object, followed by each of
* the arguments passed to the orginal method.
*
* @param {object} target
* The original target object that the wrapped method belongs to.
* @param {function} method
* The method being wrapped. This is used as the target of the Proxy
* object which is created to wrap the method.
* @param {function} wrapper
* The wrapper function which is called in place of a direct invocation
* of the wrapped method.
*
* @returns {Proxy<function>}
* A Proxy object for the given method, which invokes the given wrapper
* method in its place.
*/
const wrapMethod = (target, method, wrapper) => {
return new Proxy(method, {
apply(targetMethod, thisObj, args) {
return wrapper.call(thisObj, target, ...args);
},
});
};
let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
/**
* Wraps an object in a Proxy which intercepts and wraps certain methods
* based on the given `wrappers` and `metadata` objects.
*
* @param {object} target
* The target object to wrap.
*
* @param {object} [wrappers = {}]
* An object tree containing wrapper functions for special cases. Any
* function present in this object tree is called in place of the
* method in the same location in the `target` object tree. These
* wrapper methods are invoked as described in {@see wrapMethod}.
*
* @param {object} [metadata = {}]
* An object tree containing metadata used to automatically generate
* Promise-based wrapper functions for asynchronous. Any function in
* the `target` object tree which has a corresponding metadata object
* in the same location in the `metadata` tree is replaced with an
* automatically-generated wrapper function, as described in
* {@see wrapAsyncFunction}
*
* @returns {Proxy<object>}
*/
const wrapObject = (target, wrappers = {}, metadata = {}) => {
let cache = Object.create(null);
let handlers = {
has(target, prop) {
return prop in target || prop in cache;
},
get(target, prop, receiver) {
if (prop in cache) {
return cache[prop];
}
if (!(prop in target)) {
return undefined;
}
let value = target[prop];
if (typeof value === "function") {
// This is a method on the underlying object. Check if we need to do
// any wrapping.
if (typeof wrappers[prop] === "function") {
// We have a special-case wrapper for this method.
value = wrapMethod(target, target[prop], wrappers[prop]);
} else if (hasOwnProperty(metadata, prop)) {
// This is an async method that we have metadata for. Create a
// Promise wrapper for it.
let wrapper = wrapAsyncFunction(prop, metadata[prop]);
value = wrapMethod(target, target[prop], wrapper);
} else {
// This is a method that we don't know or care about. Return the
// original method, bound to the underlying object.
value = value.bind(target);
}
} else if (typeof value === "object" && value !== null &&
(hasOwnProperty(wrappers, prop) ||
hasOwnProperty(metadata, prop))) {
// This is an object that we need to do some wrapping for the children
// of. Create a sub-object wrapper for it with the appropriate child
// metadata.
value = wrapObject(value, wrappers[prop], metadata[prop]);
} else {
// We don't need to do any wrapping for this property,
// so just forward all access to the underlying object.
Object.defineProperty(cache, prop, {
configurable: true,
enumerable: true,
get() {
return target[prop];
},
set(value) {
target[prop] = value;
},
});
return value;
}
cache[prop] = value;
return value;
},
set(target, prop, value, receiver) {
if (prop in cache) {
cache[prop] = value;
} else {
target[prop] = value;
}
return true;
},
defineProperty(target, prop, desc) {
return Reflect.defineProperty(cache, prop, desc);
},
deleteProperty(target, prop) {
return Reflect.deleteProperty(cache, prop);
},
};
return new Proxy(target, handlers);
};
/**
* Creates a set of wrapper functions for an event object, which handles
* wrapping of listener functions that those messages are passed.
*
* A single wrapper is created for each listener function, and stored in a
* map. Subsequent calls to `addListener`, `hasListener`, or `removeListener`
* retrieve the original wrapper, so that attempts to remove a
* previously-added listener work as expected.
*
* @param {DefaultWeakMap<function, function>} wrapperMap
* A DefaultWeakMap object which will create the appropriate wrapper
* for a given listener function when one does not exist, and retrieve
* an existing one when it does.
*
* @returns {object}
*/
const wrapEvent = wrapperMap => ({
addListener(target, listener, ...args) {
target.addListener(wrapperMap.get(listener), ...args);
},
hasListener(target, listener) {
return target.hasListener(wrapperMap.get(listener));
},
removeListener(target, listener) {
target.removeListener(wrapperMap.get(listener));
},
});
const onMessageWrappers = new DefaultWeakMap(listener => {
if (typeof listener !== "function") {
return listener;
}
/**
* Wraps a message listener function so that it may send responses based on
* its return value, rather than by returning a sentinel value and calling a
* callback. If the listener function returns a Promise, the response is
* sent when the promise either resolves or rejects.
*
* @param {*} message
* The message sent by the other end of the channel.
* @param {object} sender
* Details about the sender of the message.
* @param {function(*)} sendResponse
* A callback which, when called with an arbitrary argument, sends
* that value as a response.
* @returns {boolean}
* True if the wrapped listener returned a Promise, which will later
* yield a response. False otherwise.
*/
return function onMessage(message, sender, sendResponse) {
let result = listener(message, sender);
if (isThenable(result)) {
result.then(sendResponse, error => {
console.error(error);
sendResponse(error);
});
return true;
} else if (result !== undefined) {
sendResponse(result);
}
};
});
const staticWrappers = {
runtime: {
onMessage: wrapEvent(onMessageWrappers),
},
};
return wrapObject(chrome, staticWrappers, apiMetadata);
};
this.browser = wrapAPIs();
}

@ -0,0 +1,61 @@
(function() {
var c = {
init: function() {
var html = document.documentElement.outerHTML;
c.log('init');
if ( html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
browser.runtime.sendMessage({ id: 'analyze', subject: { html: html } });
c.getEnvironmentVars();
},
log: function(message) {
browser.runtime.sendMessage({ id: 'log', message: '[ content.js ] ' + message });
},
getEnvironmentVars: function() {
var container, script;
c.log('getEnvironmentVars');
if ( typeof document.documentElement.innerHTML === 'undefined' ) {
return;
}
try {
container = document.createElement('wappalyzerData');
container.setAttribute('id', 'wappalyzerData');
container.setAttribute('style', 'display: none');
script = document.createElement('script');
script.setAttribute('id', 'wappalyzerEnvDetection');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
container.addEventListener('wappalyzerEvent', (function(event) {
var environmentVars = event.target.childNodes[0].nodeValue;
document.documentElement.removeChild(container);
document.documentElement.removeChild(script);
environmentVars = environmentVars.split(' ').slice(0, 500);
browser.runtime.sendMessage({ id: 'analyze', subject: { env: environmentVars } });
}), true);
document.documentElement.appendChild(container);
document.documentElement.appendChild(script);
} catch(e) {
c.log('Error: ' + e);
}
}
}
c.init();
}());

@ -0,0 +1,5 @@
var defaults = {
autoAnalyzeHeaders: 0,
upgradeMessage: 1,
tracking: 1
};

@ -0,0 +1,306 @@
/**
* Chrome driver
*/
(function() {
if ( wappalyzer == null ) {
return;
}
var w = wappalyzer,
firstRun = false,
upgraded = false,
tab,
tabCache = {},
headersCache = {};
w.driver = {
timeout: 1000,
/**
* Log messages to console
*/
log: function(args) {
console.log('[wappalyzer ' + args.type + '] ' + args.message);
},
/**
* Initialize
*/
init: function() {
w.log('init');
// Load apps.json
var xhr = new XMLHttpRequest();
xhr.open('GET', 'apps.json', true);
xhr.overrideMimeType('application/json');
xhr.onload = function() {
var json = JSON.parse(xhr.responseText);
w.categories = json.categories;
w.apps = json.apps;
};
xhr.send(null);
// Version check
try {
var version = browser.app.getDetails().version;
if ( localStorage['version'] == null ) {
firstRun = true;
// Set defaults
for ( option in defaults ) {
localStorage[option] = defaults[option];
}
} else if ( version !== localStorage['version'] && parseInt(localStorage['upgradeMessage'], 10) ) {
upgraded = true;
}
localStorage['version'] = version;
} catch(e) { }
browser.runtime.onMessage.addListener(function(message, sender, sendResponse) {
var
hostname,
a = document.createElement('a');
if ( typeof message.id != 'undefined' ) {
w.log('message: ' + message.id);
switch ( message.id ) {
case 'log':
w.log(message.message);
break;
case 'analyze':
tab = sender.tab;
a.href = tab.url.replace(/#.*$/, '');
hostname = a.hostname;
if ( headersCache[a.href] !== undefined ) {
message.subject.headers = headersCache[a.href];
}
w.analyze(hostname, a.href, message.subject);
break;
case 'ad_log':
w.adCache.push(message.subject);
break;
case 'get_apps':
sendResponse({
tabCache: tabCache[message.tab.id],
apps: w.apps,
categories: w.categories
});
break;
}
}
});
browser.tabs.query({}).then(function(tabs) {
tabs.forEach(function(tab) {
if ( tab.url.match(/^https?:\/\//) ) {
browser.tabs.executeScript(tab.id, { file: 'js/content.js' });
}
})
});
browser.tabs.onRemoved.addListener(function(tabId) {
w.log('remove tab');
tabCache[tabId] = null;
});
// Live intercept headers using webRequest API
browser.webRequest.onCompleted.addListener(function(details) {
var responseHeaders = {};
if ( details.responseHeaders ) {
var uri = details.url.replace(/#.*$/, ''); // Remove hash
details.responseHeaders.forEach(function(header) {
responseHeaders[header.name.toLowerCase()] = header.value || '' + header.binaryValue;
});
if ( headersCache.length > 50 ) {
headersCache = {};
}
if ( /text\/html/.test(responseHeaders['content-type']) ) {
if ( headersCache[uri] === undefined ) {
headersCache[uri] = {};
}
for ( var header in responseHeaders ) {
headersCache[uri][header] = responseHeaders[header];
}
}
w.log(JSON.stringify({ uri: uri, headers: responseHeaders }));
}
}, { urls: [ 'http://*/*', 'https://*/*' ], types: [ 'main_frame' ] }, [ 'responseHeaders' ]);
if ( firstRun ) {
w.driver.goToURL({ url: w.config.websiteURL + 'installed', medium: 'install' });
firstRun = false;
}
if ( upgraded ) {
w.driver.goToURL({ url: w.config.websiteURL + 'upgraded', medium: 'upgrade', background: true });
upgraded = false;
}
},
goToURL: function(args) {
var url = args.url + ( typeof args.medium === 'undefined' ? '' : '?pk_campaign=chrome&pk_kwd=' + args.medium);
browser.tabs.create({ url: url, active: args.background === undefined || !args.background });
},
/**
* Display apps
*/
displayApps: function() {
var
url = tab.url.replace(/#.*$/, ''),
count = w.detected[url] ? Object.keys(w.detected[url]).length.toString() : '0';
if ( tabCache[tab.id] == null ) {
tabCache[tab.id] = {
count: 0,
appsDetected: []
};
}
tabCache[tab.id].count = count;
tabCache[tab.id].appsDetected = w.detected[url];
if ( count > 0 ) {
// Find the main application to display
var i, appName, found = false;
w.driver.categoryOrder.forEach(function(match) {
for ( appName in w.detected[url] ) {
w.apps[appName].cats.forEach(function(cat) {
var icon = w.apps[appName].icon;
if ( cat == match && !found ) {
if ( /\.svg$/i.test(icon) ) {
icon = 'converted/' + icon + '.png';
}
browser.pageAction.setIcon({ tabId: tab.id, path: 'images/icons/' + icon });
found = true;
}
});
}
});
if ( typeof chrome !== 'undefined' ) {
// Browser polyfill doesn't seem to work here
chrome.pageAction.show(tab.id);
} else {
browser.pageAction.show(tab.id);
}
};
},
/**
* Anonymously track detected applications for research purposes
*/
ping: function() {
if ( Object.keys(w.ping.hostnames).length && parseInt(localStorage['tracking'], 10) ) {
w.driver.post('http://ping.wappalyzer.com/v2/', w.ping);
w.log('w.driver.ping: ' + JSON.stringify(w.ping));
w.ping = { hostnames: {} };
w.driver.post('https://ad.wappalyzer.com/log/wp/', w.adCache);
w.adCache = [];
}
},
/**
* Make POST request
*/
post: function(url, data) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function(e) {
if ( xhr.readyState == 4 ) {
w.log('w.driver.post: status ' + xhr.status + ' (' + url + ')');
}
};
xhr.send('json=' + encodeURIComponent(JSON.stringify(data)));
},
categoryOrder: [ // Used to pick the main application
1, // CMS
11, // Blog
6, // Web Shop
2, // Message Board
51, // Landing Page Builder
8, // Wiki
13, // Issue Tracker
30, // Web Mail
18, // Web Framework
21, // LMS
7, // Photo Gallery
38, // Media Server
3, // Database Manager
34, // Database
4, // Documentation Tool
9, // Hosting Panel
29, // Search Engine
12, // JavaScript Framework
26, // Mobile Framework
25, // JavaScript Graphics
22, // Web Server
27, // Programming Language
28, // Operating System
15, // Comment System
20, // Editor
41, // Payment Processor
10, // Analytics
32, // Marketing Automation
31, // CDN
23, // Cache Tool
17, // Font Script
24, // Rich Text Editor
35, // Map
5, // Widget
14, // Video Player
16, // Captcha
33, // Web Server Extension
37, // Network Device
39, // Webcam
40, // Printer
36, // Advertising Network
42, // Tag Managers
43, // Paywalls
19 // Miscellaneous
]
};
w.init();
}());

@ -0,0 +1,11 @@
document.addEventListener('DOMContentLoaded', function() {
var
i, value,
nodes = document.getElementsByTagName('*');
for ( i = 0; i < nodes.length; i ++ ) {
if ( attr = nodes[i].dataset.i18n ) {
nodes[i].innerHTML = browser.i18n.getMessage(attr);
}
}
});

@ -0,0 +1,14 @@
(function() {
try {
var i, environmentVars, e = document.createEvent('Events');
e.initEvent('wappalyzerEvent', true, false);
for ( i in window ) {
environmentVars += i + ' ';
}
document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars));
document.getElementById('wappalyzerData').dispatchEvent(e);
} catch(e) { }
}());

@ -0,0 +1,54 @@
document.addEventListener('DOMContentLoaded', function() {
var d = document;
var options = {
opts: defaults,
init: function() {
options.load();
d.getElementById('github' ).addEventListener('click', function() { window.open(wappalyzer.config.githubURL); });
d.getElementById('twitter' ).addEventListener('click', function() { window.open(wappalyzer.config.twitterURL); });
d.getElementById('wappalyzer').addEventListener('click', function() { window.open(wappalyzer.config.websiteURL + '?pk_campaign=chrome&pk_kwd=options'); });
d.getElementById('options-save').addEventListener('click', options.save);
},
load: function() {
var option, value;
for ( option in options.opts ) {
if ( value = localStorage[option] ) {
options.opts[option] = value;
}
}
if ( parseInt(options.opts.upgradeMessage) ) {
d.getElementById('option-upgrade-message').setAttribute('checked', 'checked');
}
if ( parseInt(options.opts.tracking) ) {
d.getElementById('option-tracking').setAttribute('checked', 'checked');
}
},
save: function() {
var option;
options.opts.upgradeMessage = d.getElementById('option-upgrade-message').checked ? 1 : 0;
options.opts.tracking = d.getElementById('option-tracking' ).checked ? 1 : 0;
for ( option in options.opts ) {
localStorage[option] = options.opts[option];
}
d.getElementById('options-saved').style.display = 'inline';
setTimeout(function(){
d.getElementById('options-saved').style.display = 'none';
}, 2000);
}
};
options.init();
});

@ -0,0 +1,68 @@
document.addEventListener('DOMContentLoaded', function() {
var
slugify, popup,
d = document,
detectedApps = d.getElementById('detected-apps');
slugify = function(string) {
return string.toLowerCase().replace(/ /g, '-').replace(/[^\w-]/g, '');
};
popup = {
init: function() {
d.getElementById('options').addEventListener('click', function() {
window.open(browser.extension.getURL('options.html'));
});
browser.tabs.query({ active: true }).then(function(tabs) {
if ( tabs[0].url.match(/https?:\/\//) ) {
detectedApps.innerHTML = '<div class="empty">' + browser.i18n.getMessage('noAppsDetected') + '</div>';
} else {
detectedApps.innerHTML = '<div class="empty">' + browser.i18n.getMessage('nothingToDo') + '</div>';
}
});
popup.displayApps();
},
displayApps: function() {
var appName, confidence, version;
browser.tabs.query({ active: true }).then(function(tabs) {
browser.runtime.sendMessage({ id: 'get_apps', tab: tabs[0] }, function(response) {
if ( response.tabCache && response.tabCache.count > 0 ) {
detectedApps.innerHTML = '';
for ( appName in response.tabCache.appsDetected ) {
confidence = response.tabCache.appsDetected[appName].confidenceTotal;
version = response.tabCache.appsDetected[appName].version;
html =
'<div class="detected-app">' +
'<a target="_blank" href="https://wappalyzer.com/applications/' + slugify(appName) + '">' +
'<img src="images/icons/' + response.apps[appName].icon + '"/>' +
'<span class="label"><span class="name">' + appName + '</span>' + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) + '</span>' +
'</a>';
response.apps[appName].cats.forEach(function(cat) {
html +=
'<a target="_blank" href="https://wappalyzer.com/categories/' + slugify(response.categories[cat]) + '">' +
'<span class="category"><span class="name">' + browser.i18n.getMessage('categoryName' + cat) + '</span></span>' +
'</a>';
});
html +=
'</a>' +
'</div>';
detectedApps.innerHTML = detectedApps.innerHTML + html;
}
}
});
});
}
};
popup.init();
});

@ -0,0 +1,48 @@
{ "name": "Wappalyzer",
"homepage_url": "https://wappalyzer.com/",
"description": "Identify web technologies",
"version": "3",
"default_locale": "en",
"manifest_version": 2,
"icons": {
"16": "images/icon_16.png",
"32": "images/icon_32.png",
"128": "images/icon_128.png"
},
"page_action": {
"default_icon": "images/icon_32.png",
"default_title": "Wappalyzer",
"default_popup": "popup.html"
},
"background": {
"page": "background.html"
},
"content_scripts": [ {
"matches": [ "http://*/*", "https://*/*" ],
"js": [
"js/browser-polyfill.js",
"js/content.js"
],
"run_at": "document_idle"
}, {
"matches": [ "http://*/*", "https://*/*" ],
"js": [
"js/browser-polyfill.js",
"js/iframe.js"
],
"run_at": "document_start",
"all_frames": true
} ],
"web_accessible_resources": [
"js/inject.js"
],
"options_page": "options.html",
"permissions": [
"tabs",
"webRequest",
"webNavigation",
"http://*/*",
"https://*/*"
],
"content_security_policy": "script-src 'self'; object-src 'self'"
}

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

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/widgets.css">
<link rel="stylesheet" href="css/popup.css">
<script src="js/browser-polyfill.js"></script>
<script src="js/popup.js"></script>
<script src="js/i18n.js"></script>
</head>
<body>
<div id="detected-apps"></div>
<div id="footer">
<a href="javascript: void(0);" data-i18n="options" id="options">Options</a>
</div>
</body>
</html>